用AVCodecParameters代替AVCodecContext

高版本FFmpeg中,使用AVStream.codec会报弃用警告,提示用AVStream.codecpar代替。可将AVCodecContext结构体成员值复制到AVCodecParameters。文中给出了修改后的代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用AVCodecParameters代替AVCodecContext

高版本的FFmpeg 如下代码会报 “warning: ‘AVStream::codec’ is deprecated” “Using AVStream.codec … deprecated, use AVStream.codecpar instead”,说明 AVStream.codec这个已经被遗弃,可以使用 AVStream.codecpar 代替就行,网上查到 使用avcodec_parameters_from_context()可以将AVCodecContext 结构体成员值复制到 AVCodecParameters

static AVStream * add_video_stream(AVFormatContext *oc, int codec_id, int w, int h, int fps)   
{   
    AVCodecContext *c = 0;   
    AVStream *st = 0;   

	st = avformat_new_stream(oc, 0);
    if (!st) 
	{   
        log_print(LOG_ERR, "Could not alloc stream\n");   
        return NULL;   
    }   
   
    c = st->codec;   
    c->codec_id = (AVCodecID)codec_id;   
    c->codec_type = AVMEDIA_TYPE_VIDEO;
   
    /* put sample parameters */   
    c->bit_rate = (int) (w * h * fps * 8);  

	c->qblur = 0.5f;

    /* resolution must be a multiple of two */   
    c->width = w;   
    c->height = h; 
    
	c->time_base.num = 1;    
    c->time_base.den = fps;

    c->gop_size = 60; /* emit one intra frame every twelve frames at most */   
    c->pix_fmt = AV_PIX_FMT_YUV420P;     

    if (oc->oformat->flags & AVFMT_GLOBALHEADER) 
    {
        c->flags |= CODEC_FLAG_GLOBAL_HEADER;		
    }

    if (0 == c->sample_aspect_ratio.num)
    {
        c->sample_aspect_ratio.num = c->sample_aspect_ratio.den;
    }
    
 	st->sample_aspect_ratio.num = c->sample_aspect_ratio.num;
    st->sample_aspect_ratio.den = c->sample_aspect_ratio.den;
    
    return st;   
}   

修改后的代码如下所示:

//[用AVCodecParameters代替AVCodecContext](https://blog.youkuaiyun.com/luotuo44/article/details/54981809)
static AVStream * add_video_stream(AVFormatContext *oc, int codec_id, int w, int h, int fps)   
{   
    AVCodecContext codec_ctx;
    AVCodecParameters *cp = 0;
    AVStream *st = 0;   

	st = avformat_new_stream(oc, 0);
    if (!st) 
	{   
        log_print(LOG_ERR, "Could not alloc stream\n");   
        return NULL;   
    }   
   
//    c = st->codec;
    cp = st->codecpar;
    codec_ctx.codec_id = (AVCodecID)codec_id;
    codec_ctx.codec_type = AVMEDIA_TYPE_VIDEO;
   
    /* put sample parameters */   
    codec_ctx.bit_rate = (int) (w * h * fps * 8);

    codec_ctx.qblur = 0.5f;

    /* resolution must be a multiple of two */   
    codec_ctx.width = w;
    codec_ctx.height = h;
    
    codec_ctx.time_base.num = 1;
    codec_ctx.time_base.den = fps;
    st->time_base.num = 1;
    st->time_base.den = fps;

    codec_ctx.gop_size = 60; /* emit one intra frame every twelve frames at most */
    codec_ctx.pix_fmt = AV_PIX_FMT_YUV420P;

    if (oc->oformat->flags & AVFMT_GLOBALHEADER) 
    {
        codec_ctx.flags |= CODEC_FLAG_GLOBAL_HEADER;
    }

    if (0 == codec_ctx.sample_aspect_ratio.num)
    {
        codec_ctx.sample_aspect_ratio.num = codec_ctx.sample_aspect_ratio.den;
    }
    
    st->sample_aspect_ratio.num = codec_ctx.sample_aspect_ratio.num;
    st->sample_aspect_ratio.den = codec_ctx.sample_aspect_ratio.den;

    avcodec_parameters_from_context(cp, &codec_ctx);
    
    return st;   
}
home/gc/Pangolin/src/video/drivers/ffmpeg.cpp:41:41: error: ‘AV_PIX_FMT_VDPAU_MPEG4’ was not declared in this scope; did you mean ‘AV_PIX_FMT_VDPAU’? 41 | # define TEST_PIX_FMT_RETURN(fmt) case AV_PIX_FMT_##fmt: return #fmt; | ^~~~~~~~~~~ /home/gc/Pangolin/src/video/drivers/ffmpeg.cpp:41:41: note: in definition of macro ‘TEST_PIX_FMT_RETURN’ 41 | # define TEST_PIX_FMT_RETURN(fmt) case AV_PIX_FMT_##fmt: return #fmt; | ^~~~~~~~~~~ /home/gc/Pangolin/src/video/drivers/ffmpeg.cpp: In member function ‘void pangolin::FfmpegVideo::InitUrl(std::string, std::string, std::string, bool, int)’: /home/gc/Pangolin/src/video/drivers/ffmpeg.cpp:148:21: warning: ‘void av_register_all()’ is deprecated [-Wdeprecated-declarations] 148 | av_register_all(); | ^ In file included from /home/gc/Pangolin/include/pangolin/video/drivers/ffmpeg.h:43, from /home/gc/Pangolin/src/video/drivers/ffmpeg.cpp:28: /usr/local/include/libavformat/avformat.h:2050:6: note: declared here 2050 | void av_register_all(void); | ^~~~~~~~~~~~~~~ /home/gc/Pangolin/src/video/drivers/ffmpeg.cpp:148:21: warning: ‘void av_register_all()’ is deprecated [-Wdeprecated-declarations] 148 | av_register_all(); | ^ In file included from /home/gc/Pangolin/include/pangolin/video/drivers/ffmpeg.h:43, from /home/gc/Pangolin/src/video/drivers/ffmpeg.cpp:28: /usr/local/include/libavformat/avformat.h:2050:6: note: declared here 2050 | void av_register_all(void); | ^~~~~~~~~~~~~~~ /home/gc/Pangolin/src/video/drivers/ffmpeg.cpp:199:36: warning: ‘AVStream::codecis deprecated [-Wdeprecated-declarations] 199 | if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) | ^~~~~ In file included from /home/gc/Pangolin/include/pangolin/video/drivers/ffmpeg.h:43, from /home/gc/Pangolin/src/video/drivers/ffmpeg.cpp:28: /usr/local/include/libavformat/avformat.h:880:21: note: declared here 880 | AVCodecContext *codec; | ^~~~~ /home/gc/Pangolin/src/video/drivers/ffmpeg.cpp:199:36: warning: ‘AVStream::codecis deprecated [-Wdeprecated-declarations] 199 | if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) | ^~~~~ In file included from /home/gc/Pangolin/include/pangolin/video/drivers/ffmpeg.h:43, from /home/gc/Pangolin/src/video/drivers/ffmpeg.cpp:28: /usr/local/include/libavformat/avformat.h:880:21: note: declared here
03-29
### AVCodecContextFFmpeg 中的使用与配置 #### 1. AVCodecContext 的定义与作用 `AVCodecContext` 是 FFmpeg 中一个关键结构体,用于存储编解码器的相关参数和状态信息[^1]。它定义了编解码过程中所需的各种选项和配置,包括但不限于帧率、分辨率、比特率等。该结构体的定义位于 `libavcodec/avcodec.h` 文件中。 ```c typedef struct AVCodecContext { ... int bit_rate; // 编码器的目标比特率 int width, height; // 视频分辨率 AVRational time_base; // 时间基准 enum AVPixelFormat pix_fmt; // 像素格式 ... } AVCodecContext; ``` #### 2. 初始化 AVCodecContext 初始化 `AVCodecContext` 可以通过函数 `avcodec_alloc_context3` 完成。此函数会分配内存并设置默认值,返回一个填充了默认值的 `AVCodecContext` 指针[^3]。 ```c AVCodecContext *ctx = avcodec_alloc_context3(codec); if (!ctx) { // 错误处理 } ``` 如果需要为特定的编解码器分配上下文,则可以将对应的 `AVCodec` 结构体作为参数传递给 `avcodec_alloc_context3` 函数。 #### 3. 配置 AVCodecContext 配置 `AVCodecContext` 时,可以通过直接设置其成员变量来完成。例如,设置视频编码器的分辨率和比特率: ```c ctx->width = 1920; ctx->height = 1080; ctx->bit_rate = 4000000; // 4 Mbps ctx->time_base = (AVRational){1, 25}; // 25 fps ctx->pix_fmt = AV_PIX_FMT_YUV420P; ``` 此外,还可以通过 `av_opt_set` 和 `av_opt_set_int` 等函数动态设置选项[^1]。这些函数允许用户在运行时调整编解码器的行为。 ```c av_opt_set(ctx->priv_data, "preset", "fast", 0); av_opt_set_int(ctx->priv_data, "tune", AV_CODEC_TUNE_FAST_DECODE, 0); ``` #### 4. 打开编解码器 配置完成后,调用 `avcodec_open2` 函数打开编解码器,并将配置应用到实际的编解码过程中。 ```c int ret = avcodec_open2(ctx, codec, NULL); if (ret < 0) { // 错误处理 } ``` #### 5. 使用 AVCodecContext 进行编解码 一旦编解码器被成功打开,就可以通过 `avcodec_send_frame` 和 `avcodec_receive_packet`(对于编码)或 `avcodec_send_packet` 和 `avcodec_receive_frame`(对于解码)进行数据处理。 ```c // 编码示例 AVFrame *frame = allocate_frame(); AVPacket *pkt = av_packet_alloc(); ret = avcodec_send_frame(ctx, frame); if (ret < 0) { // 错误处理 } ret = avcodec_receive_packet(ctx, pkt); if (ret < 0) { // 错误处理 } ``` #### 6. 释放资源 当编解码过程结束时,需要释放分配的资源,包括 `AVCodecContext` 和相关对象。 ```c avcodec_free_context(&ctx); av_frame_free(&frame); av_packet_free(&pkt); ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值