我有一个Objective-C类(尽管我不相信这是Obj-C所特有的),我正在用它从一系列CGImage中将视频写到磁盘上。 (我在顶部使用的获取像素数据的代码来自Apple:http://developer.apple.com/mac/library/qa/qa2007/qa1509.html)。我成功创建了编解码器和上下文-一切顺利,直到获得EXC_BAD_ACCESS的avcodec_encode_video为止。我认为这应该是一个简单的解决方法,但是我无法弄清楚哪里出了问题。

我检查了一些错误以确保简洁。 “ 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++;
}


我已经完成了数十次。这是一些数字...


dataLength = 408960
picture_buff = 0x5c85000
picture-> data [0] = 0x5c85000-我的意思是avpicture_fill工作正常...
outbuf_size = 408960


然后在avcodec_encode_video上获得EXC_BAD_ACCESS。不确定是否相关,但是大部分代码来自api-example.c。我正在使用XCode,在Snow Leopard上为armv6 / armv7进行编译。

非常感谢您的帮助!

最佳答案

我在这里没有足够的信息来指出确切的错误,但是我认为问题是输入图片包含的数据少于avcodec_encode_video()期望的数据:

avpicture_fill()仅在AVFrame结构中设置一些指针和数值。它不会复制任何内容,也不会检查缓冲区是否足够大(并且因为缓冲区大小没有传递给缓冲区,所以它不能这样做)。它执行以下操作(从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;


请注意,宽度和高度是从变量“ c”(我假设是AVCodecContext)传递的,因此它可能大于输入帧的实际大小。

宽度/高度也可能很好,但是输入帧的像素格式与传递给avpicture_fill()的像素格式不同。 (请注意,像素格式也来自AVCodecContext,可能与输入有所不同)。例如,如果c-> pix_fmt为RGBA并且输入缓冲区为YUV420格式(或者,对于iPhone,更可能是双平面YCbCr),则输入缓冲区的大小为width * height * 1.5,但是avpicture_fill()期望宽度*高度* 4的大小。

因此,检查输入/输出的几何形状和像素格式应该可以导致错误。如果没有帮助,建议您首先尝试为i386进行编译。正确地为iPhone编译FFMPEG是很难的。

07-27 23:35