<p class="">May I ask you a question regarding h264 decoding with
libavcodec?</p>
<p class=""> I’m working on a launch animation for our application. The animation is a h264 mp4 file. I’m not very familiar with video
decoding, I started by following this tutorial:</p><p class=""></p>
<p class=""> <a href="http://blog.tomaka17.com/2012/03/libavcodeclibavformat-tutorial/">http://blog.tomaka17.com/2012/03/libavcodeclibavformat-tutorial/</a></p><p class=""></p>
<p class=""> </p>
<p class="">I verified the tutorial can work fine on other video
formats, for example mpeg, but can’t work on h264.</p>
<p class=""> The reason is that a call to this function:</p><p class=""></p>
<p class=""> const auto
processedLength = avcodec_decode_video2(avCodecContext, avFrame,
&isFrameAvailable, &packetToSend);</p>
<p class=""> if
(processedLength < 0) {</p>
<p class="">
av_free_packet(&packet);</p>
<p class="">
qDebug() << "Error while processing the data";</p>
<p class="">
exit(0);</p>
<p class=""> }</p>
<p class=""> Always returns -1. libav prints an error "no frame!" or "nal is a large number".</p><p class=""></p>
<p class="">I know that there could be missing nal header that I need to tell the decoder. But I couldn't find any articles about how to do it.</p><p class="">I’m stuck here.<br></p><p class=""></p>
<p class="">Thank you,<br></p><p class=""></p>
<p class=""> <br></p>
<p class="">This is my code:</p>
<p class=""> </p>
<p class=""> avcodec_init();</p>
<p class="">
av_register_all();</p>
<p class="">
av_log_set_callback(my_log_callback);</p>
<p class="">
av_log_set_level(AV_LOG_DEBUG);</p>
<p class=""> AVFormatContext
*formatContext = avformat_alloc_context();</p>
<p class=""> </p>
<p class=""> if
(av_open_input_file(&formatContext, "C:\\ani.mp4", NULL, NULL,
NULL) != 0)</p>
<p class=""> {</p>
<p class=""> qDebug()
<< "can't open animation";</p>
<p class=""> }</p>
<p class=""> </p>
<p class=""> if
(av_find_stream_info(formatContext) < 0)</p>
<p class=""> {</p>
<p class=""> qDebug()
<< "can't find stream info";</p>
<p class=""> }</p>
<p class=""> </p>
<p class=""> AVStream*
videoStream;</p>
<p class=""> for (unsigned
int i = 0; i < formatContext->nb_streams; ++i)</p>
<p class=""> {</p>
<p class=""> AVStream
*stream = formatContext->streams[i];
// pointer to a structure about the stream</p>
<p class=""> AVMediaType
codecType = stream->codec->codec_type;
// the type of data in this stream, notable values are
AVMEDIA_TYPE_VIDEO and AVMEDIA_TYPE_AUDIO</p>
<p class=""> CodecID
codecID = stream->codec->codec_id; // identifier for the codec</p>
<p class=""> </p>
<p class=""> qDebug()
<<"media type"<< codecType << "codec_id:"
<< codecID;</p>
<p class=""> if
(codecType == AVMEDIA_TYPE_VIDEO)</p>
<p class=""> {</p>
<p class="">
videoStream = stream;</p>
<p class=""> }</p>
<p class=""> }</p>
<p class=""> </p>
<p class=""> AVCodec *codec
= avcodec_find_decoder(videoStream->codec->codec_id);</p>
<p class=""> if (codec ==
NULL)</p>
<p class=""> {</p>
<p class=""> qDebug()
<< "can't create codec";</p>
<p class=""> }</p>
<p class=""> </p>
<p class=""> AVCodecContext
*avCodecContext = avcodec_alloc_context2(videoStream->codec->codec_type);</p>
<p class=""> </p>
<p class="">
avCodecContext->width = 1920;</p>
<p class="">
avCodecContext->height = 1080;</p>
<p class=""> //avCodecContext->flags2
|= CODEC_FLAG2_FAST;</p>
<p class="">
avCodecContext->pix_fmt =
(enum PixelFormat)29;</p>
<p class=""> </p>
<p class=""> if
(avcodec_open(avCodecContext,codec ) < 0)</p>
<p class=""> {</p>
<p class=""> qDebug()
<< "can't open animation file";</p>
<p class=""> }</p>
<p class=""> </p>
<p class=""> </p>
<p class=""> qDebug()
<< "codec width:" << avCodecContext->width <<
"height:" << avCodecContext->height
<<avCodecContext->pix_fmt ;</p>
<p class=""> </p>
<p class=""> AVFrame *
avFrame =avcodec_alloc_frame();</p>
<p class=""> </p>
<p class=""> if (avFrame ==
NULL)</p>
<p class=""> {</p>
<p class=""> qDebug()
<< "can't allocation avFrame";</p>
<p class=""> </p>
<p class=""> }</p>
<p class=""> </p>
<p class="">
avcodec_get_frame_defaults(avFrame);</p>
<p class=""> </p>
<p class=""> // the current
packet of data</p>
<p class=""> AVPacket
packet;</p>
<p class="">
av_init_packet(&packet);</p>
<p class=""> packet.size =
0;</p>
<p class=""> // data in the
packet of data already processed</p>
<p class=""> size_t
offsetInData = 0;</p>
<p class=""> </p>
<p class=""> // the decoding
loop, running until EOF</p>
<p class=""> while (true)</p>
<p class=""> {</p>
<p class=""> // reading a packet using libavformat</p>
<p class=""> if
(offsetInData >= packet.size)</p>
<p class=""> {</p>
<p class="">
av_free_packet(&packet);</p>
<p class=""> while
(true)</p>
<p class=""> {</p>
<p class=""> if
(av_read_frame(formatContext, &packet) < 0)</p>
<p class=""> {</p>
<p class=""> qDebug() <<
"EOF";</p>
<p class="">
goto finished;</p>
<p class=""> }</p>
<p class=""> if
(packet.stream_index == videoStream->index)</p>
<p class="">
break;</p>
<p class="">
av_free_packet(&packet);</p>
<p class=""> }</p>
<p class=""> }</p>
<p class=""> </p>
<p class=""> qDebug()
<< "packet" << packet.size;</p>
<p class=""> </p>
<p class=""> //
preparing the packet that we will send to libavcodec</p>
<p class=""> AVPacket
packetToSend;</p>
<p class="">
packetToSend.data = packet.data + offsetInData;</p>
<p class="">
packetToSend.size = packet.size - offsetInData;</p>
<p class=""> </p>
<p class=""> // sending data to libavcodec</p>
<p class=""> int
isFrameAvailable = 0;</p>
<p class=""> const auto
processedLength = avcodec_decode_video2(avCodecContext, avFrame,
&isFrameAvailable, &packetToSend);</p>
<p class=""> if
(processedLength < 0) {</p>
<p class="">
av_free_packet(&packet);</p>
<p class="">
qDebug() << "Error while processing the data";</p>
<p class="">
exit(0);</p>
<p class=""> }</p>
<p class=""> qDebug()
<< "processed Length:" << processedLength;</p>
<p class=""> </p>
<p class="">
offsetInData += processedLength;</p>
<p class=""> </p>
<p class=""> //
processing the image if available</p>
<p class=""> if (isFrameAvailable)
{</p>
<p class="">
qDebug() << "one frame is ready!";</p>
<p class=""> }</p>
<p class=""> </p>
<p class=""> }</p>
<p class=""> </p>
<p class="">finished:</p>