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