ffmpeg升级后解码器崩溃

时间:2012-12-03 17:57:45

标签: ffmpeg libavcodec

最近我将ffmpeg从0.9升级到1.0(在Win7x64和iOS上测试),现在avcodec_decode_video2 seagfaults。长话短说:每次视频尺寸发生变化时都会发生崩溃(例如,从320x240到160x120,反之亦然)。

我从某些专有来源接收mpeg4视频流,并按如下方式对其进行解码:

// once, during initialization:
AVCodec *codec_ = avcodec_find_decoder(CODEC_ID_MPEG4);
AVCodecContext ctx_ = avcodec_alloc_context3(codec_);
avcodec_open2(ctx_, codec_, 0);
AVPacket packet_;
av_init_packet(&packet_);
AVFrame picture_ = avcodec_alloc_frame();

// on every frame:
int got_picture;
packet_.size = size;
packet_.data = (uint8_t *)buffer;
avcodec_decode_video2(ctx_, picture_, &got_picture, &packet_);

同样,以上所有内容都完美运行,直到我升级到1.0。现在,每当帧尺寸发生变化时,avcodec_decode_video2就会崩溃。请注意,我没有在AVCodecContext中指定宽度/高度 - 既不在开头,也不在流改变时 - 是否可能是原因?

我很感激任何想法!

更新:设置ctx_.width和ctx_.height无济于事。

在崩溃之前

Update2:我收到以下日志消息:

  

mpeg4,等级24:“找到2个未发布的缓冲区!”。   等级8:“断言i< avci-> buffer_count在libavcodec / utils.c:603失败”

Update3 升级到1.1.2修复了这次崩溃。解码器能够再次应对尺寸变化。

2 个答案:

答案 0 :(得分:3)

您可以尝试填写AVPacket::side_data。如果更改帧大小,编解码器将从中接收信息(请参阅libavcodec/utils.c apply_param_change function

此结构可按如下方式填写:

int my_ff_add_param_change(AVPacket *pkt, int32_t width, int32_t height)
{
    uint32_t flags = 0;
    int size = 4 * 3;
    uint8_t *data;
    if (!pkt)
        return AVERROR(EINVAL);

    flags = AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS;
    data = av_packet_new_side_data(pkt, AV_PKT_DATA_PARAM_CHANGE, size);

    if (!data)
        return AVERROR(ENOMEM);

    ((uint32_t*)data)[0] = flags;
    ((uint32_t*)data)[1] = width;
    ((uint32_t*)data)[2] = height;
    return 0;
}

每次尺寸变化时都需要调用此函数。

我认为这个功能最近出现了。直到我看到新的ffmpeg来源,我才知道它。

<强> UPD

在编写时,解决问题的最简单方法是执行编解码器重启。只需致电avcodec_close / avcodec_open2

即可

答案 1 :(得分:0)

当我的框架在运行中改变大小时,我遇到了同样的问题。但是,调用avcodec_close / avcodec_open2是超级的。更简洁的方法是在调用avcodec_decode_video2之前重置AVPacket数据结构。这是代码:

av_init_packet(&packet_)

这里的关键是此方法将AVPacket的所有值重置为默认值。查看docs了解详情。