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