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