// Copyright (C) 2019 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // A parser for H.264 bitstream. It will determine will kind of Netowrk // Abstraction Layer Unit (NALU) we have received from the guest. #pragma once #include #include namespace android { namespace emulation { // All H.264 frames are structured in the following way: // // =============================================================================== // | start code header | forbidden zero bit | nal_ref_idc | nal_unit_type | data | // | 3 or 4 bytes | 1 bit | 2 bits | 5 bits | any | // =============================================================================== // // - Start code header: // // Can be either 0x00 00 01 or 0x00 00 00 01. The start code header indicates where // each Network Abstraction Layer Unit (NALU) begins, since this is a continuous // stream of data. // // - forbidden zero bit: // // Used as an error-indicator. 0 means the transmission is normal, while 1 means there // is a syntax violation. // // - nal_ref_idc: // // Indicates whether the NALU is a reference field, frame or picture. // // - nal_unit_type: // // The type of data contained in the frame. See H264NaluType below for a list of the types. // class H264NaluParser { public: enum class H264NaluType : uint8_t { Unspecified0 = 0, CodedSliceNonIDR = 1, CodedSlicePartitionA = 2, CodedSlicePartitionB = 3, CodedSlicePartitionC = 4, CodedSliceIDR = 5, SEI = 6, SPS = 7, PPS = 8, AccessUnitDelimiter = 9, EndOfSequence = 10, EndOfStream = 11, FillerData = 12, SPSExtension = 13, PrefixNALU = 14, SPSSubset = 15, Reserved0 = 16, Reserved1 = 17, Reserved2 = 18, CodedSliceAuxiliary = 19, CodedSliceExtension = 20, CodedSliceExtDepthComponents = 21, Reserved3 = 22, Reserved4 = 23, STAP_A = 24, STAP_B = 25, MTAP16 = 26, MTAP24 = 27, FU_A = 28, FU_B = 29, Unspecified1 = 30, Unspecified2 = 31, Undefined = 32, // not in H.264 nalu type; just here to cap the enums so checking is simpler. }; static const std::string kNaluTypesStrings[]; static bool checkSpsFrame(const uint8_t* frame, size_t szBytes); static bool checkPpsFrame(const uint8_t* frame, size_t szBytes); static bool checkIFrame(const uint8_t* frame, size_t szBytes); // Returns the description of the H264NaluType. static const std::string& naluTypeToString(H264NaluType n); // Parses |frame| for the NALU type. |szBytes| is the size of |frame|, |data| will be set to // the location after the start code header. This means that the first byte of |data| will still // contain the NALU type in the lower 5-bits. static H264NaluType getFrameNaluType(const uint8_t* frame, size_t szBytes, uint8_t** data = nullptr); // Finds the position of the next start code header. Returns null if not found, otherwise returns // a pointer to the beginning of the next start code header. static const uint8_t* getNextStartCodeHeader(const uint8_t* frame, size_t szBytes); }; } // namespace emulation } // namespace android