x265-1.7版本-common/bitstream.h注释

本文介绍x265编码器中比特流处理的相关实现细节,包括比特流的写入操作、对齐操作及无符号和有符号指数哥伦布编码的使用。文章深入探讨了这些编码方式如何帮助提高编码效率。
注:问号以及未注释部分 会在x265-1.8版本内更新
/*****************************************************************************
 * Copyright (C) 2013 x265 project
 *
 * Author: Steve Borho <steve@borho.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
 *
 * This program is also available under a commercial proprietary license.
 * For more information, contact us at license @ x265.com.
 *****************************************************************************/

#ifndef X265_BITSTREAM_H
#define X265_BITSTREAM_H 1

namespace x265 {
// private namespace

class BitInterface
{
public:

    virtual void     write(uint32_t val, uint32_t numBits)  = 0;
    virtual void     writeByte(uint32_t val)                = 0;
    virtual void     resetBits()                            = 0;
    virtual uint32_t getNumberOfWrittenBits() const         = 0;
    virtual void     writeAlignOne()                        = 0;
    virtual void     writeAlignZero()                       = 0;
    virtual ~BitInterface() {}
};

class BitCounter : public BitInterface
{
protected:

    uint32_t  m_bitCounter;

public:

    BitCounter() : m_bitCounter(0) {}

    void     write(uint32_t, uint32_t num)  { m_bitCounter += num; }
    void     writeByte(uint32_t)            { m_bitCounter += 8;   }
    void     resetBits()                    { m_bitCounter = 0;    }
    uint32_t getNumberOfWrittenBits() const { return m_bitCounter; }
    void     writeAlignOne()                { }
    void     writeAlignZero()               { }
};


class Bitstream : public BitInterface
{
public:

    Bitstream();
    ~Bitstream()                             { X265_FREE(m_fifo); }

    void     resetBits()                     { m_partialByteBits = m_byteOccupancy = 0; m_partialByte = 0; }
    uint32_t getNumberOfWrittenBytes() const { return m_byteOccupancy; }
    uint32_t getNumberOfWrittenBits()  const { return m_byteOccupancy * 8 + m_partialByteBits; }
    const uint8_t* getFIFO() const           { return m_fifo; }

    void     write(uint32_t val, uint32_t numBits);
    void     writeByte(uint32_t val);

    void     writeAlignOne();      // insert one bits until the bitstream is byte-aligned
    void     writeAlignZero();     // insert zero bits until the bitstream is byte-aligned
    void     writeByteAlignment(); // insert 1 bit, then pad to byte-align with zero

private:

    uint8_t *m_fifo;
    uint32_t m_byteAlloc;
    uint32_t m_byteOccupancy;
    uint32_t m_partialByteBits;
    uint8_t  m_partialByte;

    void     push_back(uint8_t val);
};
/*
无符号指数哥伦布码占用的位数 (注意:实际编码中需要对原有数字加一 再获得指数哥伦布码,所以必须加一才是实际占用的位数)

指数哥伦布编码分为:无符号和有符号:
无符号哥伦布编码:
有前缀和后缀的概念:
1 先将要编码的数值写成二进制:0x6 ==> 0b110
2 以最高位为界(左边第一个1的位置),后面的就是后缀(就是二进制10了),总共两位,所以前缀也是两位,而且必须是0,
3 得出数值6编码后的二进制表示为:00110

解码就是反过程:
从高位开始统计0的个数直至非零位, 假设0的个数是k, 那后面k+1位就是要找的数值了
**/
static const uint8_t bitSize[256] =
{
    1, 1, 3, 3, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7,
    9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
};
/** 函数功能             : 获取无符号指数哥伦布码占用的位数
* \参数 val              : 当前待编码的值
* \返回                  : 无符号指数哥伦布码占用的位数 * */
static inline int bs_size_ue(unsigned int val)
{
    return bitSize[val + 1];//因为实际编码中需要先加一,固加一获得时间占用的位数
}

static inline int bs_size_ue_big(unsigned int val)
{
    if (val < 255)
        return bitSize[val + 1];
    else
        return bitSize[(val + 1) >> 8] + 16;
}
/*
无符号指数哥伦布码
先将编码系数映射为整数
-10 -->  20
-9 -->  18
-8 -->  16
-7 -->  14
-6 -->  12
-5 -->  10
-4 -->   8
-3 -->   6
-2 -->   4
-1 -->   2
0 -->   0
1 -->   1
2 -->   3
3 -->   5
4 -->   7
5 -->   9
6 -->  11
7 -->  13
8 -->  15
9 -->  17
10 -->  19
再调用无符号指数哥伦布码
**/
/** 函数功能             : 获取有符号指数哥伦布码占用的位数
* \参数 val              : 当前待编码的值
* \返回                  : 有符号指数哥伦布码占用的位数 * */
static inline int bs_size_se(int val)
{
    int tmp = 1 - val * 2;//这里:正数变负 负数变正  如果是负数 刚好就是对应val值+1

    if (tmp < 0) tmp = val * 2;//说明当前是正数  直接乘以2 刚好是对应val值+1  如10 对应为19 19+1=20
    if (tmp < 256)
        return bitSize[tmp];//获取bits (也是加一后数字)
    else
        return bitSize[tmp >> 8] + 16;//大于256情况
}

class SyntaxElementWriter
{
public:

    BitInterface* m_bitIf;

    SyntaxElementWriter() : m_bitIf(NULL) {}

    /* silently discard the name of the syntax element */
    inline void WRITE_CODE(uint32_t code, uint32_t length, const char *) { writeCode(code, length); }
    inline void WRITE_UVLC(uint32_t code,                  const char *) { writeUvlc(code); }
    inline void WRITE_SVLC(int32_t  code,                  const char *) { writeSvlc(code); }
    inline void WRITE_FLAG(bool flag,                      const char *) { writeFlag(flag); }

    void writeCode(uint32_t code, uint32_t length) { m_bitIf->write(code, length); }
    void writeUvlc(uint32_t code);
    void writeSvlc(int32_t code)                   { uint32_t ucode = (code <= 0) ? -code << 1 : (code << 1) - 1; writeUvlc(ucode); }
    void writeFlag(bool code)                      { m_bitIf->write(code, 1); }
};

}

#endif // ifndef X265_BITSTREAM_H
x265-1.7版本-common/bitstream.h注释
/data/k50048780/cpp_mutator/mutators/BitStream.cpp: In member function ‘BitStream BitStream::slice(size_t, size_t) const’: /data/k50048780/cpp_mutator/mutators/BitStream.cpp:154:46: error: passing ‘const BitStream’ as ‘this’ argument discards qualifiers [-fpermissive] 154 | copy_bits(*this, start_bit, 0, bit_length); | ^ In file included from /data/k50048780/cpp_mutator/mutators/BitStream.cpp:5: /data/k50048780/cpp_mutator/mutators/BitStream.h:62:10: note: in call to ‘void BitStream::copy_bits(const BitStream&, size_t, size_t, size_t)’ 62 | void copy_bits(const BitStream& src, size_t src_start, size_t dest_start, size_t bit_count); | ^~~~~~~~~ CMakeFiles/mutator.dir/build.make:446: recipe for target 'CMakeFiles/mutator.dir/mutators/BitStream.cpp.o' failed make[3]: *** [CMakeFiles/mutator.dir/mutators/BitStream.cpp.o] Error 1 make[3]: *** Waiting for unfinished jobs.... /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.cpp: In constructor ‘StringLengthEdgeCase::StringLengthEdgeCase(std::shared_ptr<StringBase>, std::mt19937)’: /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.cpp:10:37: error: no matching function for call to ‘IntegerEdgeCases::IntegerEdgeCases(std::shared_ptr<StringBase>&, std::mt19937&)’ 10 | : IntegerEdgeCases(obj, rand) { | ^ In file included from /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.h:10, from /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.cpp:5: /data/k50048780/cpp_mutator/mutators/string/../utils.h:146:5: note: candidate: ‘IntegerEdgeCases::IntegerEdgeCases(std::shared_ptr<NumberBase>, std::mt19937&)’ 146 | IntegerEdgeCases(std::shared_ptr<NumberBase> obj, std::mt19937 &rand); | ^~~~~~~~~~~~~~~~ /data/k50048780/cpp_mutator/mutators/string/../utils.h:146:50: note: no known conversion for argument 1 from ‘shared_ptr<StringBase>’ to ‘shared_ptr<NumberBase>’ 146 | IntegerEdgeCases(std::shared_ptr<NumberBase> obj, std::mt19937 &rand); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~ /data/k50048780/cpp_mutator/mutators/string/../utils.h:144:7: note: candidate: ‘IntegerEdgeCases::IntegerEdgeCases(const IntegerEdgeCases&)’ 144 | class IntegerEdgeCases : public Mutator { | ^~~~~~~~~~~~~~~~ /data/k50048780/cpp_mutator/mutators/string/../utils.h:144:7: note: candidate expects 1 argument, 2 provided /data/k50048780/cpp_mutator/mutators/string/../utils.h:144:7: note: candidate: ‘IntegerEdgeCases::IntegerEdgeCases(IntegerEdgeCases&&)’ /data/k50048780/cpp_mutator/mutators/string/../utils.h:144:7: note: candidate expects 1 argument, 2 provided /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.cpp: In member function ‘virtual std::pair<long int, long int> StringLengthEdgeCase::get_limits(std::shared_ptr<StringBase>)’: /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.cpp:24:25: error: request for member ‘has_value’ in ‘((std::__shared_ptr_access<StringBase, __gnu_cxx::_S_atomic, false, false>*)(& obj))->std::__shared_ptr_access<StringBase, __gnu_cxx::_S_atomic, false, false>::operator->()->StringBase::<anonymous>.TypeBase<StringBase>::max_length’, which is of non-class type ‘int64_t’ {aka ‘long int’} 24 | if (obj->max_length.has_value()) { | ^~~~~~~~~ /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.cpp:25:47: error: request for member ‘value’ in ‘((std::__shared_ptr_access<StringBase, __gnu_cxx::_S_atomic, false, false>*)(& obj))->std::__shared_ptr_access<StringBase, __gnu_cxx::_S_atomic, false, false>::operator->()->StringBase::<anonymous>.TypeBase<StringBase>::max_length’, which is of non-class type ‘int64_t’ {aka ‘long int’} 25 | max_ = std::min(max_, obj->max_length.value()); | ^~~~~ /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.cpp:29:25: error: request for member ‘has_value’ in ‘((std::__shared_ptr_access<StringBase, __gnu_cxx::_S_atomic, false, false>*)(& obj))->std::__shared_ptr_access<StringBase, __gnu_cxx::_S_atomic, false, false>::operator->()->StringBase::<anonymous>.TypeBase<StringBase>::min_length’, which is of non-class type ‘int64_t’ {aka ‘long int’} 29 | if (obj->min_length.has_value()) { | ^~~~~~~~~ /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.cpp:30:47: error: request for member ‘value’ in ‘((std::__shared_ptr_access<StringBase, __gnu_cxx::_S_atomic, false, false>*)(& obj))->std::__shared_ptr_access<StringBase, __gnu_cxx::_S_atomic, false, false>::operator->()->StringBase::<anonymous>.TypeBase<StringBase>::min_length’, which is of non-class type ‘int64_t’ {aka ‘long int’} 30 | min_ = std::max(min_, obj->min_length.value()); | ^~~~~ /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.cpp: At global scope: /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.cpp:42:6: error: no declaration matches ‘void StringLengthEdgeCase::perform_mutation(std::shared_ptr<StringBase>, int64_t)’ 42 | void StringLengthEdgeCase::perform_mutation(std::shared_ptr<StringBase> obj, int64_t value) { | ^~~~~~~~~~~~~~~~~~~~ In file included from /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.cpp:5: /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.h:16:10: note: candidate is: ‘void StringLengthEdgeCase::perform_mutation(std::shared_ptr<String>, size_t)’ 16 | void perform_mutation(std::shared_ptr<String> obj, size_t index); | ^~~~~~~~~~~~~~~~ /data/k50048780/cpp_mutator/mutators/string/StringLengthEdgeCase.h:13:7: note: ‘class StringLengthEdgeCase’ defined here 13 | class StringLengthEdgeCase : public IntegerEdgeCases { | ^~~~~~~~~~~~~~~~~~~~ In file included from /data/k50048780/cpp_mutator/mutators/MutatorFactory.cpp:8: /data/k50048780/cpp_mutator/mutators/number/NumberVariance.h:13:32: error: invalid covariant return type for ‘virtual std::pair<long unsigned int, long unsigned int> NumberVariance::get_limits(std::shared_ptr<NumberBase>)’ 13 | std::pair<size_t ,size_t > get_limits(std::shared_ptr<NumberBase> obj); | ^~~~~~~~~~ In file included from /data/k50048780/cpp_mutator/mutators/string/../../utils/sample_util.h:12, from /data/k50048780/cpp_mutator/mutators/string/StringCaseLower.h:8, from /data/k50048780/cpp_mutator/mutators/MutatorFactory.cpp:6: /data/k50048780/cpp_mutator/mutators/string/../../utils/../mutators/utils.h:70:51: note: overridden function is ‘virtual std::pair<long int, long int> IntegerVariance::get_limits(std::shared_ptr<NumberBase>)’ 70 | virtual std::pair<std::int64_t, std::int64_t> get_limits(std::shared_ptr<NumberBase> obj); | ^~~~~~~~~~
06-28
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值