File: avc_bitstream.h

package info (click to toggle)
libvpl-tools 1.4.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 7,652 kB
  • sloc: cpp: 107,469; python: 4,303; ansic: 3,202; sh: 159; lisp: 52; makefile: 13
file content (200 lines) | stat: -rw-r--r-- 7,810 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/*############################################################################
  # Copyright (C) 2005 Intel Corporation
  #
  # SPDX-License-Identifier: MIT
  ############################################################################*/
#ifndef __AVC_BITSTREAM_H_
#define __AVC_BITSTREAM_H_

#include "avc_headers.h"
#include "avc_structures.h"
#include "vpl/mfxstructures.h"

namespace ProtectedLibrary {

#define AVCPeek1Bit(current_data, offset) ((current_data[0] >> (offset)) & 1)

#define AVCDrop1Bit(current_data, offset) \
    {                                     \
        offset -= 1;                      \
        if (offset < 0) {                 \
            offset = 31;                  \
            current_data += 1;            \
        }                                 \
    }

// NAL unit definitions
enum { NAL_STORAGE_IDC_BITS = 0x60, NAL_UNITTYPE_BITS = 0x1f };

class AVCBaseBitstream {
public:
    AVCBaseBitstream();
    AVCBaseBitstream(mfxU8* const pb, const mfxU32 maxsize);
    virtual ~AVCBaseBitstream();

    // Reset the bitstream with new data pointer
    void Reset(mfxU8* const pb, mfxU32 maxsize);
    void Reset(mfxU8* const pb, mfxI32 offset, mfxU32 maxsize);

    inline mfxU32 GetBits(mfxU32 nbits);

    // Read one VLC mfxI32 or mfxU32 value from bitstream
    mfxI32 GetVLCElement(bool bIsSigned);

    // Reads one bit from the buffer.
    inline mfxU32 Get1Bit();

    // Check amount of data
    bool More_RBSP_Data();

    inline mfxU32 BytesDecoded();

    inline mfxU32 BitsDecoded();

    inline mfxU32 BytesLeft();

    mfxStatus GetNALUnitType(NAL_Unit_Type& uNALUnitType, mfxU8& uNALStorageIDC);
    void AlignPointerRight(void);

protected:
    mfxU32* m_pbs; // pointer to the current position of the buffer.
    mfxI32 m_bitOffset; // the bit position (0 to 31) in the dword pointed by m_pbs.
    mfxU32* m_pbsBase; // pointer to the first byte of the buffer.
    mfxU32 m_maxBsSize; // maximum buffer size in bytes.
};

class AVCHeadersBitstream : public AVCBaseBitstream {
public:
    AVCHeadersBitstream();
    AVCHeadersBitstream(mfxU8* const pb, const mfxU32 maxsize);

    // Decode sequence parameter set
    mfxStatus GetSequenceParamSet(AVCSeqParamSet* sps);
    // Decode sequence parameter set extension
    mfxStatus GetSequenceParamSetExtension(AVCSeqParamSetExtension* sps_ex);

    // Decoding picture's parameter set functions
    mfxStatus GetPictureParamSetPart1(AVCPicParamSet* pps);
    mfxStatus GetPictureParamSetPart2(AVCPicParamSet* pps, const AVCSeqParamSet* sps);

    mfxStatus GetSliceHeaderPart1(AVCSliceHeader* pSliceHeader);
    // Decoding slice header functions
    mfxStatus GetSliceHeaderPart2(AVCSliceHeader* hdr, // slice header read goes here
                                  const AVCPicParamSet* pps,
                                  const AVCSeqParamSet* sps); // from slice header NAL unit

    mfxStatus GetSliceHeaderPart3(AVCSliceHeader* hdr, // slice header read goes here
                                  PredWeightTable* pPredWeight_L0, // L0 weight table goes here
                                  PredWeightTable* pPredWeight_L1, // L1 weight table goes here
                                  RefPicListReorderInfo* pReorderInfo_L0,
                                  RefPicListReorderInfo* pReorderInfo_L1,
                                  AdaptiveMarkingInfo* pAdaptiveMarkingInfo,
                                  const AVCPicParamSet* pps,
                                  const AVCSeqParamSet* sps,
                                  mfxU8 NALRef_idc); // from slice header NAL unit

    mfxStatus GetNalUnitPrefix(AVCNalExtension* pExt, mfxU32 NALRef_idc);

    mfxI32 GetSEI(const HeaderSet<AVCSeqParamSet>& sps, mfxI32 current_sps, AVCSEIPayLoad* spl);

private:
    mfxStatus GetNalUnitExtension(AVCNalExtension* pExt);

    void GetScalingList4x4(AVCScalingList4x4* scl, mfxU8* def, mfxU8* scl_type);
    void GetScalingList8x8(AVCScalingList8x8* scl, mfxU8* def, mfxU8* scl_type);

    mfxI32 GetSEIPayload(const HeaderSet<AVCSeqParamSet>& sps,
                         mfxI32 current_sps,
                         AVCSEIPayLoad* spl);
    mfxI32 recovery_point(const HeaderSet<AVCSeqParamSet>& sps,
                          mfxI32 current_sps,
                          AVCSEIPayLoad* spl);
    mfxI32 reserved_sei_message(const HeaderSet<AVCSeqParamSet>& sps,
                                mfxI32 current_sps,
                                AVCSEIPayLoad* spl);

    mfxStatus GetVUIParam(AVCSeqParamSet* sps);
    mfxStatus GetHRDParam(AVCSeqParamSet* sps);
};

void SetDefaultScalingLists(AVCSeqParamSet* sps);

extern const mfxU32 bits_data[];

#define _avcGetBits(current_data, offset, nbits, data) \
    {                                                  \
        mfxU32 x;                                      \
                                                       \
        SAMPLE_ASSERT((nbits) > 0 && (nbits) <= 32);   \
        SAMPLE_ASSERT(offset >= 0 && offset <= 31);    \
                                                       \
        offset -= (nbits);                             \
                                                       \
        if (offset >= 0) {                             \
            x = current_data[0] >> (offset + 1);       \
        }                                              \
        else {                                         \
            offset += 32;                              \
                                                       \
            x = current_data[1] >> (offset);           \
            x >>= 1;                                   \
            x += current_data[0] << (31 - offset);     \
            current_data++;                            \
        }                                              \
                                                       \
        SAMPLE_ASSERT(offset >= 0 && offset <= 31);    \
                                                       \
        (data) = x & bits_data[nbits];                 \
    }

#define avcGetBits1(current_data, offset, data)     \
    {                                               \
        data = ((current_data[0] >> (offset)) & 1); \
        offset -= 1;                                \
        if (offset < 0) {                           \
            offset = 31;                            \
            current_data += 1;                      \
        }                                           \
    }

#define avcUngetNBits(current_data, offset, nbits)  \
    {                                               \
        SAMPLE_ASSERT(offset >= 0 && offset <= 31); \
                                                    \
        offset += (nbits);                          \
        if (offset > 31) {                          \
            offset -= 32;                           \
            current_data--;                         \
        }                                           \
                                                    \
        SAMPLE_ASSERT(offset >= 0 && offset <= 31); \
    }

#define avcGetNBits(current_data, offset, nbits, data) \
    _avcGetBits(current_data, offset, nbits, data);

inline mfxU32 AVCBaseBitstream::GetBits(mfxU32 nbits) {
    mfxU32 w, n = nbits;

    avcGetNBits(m_pbs, m_bitOffset, n, w);
    return w;
}

inline mfxU32 AVCBaseBitstream::Get1Bit() {
    mfxU32 w;
    avcGetBits1(m_pbs, m_bitOffset, w);
    return w;

} // AVCBitstream::Get1Bit()

inline mfxU32 AVCBaseBitstream::BytesDecoded() {
    return static_cast<mfxU32>((mfxU8*)m_pbs - (mfxU8*)m_pbsBase) + ((31 - m_bitOffset) >> 3);
}

inline mfxU32 AVCBaseBitstream::BytesLeft() {
    return ((mfxI32)m_maxBsSize - (mfxI32)BytesDecoded());
}

} // namespace ProtectedLibrary

#endif // __AVC_BITSTREAM_H_