
代码是使用 ffmpeg 捕获 10 秒 rtsp 流,平台是 windows ,IDE 使用 visual studio 。代码是让 chatgpt 写的 demo,执行到avcodec_receive_frame时,报错如下。

ffmpeg 使用的编译版本:ffmpeg-6.0-full_build-shared.7z
c++代码:
#include <iostream> #include <chrono> extern "C" { #include <libavformat/avformat.h> #include <libavcodec/avcodec.h> } int main(int argc, char *argv[]) { std::string url = "rtsp://example.com/stream"; int duration = 10; // 获取 10 秒视频 av_register_all(); AVFormatContext *format_ctx = nullptr; AVCodecContext *codec_ctx = nullptr; AVPacket packet = { 0 }; AVFrame *frame = nullptr; // 打开 RTSP 流并读取视频流信息 if (avformat_open_input(&format_ctx, url.c_str(), nullptr, nullptr) < 0) { std::cerr << "Error: Could not open input file: " << url << std::endl; return -1; } if (avformat_find_stream_info(format_ctx, nullptr) < 0) { std::cerr << "Error: Could not find stream information" << std::endl; return -1; } // 查找视频流索引 int video_stream_index = av_find_best_stream(format_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0); if (video_stream_index < 0) { std::cerr << "Error: Could not find video stream in input file" << std::endl; return -1; } // 根据视频流索引获取视频解码器上下文 codec_ctx = avcodec_alloc_context3(nullptr); if (!codec_ctx) { std::cerr << "Error: Could not allocate video codec context" << std::endl; return -1; } if (avcodec_parameters_to_context(codec_ctx, format_ctx->streams[video_stream_index]->codecpar) < 0) { std::cerr << "Error: Could not initialize video codec parameters" << std::endl; return -1; } AVCodec *codec = avcodec_find_decoder(codec_ctx->codec_id); if (!codec) { std::cerr << "Error: Could not find video codec" << std::endl; return -1; } if (avcodec_open2(codec_ctx, codec, nullptr) < 0) { std::cerr << "Error: Could not open video codec" << std::endl; return -1; } // 分配视频帧内存 frame = av_frame_alloc(); if (!frame) { std::cerr << "Error: Could not allocate video frame" << std::endl; return -1; } // 读取视频帧直到达到指定的时长 int64_t start_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count(); while (true) { if (av_read_frame(format_ctx, &packet) >= 0) { if (packet.stream_index == video_stream_index) { int ret = avcodec_send_packet(codec_ctx, &packet); if (ret < 0) { std::cerr << "Error: Could not send packet to video codec" << std::endl; break; } while (ret >= 0) { ret = avcodec_receive_frame(codec_ctx, frame); if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { break; } else if (ret < 0) { std::cerr << "Error: Could not receive frame from video codec" << std::endl; break; } int64_t now = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count(); if (now - start_time >= duration * 1000) { // 达到指定时长,退出循环 break; } // 处理视频帧,例如保存到文件或显示到屏幕上 // ... av_frame_unref(frame); } av_packet_unref(&packet); } } else { break; } } // 清理资源 avcodec_free_context(&codec_ctx); avformat_close_input(&format_ctx); av_frame_free(&frame); return 0; } 环境搭建后,成功执行了官方源码doc/examples中的remux.c示例。 正在学习 c++,对于这个报错实在是没有头绪。
原因找到了,在官方文档中有说明,使用AVFrame必须先调用av_frame_alloc()为它分配内存,而chatgpt给的demo中只定义了一个空指针。

1 newmlp 2023-05-17 17:48:43 +08:00 C0000005 异常就是内存访问异常,一般就是空指针和野指针 |
3 loken2020 2023-05-17 19:31:04 +08:00 我写过一本书《 FFmpeg 原理》,希望对你有帮助。 ffmpeg.xianwaizhiyin.net |