1 // Copyright (c) 2017 Intel Corporation
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in all
11 // copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 // SOFTWARE.
20 
21 #include "umc_defs.h"
22 #if defined (MFX_ENABLE_H264_VIDEO_DECODE)
23 
24 #ifndef __UMC_H264_NAL_SPL_H
25 #define __UMC_H264_NAL_SPL_H
26 
27 #include <vector>
28 #include "umc_h264_dec_defs_dec.h"
29 #include "umc_media_data_ex.h"
30 #include "umc_h264_heap.h"
31 
32 namespace UMC
33 {
34 
35 inline
IsItAllowedCode(int32_t iCode)36 bool IsItAllowedCode(int32_t iCode)
37 {
38     return ((NAL_UT_SLICE <= (iCode & NAL_UNITTYPE_BITS)) &&
39         (NAL_UT_PPS >= (iCode & NAL_UNITTYPE_BITS)) &&
40         (NAL_UT_SEI != (iCode & NAL_UNITTYPE_BITS))) ||
41         (NAL_UT_SPS_EX == (iCode & NAL_UNITTYPE_BITS)) ||
42         (NAL_UT_AUXILIARY == (iCode & NAL_UNITTYPE_BITS));
43 } // bool IsItAllowedCode(int32_t iCode)
44 
45 inline
IsHeaderCode(int32_t iCode)46 bool IsHeaderCode(int32_t iCode)
47 {
48     return (NAL_UT_SPS == (iCode & NAL_UNITTYPE_BITS)) ||
49            (NAL_UT_SPS_EX == (iCode & NAL_UNITTYPE_BITS)) ||
50            (NAL_UT_PPS == (iCode & NAL_UNITTYPE_BITS)) ||
51            (NAL_UT_SUBSET_SPS == (iCode & NAL_UNITTYPE_BITS));
52 }
53 
54 inline
IsVLCCode(int32_t iCode)55 bool IsVLCCode(int32_t iCode)
56 {
57     return ((NAL_UT_SLICE <= (iCode & NAL_UNITTYPE_BITS)) &&
58            (NAL_UT_IDR_SLICE >= (iCode & NAL_UNITTYPE_BITS))) ||
59            (NAL_UT_AUXILIARY == (iCode & NAL_UNITTYPE_BITS)) ||
60            (NAL_UT_CODED_SLICE_EXTENSION == (iCode & NAL_UNITTYPE_BITS));
61 }
62 
63 class MediaData;
64 class NALUnitSplitter;
65 
66 class NalUnit : public MediaData
67 {
68 public:
NalUnit()69     NalUnit()
70         : MediaData()
71         , m_nal_unit_type(NAL_UT_UNSPECIFIED)
72         , m_use_external_memory(false)
73     {
74     }
75 
GetNalUnitType()76     NAL_Unit_Type GetNalUnitType() const
77     {
78         return (NAL_Unit_Type)m_nal_unit_type;
79     }
80 
IsUsedExternalMem()81     bool IsUsedExternalMem() const
82     {
83         return m_use_external_memory;
84     }
85 
86     int m_nal_unit_type;
87     bool m_use_external_memory;
88 };
89 
90 class SwapperBase
91 {
92 public:
~SwapperBase()93     virtual ~SwapperBase() {}
94 
95     virtual void SwapMemory(uint8_t *pDestination, size_t &nDstSize, uint8_t *pSource, size_t nSrcSize) = 0;
96     virtual void SwapMemory(H264MemoryPiece * pMemDst, H264MemoryPiece * pMemSrc, uint8_t defaultValue = DEFAULT_NU_TAIL_VALUE) = 0;
97 
98     virtual void CopyBitStream(uint8_t *pDestination, uint8_t *pSource, size_t &nSrcSize) = 0;
99 };
100 
101 class StartCodeIteratorBase
102 {
103 public:
104 
StartCodeIteratorBase()105     StartCodeIteratorBase()
106         : m_pSource(0)
107         , m_nSourceSize(0)
108         , m_pSourceBase(0)
109         , m_nSourceBaseSize(0)
110         , m_suggestedSize(10 * 1024)
111     {
112     }
113 
~StartCodeIteratorBase()114     virtual ~StartCodeIteratorBase()
115     {
116     }
117 
Init(MediaData * pSource)118     virtual int32_t Init(MediaData * pSource)
119     {
120         m_pSourceBase = m_pSource = (uint8_t *) pSource->GetDataPointer();
121         m_nSourceBaseSize = m_nSourceSize = pSource->GetDataSize();
122         return -1;
123     }
124 
GetCurrentOffset()125     int32_t GetCurrentOffset()
126     {
127         return (int32_t)(m_pSource - m_pSourceBase);
128     }
129 
SetSuggestedSize(size_t size)130     virtual void SetSuggestedSize(size_t size)
131     {
132         if (size > m_suggestedSize)
133             m_suggestedSize = size;
134     }
135 
136     virtual int32_t GetNext() = 0;
137 
138     virtual int32_t CheckNalUnitType(MediaData * pSource) = 0;
139     virtual int32_t MoveToStartCode(MediaData * pSource) = 0;
140     virtual int32_t GetNALUnit(MediaData * pSource, NalUnit * pDst) = 0;
141 
142     virtual void Reset() = 0;
143 
144 protected:
145     uint8_t * m_pSource;
146     size_t  m_nSourceSize;
147 
148     uint8_t * m_pSourceBase;
149     size_t  m_nSourceBaseSize;
150 
151     size_t  m_suggestedSize;
152 };
153 
154 class NALUnitSplitter
155 {
156 public:
157 
158     NALUnitSplitter();
159 
160     virtual ~NALUnitSplitter();
161 
162     virtual void Init();
163     virtual void Release();
164 
165     virtual int32_t CheckNalUnitType(MediaData * pSource);
166     virtual int32_t MoveToStartCode(MediaData * pSource);
167     virtual NalUnit * GetNalUnits(MediaData * in);
168 
169     virtual void Reset();
170 
SetSuggestedSize(size_t size)171     virtual void SetSuggestedSize(size_t size)
172     {
173         if (!m_pStartCodeIter)
174             return;
175 
176         m_pStartCodeIter->SetSuggestedSize(size);
177     }
178 
GetSwapper()179     SwapperBase * GetSwapper()
180     {
181         return m_pSwapper;
182     }
183 
184 protected:
185 
186     SwapperBase *   m_pSwapper;
187     StartCodeIteratorBase * m_pStartCodeIter;
188 
189     NalUnit     m_nalUnit;
190 };
191 
192 } // namespace UMC
193 
194 #endif // __UMC_H264_NAL_SPL_H
195 #endif // MFX_ENABLE_H264_VIDEO_DECODE
196