0

一連のCGImageからビデオをディスクに書き出すために使用しているObjective-Cクラスがあります(これはObj-C固有のものではないと思いますが)。(ピクセルデータを取得するために上部で使用しているコードは、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++;
}

私はそれを何十回も踏みました。ここにいくつかの数字があります...

  1. データの長さ = 408960
  2. picture_buff = 0x5c85000
  3. picture->data[0] = 0x5c85000 -- avpicture_fill が機能したことを意味します...
  4. outbuf_size = 408960

そして、avcodec_encode_video で EXC_BAD_ACCESS を取得します。関連性があるかどうかはわかりませんが、このコードのほとんどは api-example.c からのものです。XCode を使用して、Snow Leopard で armv6/armv7 用にコンパイルしています。

助けてくれてありがとう!

4

3 に答える 3

0

関数 RGBtoYUV420P が役に立ちます。 http://www.mail-archive.com/libav-user@mplayerhq.hu/msg03956.html

于 2010-07-05T08:50:42.417 に答える
0

正確なエラーを指摘するのに十分な情報はここにはありませんが、問題は入力画像に 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 用に適切にコンパイルするのは難しいです。

于 2010-05-28T21:53:16.417 に答える
0

エンコードしているコーデックは RGB 色空間をサポートしていますか? エンコードする前に libswscale を使用して I420 に変換する必要がある場合があります。どのコーデックを使用していますか? コーデック コンテキストを初期化するコードを投稿できますか?

于 2010-06-04T14:46:46.960 に答える