我有一个 Objective-C 类(尽管我不认为这是 Obj-C 特有的东西),我用它从一系列 CGImage 中将视频写入磁盘。 (我在顶部使用的获取像素数据的代码直接来自 Apple: http://developer.apple.com/mac/library/qa/qa2007/qa1509.html )。我成功创建了编解码器和上下文 - 一切都很顺利,直到它到达 avcodec_encode_video,当我得到 EXC_BAD_ACCESS 时。我认为这应该是一个简单的修复,但我就是不知道哪里出了问题。
为了简洁起见,我进行了一些错误检查。 '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++;
}
我已经经历了几十次了。这是一些数字...
- 数据长度 = 408960
- 图片_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 是很棘手的。
关于iphone - 调用avcodec_encode_video时的EXC_BAD_ACCESS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2931885/