xref: /aosp_15_r20/external/v4l2_codec2/common/NalParser.cpp (revision 0ec5a0ec62797f775085659156625e7f1bdb369f)
1 // Copyright 2021 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 //#define LOG_NDEBUG 0
6 #define LOG_TAG "NalParser"
7 
8 #include <algorithm>
9 
10 #include <v4l2_codec2/common/NalParser.h>
11 
12 #include <media/stagefright/foundation/ABitReader.h>
13 
14 namespace android {
15 
NalParser(const uint8_t * data,size_t length)16 NalParser::NalParser(const uint8_t* data, size_t length)
17       : mCurrNalDataPos(data), mDataEnd(data + length) {
18     mNextNalStartCodePos = findNextStartCodePos();
19 }
20 
locateNextNal()21 bool NalParser::locateNextNal() {
22     if (mNextNalStartCodePos == mDataEnd) return false;
23     mCurrNalDataPos = mNextNalStartCodePos + kNalStartCodeLength;  // skip start code.
24     mNextNalStartCodePos = findNextStartCodePos();
25     return true;
26 }
27 
data() const28 const uint8_t* NalParser::data() const {
29     return mCurrNalDataPos;
30 }
31 
length() const32 size_t NalParser::length() const {
33     if (mNextNalStartCodePos == mDataEnd) return mDataEnd - mCurrNalDataPos;
34     size_t length = mNextNalStartCodePos - mCurrNalDataPos;
35     // The start code could be 3 or 4 bytes, i.e., 0x000001 or 0x00000001.
36     return *(mNextNalStartCodePos - 1) == 0x00 ? length - 1 : length;
37 }
38 
findNextStartCodePos() const39 const uint8_t* NalParser::findNextStartCodePos() const {
40     return std::search(mCurrNalDataPos, mDataEnd, kNalStartCode,
41                        kNalStartCode + kNalStartCodeLength);
42 }
43 
44 // Read unsigned int encoded with exponential-golomb.
parseUE(ABitReader * br,uint32_t * val)45 bool NalParser::parseUE(ABitReader* br, uint32_t* val) {
46     uint32_t numZeroes = 0;
47     uint32_t bit;
48     if (!br->getBitsGraceful(1, &bit)) return false;
49     while (bit == 0) {
50         ++numZeroes;
51         if (!br->getBitsGraceful(1, &bit)) return false;
52     }
53     if (!br->getBitsGraceful(numZeroes, val)) return false;
54     *val += (1u << numZeroes) - 1;
55     return true;
56 }
57 
58 // Read signed int encoded with exponential-golomb.
parseSE(ABitReader * br,int32_t * val)59 bool NalParser::parseSE(ABitReader* br, int32_t* val) {
60     uint32_t codeNum;
61     if (!parseUE(br, &codeNum)) return false;
62     *val = (codeNum & 1) ? (codeNum + 1) >> 1 : -static_cast<int32_t>(codeNum >> 1);
63     return true;
64 }
65 
66 }  // namespace android
67