Decode compressed frame to memory using LibAV: avcodec
I am completely new to libAV.
I have a single video frame coming from somewhere else (it's in memory, not in a file). It should be H.264 encoded keyframe.
I'm trying to decode with avcodec_decode_video2
is that the right function for my needs?
I'm encountering a problem using this code (basically taken from 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
}
unfortunately framefinished
always returns 0 while nres
is 18331 which equals mDataSize
Where's my fault? Do I have to specify codec information more clearly? Is my packet broken or incomplete? Am I using the wrong libAV function?
In the sample code of the framework I'm using, the image data is succesfully streamed to a file, using av_interleaved_write_frame
(and a AvFormatContext
). Can this help me configuring my packet or the codec?
With nres
being positive, and equal to mDataSize
means that everything is ok, your decoding is done with this packet. framefinished == 0
only means that the frame was not written.
It may be because your frame data is shared between several packets, so you need to call avcodec_decode_video2
with the following packets, until you have a full frame.
Another possible explanation: your codec have a delay between input and output: it gives you nothing on the first call, and need a last call with an empty packet to get the last frame. What you need to do is call something like
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);
See the note on CODEC_CAP_DELAY
here
上一篇: 解码H264帧错误