suvirai
suvirai

Reputation: 89

Not able to decode mp4 file using latest ffmpeg library : av_decode_video2

I am writing a wrapper code around latest ffmpeg library. I am supplying MP4 files from local system. My problem is that I am unable to get any decoded frames when I use av_decode_video2(). The return value comes out to be negative. I have used av_read_frame() which returns 0. I googled about the problem I am facing but no where could I find the correct explanation. Please give me insight here. Pasting the pseudo code here.

    av_init_packet(avpkt);
    picture=av_frame_alloc();
    pFrameRGB=av_frame_alloc();
    codec = avcodec_find_decoder(CODEC_ID_H264);
    c= avcodec_alloc_context3(codec)
    avcodec_open2(decoderLibraryData->c, decoderLibraryData->codec, NULL)
    FormatContext = avformat_alloc_context();
    char *pUrl ="./1.MP4";

    iRet = avformat_open_input(atContext, pUrl, pFmt, NULL);

    if(FormatContext == NULL)
    {
        printf("could not assign any memory !!!!!!!!! \n");
    }

    avformat_find_stream_info(FormatContext, NULL);


    while(av_read_frame(FormatContext,avpkt) >= 0)
    {

      len = avcodec_decode_video2(c, picture, &got_picture,avpkt);

      printf("CODEC MANAGER len %d Frame decompressed %d \n",len,got_picture);

      if (len <= 0) 
      {
        return ERROR;
      }
    }
}



        if(lastHeight != 0 && lastWidth != 0)
        {
            if(lastWidth != c->width || lastHeight != c->height )
            {
                av_free(buffer);
                buffer = NULL;
                lastWidth = c->width;
                lastHeight = c->height;

            }
        }
        else
        {
            lastWidth = c->width;
            lastHeight = c->height;
        }
        decodeFlag = 1;
        if(!buffer)
        {
            int numBytes;
            v_mutex_lock(globalCodecLock);
            switch(inPixFormat)
            {
            case RGB:


                // Determine required buffer size and allocate buffer
                numBytes=avpicture_get_size(PIX_FMT_RGB24, c->width, c->height);

                buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
                avpicture_fill((AVPicture *)pFrameRGB,buffer,PIX_FMT_RGB24,c->width, c->height);

                if(cntxt)
                    sws_freeContext(cntxt);

                cntxt = sws_getContext(c->width, c->height, c->pix_fmt,
                        c->width, c->height, PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);

                break;

            }
            v_mutex_unlock(globalCodecLock);
            if(cntxt == NULL)
            {
                printf("sws_getContext error\n");
                return ERROR;
            }
            }

        {
            sws_scale(cntxt, picture->data, picture->linesize, 0, c->height, pFrameRGB->data, pFrameRGB->linesize);
            if(rgbBuff)
            {


                if(c->width <= *width && c->height <= *height)
                {                   
                    saveFrame(pFrameRGB, c->width, c->height, rgbBuff,inPixFormat);

                    *width = c->width;
                    *height = c->height;
                    rs = SUCCESS;
                    break;
                }
                else
                {
                    rs = VA_LOWBUFFERSIZE;
                }
            }
            else
            {
                rs = VA_LOWBUFFERSIZE;
            }
        }
        if(width)
        {
            *width = c->width;
        }
        if(height)
        {
            *height = c->height;
        }
        if(rs == VA_LOWBUFFERSIZE)
        {
            break;
        }

I am getting the return value of av_read_frame as 0 but av_decode_video2 returns value in negative. I am not able to get any clue here.

Upvotes: 0

Views: 1350

Answers (1)

M.Mahdipour
M.Mahdipour

Reputation: 603

Make sure you have called

av_register_all();

or

avcodec_register_all();

at the beginning of your app.

Also it seems the problem is from calling avformat_find_stream_info. Test with the following code:

    AVPacket avpkt;
    av_init_packet(&avpkt);
    AVFrame* picture = av_frame_alloc();
    AVFrame* pFrameRGB = av_frame_alloc();

    AVFormatContext* c2 = avformat_alloc_context();

    char *pUrl = "C:/Sample Videos/20-06-34.MP4";
    int video_stream_index = 0;

    AVInputFormat* pFmt;
    int iRet = avformat_open_input(&c2, pUrl, pFmt, NULL);

    AVStream* stream = c2->streams[video_stream_index];


    AVCodec* codec = avcodec_find_decoder(stream->codec->codec_id);
    avcodec_open2(stream->codec, codec, NULL);

    if (c2 == NULL)
    {
        printf("could not assign any memory !!!!!!!!! \n");
    }

    while (av_read_frame(c2, &avpkt) >= 0)
    {

        int got_picture;
        int len = avcodec_decode_video2(stream->codec, picture, &got_picture, &avpkt);

        printf("CODEC MANAGER len %d Frame decompressed %d \n", len, got_picture);

        if (len <= 0)
        {
            return ERROR;
        }
    }

Upvotes: 1

Related Questions