FFMPEG - avcodec_decode_video2 返回“无效的帧尺寸 0x0”

use*_*612 7 ffmpeg video-streaming

我正在尝试使用 ffmpeg/doc/example/decoding__encoding_8c-source.html 在 ANDROID 上构建一个简单的 FFMPEG MPEG2 视频 PES 解码器。

我正在使用 FFMPEG 2.0 版!

我使用以下代码初始化 ffmpeg 系统:

int VideoPlayer::_setupFFmpeg()
{
    int rc;
    AVCodec *codec;

    av_register_all();
    codec = avcodec_find_decoder(AV_CODEC_ID_MPEG2VIDEO);
    if(NULL == codec){
        LOGE("_setupFFmpeg. No codec!");
        return -1;
    }
    LOGI("found: %p. name: %s", codec, codec->name);

    _video_dec_ctx = avcodec_alloc_context3(codec);
    if(NULL == _video_dec_ctx){
        LOGE("_setupFFmpeg. Could not allocate codec context space!");
        return -1;
    }
    _video_dec_ctx->debug = FF_DEBUG_PICT_INFO;
    if(codec->capabilities & CODEC_CAP_TRUNCATED) _video_dec_ctx->flags |= CODEC_FLAG_TRUNCATED;

    rc = avcodec_open2(_video_dec_ctx, codec, NULL);
    if(rc < 0) {
        LOGE("_setupFFmpeg. Could not open the codec: %s!", _video_dec_ctx->codec->name);
        return -1;
    }

    av_init_packet(&_avpkt);

    if(NULL == _video_frame) _video_frame = avcodec_alloc_frame();
    if(NULL == _video_frame){
        LOGE("_setupFFmpeg. Could not allocate memory for the video frame!");
        return -1;
    }

    LOGI("_setupFFmpeg(exit)");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

然后只是有一个循环,在调用此函数的解码器处连续发送 PES 数据包:

int VideoPlayer::_playVideoPacket(PesPacket *packet)
{
    int len, frameReady;
    _avpkt.data = packet->buf;
    _avpkt.size = packet->info.bufferSize;
    while(_avpkt.size){
        len = avcodec_decode_video2(_video_dec_ctx, _video_frame, &frameReady, &_avpkt);
        if(len < 0){
            LOGE("FFW_decodeVideo");
            return len;
        }
        if(frameReady){
            //Draw the picture...
        }
        _avpkt.size -= len;
        _avpkt.data += len;
    }
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

但是当我运行代码时,我得到:调用 avcodec_decode_video2() 后来自 FFMPEG 的“无效帧尺寸 0x0”错误。

看来我没有正确设置编解码器。mpeg12dec.c 中 Mpeg1Context 中的 MpegEncContext 设置不正确。我该怎么做才能正确设置 MpegEncContext?

sza*_*ary 2

根据您的变量名称判断,您正在将 pes 数据包传递到decode_video 中。这是错误的。您必须传入原始 ES 数据包(无 pes 标头)。最简单的方法是使用 avformat 和 av_read_frame() 为您填充 AVPacket。如果您使用自己的格式解复用器,则必须深入到 Raw ES 层。您可能还需要设置 PTS DTS 值。

注意:我不太了解 mpeg2,但某些编解码器还要求您在编解码器上下文中配置额外数据值。