1
votes

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?

1
What is the value of nres when avcodec_decode_video2 returns?biskitt
@biskitt nres = 18331 which equals mDataSize. avcodec_open2 returns 0. Do I have to specify my image resolution somewhere? Codec Options? In most examples they use av_read_frame to fill the packet, but that's not applicable here, right?Micka

1 Answers

2
votes

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_video2with 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