[Libav-user] How to decode the avcodec_decode_video2() using lowres?

nrson nrson at win4net.com
Thu May 10 02:51:26 CEST 2012


Hi ffmpeg users!
I’ve been trying to speed down for H.264 decoder. I know the lowres is 
low resolution supported by the decoder.
When decoding after setting the lowres(1), the results of 
avcodec_decode_video2() occur the errors.
My program is as following:

bool init_first = true;
main()
{
            FILE *fp, *ifs;
            uint8_t buf[1024*10];
            char *InFileStream          = "InStream.264";
            char *InFileData  = "InStreamSize.txt";
            fp = fopen("a.264", "rb");
            ifs = fopen("InStreamSize.txt", "rb");

            AVCodec*                    codec;
            AVCodecContext*                     context;
            AVFrame*                    picture;
            AVPacket                     avpkt;
            int                             frame = 0;
            AVFrame*                    pFrameRGB;
            int                             numBytes;
            uint8_t           *pFrameRGB_buffer;
            BYTE *inbuf = new BYTE [1000000];
            LPBYTE pbtYuv = NULL;
            pbtYuv = new BYTE [ 1920 * 1080 * 2 ];
            int nEncSize, len;

            av_register_all();                       //register all the 
codecs
            avcodec_register_all();
            avcodec_init();
            av_init_packet(&avpkt);
            codec = avcodec_find_decoder(CODEC_ID_H264);     //find the 
H264 video decoder
            if(!codec)
            {
                      fprintf(stderr, "codec not found\n");
                      ReleaseMutex(hMutex);
                      return false;
            }
            context            =         avcodec_alloc_context();
            picture             =         avcodec_alloc_frame();
            pFrameRGB       =         avcodec_alloc_frame();
            context->flags                         |=        
CODEC_FLAG_PART;
            context-->workaround_bugs        =         1;
            context->error_concealment        =         3;
            context->error_recognition          =         1;
            context->pix_fmt            =         PIX_FMT_YUV420P;
            context->width             =         nWidth;
            context->height            =         nHeight;
            context->skip_loop_filter  =         AVDISCARD_ALL;
            context->skip_frame                  =         
AVDISCARD_NONREF; //AVDISCARD_NONREF
            context->skip_idct                    =         
AVDISCARD_ALL;
            context->idct_algo                    =        1;
            context->has_b_frames               =         0;
            context->refs                          =         1;
            codec->max_lowres                  =         1;

            if(codec->max_lowres)
            {
                      context->lowres                       =         
codec->max_lowres; // 1->1/2 size,  2->1/4 size, 3->1/8 -> error occur
                      context->flags                         |=        
CODEC_FLAG_EMU_EDGE;
                      context->flags                         |=        
CODEC_FLAG_GRAY;
            }

            if(codec->capabilities & CODEC_CAP_TRUNCATED) // & 
CODEC_CAP_HWACCEL)
                      context->flags |= CODEC_FLAG_TRUNCATED; // we do 
not send complete frames

            if (avcodec_open(context, codec) < 0)                        
     //open it
            {
                      fprintf(stderr, "could not open codec\n");
                      return false;
            }

            PixelFormat iFormat = context->pix_fmt;
            PixelFormat dFormat = PIX_FMT_YUYV422;

            numBytes = avpicture_get_size(dFormat, context->width, 
context->height);
            pFrameRGB_buffer =(uint8_t 
*)av_malloc(numBytes*sizeof(uint8_t));
            avpicture_fill((AVPicture *)pFrameRGB, pFrameRGB_buffer, 
dFormat, context->width, context->height);

            for(;;)
            {
                      ZeroMemory(inbuf, 1000000);
                      fread(&nEncSize, sizeof(DWORD), 1, ifs);
                      fread(inbuf,1,nEncSize, fp);
                      avpkt.size = nEncSize;
                      if(avpkt.size == 0)
                                 break;
                      avpkt.data = inbuf;
                      while(avpkt.size >0)
                      {
                                 if(init_first == true)
                                 {
                                           len       = 
avcodec_decode_video2(context, picture, &got_picture, &avpkt);
                                           init_first = false;
                                 }
                                 len       = 
avcodec_decode_video2(context, Picture, &got_picture, &avpkt);
                                 if(len < 0)
                                 {
                                           fprintf(stderr, "Error while 
decoding frame %d\n", frame);
                                           exit(1);
                                 }
                                 if(got_picture)
                                 {
                                           struct SwsContext 
*img_convert_ctx = NULL;
                                           img_convert_ctx = 
sws_getContext(          context->width, context->height,
                                                      context->pix_fmt, 
context->width, context->height, dFormat,
                                                      SWS_FAST_BILINEAR, 
NULL, NULL, NULL);

                                           if(img_convert_ctx == NULL)
                                           {
                                                      
printf("[CFFH264Decode::MainDecode::SWScale] --- Exception\n");
                                                      exit(1);
                                           }
                                           int ret = 
sws_scale(img_convert_ctx, picture->data, picture->linesize, 0, 
context->height, pFrameRGB->data, pFrameRGB->linesize);
                                           if(pFrameRGB_buffer)
                                           {
                                                      av_free( 
pFrameRGB_buffer );
                                                      pFrameRGB_buffer = 
NULL;
                                           }
                                           
sws_freeContext(img_convert_ctx);
                                           if(img_convert_ctx != NULL)
                                                      img_convert_ctx = 
NULL;
                                           frame++;
                                 }
                                 avpkt.size          -= len;
                                 avpkt.data         += len;
                      }
            }

            if(inbuf != NULL || pbtYuv != NULL)
            {
                      delete [] inbuf;
                      delete [] pbtYuv;
            }
            if(context != NULL)
            {
                      avcodec_close(context);
                      pGBCodec = NULL;
                      av_free(context); context = NULL;
                      av_free(picture); picture = NULL;
            }
            fclose(fp);
            fclose(ifs);
}

How to solve the problems?

Thank you in advances,
nrson



More information about the Libav-user mailing list