8

C++ で FFMPEG API を使用して生の H264 を mp4 コンテナーにエンコードしようとしています。すべて正常に動作しますが、AVCC ボックスが空で、次のエラーが返されます: [iso file] Box "avcC" size 8 invalid

次に、出力ファイルでコマンド ライン ツールを使用すると、次のようになります。

ffmpeg -i output.mp4 -vcodec copy fixed.mp4

出力ファイルが機能し、AVCC に必要な情報が取り込まれます。このコマンド ライン引数が機能する理由がわかりませんが、API を使用して同じ結果を生成することはできません。

C++ コードで行うこと (関数呼び出しの間でも行うこと):

outputFormat_ = av_guess_format( "mp4", NULL, NULL ); //AV_CODEC_H264
formatContext_ = avformat_alloc_context();
formatContext_->oformat = outputFormat_;
...
AVDictionary *opts = NULL;
char tmpstr[50]; sprintf(tmpstr, "%i", muxRate * KILOBYTESTOBYTES);
av_dict_set(&opts, "muxrate", tmpstr, 0);
avformat_write_header( formatContext_, &opts);
av_write_trailer(formatContext_);

これの出力は正しいですが、AVCC 情報が欠落しています。これを手動で追加すると(それに応じてボックスの長さを修正すると)、ビデオを正常に再生できます。API 呼び出しが AVCC 情報を生成しない理由は何ですか?

参考までに、修正前の mp4 の文字は次のとおりです。

.avc1........................€.8.H...H........ ............................ÿÿ....avcC....stts

以降:

avc1.................................................€.8.H...H................. ..........ÿÿ...!avcC.B€(ÿá..gB€(Ú.à.—•. ..hÎ<€....stts

4

2 に答える 2

5

解決しました。必要なデータは、AVCC コーデックの SPS および PPS コンポーネントでした。生の H264 ストリームは附属書 b 形式であったため、これはすべての I フレームの先頭に存在し、NAL ユニットは0x00 0x00 0x00 0x01 0x67および0x00 0x00 0x00 0x01 0x68. したがって、その情報を AVStream コーデックの extradata フィールドにコピーする必要がありました。

codecContext = stream->codec;

...

// videoSeqHeader contains the PPS and SPS NAL unit data
codecContext->extradata = (uint8_t*)malloc( sizeof(uint8_t) * videoSeqHeader_.size() );

for( unsigned int index = 0; index < videoSeqHeader_.size(); index++ )
{
    codecContext->extradata[index] = videoSeqHeader_[index];
}

codecContext->extradata_size = (int)videoSeqHeader_.size();

これにより、AVCC ボックスが正しく読み込まれました。

于 2013-04-10T01:40:58.437 に答える