Iphone 调用avcodec\u encode\u视频时EXC\u访问错误

Iphone 调用avcodec\u encode\u视频时EXC\u访问错误,iphone,c,objective-c,ffmpeg,libavcodec,Iphone,C,Objective C,Ffmpeg,Libavcodec,我有一个Objective-C类,虽然我不相信这是我用来从一系列CG图像将视频写入磁盘的任何Obj-C特定类。我在顶部使用的获取像素数据的代码来自Apple:。我成功地创建了编解码器和上下文-一切都很顺利,直到我获得EXC\u BAD\u访问权限时,它进入了avcodec\u encode\u video。我认为这应该是一个简单的解决办法,但我就是不知道我哪里出了问题 为了简洁起见,我做了一些错误检查c'是成功创建的AVcodeContext* -(void)addFrame:(CGImageR

我有一个Objective-C类,虽然我不相信这是我用来从一系列CG图像将视频写入磁盘的任何Obj-C特定类。我在顶部使用的获取像素数据的代码来自Apple:。我成功地创建了编解码器和上下文-一切都很顺利,直到我获得EXC\u BAD\u访问权限时,它进入了avcodec\u encode\u video。我认为这应该是一个简单的解决办法,但我就是不知道我哪里出了问题

为了简洁起见,我做了一些错误检查c'是成功创建的AVcodeContext*

-(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 图片->数据[0]=0x5c85000-我认为这意味着avpicture\U fill工作正常。。。 突出尺寸=408960 然后我在avcodec视频中获得了EXC\u BAD\u访问权限。不确定它是否相关,但大部分代码来自api example.c。我正在使用XCode,为雪豹上的armv6/armv7进行编译


非常感谢您的帮助

我这里没有足够的信息指出确切的错误,但我认为问题在于输入图片包含的数据比avcodec\u encode\u 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,则输入缓冲区的大小为宽度*高度*1.5,但avpicture_fill预期的大小为宽度*高度*4


因此,检查输入/输出几何体和像素格式应该可以找到错误的原因。如果没有帮助,我建议您首先尝试编译i386。为iPhone正确编译FFMPEG是一件棘手的事情。

您正在编码的编解码器是否支持RGB颜色空间?编码之前,您可能需要使用libswscale转换为I420。你用的是什么编解码器?您可以在初始化编解码器上下文的位置发布代码吗?

函数RGBtoYUV420P可能会对您有所帮助。

非常感谢您的回答!作为测试,我把图片放大了10倍,得到了同样的错误。您复制的源需要一个PIX_FMT_YUV420P平面图像,我想这就是它设置4个不同指针的原因-它指向每个通道的开头。我想我应该提到,在我的例子中,c->pix_fmt=pix_fmt_RGB24我还做了一个检查:ifCGImageGetWidthimg=c->宽度| | CGImageGetHeightimg=c->高度{NSLog@Frame与电影大小不匹配。跳过;返回;}我可以提供哪些其他信息来帮助您?或者-为了帮助我,我应该说:好吧,那么我认为错误不在这里,而是在编解码器初始化代码中-这更难调试:最有可能的是您没有在AvcodeContext中设置一些参数。您应该检查avcodec.h中的注释以查看缺少的内容。如果它没有帮助,那么除了调试ffmpeg代码之外,就没有什么了。。。如果你犯了一个小错误,它实际上会有所帮助!它在avcodec_encode_视频中崩溃了吗?因为在这个函数中,我只看到一件事会崩溃:如果codecContext->codec为NULL,你是否调用了av_register_all?以下是我不理解的。avcodec_encode_视频应该将“picture”的编码版本放入“exputf”中,对吗picture'是408960个字节被赋予picture_buff,这是使用dataLength的malloc'd,而extuf是408960个字节被赋予了extuf_大小的malloc'd,那么坏访问可能发生在哪里?我在这里忽略了什么记忆?我很确定你是对的。我现在直接从我用来解码视频的类中传递编解码器和上下文,它似乎正在工作。我在其他地方有其他问题,但我会在这里张贴当我发现它。H.264确实支持RGB。Mpeg4没有。我两者都试过了。现在我直接从打开视频的代码中获取上下文和编解码器。有什么理由不能这样做吗?读者:作者:你解决过这个问题吗?