关于ffmpeg的avcodec_init()问题

本文探讨了FFmpeg中avcodec_init函数的使用,在0.8版本及之前的情况,以及在更高版本中如何替换为avformat_open_input进行操作。

关于ffmpeg的avcodec_init()问题 

0.8(含)有avcodec_init()

以上版本改为:avformat_open_input()

在 Qt 5.15.2 中使用 FFmpeg 的 `avcodec_decode_video2` 函数进行视频解码,通常需要先完成 FFmpeg 库的集成,并确保其头文件和动态库路径已正确配置到 Qt 项目中。以下是一个完整的示例流程,涵盖初始化解码器、读取视频帧并解码的基本步骤。 ### 初始化 FFmpeg 和打开视频文件 首先,需要注册所有编解码器并打开输入文件或流: ```cpp #include <libavformat/avformat.h> #include <libavcodec/avcodec.h> #include <libavutil/imgutils.h> int main(int argc, char *argv[]) { AVFormatContext* format_ctx = nullptr; int video_stream_index = -1; // 注册所有格式和编解码器 avformat_network_init(); if (avformat_open_input(&format_ctx, "your_video_file.mp4", nullptr, nullptr) != 0) { // 打开输入失败 return -1; } if (avformat_find_stream_info(format_ctx, nullptr) < 0) { // 获取流信息失败 return -1; } // 查找视频流 for (int i = 0; i < format_ctx->nb_streams; ++i) { if (format_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { video_stream_index = i; break; } } if (video_stream_index == -1) { // 没有找到视频流 return -1; } AVCodecParameters* codec_params = format_ctx->streams[video_stream_index]->codecpar; const AVCodec* codec = avcodec_find_decoder(codec_params->codec_id); if (!codec) { // 找不到对应的解码器 return -1; } AVCodecContext* codec_ctx = avcodec_alloc_context3(codec); if (!codec_ctx) { // 分配解码器上下文失败 return -1; } if (avcodec_parameters_to_context(codec_ctx, codec_params) < 0) { // 设置解码器上下文参数失败 return -1; } if (avcodec_open2(codec_ctx, codec, nullptr) < 0) { // 打开解码器失败 return -1; } AVPacket* packet = av_packet_alloc(); AVFrame* frame = av_frame_alloc(); AVFrame* rgb_frame = av_frame_alloc(); int num_bytes = av_image_get_buffer_size(AV_PIX_FMT_RGB24, codec_ctx->width, codec_ctx->height, 1); uint8_t* buffer = (uint8_t*)av_malloc(num_bytes * sizeof(uint8_t)); av_image_fill_arrays(rgb_frame->data, rgb_frame->linesize, buffer, AV_PIX_FMT_RGB24, codec_ctx->width, codec_ctx->height, 1); struct SwsContext* sws_ctx = sws_getContext(codec_ctx->width, codec_ctx->height, codec_ctx->pix_fmt, codec_ctx->width, codec_ctx->height, AV_PIX_FMT_RGB24, SWS_BILINEAR, nullptr, nullptr, nullptr); while (av_read_frame(format_ctx, packet) >= 0) { if (packet->stream_index == video_stream_index) { int ret = avcodec_send_packet(codec_ctx, packet); while (ret >= 0) { ret = avcodec_receive_frame(codec_ctx, frame); if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { break; } else if (ret < 0) { // 解码错误 break; } // 转换为 RGB 格式 sws_scale(sws_ctx, frame->data, frame->linesize, 0, codec_ctx->height, rgb_frame->data, rgb_frame->linesize); // 在这里可以将 rgb_frame 数据用于显示,例如通过 QImage 或 OpenGL 等方式 } } av_packet_unref(packet); } // 清理资源 avcodec_free_context(&codec_ctx); avformat_close_input(&format_ctx); av_frame_free(&frame); av_frame_free(&rgb_frame); av_free(buffer); sws_freeContext(sws_ctx); av_packet_free(&packet); return 0; } ``` ### 项目配置建议 在 `.pro` 文件中添加 FFmpeg 相关的库路径和链接选项: ```qmake INCLUDEPATH += /path/to/ffmpeg/include LIBS += -L/path/to/ffmpeg/lib \ -lavformat \ -lavcodec \ -lavutil \ -lswscale ``` 确保路径替换为实际的 FFmpeg 安装目录。 ### 注意事项 - `avcodec_decode_video2` 是较旧的 API,在 FFmpeg 3.1 及以后版本中已被弃用,推荐使用 `avcodec_send_packet` 和 `avcodec_receive_frame` 的新式 API [^2]。 - 如果你使用的是较新的 FFmpeg 版本(如 4.x 或以上),请确保代码与当前版本兼容,可能需要调整部分函数调用。 - Qt 5.15.2 本身不提供任何 FFmpeg 集成功能,因此必须手动链接外部库 [^3]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值