美文网首页
FFmpeg 像素格式转换和尺寸转换

FFmpeg 像素格式转换和尺寸转换

作者: 遇见猫的大鱼 | 来源:发表于2018-08-03 19:17 被阅读268次

    Demo

    FFmpeg 可以实现像素格式转换和尺寸转换,但是性能开销非常大,对视频帧率影响比较大,实际开发中最好用 Shader来实现,FFmpeg的优势转换接口比较简单。

    像素格式转换上下文 SwsContext

    (1)sws_getContext
    (2)sws_getCachedContext(
    struct SwsContext *context,
    int srcW, int srcH, 原宽高
    enum AVPixelFormat srcFormat,原像素格式
    int dstW, int dstH, 目标宽高
    enum AVPixelFormat dstFormat,目标格式
    int flags, 算法标签(性能差异 效果差异 针对尺寸变化)
    SwsFilter *srcFilter,过滤器
    SwsFilter *dstFilter,过滤器
    const double *param 算法中默认值的设定 可以默认);
    两个函数的差别是第一个参数:SwsContext
    sws_getContext 会创建一个上下文空间,sws_getCachedContext会去缓冲中找,前后两次参数没变时返回同一个

    //每一帧数据的处理
    int sws_scale(struct SwsContext *c,
    const uint8_t *const srcSlice[],具体数据的数组
    const int srcStride[],一行数据的大小
    int srcSliceY, 传0
    int srcSliceH, 图形高度
    uint8_t *const dst[], 目标的地址(指针数组)
    const int dstStride[]) 输出的一行数据的大小;

    void sws_freeContext(struct SwsContext *swsContext);//是否

         for (; ; ) {//保证能搜到全部的解码数据
                re = avcodec_receive_frame(cc, frame);
                if (re != 0) {
                    break;
                }
                if (cc == vc) {
                    frameCount++;
                    vctx = sws_getCachedContext(vctx, frame->width, frame->height, (AVPixelFormat)frame->format, outWidth, outHeight, AV_PIX_FMT_RGBA, SWS_FAST_BILINEAR, 0, 0, 0);
                    if (!vctx) {
                        NSLog(@"sws_getCachedContext failed!");
    
                    }else{
                        uint8_t *data[AV_NUM_DATA_POINTERS] = {0};
                        data[0] = (uint8_t *)rgb;
                        int lines[AV_NUM_DATA_POINTERS] = {0};
                        lines[0] = outWidth * 4;
                        int h = sws_scale(vctx, frame->data, frame->linesize, 0, frame->height
                                          , data, lines);
                        NSLog(@"sws_scale h :%d ",h);
                    }
                }
    
            }
            //最后一针的时候 avcodec_send_packet(cc, NULL)
            av_packet_unref(pkt);
    
    2018-08-03 19:16:54.397601+0800 FFmpeg402[611:176423] sws_scale h :720
    2018-08-03 19:16:54.409398+0800 FFmpeg402[611:176423] sws_scale h :720
    2018-08-03 19:16:54.417052+0800 FFmpeg402[611:176423] sws_scale h :720
    2018-08-03 19:16:54.425106+0800 FFmpeg402[611:176423] sws_scale h :720
    2018-08-03 19:16:54.440420+0800 FFmpeg402[611:176423] sws_scale h :720
    2018-08-03 19:16:54.448448+0800 FFmpeg402[611:176423] sws_scale h :720
    2018-08-03 19:16:54.457397+0800 FFmpeg402[611:176423] sws_scale h :720
    2018-08-03 19:16:54.465670+0800 FFmpeg402[611:176423] sws_scale h :720
    2018-08-03 19:16:54.473706+0800 FFmpeg402[611:176423] sws_scale h :720
    2018-08-03 19:16:54.481495+0800 FFmpeg402[611:176423] sws_scale h :720
    2018-08-03 19:16:54.489395+0800 FFmpeg402[611:176423] sws_scale h :720
    2018-08-03 19:16:54.497006+0800 FFmpeg402[611:176423] sws_scale h :720
    2018-08-03 19:16:54.504962+0800 FFmpeg402[611:176423] sws_scale h :720
    2018-08-03 19:16:54.512761+0800 FFmpeg402[611:176423] sws_scale h :720
    2018-08-03 19:16:54.520280+0800 FFmpeg402[611:176423] sws_scale h :720
    2018-08-03 19:16:54.528375+0800 FFmpeg402[611:176423] sws_scale h :720
    2018-08-03 19:16:54.543610+0800 FFmpeg402[611:176423] sws_scale h :720
    2018-08-03 19:16:54.551972+0800 FFmpeg402[611:176423] sws_scale h :720
    2018-08-03 19:16:54.559866+0800 FFmpeg402[611:176423] sws_scale h :720
    

    音频冲采样 SwrContext

    一般音频解码出来直播不能直接播放,需要经过冲采样

    SwrContext *swr_alloc(void); 上下文

    SwrContext *swr_alloc_set_opts(设置参数
    struct SwrContext *s,
    int64_t out_ch_layout,输出layout
    AVSampleFormat out_sample_fmt,输出的样本格式
    int out_sample_rate,输出样本率
    int64_t in_ch_layout,输入layout
    AVSampleFormat in_sample_fmt,输入的样本格式
    int in_sample_rate, 输入样本率
    int log_offset, 0
    void *log_ctx);日志 0

    int swr_init(struct SwrContext *s); 初始化

    void swr_free(struct SwrContext **s);释放

    转换函数swr_convert 对每一帧音频做重采样

    • int swr_convert(struct SwrContext *s,
    uint8_t **out,输出的数组
    int out_count,样本的数量 单通道
    • const uint8_t **in , 输入参数指针数组
    int in_count);

       //音频重采样上下文初始化
        SwrContext *actx = swr_alloc();
        //设置参数
        actx = swr_alloc_set_opts(actx,
                                  av_get_default_channel_layout(2),//2
                                  AV_SAMPLE_FMT_S16,
                                  ac->sample_rate,
                                  av_get_default_channel_layout(ac->channels),
                                  ac->sample_fmt,
                                  ac->sample_rate,
                                  0,
                                  0);
        re = swr_init(actx);
        if (re != 0) {
            NSLog(@"swr_init failed!");
        }else{
            NSLog(@"swr_init success!");
        }
    
             uint8_t *outData[2] = {0};
                    outData[0]  = (uint8_t *)pcm;
                    //重采样
                    int len = swr_convert(actx,//上下文
                                          outData,
                                          frame->nb_samples,
                                          (const uint8_t **)frame->data,
                                          frame->nb_samples);
            
                   NSLog(@"swr_convert len :%d ",len);
                    
    
    2018-08-03 19:45:47.054517+0800 FFmpeg402[630:182386] swr_convert len :1024
    2018-08-03 19:45:47.054560+0800 FFmpeg402[630:182386] swr_convert len :1024
    2018-08-03 19:45:47.066537+0800 FFmpeg402[630:182386] swr_convert len :1024
    2018-08-03 19:45:47.066658+0800 FFmpeg402[630:182386] swr_convert len :1024
    2018-08-03 19:45:47.066744+0800 FFmpeg402[630:182386] swr_convert len :1024
    2018-08-03 19:45:47.066872+0800 FFmpeg402[630:182386] swr_convert len :1024
    2018-08-03 19:45:47.066932+0800 FFmpeg402[630:182386] swr_convert len :1024
    2018-08-03 19:45:47.066977+0800 FFmpeg402[630:182386] swr_convert len :1024
    

    打完收工

    相关文章

      网友评论

          本文标题:FFmpeg 像素格式转换和尺寸转换

          本文链接:https://www.haomeiwen.com/subject/xgjyvftx.html