2013-04-09 12 views
7

Próbuję kodować surowe H264 do kontenera mp4 przy użyciu FFMPEG API w C++. To wszystko działa dobrze, jednak pole AVCC jest pusta, i zwraca błąd: [plik iso] Box „AVCC” rozmiar 8 nieprawidłowejC++ FFMPEG nie zapisywanie informacji o polu AVCC

Gdybym wtedy użyć narzędzia wiersza poleceń w pliku wyjściowym: ffmpeg - i output.mp4 -vcodec copy fixed.mp4

Plik wyjściowy działa, a AVCC jest wypełniony wymaganymi informacjami. Nie rozumiem, dlaczego ten argument wiersza polecenia działa, ale nie mogę wygenerować tego samego wyniku za pomocą interfejsu API.

Co zrobić w C++ kod (również robić rzeczy między wywołań funkcji):

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

Wyjście to jest prawidłowe, z wyjątkiem to brakuje AVCC informacji. Dodanie tego jest ręczne (i odpowiednie ustawienie długości skrzynek) pozwala mi odtworzyć wideo w porządku. Każdy pomysł, dlaczego wywołania API nie generują informacji AVCC?

Tutaj znajdują się znaki z mp4 przed naprawą: .avc1 ......................... .8.H ... H .......................................... ÿÿ ... .avcC .... stts

i po: avc1 ......................... .8.H ... H .......................................... ÿÿ ...! avcC.B € (ÿá..gB € (Ú.à.- • ... hÎ < € ... stts

Odpowiedz

3

Rozwiązane, wymagane dane to komponenty SPS i PPS kodeka AVCC. surowy strumień H264 był w formacie b załącznika, był obecny na początku każdego I-ramka, w jednostkach NAL począwszy od 0x00 0x00 0x00 0x01 0x6 7 i 0x00 0x00 0x00 0x01 0x68. Więc co było potrzebne było skopiować te informacje do dodatkowymi danymi pola AVStream kodeka:

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

Spowodowało polu AVCC jest poprawnie wypełniona.

+0

Mam do czynienia z tym samym problemem, gdy przechwytuję ramkę z kamery i koduję do h264 wewnątrz kontenera mp4. Czy masz pojęcie, w jaki sposób mogę ustawić "extradata"? – alijandro

+0

Czy dane wyjściowe kamery h264? Jeśli tak, poszukaj bloków PPS i SPS (0x00 0x00 0x00 0x01 0x67 i 0x00 0x00 0x00 0x01 0x68). – awr

+0

Dziękuję za odpowiedź. Jest to problem powodowany przez nową API ffmpeg, kopiowanie danych z AVCodecContext do AVStream-> codecpar-> extradata naprawia ten problem. – alijandro

2

Miałem też problem z pustymi skrzynkami AVCC z moimi plikami MP4. Okazało się, że ustawiam flagę CODEC_FLAG_GLOBAL_HEADER na instancji AVCodecContextpo dzwoniąc pod numer avcodec_open2. Flaga powinna być ustawiona na przed dzwoniąc pod numer avcodec_open2.

Powiązane problemy