1 // Copyright (c) 2017-2019 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_SLICE_DECODING_H
25 #define __UMC_H264_SLICE_DECODING_H
26
27 #include <list>
28 #include "umc_h264_dec_defs_dec.h"
29 #include "umc_h264_dec.h"
30 #include "umc_h264_bitstream_headers.h"
31 #include "umc_h264_heap.h"
32
33 namespace UMC
34 {
35 struct H264RefListInfo
36 {
37 int32_t m_iNumShortEntriesInList;
38 int32_t m_iNumLongEntriesInList;
39 int32_t m_iNumFramesInL0List;
40 int32_t m_iNumFramesInL1List;
41 int32_t m_iNumFramesInLTList;
42
H264RefListInfoH264RefListInfo43 H264RefListInfo()
44 : m_iNumShortEntriesInList(0)
45 , m_iNumLongEntriesInList(0)
46 , m_iNumFramesInL0List(0)
47 , m_iNumFramesInL1List(0)
48 , m_iNumFramesInLTList(0)
49 {
50 }
51 };
52
53 class H264MemoryPiece;
54 class H264DecoderFrame;
55 class H264DecoderFrameInfo;
56
57 struct ViewItem;
58 typedef std::list<ViewItem> ViewList;
59
60 class H264Slice : public HeapObject
61 {
62 // It is OK. H264SliceStore is owner of H264Slice object.
63 // He can do what he wants.
64 friend class H264SegmentDecoderMultiThreaded;
65 friend class TaskSupplier;
66 friend class TaskBroker;
67 friend class TaskBrokerTwoThread;
68 friend class H264DecoderFrameInfo;
69 friend void PrintInfoStatus(H264DecoderFrameInfo * info);
70
71 public:
72 // Default constructor
73 H264Slice(MemoryAllocator *pMemoryAllocator = 0);
74 // Destructor
75 virtual
76 ~H264Slice(void);
77
78 // Set slice source data
79 virtual bool Reset(UMC_H264_DECODER::H264NalExtension *pNalExt);
80 // Set current slice number
81 void SetSliceNumber(int32_t iSliceNumber);
82
83 virtual void FreeResources();
84
85
86 int32_t RetrievePicParamSetNumber();
87
88 //
89 // method(s) to obtain slice specific information
90 //
91
92 // Obtain pointer to slice header
GetSliceHeader(void)93 const UMC_H264_DECODER::H264SliceHeader *GetSliceHeader(void) const {return &m_SliceHeader;}
GetSliceHeader(void)94 UMC_H264_DECODER::H264SliceHeader *GetSliceHeader(void) {return &m_SliceHeader;}
95 // Obtain bit stream object
GetBitStream(void)96 H264HeadersBitstream *GetBitStream(void){return &m_BitStream;}
97 // Obtain prediction weigth table
GetPredWeigthTable(int32_t iNum)98 const UMC_H264_DECODER::PredWeightTable *GetPredWeigthTable(int32_t iNum) const {return m_PredWeight[iNum & 1];}
99 // Obtain first MB number
GetFirstMBNumber(void)100 int32_t GetFirstMBNumber(void) const {return m_iFirstMBFld;}
GetStreamFirstMB(void)101 int32_t GetStreamFirstMB(void) const {return m_iFirstMB;}
SetFirstMBNumber(int32_t x)102 void SetFirstMBNumber(int32_t x) {m_iFirstMB = x;}
103 // Obtain MB width
GetMBWidth(void)104 int32_t GetMBWidth(void) const {return m_iMBWidth;}
105 // Obtain MB row width
GetMBRowWidth(void)106 int32_t GetMBRowWidth(void) const {return (m_iMBWidth * (m_SliceHeader.MbaffFrameFlag + 1));}
107 // Obtain MB height
GetMBHeight(void)108 int32_t GetMBHeight(void) const {return m_iMBHeight;}
109 // Obtain current picture parameter set number
GetPicParamSet(void)110 int32_t GetPicParamSet(void) const {return m_pPicParamSet->pic_parameter_set_id;}
111 // Obtain current sequence parameter set number
GetSeqParamSet(void)112 int32_t GetSeqParamSet(void) const {return m_pSeqParamSet->seq_parameter_set_id;}
113 // Obtain current picture parameter set
GetPicParam(void)114 const UMC_H264_DECODER::H264PicParamSet *GetPicParam(void) const {return m_pPicParamSet;}
SetPicParam(const UMC_H264_DECODER::H264PicParamSet * pps)115 void SetPicParam(const UMC_H264_DECODER::H264PicParamSet * pps) {m_pPicParamSet = pps;}
116 // Obtain current sequence parameter set
GetSeqParam(void)117 const UMC_H264_DECODER::H264SeqParamSet *GetSeqParam(void) const {return m_pSeqParamSet;}
SetSeqParam(const UMC_H264_DECODER::H264SeqParamSet * sps)118 void SetSeqParam(const UMC_H264_DECODER::H264SeqParamSet * sps) {m_pSeqParamSet = sps;}
119
120 // Obtain current sequence extension parameter set
GetSeqParamEx(void)121 const UMC_H264_DECODER::H264SeqParamSetExtension *GetSeqParamEx(void) const {return m_pSeqParamSetEx;}
SetSeqExParam(const UMC_H264_DECODER::H264SeqParamSetExtension * spsex)122 void SetSeqExParam(const UMC_H264_DECODER::H264SeqParamSetExtension * spsex) {m_pSeqParamSetEx = spsex;}
123
GetSeqMVCParam(void)124 const UMC_H264_DECODER::H264SeqParamSetMVCExtension *GetSeqMVCParam(void) const {return m_pSeqParamSetMvcEx;}
125 void SetSeqMVCParam(const UMC_H264_DECODER::H264SeqParamSetMVCExtension * sps);
126
GetSeqSVCParam(void)127 const UMC_H264_DECODER::H264SeqParamSetSVCExtension *GetSeqSVCParam(void) const {return m_pSeqParamSetSvcEx;}
128 void SetSeqSVCParam(const UMC_H264_DECODER::H264SeqParamSetSVCExtension * sps);
129
130 // Obtain current destination frame
GetCurrentFrame(void)131 H264DecoderFrame *GetCurrentFrame(void){return m_pCurrentFrame;}
SetCurrentFrame(H264DecoderFrame * pFrame)132 void SetCurrentFrame(H264DecoderFrame * pFrame){m_pCurrentFrame = pFrame;}
133
134 // Obtain slice number
GetSliceNum(void)135 int32_t GetSliceNum(void) const {return m_iNumber;}
136 // Obtain maximum of macroblock
GetMaxMB(void)137 int32_t GetMaxMB(void) const {return m_iMaxMB;}
SetMaxMB(int32_t x)138 void SetMaxMB(int32_t x) {m_iMaxMB = x;}
139
GetMBCount()140 int32_t GetMBCount() const { return m_iMaxMB - m_iFirstMB;}
141
142 // Check field slice
IsField()143 bool IsField() const {return m_SliceHeader.field_pic_flag != 0;}
144 // Check top field slice
IsTopField()145 bool IsTopField() const {return m_SliceHeader.bottom_field_flag == 0;}
146 // Check top field slice
IsBottomField()147 bool IsBottomField() const {return !IsTopField();}
148
149 // Check slice organization
IsSliceGroups(void)150 bool IsSliceGroups(void) const {return (1 < m_pPicParamSet->num_slice_groups);};
151 // Do we require to do deblocking through slice boundaries
DeblockThroughBoundaries(void)152 bool DeblockThroughBoundaries(void) const {return (DEBLOCK_FILTER_ON_NO_SLICE_EDGES != m_SliceHeader.disable_deblocking_filter_idc);};
153
154 // Update reference list
155 virtual Status UpdateReferenceList(ViewList &views,
156 int32_t dIdIndex);
157
158 //
159 // Segment decoding mode's variables
160 //
161
162 UMC_H264_DECODER::AdaptiveMarkingInfo * GetAdaptiveMarkingInfo();
163
IsError()164 bool IsError() const {return m_bError;}
165
IsReference()166 bool IsReference() const {return m_SliceHeader.nal_ref_idc != 0;}
167
SetHeap(H264_Heap_Objects * pObjHeap)168 void SetHeap(H264_Heap_Objects *pObjHeap)
169 {
170 m_pObjHeap = pObjHeap;
171 }
172
173 void CompleteDecoding();
174
175 public:
176
177 H264MemoryPiece m_pSource; // (H264MemoryPiece *) pointer to owning memory piece
178 double m_dTime; // (double) slice's time stamp
179
180 public: // DEBUG !!!! should remove dependence
181
182 void Reset();
183
184 virtual void Release();
185
186 virtual void ZeroedMembers();
187
188 // Decode slice header
189 bool DecodeSliceHeader(UMC_H264_DECODER::H264NalExtension *pNalExt);
190
191 // Reference list(s) management functions & tools
192 int32_t AdjustRefPicListForFields(H264DecoderFrame **pRefPicList, ReferenceFlags *pFields, H264RefListInfo &rli);
193 void ReOrderRefPicList(H264DecoderFrame **pRefPicList, ReferenceFlags *pFields, UMC_H264_DECODER::RefPicListReorderInfo *pReorderInfo, int32_t MaxPicNum, ViewList &views, int32_t dIdIndex, uint32_t listNum);
194
195 UMC_H264_DECODER::RefPicListReorderInfo ReorderInfoL0; // (RefPicListReorderInfo) reference list 0 info
196 UMC_H264_DECODER::RefPicListReorderInfo ReorderInfoL1; // (RefPicListReorderInfo) reference list 1 info
197
198 UMC_H264_DECODER::H264SliceHeader m_SliceHeader; // (H264SliceHeader) slice header
199 H264HeadersBitstream m_BitStream; // (H264Bitstream) slice bit stream
200
201 UMC_H264_DECODER::PredWeightTable m_PredWeight[2][MAX_NUM_REF_FRAMES]; // (PredWeightTable []) prediction weight table
202
203 const UMC_H264_DECODER::H264PicParamSet* m_pPicParamSet; // (H264PicParamSet *) pointer to array of picture parameters sets
204 const UMC_H264_DECODER::H264SeqParamSet* m_pSeqParamSet; // (H264SeqParamSet *) pointer to array of sequence parameters sets
205 const UMC_H264_DECODER::H264SeqParamSetExtension* m_pSeqParamSetEx;
206 const UMC_H264_DECODER::H264SeqParamSetMVCExtension* m_pSeqParamSetMvcEx;
207 const UMC_H264_DECODER::H264SeqParamSetSVCExtension* m_pSeqParamSetSvcEx;
208
209 H264DecoderFrame *m_pCurrentFrame; // (H264DecoderFrame *) pointer to destination frame
210
211 int32_t m_iMBWidth; // (int32_t) width in macroblock units
212 int32_t m_iMBHeight; // (int32_t) height in macroblock units
213
214 int32_t m_iNumber; // (int32_t) current slice number
215 int32_t m_iFirstMB; // (int32_t) first MB number in slice
216 int32_t m_iMaxMB; // (int32_t) last unavailable MB number in slice
217
218 int32_t m_iFirstMBFld; // (int32_t) first MB number in slice
219
220 int32_t m_iAvailableMB; // (int32_t) available number of macroblocks (used in "unknown mode")
221
222 bool m_bFirstDebThreadedCall; // (bool) "first threaded deblocking call" flag
223 bool m_bPermanentTurnOffDeblocking; // (bool) "disable deblocking" flag
224 bool m_bError; // (bool) there is an error in decoding
225 bool m_isInitialized;
226
227 UMC_H264_DECODER::AdaptiveMarkingInfo m_AdaptiveMarkingInfo;
228 UMC_H264_DECODER::AdaptiveMarkingInfo m_BaseAdaptiveMarkingInfo;
229
230 bool m_bDecoded; // (bool) "slice has been decoded" flag
231 bool m_bPrevDeblocked; // (bool) "previous slice has been deblocked" flag
232 bool m_bDeblocked; // (bool) "slice has been deblocked" flag
233 bool m_bInited;
234
235 // memory management tools
236 MemoryAllocator *m_pMemoryAllocator; // (MemoryAllocator *) pointer to memory allocation tool
237
238 H264_Heap_Objects *m_pObjHeap;
239 };
240
241 inline
IsPictureTheSame(H264Slice * pSliceOne,H264Slice * pSliceTwo)242 bool IsPictureTheSame(H264Slice *pSliceOne, H264Slice *pSliceTwo)
243 {
244 if (!pSliceOne)
245 return true;
246
247 const UMC_H264_DECODER::H264SliceHeader *pOne = pSliceOne->GetSliceHeader();
248 const UMC_H264_DECODER::H264SliceHeader *pTwo = pSliceTwo->GetSliceHeader();
249
250 // this function checks two slices are from same picture or not
251 // 7.4.1.2.4 and G.7.4.1.2.4 parts of h264 standard
252
253 if (pOne->nal_ext.mvc.view_id != pTwo->nal_ext.mvc.view_id)
254 {
255 return false;
256 }
257
258 if (pOne->nal_ext.svc.dependency_id < pTwo->nal_ext.svc.dependency_id)
259 return true;
260
261 if (pOne->nal_ext.svc.dependency_id > pTwo->nal_ext.svc.dependency_id)
262 return false;
263
264 if (pOne->nal_ext.svc.quality_id < pTwo->nal_ext.svc.quality_id)
265 return true;
266
267 if (pOne->nal_ext.svc.quality_id > pTwo->nal_ext.svc.quality_id)
268 return false;
269
270 if ((pOne->frame_num != pTwo->frame_num) ||
271 //(pOne->first_mb_in_slice == pTwo->first_mb_in_slice) || // need to remove in case of duplicate slices !!!
272 (pOne->pic_parameter_set_id != pTwo->pic_parameter_set_id) ||
273 (pOne->field_pic_flag != pTwo->field_pic_flag) ||
274 (pOne->bottom_field_flag != pTwo->bottom_field_flag))
275 return false;
276
277 if ((pOne->nal_ref_idc != pTwo->nal_ref_idc) &&
278 (0 == std::min(pOne->nal_ref_idc, pTwo->nal_ref_idc)))
279 return false;
280
281 if (0 == pSliceTwo->GetSeqParam()->pic_order_cnt_type)
282 {
283 if ((pOne->pic_order_cnt_lsb != pTwo->pic_order_cnt_lsb) ||
284 (pOne->delta_pic_order_cnt_bottom != pTwo->delta_pic_order_cnt_bottom))
285 return false;
286 }
287 else
288 {
289 if ((pOne->delta_pic_order_cnt[0] != pTwo->delta_pic_order_cnt[0]) ||
290 (pOne->delta_pic_order_cnt[1] != pTwo->delta_pic_order_cnt[1]))
291 return false;
292 }
293
294 if (pOne->IdrPicFlag != pTwo->IdrPicFlag)
295 {
296 return false;
297 }
298
299 if (pOne->IdrPicFlag)
300 {
301 if (pOne->idr_pic_id != pTwo->idr_pic_id)
302 return false;
303 }
304
305 return true;
306
307 } // bool IsPictureTheSame(H264SliceHeader *pOne, H264SliceHeader *pTwo)
308
309
310 // Declare function to swapping memory
311 extern void SwapMemoryAndRemovePreventingBytes(void *pDst, size_t &nDstSize, void *pSrc, size_t nSrcSize);
312
313 } // namespace UMC
314
315 #endif // __UMC_H264_SLICE_DECODING_H
316 #endif // MFX_ENABLE_H264_VIDEO_DECODE
317