Search code examples
c++jpegpicturebox

An Unhandled exception: YUV Packed to JPEG Conversion On Button Press VC++2010 Form Application


i have YUV packed images which i have first convert to planar and then jpeg format (on button press) for Displaying in a picture box in VC++ 2010, using command at the end of entire code (after jpeg conversion done)

pictureBox1->Image = Image::FromFile("d:\\encoded_pic_420.jpg"); 

i am able to store and format convert these received images from YUV packed to YUV planar First and then Second from "Planar to JPEG format" (below Code First & Second).

on first time it Convert and Display image in picture box sucessfully, but when i press button second time it generate an error (in this below code section) SECOND PART OF CODE (PLANAR TO JPEG CONVERSION

            if (got_picture==1)
            {
                pkt.stream_index = video_st->index;
                ret = av_write_frame(pFormatCtx, &pkt);
            } 

error mesage is at Code Line (above) ret = av_write_frame (pFormatCtx,&pkt);

message is :

"An unhandled exception of type accured System.AccessViolationException , Additional information: Attempted to read or write protected memory, this is often an indication that other memory is corrupted"

the Complete code which i am using for YUV packet to Planar first and then second Planar to Jpeg conversion is below one. First: YUV PACKED to PLANAR CONVERSION

FILE    *in_file    =   NULL;  //fopen("myHexFile.yuv","rb"); input PACKED
FILE    *out_file   =   NULL;  //Output File Planar format

 int    in_width        =   2448;               //YUV's width 
 int    in_height       =   2050;               //YUV's heigh
 int    out_width       =   2448;               //YUV's width 
 int    out_height      =   2050;               //YUV's heigh

int     in_linesize[4];
int     out_linesize[4];
uint8_t     *in_data[4], *out_data[4];

unsigned long int       out_bufsize,in_bufsize;

in_file = fopen("myHexFile.yuv","rb"); //This is YUV422-UYVY Input packed image

if(in_file == NULL) 
{  
this->Print2TextBox1(L"Input File Opening error...!"); 
exit(1); 
}

out_file = fopen("d:\\myHexFile_Planar.yuv", "wb");     //Source Input File
if(out_file == NULL) 
{    
this->Print2TextBox1(L"toutput File Opening error...!!"); 
exit(1); 
}

else  {  this->Print2TextBox1(L"Output File Created...!!\n");  }    

//-Loads the whole database of available codecs and formats-------
    av_register_all();  
    this->Print2TextBox1(L"Codac database Loaded...\n");

//---Create scaling context------------------------sws_getContex
this->Print2TextBox1(L"Creating Scaling context..\n");

sws_ctx =   sws_getContext( in_width, in_height, src_pix_fmt,
                            out_width,out_height,dst_pix_fmt,
                            SWS_BICUBIC, NULL, NULL, NULL);

if(!sws_ctx) { this->Print2TextBox1(L"Context Error..\n"); }



  //--Allocate Source Image Buffer--------------------------
    this->Print2TextBox1(L"Allocate Source Image Buffer...\n");
AVFrame *RawPic =   av_frame_alloc();   
if(!RawPic) 
   {    
   this->Print2TextBox1(L"Could not allocate Raw Image frame\n");   
   exit(1);
   }



RawPic->format  =   src_pix_fmt;
RawPic->width   =   in_width;
RawPic->height  =   in_height;  

int num_bytes1  =   avpicture_get_size(src_pix_fmt,in_width,in_height);
uint8_t* RawPic_Buffer  =   (uint8_t*)av_malloc(num_bytes1*sizeof(int8_t));
ret =av_image_alloc(RawPic->data,in_linesize,in_width,in_height,src_pix_fmt, 1); 

if(ret < 0) 
{   
this->Print2TextBox1(L"Could not allocate raw picture buffer\n"); 
exit(1);
}

in_bufsize  =   ret;
//------Reading Input Image and Store in RawPic->Data Pointer---
fread(RawPic->data[0],1,in_bufsize,in_file);

//----Allocate Desitnation Image Buffer-------------------
this->Print2TextBox1(L"Allocate Destination Image Buffer...\n");

AVFrame *ScalePic   =   av_frame_alloc();

if(!ScalePic)   
{   
this->Print2TextBox1(L"Could not allocate Scale Image frame\n");    
exit(1);
}       

ScalePic->format    =   dst_pix_fmt;//pCodecCtx->pix_fmt;
ScalePic->width     =   out_width;
ScalePic->height    =   out_height;     
int num_bytes2  =   avpicture_get_size(dst_pix_fmt,out_width,out_height);
uint8_t*    ScalePic_Buffer =   (uint8_t *)av_malloc(num_bytes2*sizeof(int8_t));

ret =   av_image_alloc(ScalePic->data,out_linesize,out_width,out_height,dst_pix_fmt, 1); //16

if(ret < 0) {   this->Print2TextBox1(L"Could not allocate Scale picture buffer\n"); exit(1);}
out_bufsize =   ret;

//-Create scaling context-OR CONVERTED TO DESTINATION FORMAT-----sws_scale  
this->Print2TextBox1(L"Creating Scaling context...sws_scale\n");


sws_scale(sws_ctx, RawPic->data, in_linesize, 0, ScalePic->height, ScalePic->data, out_linesize);   

//-----Write Scale Image to outputfile-

    this->Print2TextBox1(L"Write Scale Image to outputfile..\n");
    fwrite(ScalePic->data[0],1,out_bufsize,out_file);

//---Release all memory and close file--
                fclose(in_file);
                fclose(out_file);

        av_freep(&RawPic->data[0]);
        av_freep(&ScalePic->data[0]);

        av_frame_free(&ScalePic);
        av_frame_free(&RawPic);

SECOND--CONVERT to PLANAR TO JPEG FORMAT------(in Continuation to Above Code)

    const char*     myJpeg_file     =   "d:\\encoded_pic_444.jpg";  //Output JPEG

in_file = fopen("d:\\myHexFile_Planar.yuv", "rb");         //Input Planar File
if(in_file == NULL) 
{ 
this->Print2TextBox1(L"File Opening error...!!"); 
exit(1); 
}

else this->Print2TextBox1(L"YUV File Open Sucessfully...!!\n\n");

av_register_all();  // Loads the whole database of available codecs and formats.

pFormatCtx              =   avformat_alloc_context();
fmt                     =   NULL;
fmt                     =   av_guess_format("mjpeg",NULL,NULL);
pFormatCtx->oformat     =   fmt;


if (avio_open(&pFormatCtx->pb,myJpeg_file, AVIO_FLAG_READ_WRITE) < 0)
    {
    this->Print2TextBox1(L"Couldn't open output file.");
    }

video_st = avformat_new_stream(pFormatCtx, 0);
if (video_st==NULL)  
    {   
      this->Print2TextBox1(L"avformat_new_stream.");
    }


            pCodecCtx               =   video_st->codec;
            pCodecCtx->codec_id     =   fmt->video_codec;
            pCodecCtx->codec_type   =   AVMEDIA_TYPE_VIDEO;
            pCodecCtx->pix_fmt      =   AV_PIX_FMT_YUVJ420P;


            pCodecCtx->width        =   in_width;
            pCodecCtx->height       =   in_height;

            pCodecCtx->time_base.num = 1;
            pCodecCtx->time_base.den = 1;//25;


            this->Print2TextBox1(L"Conversion start\n");

                            //Output some information
            av_dump_format(pFormatCtx, 0, myJpeg_file, 1);

            // Determine if desired video encoder is installed 
            pCodec = avcodec_find_encoder(pCodecCtx->codec_id);

            if (!pCodec)
            {
                this->Print2TextBox1(L"Codec not found.");
                //return -1;
            }

                this->Print2TextBox1(L"Codec Identified done\n");

            if (avcodec_open2(pCodecCtx, pCodec,NULL) < 0){
                this->Print2TextBox1(L"Could not open codec.\n");
                //return -1;
            }

                this->Print2TextBox1(L"Codec Open done\n");

                //-----------------------------------------------
                picture         =   av_frame_alloc();
                size            =   avpicture_get_size(pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);
                picture_buf     =   (uint8_t *)av_malloc(size);
                if (!picture_buf)    
                    {   this->Print2TextBox1(L"Size Allocation error\n");
                    //return -1;
                    }
                avpicture_fill((AVPicture *)picture, picture_buf, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);


                this->Print2TextBox1(L"Write Header..");
                avformat_write_header(pFormatCtx,NULL);

                y_size = pCodecCtx->width * pCodecCtx->height;

                av_new_packet(&pkt,y_size*3);

                //-------------------------------------------------------420 Format
                //Read YUV
                if (fread(picture_buf, 1, y_size*3/2, in_file) <=0)
                {
                    this->Print2TextBox1(L"Could not read input file.");
                    //return -1;
                }
                //--------------------------------------------input image format UYVY
                picture->data[0] = picture_buf;                 // Y
                picture->data[1] = picture_buf+ y_size;         // U
                picture->data[2] = picture_buf+ y_size*5/4;     // V

                this->Print2TextBox1(L" Encode the image..\n");
                ret = avcodec_encode_video2(pCodecCtx, &pkt,picture, &got_picture);
                if(ret < 0)
                {
                    this->Print2TextBox1(L"Encode Error.\n");
                    //return -1;
                }

                if (got_picture==1)
                {
                    pkt.stream_index = video_st->index;
//@@@@  PROBLEM IN THIS LINE BELOW WHEN RE-EXECUTE THE CODE  @@@
                    ret = av_write_frame(pFormatCtx, &pkt);
                }


                av_free_packet(&pkt);
                //Write Trailer
                av_write_trailer(pFormatCtx);


                this->Print2TextBox1(L"Encode Successful.\n");

                if (video_st)
                {
                    avcodec_close(video_st->codec);
                    av_free(picture);
                    av_free(picture_buf);
                }

                avio_close(pFormatCtx->pb);
                avformat_free_context(pFormatCtx);

                fclose(in_file);

it seems that some of memory is not yet free or when i am trying to re-use this above code in second time in a loop,

plz suggest/guide me where i am doing wrong and not freeing up the memory..?

i am trying to Display Image (Current/updated) on every button press in VC++2010


Solution

  • solved by renaming the "encoded_pic_420.jpg" file with some other name and display it on PictureBox

    https://msdn.microsoft.com/en-us/library/windows/desktop/aa363851(v=vs.85).aspx