Avcodec_open分段错误

avcodec_open segmentation fault

本文关键字:错误 分段 open Avcodec      更新时间:2023-10-16

下午好,

我得到了ffmpeg的api-example.c的副本(https://www.ffmpeg.org/doxygen/0.6/api-example_8c-source.html)。我测试了函数video_encode_example(),并获得了预期的代码工作。

然后我将这个函数重构为不同的类方法,现在我在调用avcodev_open()时得到了一个seg错误。然后,我更改了代码,从类方法调用原始的video_encode_example(),并调用avcodec…是成功的。

似乎从函数调用时(例如video_encode_example()),行为是预期的,但avcodev_open从类方法调用时失败。我跟踪了代码,在这两种情况下,avcodev_open()参数的值都被分配(和类似)指针值。CGDB报告avcodev_open2()发生seg故障

有什么建议吗?该代码是在Ubuntu 12.04 64位机器上编译和测试的,使用通过apt-get (libavcodec.so.53.35.0)获得的libav包

问候,丹尼尔

在第一个回复后添加注释:

从上面的链接中,我复制了函数video_encode_example(),并将调用放置在一个类构造函数中。这部分起作用了。

VideoEncoder::VideoEncoder( const std::string& aFileName)
    : mCodec( NULL)
    , mCodecContext( NULL)
    , picture (NULL)
    , mFileName( aFileName)
    , mFileHandler( NULL)
{
    // must be called before using avcodec lib
    ::avcodec_init();
    // register all the codecs
    ::avcodec_register_all();
    video_encode_example( aFileName.c_str());
    return;
    ...
}
重构的部分包括将avcodev调用(从原始的video_encode_example()函数)拆分为不同的VideoEncoder方法。构造函数现在看起来像:
VideoEncoder::VideoEncoder( const std::string& aFileName)
    : mCodec( NULL)
    , mCodecContext( NULL)
    , picture (NULL)
    , mFileName( aFileName)
    , mFileHandler( NULL)
{
    // must be called before using avcodec lib
    ::avcodec_init();
    // register all the codecs
    ::avcodec_register_all();
    // find the mpeg1 video encoder
    mCodec = ::avcodec_find_encoder( CODEC_ID_MPEG1VIDEO);
    if (!mCodec) {
        fprintf( stderr, "codec not foundn");
        exit( 1);
    }
    mCodecContext = ::avcodec_alloc_context3( mCodec);
    picture = ::avcodec_alloc_frame();
    // put sample parameters
    mCodecContext->bit_rate = 400000;
    // frames per second
    mCodecContext->time_base = (AVRational){1,25};
    mCodecContext->gop_size = 10;               // emit one intra frame every ten frames
    mCodecContext->max_b_frames = 1;
    mCodecContext->pix_fmt = PIX_FMT_YUV420P;
    // open it
    // Initializes the AVCodecContext to use the given AVCodec. Prior to using this function the context has to be allocated.
    if (::avcodec_open( mCodecContext, mCodec) < 0) {
        fprintf(stderr, "could not open codecn");
        exit( 1);
    }
    mFileHandler = fopen( mFileName.c_str(), "wb");
    if (!mFileHandler) {
        fprintf( stderr, "could not open %sn", mFileName.c_str());
        exit( 1);
    }
}

调用avcodec_open导致segfault。另外,是否使用avcodev_..或:avcodev_……

您的代码没有设置mCodecContext.width/.height成员,这将导致随后的崩溃。

Ubuntu 12.04附带了ffmpeg分支libav的0.8版本,这与ffmpeg 1.0+甚至更高的ffmpeg版本IIRC更加兼容。我假设您正在使用那个存储库版本,并且在测试期间使用了libav-0.8.12(尽管我个人非常喜欢真实的 ffmpeg,目前是ffmpeg-2.2)。

有趣的是,使用ffmpeg-2.2(使用av_codec_open2)而不是libav-0.8不会崩溃,而是通常返回失败并打印关于宽度和高度未设置的警告(ffmpeg而不是libav的另一个支持点)。