【问题标题】:Decode compressed frame to memory using LibAV: avcodec_decode_video2?使用 LibAV 将压缩帧解码到内存:avcodec_decode_video2?
【发布时间】:2014-10-15 09:16:54
【问题描述】:

我对 libAV 完全陌生。

我有一个来自其他地方的视频帧(它在内存中,而不是在文件中)。应该是 H.264 编码的关键帧。

我正在尝试使用avcodec_decode_video2 进行解码,这是否适合我的需求?

我在使用这段代码时遇到了问题(基本上取自FFmpeg decode raw buffer with avcodec_decode_video2):

AVCodecContext  *m_pCodecCtx;
AVCodec         *m_pCodec;
AVFrame         *m_pFrame;

m_pCodec= avcodec_find_decoder(CODEC_ID_H264);
m_pCodecCtx = avcodec_alloc_context3(m_pCodec);
avcodec_open2(m_pCodecCtx,m_pCodec,0);

// since avcodec_alloc_frame() isn't existing anymore, I changed to following:
//m_pFrame=m_fc.avcodec_alloc_frame(); // and what is/was m_fc?!?
m_pFrame = av_frame_alloc();


AVPacket        packet;
av_init_packet(&packet);

packet.data = (unsigned char*)mData;
packet.size=(int)mDataSize;

// this is for decoding a keyframe?
packet.flags |= AV_PKT_FLAG_KEY;

int framefinished=0;
int nres=avcodec_decode_video2(m_pCodecCtx,m_pFrame,&framefinished,&packet);

if(framefinished)
{
    std::cout << "decoded frame" << std::endl
}

不幸的是 framefinished 总是返回 0 而 nres 是 18331 等于 mDataSize

我的错在哪里? 我必须更清楚地指定编解码器信息吗? 我的数据包是否损坏或不完整? 我使用了错误的 libAV 函数吗?

在我正在使用的框架的示例代码中,图像数据使用av_interleaved_write_frame(和AvFormatContext)成功地流式传输到一个文件中。这可以帮助我配置我的数据包或编解码器吗?

【问题讨论】:

  • avcodec_decode_video2返回时nres的值是多少?
  • @biskitt nres = 18331 等于 mDataSizeavcodec_open2 返回 0。我必须在某处指定我的图像分辨率吗?编解码器选项?在大多数示例中,他们使用av_read_frame 来填充数据包,但这不适用于这里,对吧?

标签: c++ video ffmpeg decode libav


【解决方案1】:

nres 为正数,等于mDataSize 表示一切正常,您的解码已使用此数据包完成。 framefinished == 0 只表示没有写入帧。

可能是因为你的帧数据在几个包之间共享,所以你需要用下面的包调用avcodec_decode_video2,直到你有一个完整的帧。

另一种可能的解释:您的编解码器在输入和输出之间存在延迟:它在第一次调用时没有给您任何信息,并且需要最后一次调用空包来获取最后一帧。你需要做的是调用类似的东西

AVPacket emptyPacket;
av_init_packet(&emptyPacket);
emptyPacket.data = NULL;
emptyPacket.size = 0;
emptyPacket.stream_index = packet.stream_index;
nres=avcodec_decode_video2(m_pCodecCtx,m_pFrame,&framefinished,&emptyPacket);

查看CODEC_CAP_DELAYhere上的注释

【讨论】:

  • 非常感谢。在上一次通话后,我得到一个空包调用的框架。这个框架有什么样的格式?我假设 YUV 24 Bit per Pixel,但图像上只有垂直线。我现在先尝试收集更多数据包。
  • 您的格式为m_pFrame-&gt;format。可能的值有ffmpeg.org/doxygen/trunk/…。它通常是 YUV420P,它是一种平面格式(一个完整大小的缓冲区用于 Y,两个较小的缓冲区用于 U 和 V)。
  • 我面临同样的问题,但用空包再次解码并不能解决我的问题。但是,如果我在从流中读取数据后给它下一个数据包,那么它会解码 0 个字节但将帧完成为 1。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-30
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-30
  • 2011-08-30
相关资源
最近更新 更多