简体   繁体   English

调用avcodec_encode_video时为EXC_BAD_ACCESS

[英]EXC_BAD_ACCESS when calling avcodec_encode_video

I have an Objective-C class (although I don't believe this is anything Obj-C specific) that I am using to write a video out to disk from a series of CGImages. 我有一个Objective-C类(尽管我不相信这是Obj-C所特有的),我正在用它从一系列CGImage中将视频写到磁盘上。 (The code I am using at the top to get the pixel data comes right from Apple: http://developer.apple.com/mac/library/qa/qa2007/qa1509.html ). (我在顶部使用的获取像素数据的代码直接来自Apple: http : //developer.apple.com/mac/library/qa/qa2007/qa1509.html )。 I successfully create the codec and context - everything is going fine until it gets to avcodec_encode_video, when I get EXC_BAD_ACCESS. 我成功创建了编解码器和上下文-一切顺利,直到获得EXC_BAD_ACCESS的avcodec_encode_video为止。 I think this should be a simple fix, but I just can't figure out where I am going wrong. 我认为这应该是一个简单的解决方法,但是我无法弄清楚哪里出了问题。

I took out some error checking for succinctness. 我检查了一些错误以确保简洁。 'c' is an AVCodecContext*, which is created successfully. “ c”是成功创建的AVCodecContext *。

-(void)addFrame:(CGImageRef)img
{
  CFDataRef bitmapData = CGDataProviderCopyData(CGImageGetDataProvider(img));
  long dataLength = CFDataGetLength(bitmapData);
  uint8_t* picture_buff = (uint8_t*)malloc(dataLength);
  CFDataGetBytes(bitmapData, CFRangeMake(0, dataLength), picture_buff);

  AVFrame *picture = avcodec_alloc_frame();
  avpicture_fill((AVPicture*)picture, picture_buff, c->pix_fmt, c->width, c->height);

  int outbuf_size = avpicture_get_size(c->pix_fmt, c->width, c->height);
  uint8_t *outbuf = (uint8_t*)av_malloc(outbuf_size);

  out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture); // ERROR occurs here
  printf("encoding frame %3d (size=%5d)\n", i, out_size);
  fwrite(outbuf, 1, out_size, f);

  CFRelease(bitmapData);
  free(picture_buff);
  free(outbuf);
  av_free(picture);
  i++;
}

I have stepped through it dozens of times. 我已经完成了数十次。 Here are some numbers... 这是一些数字...

  1. dataLength = 408960 dataLength = 408960
  2. picture_buff = 0x5c85000 picture_buff = 0x5c85000
  3. picture->data[0] = 0x5c85000 -- which I take to mean that avpicture_fill worked... picture-> data [0] = 0x5c85000-我的意思是avpicture_fill工作正常...
  4. outbuf_size = 408960 outbuf_size = 408960

and then I get EXC_BAD_ACCESS at avcodec_encode_video. 然后在avcodec_encode_video上获得EXC_BAD_ACCESS。 Not sure if it's relevant, but most of this code comes from api-example.c. 不确定是否相关,但是大部分代码来自api-example.c。 I am using XCode, compiling for armv6/armv7 on Snow Leopard. 我正在使用XCode,在Snow Leopard上为armv6 / armv7进行编译。

Thanks so much in advance for help! 非常感谢您的帮助!

I have not enough information here to point to the exact error, but I think that the problem is that the input picture contains less data than avcodec_encode_video() expects: 我在这里没有足够的信息来指出确切的错误,但是我认为问题是输入图片包含的数据少于avcodec_encode_video()的预期:

avpicture_fill() only sets some pointers and numeric values in the AVFrame structure. avpicture_fill()仅在AVFrame结构中设置一些指针和数值。 It does not copy anything, and does not check whether the buffer is large enough (and it cannot, since the buffer size is not passed to it). 它不会复制任何内容,也不会检查缓冲区是否足够大(并且不能,因为缓冲区大小没有传递给它)。 It does something like this (copied from ffmpeg source): 它执行以下操作(从ffmpeg来源复制):

    size = picture->linesize[0] * height;
    picture->data[0] = ptr;
    picture->data[1] = picture->data[0] + size;
    picture->data[2] = picture->data[1] + size2;
    picture->data[3] = picture->data[1] + size2 + size2;

Note that the width and height is passed from the variable "c" (the AVCodecContext, I assume), so it may be larger than the actual size of the input frame. 请注意,宽度和高度是从变量“ c”(我假设是AVCodecContext)传递的,因此它可能大于输入帧的实际大小。

It is also possible that the width/height is good, but the pixel format of the input frame is different from what is passed to avpicture_fill(). 宽度/高度也可能很好,但是输入帧的像素格式与传递给avpicture_fill()的像素格式不同。 (note that the pixel format also comes from the AVCodecContext, which may differ from the input). (请注意,像素格式也来自AVCodecContext,可能与输入有所不同)。 For example, if c->pix_fmt is RGBA and the input buffer is in YUV420 format (or, more likely for iPhone, a biplanar YCbCr), then the size of the input buffer is width*height*1.5, but avpicture_fill() expects the size of width*height*4. 例如,如果c-> pix_fmt为RGBA并且输入缓冲区为YUV420格式(或者,对于iPhone,更可能是双平面YCbCr),则输入缓冲区的大小为width * height * 1.5,但是avpicture_fill()期望宽度*高度* 4的大小。

So checking the input/output geometry and pixel formats should lead you to the cause of the error. 因此,检查输入/输出的几何形状和像素格式应该可以导致错误。 If it does not help, I suggest that you should try to compile for i386 first. 如果没有帮助,建议您首先尝试为i386进行编译。 It is tricky to compile FFMPEG for the iPhone properly. 正确地为iPhone编译FFMPEG是很难的。

Does the codec you are encoding support the RGB color space? 您要编码的编解码器是否支持RGB颜色空间? You may need to use libswscale to convert to I420 before encoding. 编码之前,可能需要使用libswscale转换为I420。 What codec are you using? 您正在使用什么编解码器? Can you post the code where you initialize your codec context? 您可以将代码发布到初始化编解码器上下文的位置吗?

The function RGBtoYUV420P may help you. RGBtoYUV420P功能可能会为您提供帮助。 http://www.mail-archive.com/libav-user@mplayerhq.hu/msg03956.html http://www.mail-archive.com/libav-user@mplayerhq.hu/msg03956.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM