温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

FFmpeg avcodec_parameters_to_context函数剖析

发布时间:2020-07-16 07:07:13 来源:网络 阅读:11140 作者:fengyuzaitu 栏目:编程语言

历史说明
            以往FFmpeg版本中保存视音频流信息参数是AVStream结构体中的AVCodecContext字段。当前FFmpeg版本是3.4,新的版本已经将AVStream结构体中的AVCodecContext字段定义为废弃属性。因此无法像以前旧的版本直接通过如下的代码获取到AVCodecContext结构体参数:
AVCodecContext* pAVCodecContext = avcodec_alloc_context3(NULL);
pAVCodecContext = pAVFormatContext->streams[videoStream]->codec;
    当前版本保存视音频流信息的结构体AVCodecParameters,FFmpeg提供了函数avcodec_parameters_to_context将音频流信息拷贝到新的AVCodecContext结构体中

函数说明
    将AVCodecParameters结构体中码流参数拷贝到AVCodecContext结构体中,并且重新拷贝一份extradata内容,涉及到的视频的关键参数有format, width, height, codec_type等,这些参数在优化avformat_find_stream_info函数的时候,手动指定该参数通过InitDecoder函数解码统一指定H264,分辨率是1920*1080

调用avformat_open_input打开网络流后,下一步调用av_find_stream_info从网络流中读取视音频流的信息,通过调试查看AVCodecParameters结构体的视频参数
int avcodec_parameters_to_context(AVCodecContext *codec,
                                  const AVCodecParameters *par)
{
    codec->codec_type = par->codec_type;//AVMEDIA_TYPE_VIDEO
    codec->codec_id   = par->codec_id;//AV_CODEC_ID_H264
    codec->codec_tag  = par->codec_tag;//0

    codec->bit_rate              = par->bit_rate;//0
    codec->bits_per_coded_sample = par->bits_per_coded_sample;//0
    codec->bits_per_raw_sample   = par->bits_per_raw_sample;//8
    codec->profile               = par->profile;//66
    codec->level                 = par->level;//42

    switch (par->codec_type) {
    case AVMEDIA_TYPE_VIDEO:
        codec->pix_fmt                = par->format;//12
        codec->width                  = par->width;//1920
        codec->height                 = par->height;//1080
        codec->field_order            = par->field_order;//AV_FIELD_PROGRESSIVE
        codec->color_range            = par->color_range;//AVCOL_RANGE_JPEG
        codec->color_primaries        = par->color_primaries;//AVCOL_PRI_BT709
        codec->color_trc              = par->color_trc;//AVCOL_TRC_BT709
        codec->colorspace             = par->color_space;//AVCOL_SPC_BT709
        codec->chroma_sample_location = par->chroma_location;//AVCHROMA_LOC_LEFT
        codec->sample_aspect_ratio    = par->sample_aspect_ratio;//num=0,den=1
        codec->has_b_frames           = par->video_delay;//0
        break;
    case AVMEDIA_TYPE_AUDIO:
        codec->sample_fmt       = par->format;
        codec->channel_layout   = par->channel_layout;
        codec->channels         = par->channels;
        codec->sample_rate      = par->sample_rate;
        codec->block_align      = par->block_align;
        codec->frame_size       = par->frame_size;
        codec->delay            =
        codec->initial_padding  = par->initial_padding;
        codec->trailing_padding = par->trailing_padding;
        codec->seek_preroll     = par->seek_preroll;
        break;
    case AVMEDIA_TYPE_SUBTITLE:
        codec->width  = par->width;
        codec->height = par->height;
        break;
    }

    //extradata保存SPS/PPS信息,重新拷贝一份到AVCodecContext中,用于解码
    if (par->extradata) {
        av_freep(&codec->extradata);
        codec->extradata = av_mallocz(par->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
        if (!codec->extradata)
            return AVERROR(ENOMEM);
        memcpy(codec->extradata, par->extradata, par->extradata_size);
        codec->extradata_size = par->extradata_size;
    }

    return 0;
}


代码定义
typedef struct AVStream
{
#if FF_API_LAVF_AVCTX
    
/**
     
* @deprecated use the codecpar struct instead
     
*/
    
attribute_deprecated
    AVCodecContext *codec;

#endif    
}

说明:
当手动指定编码格式的时候,说明探测码流格式的代码是可以省略的,例如
avformat_open_input
avformat_find_stream_info
在其他章节中调用InitDecoder函数替换上面的函数

avformat_open_input缺省情况下,无法播放图像,这个目前还在研究当中

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI