2012-06-18 6 views
6

Próbuję jednocześnie odczytać i zapisać plik mov H.264 napisany przez AVAssetWriter. Udało mi się wyodrębnić poszczególne jednostki NAL, spakować je do AVPackets ffmpeg i zapisać je w innym formacie wideo za pomocą ffmpeg. Działa i wynikowy plik jest dobrze odtwarzany, ale prędkość odtwarzania jest niewłaściwa. Jak obliczyć poprawne wartości PTS/DTS na podstawie surowych danych H.264? A może istnieje inny sposób ich zdobycia?Pobierz PTS z surowego H264 mdat wygenerowanego przez iOS AVAssetWriter

Oto co próbowałem:

  1. Limit przechwytywania min/max do 30 klatek na sekundę i zakładamy, że plik wyjściowy będzie 30 fps. W rzeczywistości jego fps jest zawsze mniejszy niż ustawione przeze mnie wartości. I myślę, że fps nie jest stały od pakietu do pakietu.

  2. Zapamiętaj oznaczenie czasowe każdej próbki z zapisaną próbką i przyjmij, że próbki mapują jeden do jednego na NALU i stosują zapisany znacznik czasu do pakietu wyjściowego. To nie działa.

  3. Ustawienie PTS na 0 lub AV_NOPTS_VALUE. Nie działa.

Z googlowania na ten temat Rozumiem, że surowe dane H.264 zwykle nie zawierają żadnych informacji o czasie. Może czasami mieć pewne informacje o czasie wewnątrz SEI, ale pliki, których używam, nie mają go. Z drugiej strony istnieją aplikacje, które robią dokładnie to, co próbuję zrobić, więc przypuszczam, że jest to jakoś możliwe.

+2

Próbuję jednocześnie odczytać H.264 z pliku mov napisanego przez AVAssetWriter i nie mogłem tego zrobić za pomocą rur/zwykłego odczytu pliku. Jak udało ci się go przeczytać podczas pisania? Dzięki! –

+3

Skorzystaj ze zwykłego odczytu pliku, ale zamiast zatrzymywać ponownie na EOF. Prędzej czy później twoja operacja czytania się powiedzie. – kolyuchiy

+2

@kolyuchiy - źródła wysyłki lepiej wykorzystują system. Skonfiguruj źródło odczytu na deskryptorze PLIKU. Blok zostanie wywołany, gdy będą dane do odczytania. Jeśli pojawi się EOF, po prostu usuń błąd z pliku. –

Odpowiedz

5

Będziesz musiał je wygenerować samodzielnie lub uzyskać dostęp do informacji o taktowaniu zawierających atom w pojemniku MP4/MOV w celu wygenerowania informacji PTS/DTS. Pomocna może być funkcja mov.c w pliku libavformat firmy FFmpeg.

Każda próbka/ramka zapisana za pomocą AVAssetWriter będzie mapować jeden do jednego za pomocą NAL VCL. Jeśli wszystko, co robisz, to konwersja, wtedy FFmpeg wykona wszystkie ciężkie operacje podnoszenia. Będzie prawidłowo zachowywać informacje o czasie, przechodząc z jednego formatu do drugiego.

Strumień wygenerowany przez AVAssetWriter nie zawiera danych SEI. Zawiera tylko ramki SPS/PPS/I/P. SPS również nie zawiera parametrów VUI ani HRD.

- Edit -

Ponadto, należy pamiętać, że jeśli zapisywanie informacji PTS Odtąd podstawy czasowej CMSampleBufferRef może być różna od pojemnika docelowego. Na przykład baza czasu AVFoundation to nanosekundy, a plik FLV to milisekundy.

+1

Dzięki! Właściwie CMSampleBuffers naprawdę zawierają poprawny PTS, który mapuje na pakiety wyjściowe. Byłem zbyt leniwy, aby przejść całą drogę w tym kierunku. To rozwiązało mój problem. – kolyuchiy

Powiązane problemy