2016-05-17 12 views
1

Androidカメラのプレビューフレームをh264にエンコードしようとしましたが、muxをmp4コンテナにエンコードしようとしました。FFmpegカメラエンコードh264 mp4 muxing atom avcCが小さすぎます

私はmp4ファイルを正常に作成できます。しかし、mp4形式が壊れているようです。

ffprobeを使用すると、次のエラーが表示されます。

$ ffprobe o.mp4 
[h264 @ 0x209fe50] non-existing PPS 0 referenced 
[h264 @ 0x209fe50] decode_slice_header error 
[h264 @ 0x209fe50] no frame! 
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x209ea60] decoding for stream 0 failed 
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x209ea60] Could not find codec parameters for stream 0 (Video: h264 (avc1/0x31637661), none, 568x320, 505 kb/s): unspecified pixel format 

それから私は、情報が正しいかどうかを確認するためにmp4infoツールを使用します。私はこれを見つけました。ファイルのhexdumpに対して内容によって

$ mp4info o.mp4 
mp4info version 2.0.0 
o.mp4: 
ReadProperties: atom 'avcC' is too small; overrun at property: configurationVersion (src/mp4atom.cpp,386) 
mp4info: can't open o.mp4 

私は

if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER) { 
    // oc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; 
} 

ffprobeAVCodecContextにグローバルヘッダーを追加しなかった場合、私はエラーなしでフォーマットを検出することができ、この

$ xxd o.mp4 |grep -A 5 -B 5 avcC 
0039170: 6331 0000 0000 0000 0001 0000 0000 0000 c1.............. 
0039180: 0000 0000 0000 0000 0000 0238 0140 0048 [email protected] 
0039190: 0000 0048 0000 0000 0000 0001 0000 0000 ...H............ 
00391a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 
00391b0: 0000 0000 0000 0000 0000 0000 0018 ffff ................ 
00391c0: 0000 0008 6176 6343 0000 0020 7374 7473 ....avcC... stts 
00391d0: 0000 0000 0000 0002 0000 004f 0000 0ea6 ...........O.... 
00391e0: 0000 0001 0000 0000 0000 0058 7374 7373 ...........Xstss 
00391f0: 0000 0000 0000 0012 0000 0001 0000 0005 ................ 
0039200: 0000 000a 0000 000f 0000 0014 0000 0019 ................ 
0039210: 0000 001e 0000 0023 0000 0028 0000 0029 .......#...(...) 

を得ました、またffplayを再生することができます。しかし、avcCアトムは依然として正しくありません。他のプレイヤーは再生できません。

muxerが正しいavcCアトムを書き込んでいないのはなぜですか?

どうすれば解決できますか?

答えて

1

解決済み。この問題は新しいバージョンのffmpegでのみ発生しました。

ffmpeg api avformat_write_header/av_write_tailerを呼び出すと、のデータが使用されます。AVStream->codecは推奨されなくなりました。

avcodec_open2の後に余分なデータが入力されるため、余分なデータをAVStream->codecparにコピーする必要があります。

stream->codecpar->extradata = av_malloc(oc_ctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); 
stream->codecpar->extradata_size = oc_ctx->extradata_size; 
memcpy(stream->codecpar->extradata, oc_ctx->extradata, oc_ctx->extradata_size); 

もffmpegのプロジェクトで見つけることができ、同様のコードスニペットffmpeg.c

if (!ost->st->codecpar->extradata && avctx->extradata) { 
    ost->st->codecpar->extradata = av_malloc(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); 
    if (!ost->st->codecpar->extradata) { 
     av_log(NULL, AV_LOG_ERROR, "Could not allocate extradata buffer to copy parser data.\n"); 
     exit_program(1); 
    }  
    ost->st->codecpar->extradata_size = avctx->extradata_size; 
    memcpy(ost->st->codecpar->extradata, avctx->extradata, avctx->extradata_size); 
} 
関連する問題