1

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?

Community
  • 1
  • 1
Micka
  • 19,585
  • 4
  • 56
  • 74
  • 1
    What is the value of nres when avcodec_decode_video2 returns? – biskitt Aug 22 '14 at 07:46
  • 1
    @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 Aug 22 '14 at 09:08

1 Answers1

2

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

techbull
  • 118
  • 2
  • 16
biskitt
  • 1,381
  • 1
  • 10
  • 13
  • 1
    thx alot. I get a frame on calling with empty package after the previous call. What kind of format does this frame have? I assumed YUV 24 Bit per Pixel, but there are only vertical lines on the image. I'll try to collect more packets first now. – Micka Aug 22 '14 at 09:54
  • 2
    Your format is in `m_pFrame->format`. Possible values are there https://www.ffmpeg.org/doxygen/trunk/pixfmt_8h.html#a9a8e335cf3be472042bc9f0cf80cd4c5. It often is YUV420P, which is a planar format (one full size buffer for Y, two smaller buffers for U and V). – biskitt Aug 22 '14 at 10:06
  • 1
    I am facing same issue but decoding again with empty packet is not solving my problem. But if I give it next packet after reading data from stream, then it decodes 0 bytes but gives framefinished as 1. – techbull Dec 14 '16 at 14:50