- error:无法从“AVCodecParameters ”转换为“AVCodecContext ”
从提示来看,需要使用AVStream.codecpar代替AVStream.codec,前者的类型是AVCodecParameters,后者的类型是AVCodecContext。事实上,AVCodecContext结构体仍然是编解码时不可或缺的结构体。换言之,AVCodecContext结构体的重要成员仍然需要设置,才能使用(特别是编码),比如bit_rate。
之所以使用AVStream.codec,是因为解码时很容易获得源视频的一些基本信息。
const char *filename = "a.mp4";AVFormatContext fmt_ctx = nullptr;avformat_open_input(&fmt_ctx, filename, nullptr, nullptr);//打开一个视频avformat_find_stream_info(fmt_ctx, nullptr);//读取视频,然后得到流和码率等信息for(size_t i = 0; i < fmt_ctx->nb_streams; ++i){AVStream *stream = m_fmt_ctx->streams[i];AVCodecContext *codec_ctx = stream->codec;//此时就可以通过stream和codec_ctx的结构体成员获取流的绝大部分信息,相当方便}
上面的代码十分简洁,又能获取大部分流相关的信息。编码时直接从源视频的AVCodecContext中复制成员值,并作简单的修改即可。
但是,无论是编解码,使用AVCodecParameters的代码都相当简洁。
解码
const char *filename = "a.mp4";AVFormatContext fmt_ctx = nullptr;avformat_open_input(&fmt_ctx, filename, nullptr, nullptr);//打开一个视频avformat_find_stream_info(fmt_ctx, nullptr);//读取视频,然后得到流和码率等信息for(size_t i = 0; i < fmt_ctx->nb_streams; ++i){AVStream *stream = fmt_ctx->streams[i];AVCodec *codec = avcodec_find_decoder(stream->codecpar->codec_id);AVCodecContext *codec_ctx = avcodec_alloc_context3(codec);//需要使用avcodec_free_context释放//事实上codecpar包含了大部分解码器相关的信息,这里是直接从AVCodecParameters复制到AVCodecContextavcodec_parameters_to_context(codec_ctx, stream->codecpar);av_codec_set_pkt_timebase(codec_ctx, stream->time_base);avcodec_open2(codec_ctx, codec, nullptr);}
视频的帧率,应该从AVStream结构的avg_frame_rate成员获取,而非AVCodecContext结构体。如果avg_frame_rate为{0, 1},那么再尝试从r_frame_rate成员获取。
- error:av_codec_set_pkt_timebase声明已被否决
编码
编码时,需要分配一个AVCodecContext,然后为成员变量设置适当的值,最后将设置值复制到AVCodecParameters。
const char *filename = "b.mp4";AVFormatContext *fmt_ctx = nullptr;avformat_alloc_output_context2(&fmt_ctx, nullptr, nullptr, filename); //需要调用avformat_free_context释放//new一个流并挂到fmt_ctx名下,调用avformat_free_context时会释放该流AVStream *stream = avformat_new_stream(fmt_ctx, nullptr);AVCodec *codec = avcodec_find_encoder(fmt_ctx->oformat->video_codec);//音频为audio_codecAVCodecContext *codec_ctx = avcodec_alloc_context3(codec);codec_ctx->video_type = AVMEDIA_TYPE_VIDEO;codec_ctx->codec_id = m_fmt_ctx->oformat->video_codec;codec_ctx->width = 1280;//你想要的宽度codec_ctx->height = 720;//你想要的高度codec_ctx->format = AV_PIX_FMT_YUV420P;//受codec->pix_fmts数组限制codec_ctx->gop_size = 12;codec_ctx->time_base = AVRational{1, 25};//应该根据帧率设置codec_ctx->bit_rate = 1400 * 1000;avcodec_open2(codec_ctx, codec, nullptr);//将AVCodecContext的成员复制到AVCodecParameters结构体。前后两行不能调换顺序avcodec_parameters_from_context(stream->codecpar, codec_ctx);av_stream_set_r_frame_rate(stream, {1, 25});
来自
https://blog.csdn.net/luotuo44/article/details/54981809?utm_source=blogxgwz4
