EXC_BAD_ACCESS при вызове avcodec_encode_video - PullRequest
0 голосов
/ 28 мая 2010

У меня есть класс Objective-C (хотя я не верю, что это что-то специфичное для Obj-C), который я использую для записи видео на диск из серии CGImages. (Код, который я использую в верхней части для получения данных пикселей, поступает прямо от 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++;
}

Я прошел через это десятки раз. Вот несколько цифр ...

  1. dataLength = 408960
  2. picture_buff = 0x5c85000
  3. picture-> data [0] = 0x5c85000 - это означает, что avpicture_fill работал ...
  4. outbuf_size = 408960

и затем я получаю EXC_BAD_ACCESS по адресу avcodec_encode_video. Не уверен, что это актуально, но большая часть этого кода взята из api-example.c. Я использую XCode, компилируя для armv6 / armv7 на Snow Leopard.

Заранее большое спасибо за помощь!

Ответы [ 3 ]

0 голосов
/ 04 июня 2010

Поддерживает ли кодируемый вами кодек цветовое пространство RGB? Возможно, вам придется использовать libswscale для преобразования в I420 перед кодированием. Какой кодек вы используете? Можете ли вы опубликовать код, где вы инициализируете свой контекст кодека?

0 голосов
/ 05 июля 2010

Функция RGBtoYUV420P может вам помочь. http://www.mail-archive.com/libav-user@mplayerhq.hu/msg03956.html

0 голосов
/ 29 мая 2010

У меня недостаточно информации, чтобы указать на точную ошибку, но я думаю, что проблема в том, что входное изображение содержит меньше данных, чем ожидает 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. Сложно правильно скомпилировать FFMPEG для iPhone.

...