[Libav-user] unable to decode h264 video within mp4

Shi Yan billconan at gmail.com
Wed Dec 5 23:52:56 CET 2012


May I ask you a question regarding h264 decoding with libavcodec?

 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:

 http://blog.tomaka17.com/2012/03/libavcodeclibavformat-tutorial/



I verified the tutorial can work fine on other video formats, for example
mpeg, but can’t work on h264.

 The reason is that a call to this function:

        const auto processedLength = avcodec_decode_video2(avCodecContext,
avFrame, &isFrameAvailable, &packetToSend);

        if (processedLength < 0) {

            av_free_packet(&packet);

            qDebug() << "Error while processing the data";

            exit(0);

        }

 Always returns -1. libav prints an error "no frame!" or "nal is a large
number".

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.

I’m stuck here.

Thank you,



This is my code:



    avcodec_init();

    av_register_all();

    av_log_set_callback(my_log_callback);

    av_log_set_level(AV_LOG_DEBUG);

    AVFormatContext *formatContext = avformat_alloc_context();



    if (av_open_input_file(&formatContext, "C:\\ani.mp4", NULL, NULL, NULL)
!= 0)

    {

        qDebug() << "can't open animation";

    }



    if (av_find_stream_info(formatContext) < 0)

    {

        qDebug() << "can't find stream info";

    }



    AVStream* videoStream;

    for (unsigned int i = 0; i < formatContext->nb_streams; ++i)

    {

        AVStream *stream = formatContext->streams[i];        // pointer to
a structure about the stream

        AVMediaType codecType = stream->codec->codec_type;   // the type of
data in this stream, notable values are AVMEDIA_TYPE_VIDEO and
AVMEDIA_TYPE_AUDIO

        CodecID codecID = stream->codec->codec_id;           // identifier
for the codec



        qDebug() <<"media type"<< codecType << "codec_id:" << codecID;

        if (codecType == AVMEDIA_TYPE_VIDEO)

        {

            videoStream = stream;

        }

    }



    AVCodec *codec = avcodec_find_decoder(videoStream->codec->codec_id);

    if (codec == NULL)

    {

        qDebug() << "can't create codec";

    }



    AVCodecContext *avCodecContext =
avcodec_alloc_context2(videoStream->codec->codec_type);



    avCodecContext->width = 1920;

    avCodecContext->height = 1080;

    //avCodecContext->flags2 |= CODEC_FLAG2_FAST;

    avCodecContext->pix_fmt =  (enum PixelFormat)29;



    if (avcodec_open(avCodecContext,codec ) < 0)

    {

        qDebug() << "can't open animation file";

    }





    qDebug() << "codec width:" << avCodecContext->width << "height:" <<
avCodecContext->height <<avCodecContext->pix_fmt ;



    AVFrame * avFrame =avcodec_alloc_frame();



    if (avFrame == NULL)

    {

        qDebug() << "can't allocation avFrame";



    }



    avcodec_get_frame_defaults(avFrame);



    // the current packet of data

    AVPacket packet;

    av_init_packet(&packet);

    packet.size = 0;

    // data in the packet of data already processed

    size_t offsetInData = 0;



    // the decoding loop, running until EOF

    while (true)

    {

        // reading a packet using libavformat

        if (offsetInData >= packet.size)

        {

            av_free_packet(&packet);

            while (true)

            {

                if (av_read_frame(formatContext, &packet) < 0)

                {

                    qDebug() << "EOF";

                    goto finished;

                }

                if (packet.stream_index == videoStream->index)

                    break;

                av_free_packet(&packet);

            }

        }



        qDebug() << "packet" << packet.size;



        // preparing the packet that we will send to libavcodec

        AVPacket packetToSend;

        packetToSend.data = packet.data + offsetInData;

        packetToSend.size = packet.size - offsetInData;



        // sending data to libavcodec

        int isFrameAvailable = 0;

        const auto processedLength = avcodec_decode_video2(avCodecContext,
avFrame, &isFrameAvailable, &packetToSend);

        if (processedLength < 0) {

            av_free_packet(&packet);

            qDebug() << "Error while processing the data";

            exit(0);

        }

        qDebug() << "processed Length:" << processedLength;



        offsetInData += processedLength;



        // processing the image if available

        if (isFrameAvailable) {

            qDebug() << "one frame is ready!";

        }



    }



finished:
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20121205/63780863/attachment.html>


More information about the Libav-user mailing list