1 // Copyright (C) 2019 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // A parser for H.264 bitstream. It will determine will kind of Netowrk
16 // Abstraction Layer Unit (NALU) we have received from the guest.
17 
18 #pragma once
19 
20 #include <cstdint>
21 #include <string>
22 
23 namespace android {
24 namespace emulation {
25 
26 // All H.264 frames are structured in the following way:
27 //
28 // ===============================================================================
29 // | start code header | forbidden zero bit | nal_ref_idc | nal_unit_type | data |
30 // | 3 or 4 bytes      | 1 bit              | 2 bits      | 5 bits        | any  |
31 // ===============================================================================
32 //
33 // - Start code header:
34 //
35 //   Can be either 0x00 00 01 or 0x00 00 00 01. The start code header indicates where
36 //   each Network Abstraction Layer Unit (NALU) begins, since this is a continuous
37 //   stream of data.
38 //
39 // - forbidden zero bit:
40 //
41 //   Used as an error-indicator. 0 means the transmission is normal, while 1 means there
42 //   is a syntax violation.
43 //
44 // - nal_ref_idc:
45 //
46 //   Indicates whether the NALU is a reference field, frame or picture.
47 //
48 // - nal_unit_type:
49 //
50 //   The type of data contained in the frame. See H264NaluType below for a list of the types.
51 //
52 
53 class H264NaluParser {
54 public:
55 enum class H264NaluType : uint8_t {
56     Unspecified0 = 0,
57     CodedSliceNonIDR = 1,
58     CodedSlicePartitionA = 2,
59     CodedSlicePartitionB = 3,
60     CodedSlicePartitionC = 4,
61     CodedSliceIDR = 5,
62     SEI = 6,
63     SPS = 7,
64     PPS = 8,
65     AccessUnitDelimiter = 9,
66     EndOfSequence = 10,
67     EndOfStream = 11,
68     FillerData = 12,
69     SPSExtension = 13,
70     PrefixNALU = 14,
71     SPSSubset = 15,
72     Reserved0 = 16,
73     Reserved1 = 17,
74     Reserved2 = 18,
75     CodedSliceAuxiliary = 19,
76     CodedSliceExtension = 20,
77     CodedSliceExtDepthComponents = 21,
78     Reserved3 = 22,
79     Reserved4 = 23,
80     STAP_A = 24,
81     STAP_B = 25,
82     MTAP16 = 26,
83     MTAP24 = 27,
84     FU_A = 28,
85     FU_B = 29,
86     Unspecified1 = 30,
87     Unspecified2 = 31,
88     Undefined = 32, // not in H.264 nalu type; just here to cap the enums so checking is simpler.
89 };
90 
91 static bool checkSpsFrame(const uint8_t* frame, size_t szBytes);
92 static bool checkPpsFrame(const uint8_t* frame, size_t szBytes);
93 static bool checkIFrame(const uint8_t* frame, size_t szBytes);
94 // Returns the description of the H264NaluType.
95 static const std::string& naluTypeToString(H264NaluType n);
96 // Parses |frame| for the NALU type. |szBytes| is the size of |frame|, |data| will be set to
97 // the location after the start code header. This means that the first byte of |data| will still
98 // contain the NALU type in the lower 5-bits.
99 static H264NaluType getFrameNaluType(const uint8_t* frame, size_t szBytes, uint8_t** data = nullptr);
100 
101 // Finds the position of the next start code header. Returns null if not found, otherwise returns
102 // a pointer to the beginning of the next start code header.
103 static const uint8_t* getNextStartCodeHeader(const uint8_t* frame, size_t szBytes);
104 };
105 
106 }  // namespace emulation
107 }  // namespace android
108