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