求助, ffmpeg 符号文件报错

348 天前
 lingeo

代码是使用 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++,对于这个报错实在是没有头绪。

692 次点击
所在节点    程序员
4 条回复
newmlp
348 天前
C0000005 异常就是内存访问异常,一般就是空指针和野指针
lingeo
348 天前
@newmlp C++才写没多久,这方面的经验不足,今天学到了。
loken2020
348 天前
我写过一本书《 FFmpeg 原理》,希望对你有帮助。
ffmpeg.xianwaizhiyin.net
lingeo
348 天前
@loken2020 万分感谢!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/940741

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX