Możliwe lokalizacje zestawów parametrów sekwencji / obrazu dla strumienia H. 264

Pracuję nad dekoderem H. 264 i zastanawiam się gdzie znaleźć SPS i PPS. Moja Literatura referencyjna mówi mi, że są to jednostki NAL zakodowane w Strumieniu H. 264, ale kiedy patrzę na przykład-plik MP4 z IsoViewer, mówi, że SPS i PPS są w polu avcC.

Jak to dokładnie działa? Jak to wygląda .pliki mkv czy inne kontenery H. 264?

Z góry dzięki!

Author: bananenbär, 2014-07-22

2 answers

Po pierwsze, ważne jest, aby zrozumieć, że nie ma jednego standardowego formatu podstawowego strumienia bitów H. 264. Dokument specyfikacji zawiera załącznik, w szczególności Załącznik B, który opisuje jeden możliwy format, ale nie jest to rzeczywisty wymóg. Standard określa sposób kodowania wideo w poszczególnych pakietach. Sposób przechowywania i przesyłania tych pakietów pozostaje otwarty dla integratora.


1. Załącznik B

Warstwa Abstrakcji Sieci Jednostki

Pakiety nazywane są jednostkami warstwy abstrakcji sieciowej. Często skracane NALU (lub czasami po prostu NAL) każdy pakiet może być indywidualnie parsowany i przetwarzany. Pierwszy bajt każdego NALU zawiera typ NALU, konkretnie bity od 3 do 7. (bit 0 jest zawsze wyłączony, a bity 1-2 wskazują, czy NALU odnosi się do innego NALU).

Istnieje 19 różnych typów NALU podzielonych na dwie kategorie, VCL i non-VCL:

  • VCL, czyli kodowanie wideo Pakiety warstw zawierają rzeczywiste informacje wizualne.
  • inne niż VCL zawierają metadane, które mogą, ale nie muszą być wymagane do dekodowania wideo.
Pojedynczy NALU, a nawet VCL NALU to nie to samo co ramka. Ramkę można "pokroić" na kilka Nalusów. Tak jak ty możesz kroić pizzę. Jeden lub więcej plastrów jest następnie praktycznie zgrupowanych w jednostki dostępu (AU), które zawierają jedną ramkę. Krojenie ma niewielki koszt jakości, więc nie jest często używany.

Poniżej znajduje się tabela wszystkich zdefiniowanych Nalusów.

0      Unspecified                                                    non-VCL
1      Coded slice of a non-IDR picture                               VCL
2      Coded slice data partition A                                   VCL
3      Coded slice data partition B                                   VCL
4      Coded slice data partition C                                   VCL
5      Coded slice of an IDR picture                                  VCL
6      Supplemental enhancement information (SEI)                     non-VCL
7      Sequence parameter set                                         non-VCL
8      Picture parameter set                                          non-VCL
9      Access unit delimiter                                          non-VCL
10     End of sequence                                                non-VCL
11     End of stream                                                  non-VCL
12     Filler data                                                    non-VCL
13     Sequence parameter set extension                               non-VCL
14     Prefix NAL unit                                                non-VCL
15     Subset sequence parameter set                                  non-VCL
16     Depth parameter set                                            non-VCL
17..18 Reserved                                                       non-VCL
19     Coded slice of an auxiliary coded picture without partitioning non-VCL
20     Coded slice extension                                          non-VCL
21     Coded slice extension for depth view components                non-VCL
22..23 Reserved                                                       non-VCL
24..31 Unspecified                                                    non-VCL

Jest kilka rodzajów NALU, w których znajomość może być pomocna później.

  • zestaw parametrów sekwencji (SPS). ten nie-VCL NALU zawiera informacje wymagane do konfiguracji dekodera, takie jak profil, poziom, rozdzielczość, liczba klatek na sekundę.
  • zestaw parametrów obrazu (PPS). podobnie jak SPS, ten non-VCL zawiera informacje o trybie kodowania entropii, grupach plasterków, przewidywaniu ruchu i deblockingu filtry.
  • natychmiastowe Odświeżanie dekodera (IDR). ten VCL NALU jest samodzielnym wycinkiem obrazu. Oznacza to, że IDR może być dekodowany i wyświetlany bez odwoływania się do innych NALU save SPS i PPS.
  • Ogranicznik jednostek dostępu (AUD). AUD jest opcjonalnym NALU, który może być użyty do rozdzielania ramek w strumieniu elementarnym. Nie jest wymagany (o ile nie określono inaczej w kontenerze/protokole, takim jak TS) i często nie jest uwzględniany w celu zaoszczędzenia miejsca, ale może przydaje się, aby znaleźć początek ramki bez konieczności pełnego parsowania każdego NALU.

Kody startowe NALU

NALU nie zawiera swojej wielkości. Dlatego po prostu połączenie Nalusa w celu utworzenia strumienia nie zadziała, ponieważ nie będziesz wiedział, gdzie jeden się zatrzymuje, a następny się zaczyna.

Specyfikacja załącznika B rozwiązuje ten problem, wymagając, aby "kody startowe" poprzedzały poszczególne NALU. Kod startowy to 2 lub 3 0x00 bajty, po których następuje 0x01 bajt. np. 0x000001 lub 0x00000001.

Wariant 4-bajtowy jest przydatny do transmisji przez łącze szeregowe, ponieważ jest trywialne, aby bajt wyrównał strumień, szukając 31 bitów zerowych, po których następuje Jedynka. Jeśli następnym bitem jest 0 (ponieważ każdy NALU zaczyna się od bitu 0), jest to początek NALU. Wariacja 4-bajtowa jest zwykle używana tylko do sygnalizowania losowych punktów dostępu w strumieniu, takich jak SPS PPS AUD i IDR, gdzie jako wariacja 3-bajtowa jest używana wszędzie indziej, aby zaoszczędzić miejsce.

Zapobieganie Emulacji Bajty

Kody startowe działają, ponieważ cztery sekwencje bajtowe0x000000, 0x000001, 0x000002 i 0x000003 są nielegalne w ramach Nie-RBSP NALU. Tak więc podczas tworzenia NALU, należy zachować ostrożność, aby uniknąć tych wartości, które w przeciwnym razie mogłyby być mylone z kodem startowym. Jest to możliwe dzięki wstawieniu bajtu "zapobieganie Emulacjom" 0x03, tak że 0x000001 staje się 0x00000301.

Podczas dekodowania ważne jest, aby szukać i ignorować bajty zapobiegające emulacji. Ponieważ mogą wystąpić bajty zapobiegające emulacji prawie wszędzie w obrębie NALU, często wygodniej jest w dokumentacji zakładać, że zostały już usunięte. Reprezentacja bez emulacji prevention bajtów jest nazywana Raw Byte Sequence Payload (RBSP).

Przykład

Spójrzmy na kompletny przykład.
0x0000 | 00 00 00 01 67 64 00 0A AC 72 84 44 26 84 00 00
0x0010 | 03 00 04 00 00 03 00 CA 3C 48 96 11 80 00 00 00
0x0020 | 01 68 E8 43 8F 13 21 30 00 00 01 65 88 81 00 05
0x0030 | 4E 7F 87 DF 61 A5 8B 95 EE A4 E9 38 B7 6A 30 6A
0x0040 | 71 B9 55 60 0B 76 2E B5 0E E4 80 59 27 B8 67 A9
0x0050 | 63 37 5E 82 20 55 FB E4 6A E9 37 35 72 E2 22 91
0x0060 | 9E 4D FF 60 86 CE 7E 42 B7 95 CE 2A E1 26 BE 87
0x0070 | 73 84 26 BA 16 36 F4 E6 9F 17 DA D8 64 75 54 B1
0x0080 | F3 45 0C 0B 3C 74 B3 9D BC EB 53 73 87 C3 0E 62
0x0090 | 47 48 62 CA 59 EB 86 3F 3A FA 86 B5 BF A8 6D 06
0x00A0 | 16 50 82 C4 CE 62 9E 4E E6 4C C7 30 3E DE A1 0B
0x00B0 | D8 83 0B B6 B8 28 BC A9 EB 77 43 FC 7A 17 94 85
0x00C0 | 21 CA 37 6B 30 95 B5 46 77 30 60 B7 12 D6 8C C5
0x00D0 | 54 85 29 D8 69 A9 6F 12 4E 71 DF E3 E2 B1 6B 6B
0x00E0 | BF 9F FB 2E 57 30 A9 69 76 C4 46 A2 DF FA 91 D9
0x00F0 | 50 74 55 1D 49 04 5A 1C D6 86 68 7C B6 61 48 6C
0x0100 | 96 E6 12 4C 27 AD BA C7 51 99 8E D0 F0 ED 8E F6
0x0110 | 65 79 79 A6 12 A1 95 DB C8 AE E3 B6 35 E6 8D BC
0x0120 | 48 A3 7F AF 4A 28 8A 53 E2 7E 68 08 9F 67 77 98
0x0130 | 52 DB 50 84 D6 5E 25 E1 4A 99 58 34 C7 11 D6 43
0x0140 | FF C4 FD 9A 44 16 D1 B2 FB 02 DB A1 89 69 34 C2
0x0150 | 32 55 98 F9 9B B2 31 3F 49 59 0C 06 8C DB A5 B2
0x0160 | 9D 7E 12 2F D0 87 94 44 E4 0A 76 EF 99 2D 91 18
0x0170 | 39 50 3B 29 3B F5 2C 97 73 48 91 83 B0 A6 F3 4B
0x0180 | 70 2F 1C 8F 3B 78 23 C6 AA 86 46 43 1D D7 2A 23
0x0190 | 5E 2C D9 48 0A F5 F5 2C D1 FB 3F F0 4B 78 37 E9
0x01A0 | 45 DD 72 CF 80 35 C3 95 07 F3 D9 06 E5 4A 58 76
0x01B0 | 03 6C 81 20 62 45 65 44 73 BC FE C1 9F 31 E5 DB
0x01C0 | 89 5C 6B 79 D8 68 90 D7 26 A8 A1 88 86 81 DC 9A
0x01D0 | 4F 40 A5 23 C7 DE BE 6F 76 AB 79 16 51 21 67 83
0x01E0 | 2E F3 D6 27 1A 42 C2 94 D1 5D 6C DB 4A 7A E2 CB
0x01F0 | 0B B0 68 0B BE 19 59 00 50 FC C0 BD 9D F5 F5 F8
0x0200 | A8 17 19 D6 B3 E9 74 BA 50 E5 2C 45 7B F9 93 EA
0x0210 | 5A F9 A9 30 B1 6F 5B 36 24 1E 8D 55 57 F4 CC 67
0x0220 | B2 65 6A A9 36 26 D0 06 B8 E2 E3 73 8B D1 C0 1C
0x0230 | 52 15 CA B5 AC 60 3E 36 42 F1 2C BD 99 77 AB A8
0x0240 | A9 A4 8E 9C 8B 84 DE 73 F0 91 29 97 AE DB AF D6
0x0250 | F8 5E 9B 86 B3 B3 03 B3 AC 75 6F A6 11 69 2F 3D
0x0260 | 3A CE FA 53 86 60 95 6C BB C5 4E F3

To jest kompletny AU zawierający 3 NALUs. Jak widać, zaczynamy od kodu startowego, a następnie SPS (SPS zaczyna się od 67). W SPS zobaczysz dwa bajty zapobiegania emulacji. Bez te bajty nielegalna Sekwencja 0x000000 wystąpiłaby w tych miejscach. Następnie zobaczysz kod startowy, a następnie PPS (PPS zaczyna się od 68) i jeden końcowy kod startowy, a następnie plasterek IDR. To kompletny Strumień H. 264. Jeśli wpiszesz te wartości do edytora szesnastkowego i zapiszesz plik z rozszerzeniem .264, będziesz mógł przekonwertować go na ten obraz:

Lena

Załącznik B jest powszechnie stosowany w formatach transmisji na żywo i strumieniowych, takich jak strumienie transportowe, transmisje w powietrzu, i DVD. W tych formatach często powtarza się okresowo SPS i PPS, Zwykle poprzedzając każdy IDR, tworząc w ten sposób losowy punkt dostępu dla dekodera. Umożliwia to dołączenie do już trwającego strumienia.


2. AVCC

Inną popularną metodą przechowywania strumienia H. 264 jest format AVCC. W tym formacie każda NALU poprzedzona jest swoją długością(w formacie big endian). Ta metoda jest łatwiejsza do przetworzenia, ale tracisz funkcje wyrównania bajtów z załącznika B. Aby skomplikować sprawę, długość może być zakodowana za pomocą 1, 2 lub 4 bajtów. Wartość ta jest przechowywana w obiekcie nagłówka. Ten nagłówek jest często nazywany "extradata" lub "sequence header". Jego podstawowy format jest następujący:
bits    
8   version ( always 0x01 )
8   avc profile ( sps[0][1] )
8   avc compatibility ( sps[0][2] )
8   avc level ( sps[0][3] )
6   reserved ( all bits on )
2   NALULengthSizeMinusOne
3   reserved ( all bits on )
5   number of SPS NALUs (usually 1)
repeated once per SPS:
  16     SPS size
  variable   SPS NALU data
8   number of PPS NALUs (usually 1)
repeated once per PPS
  16    PPS size
  variable PPS NALU data

Używając tego samego przykładu powyżej, avcc extadata będzie wyglądać następująco:

0x0000 | 01 64 00 0A FF E1 00 19 67 64 00 0A AC 72 84 44
0x0010 | 26 84 00 00 03 00 04 00 00 03 00 CA 3C 48 96 11
0x0020 | 80 01 00 07 68 E8 43 8F 13 21 30

Zauważysz, że SPS i PPS są teraz przechowywane poza pasmem. Oznacza to, że oddzielone od podstawowych danych strumienia. Przechowywanie i przesyłanie tych danych jest zadaniem kontenera plików, i poza zakresem niniejszego dokumentu. Zauważ, że nawet jeśli nie używamy kodów startowych, bajty zapobiegania emulacji są nadal wstawiane.

Dodatkowo istnieje nowa zmienna o nazwie NALULengthSizeMinusOne. Ta mylnie nazwana zmienna mówi nam, ile bajtów użyć do przechowywania długości każdego NALU. Jeśli więc NALULengthSizeMinusOne jest ustawione na 0, to każdy NALU jest poprzedzony pojedynczym bajtem wskazującym jego długość. Przy użyciu pojedynczego bajtu do przechowywania rozmiaru, maksymalny rozmiar NALU wynosi 255 bajtów. To jest oczywiście dość mały. Za mała na całą ramkę. Użycie 2 bajtów daje nam 64k na NALU. Zadziałałoby to w naszym przykładzie, ale nadal jest to dość niski limit. 3 bajty byłyby idealne, ale z jakiegoś powodu nie są powszechnie obsługiwane. Dlatego 4 bajty są zdecydowanie najczęstsze i to jest to, czego tutaj użyliśmy:

0x0000 | 00 00 02 41 65 88 81 00 05 4E 7F 87 DF 61 A5 8B
0x0010 | 95 EE A4 E9 38 B7 6A 30 6A 71 B9 55 60 0B 76 2E
0x0020 | B5 0E E4 80 59 27 B8 67 A9 63 37 5E 82 20 55 FB
0x0030 | E4 6A E9 37 35 72 E2 22 91 9E 4D FF 60 86 CE 7E
0x0040 | 42 B7 95 CE 2A E1 26 BE 87 73 84 26 BA 16 36 F4
0x0050 | E6 9F 17 DA D8 64 75 54 B1 F3 45 0C 0B 3C 74 B3
0x0060 | 9D BC EB 53 73 87 C3 0E 62 47 48 62 CA 59 EB 86
0x0070 | 3F 3A FA 86 B5 BF A8 6D 06 16 50 82 C4 CE 62 9E
0x0080 | 4E E6 4C C7 30 3E DE A1 0B D8 83 0B B6 B8 28 BC
0x0090 | A9 EB 77 43 FC 7A 17 94 85 21 CA 37 6B 30 95 B5
0x00A0 | 46 77 30 60 B7 12 D6 8C C5 54 85 29 D8 69 A9 6F
0x00B0 | 12 4E 71 DF E3 E2 B1 6B 6B BF 9F FB 2E 57 30 A9
0x00C0 | 69 76 C4 46 A2 DF FA 91 D9 50 74 55 1D 49 04 5A
0x00D0 | 1C D6 86 68 7C B6 61 48 6C 96 E6 12 4C 27 AD BA
0x00E0 | C7 51 99 8E D0 F0 ED 8E F6 65 79 79 A6 12 A1 95
0x00F0 | DB C8 AE E3 B6 35 E6 8D BC 48 A3 7F AF 4A 28 8A
0x0100 | 53 E2 7E 68 08 9F 67 77 98 52 DB 50 84 D6 5E 25
0x0110 | E1 4A 99 58 34 C7 11 D6 43 FF C4 FD 9A 44 16 D1
0x0120 | B2 FB 02 DB A1 89 69 34 C2 32 55 98 F9 9B B2 31
0x0130 | 3F 49 59 0C 06 8C DB A5 B2 9D 7E 12 2F D0 87 94
0x0140 | 44 E4 0A 76 EF 99 2D 91 18 39 50 3B 29 3B F5 2C
0x0150 | 97 73 48 91 83 B0 A6 F3 4B 70 2F 1C 8F 3B 78 23
0x0160 | C6 AA 86 46 43 1D D7 2A 23 5E 2C D9 48 0A F5 F5
0x0170 | 2C D1 FB 3F F0 4B 78 37 E9 45 DD 72 CF 80 35 C3
0x0180 | 95 07 F3 D9 06 E5 4A 58 76 03 6C 81 20 62 45 65
0x0190 | 44 73 BC FE C1 9F 31 E5 DB 89 5C 6B 79 D8 68 90
0x01A0 | D7 26 A8 A1 88 86 81 DC 9A 4F 40 A5 23 C7 DE BE
0x01B0 | 6F 76 AB 79 16 51 21 67 83 2E F3 D6 27 1A 42 C2
0x01C0 | 94 D1 5D 6C DB 4A 7A E2 CB 0B B0 68 0B BE 19 59
0x01D0 | 00 50 FC C0 BD 9D F5 F5 F8 A8 17 19 D6 B3 E9 74
0x01E0 | BA 50 E5 2C 45 7B F9 93 EA 5A F9 A9 30 B1 6F 5B
0x01F0 | 36 24 1E 8D 55 57 F4 CC 67 B2 65 6A A9 36 26 D0
0x0200 | 06 B8 E2 E3 73 8B D1 C0 1C 52 15 CA B5 AC 60 3E
0x0210 | 36 42 F1 2C BD 99 77 AB A8 A9 A4 8E 9C 8B 84 DE
0x0220 | 73 F0 91 29 97 AE DB AF D6 F8 5E 9B 86 B3 B3 03
0x0230 | B3 AC 75 6F A6 11 69 2F 3D 3A CE FA 53 86 60 95
0x0240 | 6C BB C5 4E F3

Zaletą tego formatu jest możliwość skonfigurowania dekodera na początku i przeskoczenia do środka strumienia. Jest to powszechny przypadek użycia, w którym media są dostępne na nośniku dostępu losowego, takim jak dysk twardy, i dlatego jest używany w popularnych formatach kontenerów, takich jak MP4 i MKV.

 209
Author: szatmary,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-15 22:55:00

Ostatnio pracowałem nad czymś takim.

Sprawdź Inspektora mp4. Jak widać na tym zdjęciu mp4 ma wiele pól, które muszą być przetwarzane, aby znaleźć potrzebne dane.

Tutaj wpisz opis obrazka

Tutaj oznaczyłem części pudełka avcc

Tutaj wpisz opis obrazka

Jestem świeżo po napisaniu bloga multi post o moim radzeniu sobie z h264. Myślę, że to zbyt długo, aby pisać tutaj http://cagneymoreau.com/stream-video-android/

 0
Author: cagney,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-03 23:26:17