访问冲突读取位置0x000000148965F000

时间:2014-02-07 00:14:09

标签: c++ c ffmpeg

我尝试编码BMP图像,我从缓冲区获取并将其存储为H264视频。我经常随机地重复这些错误

我正在使用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");
                }
            }

1 个答案:

答案 0 :(得分:1)

访问冲突可能很难调试。 由于你有一个读取访问冲突,可能是你在指针上运行了数据并且只是现在,当你尝试从那里读取时,你会得到异常。

我建议您使用GFLAGS和Full PageHeap精确定位AccessViolation的位置:

gflags / p /启用ImageFileName / full。

GFlags and PageHeap

我希望这会有所帮助