2013-04-09 12 views
7

Ich versuche, rohe H264 in einem mp4-Container mit der FFMPEG-API in C++ zu codieren. Es funktioniert alles gut, aber die AVCC Box leer ist, und es gibt den Fehler: [ISO-Datei] Box „AVcc“ Größe 8 ungültigC++ FFMPEG nicht schreiben AVCC-Box-Informationen

Wenn ich dann das Kommandozeilen-Tool auf der Ausgabedatei verwenden: ffmpeg - i output.mp4 -vcodec Kopieren fixed.mp4

Die Ausgabedatei funktioniert und AVCC ist mit den erforderlichen Informationen ausgefüllt. Ich weiß nicht, warum dieses Befehlszeilenargument funktioniert, aber ich kann nicht das gleiche Ergebnis mit der API erzeugen.

Was ich in der C++ tun Code (auch tun, die Dinge zwischen den Funktionsaufrufen):

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_); 

Der Ausgang dieses korrekt ist, außer es die AVCC Informationen fehlt. Das Hinzufügen ist manuell (und die Boxlängen entsprechend zu fixieren) lässt mich das Video gut wiedergeben. Irgendeine Idee, warum die API-Aufrufe die AVCC-Informationen nicht generieren?

Als Referenz sind hier die Zeichen aus dem mp4 vor dem Fix: .avc1 ......................... € .8.H ... H .......................................... ÿÿ ... .avcC .... stts

und nachher: ​​ avc1 ......................... € .8.H ... H .......................................... ÿÿ ...! avcC.B € (Úá..gB € (Ú.à.- • ... hB < € .... stts

Antwort

3

Gelöst es. Die Daten, die erforderlich waren, waren die SPS- und PPS-Komponenten des AVCC-Codec roher H264-Strom war im Anhang b-Format, dies war am Anfang jedes I-Rahmens vorhanden, in den NAL-Einheiten beginnend mit 0x00 0x00 0x00 0x01 0x6 7 und 0x00 0x00 0x00 0x01 0x68. Also, was benötigt wurde, war, dass die Informationen in die AVStream Codecs Extrainformationen Feld zu kopieren:

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(); 

Das im AVCC Feld geführt korrekt aufgefüllt werden.

+0

Ich konfrontiert mit dem gleichen Problem, wenn Frame von der Kamera erfassen, und codieren zu h264 in MP4-Container. Hast du eine Idee, wie kann ich 'Extradata' einstellen? – alijandro

+0

Gibt Ihre Kameradaten h264 aus? Wenn ja, suchen Sie nach den PPS- und SPS-Blöcken (0x00 0x00 0x00 0x01 0x67 bzw. 0x00 0x00 0x00 0x01 0x68). – awr

+0

Vielen Dank für Ihre Antwort. Es ist ein Problem, das durch die API der neuen Version von ffmpeg verursacht wird. Durch das Kopieren der Extradata von AVCodecContext nach AVStream-> codecpar-> extradata werden diese Probleme behoben. – alijandro

2

Ich hatte das Problem mit leeren AVCC-Boxen mit meinen MP4-Dateien zu. Es stellte sich heraus, dass ich CODEC_FLAG_GLOBAL_HEADER Flagge auf der AVCodecContext Instanz nach Anruf avcodec_open2. Das Flag sollte voravcodec_open2 aufrufen.