H.264 Akışı için Sıra / Resim Parametre Set (ler) i için Olası Konumlar


84

Bir H.264 Kod Çözücü üzerinde çalışıyorum ve SPS ve PPS'yi nerede bulacağımı merak ediyorum. Referans literatürüm bana bunların H.264-Stream'de kodlanmış NAL Birimleri olduğunu söylüyor, ancak IsoViewer ile bir örnek-MP4-Dosyasına baktığımda, SPS ve PPS'nin avcC Kutusunda olduğunu söylüyor.

Bu tam olarak nasıl çalışıyor? .Mkv dosyalarını veya diğer H.264 kapsayıcılarını nasıl arar?

Şimdiden teşekkürler!

Yanıtlar:


300

Öncelikle, tek bir standart H.264 temel bit akışı biçiminin olmadığını anlamak önemlidir. Şartname belgesi, olası bir formatı tanımlayan bir Ek, ​​özellikle Ek B içerir, ancak bu gerçek bir gereklilik değildir. Standart, videonun tek tek paketlere nasıl kodlandığını belirtir. Bu paketlerin nasıl saklandığı ve iletildiği, entegratör için açık bırakılır.


1. Ek B

Ağ Soyutlama Katmanı Birimleri

Paketlere Ağ Soyutlama Katmanı Birimleri adı verilir. Genellikle kısaltılmış NALU (veya bazen sadece NAL), her paket ayrı ayrı ayrıştırılabilir ve işlenebilir. Her NALU'nun ilk baytı, NALU tipini, özellikle 3 ila 7. bitleri içerir (bit 0 her zaman kapalıdır ve 1-2 bitleri, bir NALU'ya başka bir NALU tarafından başvurulup başvurulmadığını gösterir).

VCL ve VCL olmayan olmak üzere iki kategoriye ayrılmış olarak tanımlanmış 19 farklı NALU türü vardır:

  • VCL veya Video Kodlama Katmanı paketleri, gerçek görsel bilgileri içerir.
  • VCL olmayanlar, videonun kodunu çözmek için gerekli olabilecek veya olmayabilecek meta veriler içerir.

Tek bir NALU veya hatta bir VCL NALU, çerçeve ile aynı şey DEĞİLDİR. Bir çerçeve birkaç NALU'ya 'dilimlenebilir'. Tıpkı pizzayı dilimleyebildiğin gibi. Bir veya daha fazla dilim daha sonra sanal olarak bir çerçeve içeren bir Erişim Birimlerine (AU) gruplanır. Dilimlemenin düşük bir kalite maliyeti vardır, bu nedenle sıklıkla kullanılmaz.

Aşağıda, tüm tanımlanmış NALU'ların bir tablosu bulunmaktadır.

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

Daha sonra bilgi sahibi olmanın yardımcı olabileceği birkaç NALU türü vardır.

  • Sıra Parametre Seti (SPS). Bu VCL olmayan NALU, profil, seviye, çözünürlük, kare hızı gibi kod çözücüyü yapılandırmak için gerekli bilgileri içerir.
  • Resim Parametre Seti (PPS). SPS'ye benzer şekilde, bu VCL olmayan entropi kodlama modu, dilim grupları, hareket tahmini ve deblokaj filtreleri hakkında bilgi içerir.
  • Anında Kod Çözücü Yenileme (IDR). Bu VCL NALU, kendi kendine yeten bir görüntü dilimidir. Yani, bir IDR'nin kodu çözülebilir ve başka herhangi bir NALU kaydetme SPS ve PPS'ye referans verilmeden görüntülenebilir.
  • Erişim Birimi Sınırlayıcı (AUD). AUD, temel bir akıştaki çerçeveleri sınırlandırmak için kullanılabilen isteğe bağlı bir NALU'dur. Gerekli değildir (TS gibi konteyner / protokol tarafından aksi belirtilmedikçe) ve genellikle yer kazanmak için dahil edilmez, ancak her bir NALU'yu tam olarak ayrıştırmak zorunda kalmadan bir çerçevenin başlangıcını bulmak faydalı olabilir.

NALU Başlangıç ​​Kodları

Bir NALU'nun boyutu yoktur. Bu nedenle, bir akış oluşturmak için NALU'ları basitçe birleştirmek işe yaramayacaktır çünkü birinin nerede durduğunu ve bir sonrakinin nerede başladığını bilmeyeceksiniz.

Ek B spesifikasyonu, her NALU'dan önce 'Başlangıç ​​Kodları'nı gerektirerek bunu çözer. Başlangıç ​​kodu 2 veya 3 0x00bayt ve ardından bir 0x01bayttır. örneğin 0x000001veya 0x00000001.

4 bayt varyasyonu, bir seri bağlantı üzerinden iletim için kullanışlıdır, çünkü akışı bayt hizalamak için 31 sıfır bit ve ardından bir tane aramak önemsizdir. Sonraki bit 0 ise (çünkü her NALU 0 bit ile başlar), bu bir NALU'nun başlangıcıdır. 4 bayt varyasyonu genellikle yalnızca akıştaki bir SPS PPS AUD ve IDR gibi rastgele erişim noktalarına sinyal göndermek için kullanılır. Burada 3 bayt varyasyonu, yerden tasarruf etmek için her yerde kullanılır.

Emülasyon Önleme Baytları

Başlangıç kodları işe dört bayt dizileri nedeniyle 0x000000, 0x000001, 0x000002ve 0x000003olmayan bir RBSF Nalu içinde yasadışı. Bu nedenle, bir NALU oluştururken, aksi takdirde bir başlangıç ​​koduyla karıştırılabilecek bu değerlerden kaçınmaya özen gösterilir. Bu 'Benzetim Önleme' byte eklenmesi ile sağlanır 0x03, böylece 0x000001olur 0x00000301.

Kod çözerken, öykünme önleme baytlarını aramak ve yok saymak önemlidir. Öykünme önleme baytları bir NALU içinde hemen hemen her yerde ortaya çıkabildiğinden, belgelerde zaten kaldırılmış olduklarını varsaymak genellikle daha uygundur. Öykünme önleme baytları olmayan bir temsil, Ham Bayt Sırası Yükü (RBSP) olarak adlandırılır.

Misal

Tam bir örneğe bakalım.

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

Bu, 3 NALU içeren eksiksiz bir AU'dur. Gördüğünüz gibi, bir Başlangıç ​​kodu ile başlıyoruz ve ardından bir SPS (SPS 67 ile başlıyor). SPS içinde iki Emülasyon Engelleme baytı göreceksiniz. Bu baytlar olmadan 0x000000, bu konumlarda geçersiz dizi meydana gelir. Daha sonra bir başlangıç ​​kodu ve ardından bir PPS (PPS 68 ile başlar) ve bir son başlangıç ​​kodu ve ardından bir IDR dilimi göreceksiniz. Bu tam bir H.264 akışıdır. Bu değerleri bir onaltılık düzenleyiciye .264yazarsanız ve dosyayı bir uzantıyla kaydederseniz , bu resme dönüştürebilirsiniz:

Lena

Ek B, genellikle aktarım akışları, havadan yayınlar ve DVD'ler gibi canlı ve akış biçimlerinde kullanılır. Bu formatlarda SPS ve PPS'nin periyodik olarak tekrarlanması yaygındır, genellikle her IDR'den önce gelir, böylece kod çözücü için rastgele bir erişim noktası oluşturulur. Bu, halihazırda devam eden bir akışa katılma olanağını sağlar.


2. AVCC

Bir H.264 akışını depolamanın diğer yaygın yöntemi AVCC biçimidir. Bu formatta, her NALU'nun önünde uzunluğu (büyük endian formatında) bulunur. Bu yöntemin ayrıştırılması daha kolaydır, ancak Ek B'nin bayt hizalama özelliklerini kaybedersiniz. İşleri karmaşıklaştırmak için uzunluk 1, 2 veya 4 bayt kullanılarak kodlanabilir. Bu değer, bir başlık nesnesinde saklanır. Bu başlık genellikle 'extradata' veya 'sıra başlığı' olarak adlandırılır. Temel biçimi aşağıdaki gibidir:

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

Yukarıdaki aynı örneği kullanarak, AVCC ekstradata şu şekilde görünecektir:

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

SPS ve PPS'nin artık bant dışında depolandığını fark edeceksiniz. Yani, temel akış verilerinden ayrıdır. Bu verilerin saklanması ve iletilmesi, dosya kabının işidir ve bu belgenin kapsamı dışındadır. Başlatma kodlarını kullanmasak bile, öykünme önleme baytlarının hala eklendiğine dikkat edin.

Ek olarak, adında yeni bir değişken var NALULengthSizeMinusOne. Bu kafa karıştırıcı bir şekilde adlandırılmış değişken, bize her NALU'nun uzunluğunu depolamak için kaç bayt kullanılacağını söyler. Dolayısıyla, NALULengthSizeMinusOne0 olarak ayarlanmışsa, her NALU'nun önünde uzunluğunu gösteren tek bir bayt bulunur. Boyutu saklamak için tek bir bayt kullanıldığında, bir NALU'nun maksimum boyutu 255 bayttır. Bu açıkça oldukça küçük. Tüm bir anahtar çerçeve için çok küçük. 2 bayt kullanmak bize NALU başına 64k verir. Örneğimizde işe yarayacaktır, ancak yine de oldukça düşük bir sınırdır. 3 bayt mükemmel olurdu, ancak bazı nedenlerden dolayı evrensel olarak desteklenmiyor. Bu nedenle, 4 bayt en yaygın olanıdır ve burada kullandığımız şey budur:

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

Bu formatın bir avantajı, kod çözücüyü bir akışın başlangıcında konfigüre etme ve ortasına atlama yeteneğidir. Bu, medyanın sabit sürücü gibi rastgele erişim ortamında mevcut olduğu ve bu nedenle MP4 ve MKV gibi yaygın konteyner formatlarında kullanıldığı yaygın bir kullanım durumudur.


3
Teşekkürler adamım, bu bana gerçekten yardımcı oldu! Yine de makalenizde bazı yazım hataları var ... Sanırım;) Bazen VCL'den 'VLC' olarak bahsediyorsunuz, bu oldukça kafa karıştırıcı olabilir çünkü VLC'yi 'değişken uzunluklu kodlama' olarak biliyorum. Ama yine de makaleniz benim için birkaç şeyi açıklığa kavuşturdu, iyi iş çıkardınız! Ve ... üzgünüm size oy veremem, burada yeniyim ve burada bir tür yeni filtre var;)
bananenbär

6
Evet, yazım hataları için üzgünüm. Ben biraz disleksim ve çok zayıf bir daktilo. Haklısın. VLC'nin bu metinde yeri yoktur.
szatmary

2
Harika özet! Bu bana gerçekten yardımcı oldu. 2. (AVCC) bayt kümesine yakından bakıldığında açık olsa da, NALU verisinden önce gelen 4 bayt uzunluk değerinin Big-Endian formatında olduğuna dikkat çekmek gerektiğini düşünüyorum. Uzunluk değerinin bayt takas edilmesi gerektiğini fark edene kadar akışı iOS'ta çözemedim.
12on

1
Çok teşekkürler dostum! BTW, Windows Media Foundation h264 kod çözücü yalnızca "Ek B" örnekleri istiyor. Neyse ki, bunları Ek B ve AVCC arasında dönüştürmek oldukça basit.
Yakında

2
AVCC ekstradata örneğinin 0x0022 ofsetinde eksik bir sıfır bayt var mı? Biçim açıklaması PPS boyutu için 16 bitlik bir alan olduğunu söylüyor, bu yüzden 0x00 0x07bunun sadece yerine olması gerektiğini düşünüyorum 0x07.
rhashimoto
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.