ABitReader简介


前言

      在前一篇介绍了Extractor的整个框架以及关键的AnohterPacketSource之后, 我们来介绍一下Extractor中用来读取文件二进制bit数据的类. 她的芳名为: ABitReader(哈哈, 还真是顾名思义呀~).


1. 从"头"开始

      按照惯例, 我们首先来看一下这个类的头文件声明. 文件路径为: /frameworks/av/include/media/stagefright/fundation/ABitReader.h(我会在关键方法后加上本菜鸟自己的理解)

28class ABitReader {
29public:
30    ABitReader(const uint8_t *data, size_t size);
31    virtual ~ABitReader();
32
33    // Tries to get |n| bits. If not successful, returns |fallback|. Otherwise, returns result.
34    // Reading 0 bits will always succeed and return 0.
35    uint32_t getBitsWithFallback(size_t n, uint32_t fallback);
36
37    // Tries to get |n| bits. If not successful, returns false. Otherwise, stores result in |out|
38    // and returns true. Use !overRead() to determine if this call was successful. Reading 0 bits
39    // will always succeed and write 0 in |out|.
40    bool getBitsGraceful(size_t n, uint32_t *out);
41
42    // Gets |n| bits and returns result. ABORTS if unsuccessful. Reading 0 bits will always
43    // succeed.
44    uint32_t getBits(size_t n);
45
46    // Tries to skip |n| bits. Returns true iff successful. Skipping 0 bits will always succeed.
47    bool skipBits(size_t n);
48
49    // "Puts" |n| bits with the value |x| back virtually into the bit stream. The put-back bits
50    // are not actually written into the data, but are tracked in a separate buffer that can
51    // store at most 32 bits. This is a no-op if the stream has already been over-read.
52    void putBits(uint32_t x, size_t n);
53    //返回当前一共读了多少个bit
54    size_t numBitsLeft() const;
55    //返回本次读取bit时, 起始Byte的指针
56    const uint8_t *data() const;
57
58    // Returns true iff the stream was over-read (e.g. any getBits operation has been unsuccessful
59    // due to overread (and not trying to read >32 bits).)
60    bool overRead() const { return mOverRead; }
61
62protected:
63    const uint8_t *mData; //要开始读取的位置的指针
64    size_t mSize; //要读取的Byte数
65
66    uint32_t mReservoir;  // left-aligned bits
67    size_t mNumBitsLeft; //本次读取工作剩余bit数(多少bit是剩下的)
68    bool mOverRead; //标识是否读取bit越界
69    //这是个基本的函数,名字叫:"填充蓄水池". 作用是检查mOverRead, 如果没有OverReader, mNumBitsLedt记录读取了多少bit(8的倍数)
70    virtual bool fillReservoir();
71
72    DISALLOW_EVIL_CONSTRUCTORS(ABitReader);
73};
74
75class NALBitReader : public ABitReader {
76public:
77    NALBitReader(const uint8_t *data, size_t size);
78
79    bool atLeastNumBitsLeft(size_t n) const;
80
81private:
82    int32_t mNumZeros;
83
84    virtual bool fillReservoir();
85
86    DISALLOW_EVIL_CONSTRUCTORS(NALBitReader);
87};

2. 追寻本"源"

      这个头文件还是非常友好的说, 关键的方法都加了注释, 小弟只是在没有注释的地方, 加了点自己的理解.
      其实, 常用方法只有getBits或者是skipBits. 让我们一起来看下.

2.1. getBits

54 uint32_t ABitReader::getBits(size_t n) {
55    uint32_t ret;
56    CHECK(getBitsGraceful(n, &ret));
57    return ret;
58 }

      我们可以看到, 直接简单的调用了getBitGraceful, 然后将拿到的result放入ret中. 哈哈, 接下来看看是如何get bit Graceful(优雅的).

2.2 getBitsGraceful

66bool ABitReader::getBitsGraceful(size_t n, uint32_t *out) {
67    if (n > 32) {
68        return false;
69    }
70
71    uint32_t result = 0;
72    while (n > 0) {
73        if (mNumBitsLeft == 0) {
74            if (!fillReservoir()) {
75                return false;
76            }
77        }
78
79        size_t m = n;
80        if (m > mNumBitsLeft) {
81            m = mNumBitsLeft;
82        }
83
84        result = (result << m) | (mReservoir >> (32 - m));
85        mReservoir <<= m;
86        mNumBitsLeft -= m;
87
88        n -= m;
89    }
90
91    *out = result;
92    return true;
93}

67 - 69: 如果有人要搞事情, 一次性读取bit数超过了32, 那还是无情的返回false吧;

71 - 89: 开始循环读取bit位. 大家一定发现了一个有趣的方法fillReservoir(), 顾名思义, 他是一个容量最大为32bit的容器. 我们来看看他的实现.

34 bool ABitReader::fillReservoir() {
35    if (mSize == 0) {
36        mOverRead = true;
37        return false;
38    }
39
40    mReservoir = 0;
41    size_t i;
42    for (i = 0; mSize > 0 && i < 4; ++i) {
43        mReservoir = (mReservoir << 8) | *mData;
44
45        ++mData;
46        --mSize;
47    }
48
49    mNumBitsLeft = 8 * i;
50    mReservoir <<= 32 - mNumBitsLeft;
51    return true;
52}

35- 37: 如果读到mSize都没有了, 那就直接返回false吧;
42- 47: 逐个Byte(8bit去读mData指向的内容), 放入mReservoir;
49 - 50: 更新mNumBitsLeft, mReservoir;
之后就是更新下各私有变量的值, 以便下次读取之用.

91 - 92 把结果放入out, 返回读取成功true.

2.2. skipBits

95 bool ABitReader::skipBits(size_t n) {
96    uint32_t dummy;
97    while (n > 32) {
98        if (!getBitsGraceful(32, &dummy)) {
99            return false;
100        }
101        n -= 32;
102    }
103
104    if (n > 0) {
105        return getBitsGraceful(n, &dummy);
106    }
107    return true;
108}

96: 造一个假的接收数据的变量dummy;
97 - 108: 优雅的去使用getBitsGraceful去读取bit位, 反正读取出来的放在dummy中, 我们不用管. 这样就达到了我们skip n bit的目的.(有点意思)


小结

      这是Extractor中读取bit位做判断的基础. 核心方法是getBitsGracefulfillReservoir. 我们搞清楚他的实现, 对于以后自己写Extractror还是很有帮助的, (更何况, 他的命名规则和逻辑处理方法也比较有意思_).

你可能感兴趣的:(ABitReader简介)