2014-02-07 134 views
1

我試圖編碼BMP圖像,我從緩衝區獲取並將其存儲爲H264視頻。我堅持這些錯誤隨機到達,並反覆訪問衝突讀取位置0x000000148965F000

我使用Visual Studio 2012

1)訪問衝突閱讀位置0x000000148965F000。

2)堆損壞

調試顯示錯誤在這一點上

struct SwsContext* fooContext = sws_getContext(_imgWidth,_imgHeight,PIX_FMT_RGB32,c->width,c->height,PIX_FMT_YUV420P, SWS_FAST_BILINEAR,NULL,NULL,NULL); 
        sws_scale(fooContext, inpic->data, inpic->linesize, 0, c->height, outpic->data, outpic->linesize); // converting frame size and format 

我想讀違規行爲,會由於非 - 預初始化值。但我不明白爲什麼。我也附上了部分代碼

PagedImage *inImg = getUpdatedInputImage(0); 
     ML_CHECK(inImg); 
     ImageVector imgExt = inImg->getImageExtent(); 
     if ((imgExt.x == _imgWidth) && (imgExt.y == _imgHeight)) 
     { 
      if (((imgExt.x % 4) == 0) && ((imgExt.y % 4) == 0)) 
      { 
       _numFramesFld->setIntValue(_numFramesFld->getIntValue() + 1); 
       MLFree(unicodeFilename); 
       // configure header 
       //BITMAPINFO bitmapInfo 
       // read out input image and write output image into video 
       // get input image as an array 
       void* imgData = NULL; 
       SubImageBox imageBox(imgExt); // get the whole image 
       getTile(inImg, imageBox, MLuint8Type, &imgData); 
       MLuint8* iData = (MLuint8*)imgData; 
       // since we have only images with 
       // a z-ext of 1, we can compute the c stride as follows 
       int cStride = _imgWidth * _imgHeight; 
       int offset = 0; 
       MLuint8 r=0, g=0, b=0; 
       // pointer into the bitmap that is 
       // used to write images into an video 
       UCHAR* dst = (UCHAR*)_bits; 
       for (int y = _imgHeight-1; y >= 0; y--) 
       { // reversely scan the image. if y-rows of DIB are set in normal order, no compression will be available. 
        offset = _imgWidth * y; 
        for (int x = 0; x < _imgWidth; x++) 
        { 
         if (_isGreyValueImage) 
         { 
          r = iData[offset + x]; 
          *dst++ = (UCHAR)r; 
          *dst++ = (UCHAR)r; 
          *dst++ = (UCHAR)r; 
         } 
         else 
         { 
          b = iData[offset + x]; // windows bitmap need reverse order: bgr instead of rgb 
          g = iData[offset + x + cStride   ]; 
          r = iData[offset + x + cStride + cStride]; 
          *dst++ = (UCHAR)r; 
          *dst++ = (UCHAR)g; 
          *dst++ = (UCHAR)b; 
         } 
         // alpha channel in input image is ignored 
        } 
       } 
       outbuf_size = 100000 + c->width*c->height*(32>>3);  // allocate output buffer 
       outbuf = static_cast<uint8_t *>(malloc(outbuf_size)); 
       fileName_ = (_outputFilenameFld->getStringValue()).c_str(); 
       FILE* f = fopen(fileName_,"wb");     // opening video file for writing 
       if(!f) 
       { 
        _messageFld->setStringValue("Cannot open file"); 
       } 
       else _messageFld->setStringValue("Opened video file for writing\n"); 

       //for(i=0;i<_numFramesFld->getIntValue();i++) 
       //{ 
        fflush(stdout); 
        int nbytes = avpicture_get_size(PIX_FMT_YUV420P, c->width, c->height);        // allocating outbuffer 
        uint8_t* outbuffer = (uint8_t*)av_malloc(nbytes*sizeof(uint8_t)); 
        AVFrame* inpic = avcodec_alloc_frame();                // mandatory frame allocation 
        AVFrame* outpic = avcodec_alloc_frame(); 
        //outpic->pts = (int64_t)((float)i * (1000.0/((float)(c->time_base.den))) * 90);      // setting frame pts 
        avpicture_fill((AVPicture*)inpic,(uint8_t*)dst, PIX_FMT_RGB32, c->width, c->height);       // fill image with input screenshot 
        avpicture_fill((AVPicture*)outpic, outbuffer, PIX_FMT_YUV420P, c->width, c->height);     // clear output picture for buffer copy 
        av_image_alloc(outpic->data, outpic->linesize, c->width, c->height, c->pix_fmt, 1); 

        inpic->data[0] += inpic->linesize[0]*(c->height-1);             // flipping frame 
        inpic->linesize[0] = -inpic->linesize[0];                // flipping frame 

        struct SwsContext* fooContext = sws_getContext(_imgWidth,_imgHeight,PIX_FMT_RGB32,c->width,c->height,PIX_FMT_YUV420P, SWS_FAST_BILINEAR,NULL,NULL,NULL); 
        sws_scale(fooContext, inpic->data, inpic->linesize, 0, c->height, outpic->data, outpic->linesize); // converting frame size and format 
        out_size = avcodec_encode_video(c, outbuf, outbuf_size, outpic);          // encoding video 
        _messageFld->setStringValue("Encoding frame %3d (size=%5d)\n"); 
        fwrite(outbuf, 1, out_size, f); 
        delete [] dst;                       // freeing memory 
        av_free(outbuffer);  
        av_free(inpic); 
        av_free(outpic); 
        av_free(fooContext); 
        DeleteObject(_hbitmap); 

        for(int Z = 0; Z<out_size; i++) 
        { 
         fflush(stdout); 
         out_size = avcodec_encode_video(c, outbuf, outbuf_size, outpic);            // encode the delayed frames 
         fwrite(outbuf, 1, out_size, f); 
        } 
        //outbuf[0] = 0x00; 
        //outbuf[1] = 0x00;                        // add sequence end code to have a real mpeg file 
        //outbuf[2] = 0x01; 
        //outbuf[3] = 0xb7; 
        //fwrite(outbuf, 1, 4, f); 
        fclose(f); 
        avcodec_close(c);                        // freeing memory 
        free(outbuf); 
        av_free(c); 
        printf("Closed codec and Freed\n"); 
       } 
      } 
+0

您可能要標記這是C.你會發現越來越多的人誰可以讀取該標籤的代碼。 – juanchopanza

+0

valgrind valgrind和valgrind。 – bmargulies

+0

@bmargulies不支持Windows,不支持Windows,並且(仍然)不支持Windows。 –

回答

1

訪問衝突可能會很難調試。 由於您有讀取訪問衝突,可能是因爲您已經在數據的指針上運行了某個地方,現在只有當您嘗試從該地址讀取數據時纔會發生異常。

我建議你使用GFLAGS與全頁堆找出究竟你AccessViolation的位置:

GFLAGS/P /啓用映像文件名稱/滿。

GFlags and PageHeap

我希望這將有助於

+0

嗨,我找不到VS中的GFLAGS,我有Windows SDK,但我找不到Windbg.exe文件...我怎麼能確切地啓用此標誌?在Visual Studio中... – user3652437

+0

在此處: http://msdn.microsoft.com/en-us/windows/hardware/hh852365.aspx 向下滾動以下載: Windows 8.1的獨立調試工具(WinDbg) 然後它將在: C:\ Program Files(x86)\ Windows Kits \ 8.1 \ Debuggers \ x86 – eyalsn

+0

@ user3012914就像我向你發送的用法一樣,使用命令提示符中的gflags更容易: gflags/p/enable ImageFileName/full 我發現用戶界面太複雜了...... 只記得在完成後禁用整個頁面堆,正如文檔所述,啓動gflags的過程會消耗更多的內存。 – eyalsn