• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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