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