1 // Copyright (c) 2018-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_FRAME_H__
25 #define __UMC_H264_FRAME_H__
26 
27 #include "umc_h264_dec_defs_yuv.h"
28 #include "umc_h264_slice_decoding.h"
29 #include "umc_h264_frame_info.h"
30 
31 namespace UMC
32 {
33 class H264DecoderFrameInfo;
34 class H264StreamOut;
35 
36 enum BusyStates
37 {
38     BUSY_STATE_FREE = 0,
39     BUSY_STATE_LOCK1 = 1,
40     BUSY_STATE_LOCK2 = 2,
41     BUSY_STATE_NOT_DECODED = 3
42 };
43 
44 class H264DecoderFrame
45     : public H264DecYUVBufferPadded
46     , public RefCounter
47 {
48     DYNAMIC_CAST_DECL(H264DecoderFrame, H264DecYUVBufferPadded)
49 
50     int32_t  m_PictureStructureForRef;
51     int32_t  m_PicOrderCnt[2];    // Display order picture count mod MAX_PIC_ORDER_CNT.
52     int32_t  m_bottom_field_flag[2];
53     int32_t  m_PicNum[2];
54     int32_t  m_LongTermPicNum[2];
55     int32_t  m_FrameNum;
56     int32_t  m_FrameNumWrap;
57     int32_t  m_LongTermFrameIdx;
58     // ID of view the frame belongs to
59     int32_t m_viewId;
60 
61     int32_t  m_TopSliceCount;
62 
63     int32_t  m_frameOrder;
64     int32_t  m_ErrorType;
65 
66     H264DecoderFrameInfo m_pSlicesInfo;
67     H264DecoderFrameInfo m_pSlicesInfoBottom;
68 
69     bool prepared[2];
70 
71     H264DecoderFrameInfo * GetAU(int32_t field = 0)
72     {
73         return (field) ? &m_pSlicesInfoBottom : &m_pSlicesInfo;
74     }
75 
76     const H264DecoderFrameInfo * GetAU(int32_t field = 0) const
77     {
78         return (field) ? &m_pSlicesInfoBottom : &m_pSlicesInfo;
79     }
80 
81     H264DecoderFrame *m_pPreviousFrame;
82     H264DecoderFrame *m_pFutureFrame;
83 
84     UMC_H264_DECODER::H264SEIPayLoad m_UserData;
85 
86     double           m_dFrameTime;
87     bool             m_isOriginalPTS;
88 
89     bool             m_IsFrameExist;
90 
91     int32_t           m_dpb_output_delay;
92     int32_t           m_PictureStructureForDec;
93     DisplayPictureStruct  m_displayPictureStruct;
94 
95     int32_t           totalMBs;
96 
97     // For type 1 calculation of m_PicOrderCnt. m_FrameNum is needed to
98     // be used as previous frame num.
99 
100     bool post_procces_complete;
101 
102     int32_t m_iNumberOfSlices;
103     int32_t m_iResourceNumber;
104 
105     int32_t m_auIndex;
106     int32_t m_index;
107     int32_t m_UID;
108     size_t m_ID[2];
109     FrameType m_FrameType;
110 
111     MemID m_MemID;
112 
113     int32_t           m_RefPicListResetCount[2];
114     int32_t           m_crop_left;
115     int32_t           m_crop_right;
116     int32_t           m_crop_top;
117     int32_t           m_crop_bottom;
118     int32_t           m_crop_flag;
119 
120     int32_t           m_aspect_width;
121     int32_t           m_aspect_height;
122 
123     bool             m_isShortTermRef[2];
124     bool             m_isLongTermRef[2];
125     bool             m_isInterViewRef[2];
126 
127     bool             m_bIDRFlag;
128     bool             m_bIFlag;
129 
130     bool IsFullFrame() const;
131     void SetFullFrame(bool isFull);
132 
133     uint8_t  m_isFull;
134     uint8_t  m_isDecoded;
135     uint8_t  m_isDecodingStarted;
136     uint8_t  m_isDecodingCompleted;
137     uint8_t  m_isSkipped;
138 
139     uint8_t  m_wasDisplayed;
140     uint8_t  m_wasOutputted;
141 
142     typedef std::list<RefCounter *>  ReferenceList;
143     ReferenceList m_references;
144 
145     void FreeReferenceFrames();
146 
147     void Reset();
148     virtual void FreeResources();
149 
150     H264DecoderFrame( const H264DecoderFrame &s );                 // no copy CTR
151     H264DecoderFrame & operator=(const H264DecoderFrame &s );
152 
153 public:
154 
155     void AddReference(RefCounter * reference);
156 
157     void OnDecodingCompleted();
158 
159     virtual void Free();
160 
SetSkipped(bool isSkipped)161     void SetSkipped(bool isSkipped)
162     {
163         m_isSkipped = (uint8_t) (isSkipped ? 1 : 0);
164     }
165 
IsSkipped()166     bool IsSkipped() const
167     {
168         return m_isSkipped != 0;
169     }
170 
171     bool IsDecoded() const;
172 
IsFrameExist()173     bool IsFrameExist() const
174     {
175         return m_IsFrameExist;
176     }
177 
SetFrameAsNonExist()178     void SetFrameAsNonExist()
179     {
180         m_IsFrameExist = false;
181         m_isFull = true;
182         m_isSkipped = true;
183         m_isDecoded = 1;
184         m_wasOutputted = 1;
185         m_wasDisplayed = 1;
186     }
187 
188     // m_pParsedFrameData's allocated size is remembered so that a
189     // re-allocation is done only if size requirements exceed the
190     // existing allocation.
191     // m_paddedParsedFrameDataSize contains the image dimensions,
192     // rounded up to a multiple of 16, that were used.
193 
194     H264DecoderFrame(MemoryAllocator *pMemoryAllocator, H264_Heap_Objects * pObjHeap);
195 
196     virtual ~H264DecoderFrame();
197 
198     // The following methods provide access to the H264Decoder's doubly
199     // linked list of H264DecoderFrames.  Note that m_pPreviousFrame can
200     // be non-NULL even for an I frame.
previous()201     H264DecoderFrame *previous() { return m_pPreviousFrame; }
future()202     H264DecoderFrame *future()   { return m_pFutureFrame; }
203 
previous()204     const H264DecoderFrame *previous() const { return m_pPreviousFrame; }
future()205     const H264DecoderFrame *future() const { return m_pFutureFrame; }
206 
setPrevious(H264DecoderFrame * pPrev)207     void setPrevious(H264DecoderFrame *pPrev)
208     {
209         m_pPreviousFrame = pPrev;
210     }
211 
setFuture(H264DecoderFrame * pFut)212     void setFuture(H264DecoderFrame *pFut)
213     {
214         m_pFutureFrame = pFut;
215     }
216 
IsDecodingStarted()217     bool IsDecodingStarted() const { return m_isDecodingStarted != 0;}
StartDecoding()218     void StartDecoding() { m_isDecodingStarted = 1;}
219 
IsDecodingCompleted()220     bool IsDecodingCompleted() const { return m_isDecodingCompleted != 0;}
221     void CompleteDecoding();
222 
223     void UpdateErrorWithRefFrameStatus();
224 
wasDisplayed()225     bool        wasDisplayed()    { return m_wasDisplayed != 0; }
setWasDisplayed()226     void        setWasDisplayed() { m_wasDisplayed = 1; }
227 
wasOutputted()228     bool        wasOutputted()    { return m_wasOutputted != 0; }
229     void        setWasOutputted();
230 
isDisposable()231     bool        isDisposable()    { return (!IsFullFrame() || (m_wasOutputted && m_wasDisplayed)) && !GetRefCounter(); }
232 
233     // A decoded frame can be "disposed" if it is not an active reference
234     // and it is not locked by the calling application and it has been
235     // output for display.
236     int32_t PicNum(int32_t f, int32_t force=0) const
237     {
238         if ((m_PictureStructureForRef >= FRM_STRUCTURE && force==0) || force==3)
239         {
240             return std::min(m_PicNum[0],m_PicNum[1]);
241         }
242 
243         return m_PicNum[f];
244     }
245 
setPicNum(int32_t picNum,int32_t f)246     void setPicNum(int32_t picNum, int32_t f)
247     {
248         if (m_PictureStructureForRef >= FRM_STRUCTURE)
249         {
250             m_PicNum[0] = m_PicNum[1] = picNum;
251         }
252         else
253             m_PicNum[f] = picNum;
254     }
255 
256     // Updates m_LongTermPicNum for if long term reference, based upon
257     // m_LongTermFrameIdx.
FrameNum()258     int32_t FrameNum() const
259     {
260         return m_FrameNum;
261     }
262 
setFrameNum(int32_t FrameNum)263     void setFrameNum(int32_t FrameNum)
264     {
265         m_FrameNum = FrameNum;
266     }
267 
FrameNumWrap()268     int32_t FrameNumWrap() const
269     {
270         return m_FrameNumWrap;
271     }
272 
setFrameNumWrap(int32_t FrameNumWrap)273     void setFrameNumWrap(int32_t FrameNumWrap)
274     {
275         m_FrameNumWrap = FrameNumWrap;
276     }
277 
278     void UpdateFrameNumWrap(int32_t CurrFrameNum, int32_t MaxFrameNum, int32_t CurrPicStruct);
279     // Updates m_FrameNumWrap and m_PicNum if the frame is a short-term
280     // reference and a frame number wrap has occurred.
281 
LongTermFrameIdx()282     int32_t LongTermFrameIdx() const
283     {
284         return m_LongTermFrameIdx;
285     }
286 
setLongTermFrameIdx(int32_t LongTermFrameIdx)287     void setLongTermFrameIdx(int32_t LongTermFrameIdx)
288     {
289         m_LongTermFrameIdx = LongTermFrameIdx;
290     }
291 
isShortTermRef(int32_t WhichField)292     bool isShortTermRef(int32_t WhichField) const
293     {
294         if (m_PictureStructureForRef>=FRM_STRUCTURE )
295             return m_isShortTermRef[0] && m_isShortTermRef[1];
296         else
297             return m_isShortTermRef[WhichField];
298     }
299 
isShortTermRef()300     int32_t isShortTermRef() const
301     {
302         return m_isShortTermRef[0] + m_isShortTermRef[1]*2;
303     }
304 
305     void SetisShortTermRef(bool isRef, int32_t WhichField);
306 
307     int32_t PicOrderCnt(int32_t index, int32_t force=0) const
308     {
309         if ((m_PictureStructureForRef>=FRM_STRUCTURE && force==0) || force==3)
310         {
311             return std::min(m_PicOrderCnt[0],m_PicOrderCnt[1]);
312         }
313         else if (force==2)
314         {
315             if (isShortTermRef(0) && isShortTermRef(1))
316                 return std::min(m_PicOrderCnt[0],m_PicOrderCnt[1]);
317             else if (isShortTermRef(0))
318                 return m_PicOrderCnt[0];
319             else
320                 return m_PicOrderCnt[1];
321         }
322         return m_PicOrderCnt[index];
323     }
324 
DeblockPicID(int32_t index)325     size_t DeblockPicID(int32_t index) const
326     {
327         return m_ID[index];
328     }
329 
setPicOrderCnt(int32_t PicOrderCnt,int32_t index)330     void setPicOrderCnt(int32_t PicOrderCnt, int32_t index) {m_PicOrderCnt[index] = PicOrderCnt;}
isLongTermRef(int32_t WhichField)331     bool isLongTermRef(int32_t WhichField) const
332     {
333         if (m_PictureStructureForRef>=FRM_STRUCTURE)
334             return m_isLongTermRef[0] && m_isLongTermRef[1];
335         else
336             return m_isLongTermRef[WhichField];
337     }
338 
isLongTermRef()339     int32_t isLongTermRef() const
340     {
341         return m_isLongTermRef[0] + m_isLongTermRef[1]*2;
342     }
343 
344     void SetisLongTermRef(bool isRef, int32_t WhichField);
345 
346     int32_t LongTermPicNum(int32_t f, int32_t force=0) const
347     {
348         if ((m_PictureStructureForRef>=FRM_STRUCTURE && force==0) || force==3)
349         {
350             return std::min(m_LongTermPicNum[0],m_LongTermPicNum[1]);
351         }
352         else if (force==2)
353         {
354             if (isLongTermRef(0) && isLongTermRef(1))
355                 return std::min(m_LongTermPicNum[0],m_LongTermPicNum[1]);
356             else if (isLongTermRef(0))
357                 return m_LongTermPicNum[0];
358             else return m_LongTermPicNum[1];
359         }
360         return m_LongTermPicNum[f];
361     }
362 
setLongTermPicNum(int32_t LongTermPicNum,int32_t f)363     void setLongTermPicNum(int32_t LongTermPicNum,int32_t f) {m_LongTermPicNum[f] = LongTermPicNum;}
364     void UpdateLongTermPicNum(int32_t CurrPicStruct);
365 
isInterViewRef(uint32_t WhichField)366     bool isInterViewRef(uint32_t WhichField) const
367     {
368         if (m_PictureStructureForDec>=FRM_STRUCTURE )
369             return m_isInterViewRef[0];
370         else
371             return m_isInterViewRef[WhichField];
372     }
373 
SetInterViewRef(bool bInterViewRef,uint32_t WhichField)374     void SetInterViewRef(bool bInterViewRef, uint32_t WhichField)
375     {
376         if (m_PictureStructureForDec >= FRM_STRUCTURE)
377             m_isInterViewRef[0] = m_isInterViewRef[1] = bInterViewRef;
378         else
379             m_isInterViewRef[WhichField] = bInterViewRef;
380     }
381 
382     // set the view_id the frame belongs to
setViewId(uint32_t view_id)383     void setViewId(uint32_t view_id)
384     {
385         m_viewId = view_id;
386     }
387 
IncreaseRefPicListResetCount(uint32_t f)388     void IncreaseRefPicListResetCount(uint32_t f)
389     {
390         m_RefPicListResetCount[f]++;
391     }
392 
InitRefPicListResetCount(uint32_t f)393     void InitRefPicListResetCount(uint32_t f)
394     {
395         if (m_PictureStructureForRef >= FRM_STRUCTURE)
396             m_RefPicListResetCount[0]=m_RefPicListResetCount[1]=0;
397         else
398             m_RefPicListResetCount[f]=0;
399     }
400 
RefPicListResetCount(int32_t f)401     uint32_t RefPicListResetCount(int32_t f) const
402     {
403         if (m_PictureStructureForRef >= FRM_STRUCTURE)
404             return std::max(m_RefPicListResetCount[0], m_RefPicListResetCount[1]);
405         else
406             return m_RefPicListResetCount[f];
407     }
408 
GetNumberByParity(int32_t parity)409     int8_t GetNumberByParity(int32_t parity) const
410     {
411         VM_ASSERT(!parity || parity == 1);
412         return m_bottom_field_flag[1]==parity ? 1 : 0;
413     }
414 
415     //////////////////////////////////////////////////////////////////////////////
416     // GetRefPicList
417     // Returns pointer to start of specified ref pic list.
418     //////////////////////////////////////////////////////////////////////////////
419     H264DecoderRefPicList* GetRefPicList(int32_t sliceNumber, int32_t list);
420 
GetError()421     int32_t GetError() const
422     {
423         return m_ErrorType;
424     }
425 
SetError(int32_t errorType)426     void SetError(int32_t errorType)
427     {
428         m_ErrorType = errorType;
429     }
430 
SetErrorFlagged(int32_t errorType)431     void SetErrorFlagged(int32_t errorType)
432     {
433         m_ErrorType |= errorType;
434     }
435 
GetTotalMBs()436     int32_t GetTotalMBs() const
437     { return totalMBs; }
438 
439 protected:
440     // Declare memory management tools
441     MemoryAllocator *m_pMemoryAllocator;
442     H264_Heap_Objects * m_pObjHeap;
443 };
444 
isAlmostDisposable(H264DecoderFrame * pTmp)445 inline bool isAlmostDisposable(H264DecoderFrame * pTmp)
446 {
447     return (pTmp->m_wasOutputted || !pTmp->IsFullFrame())&& !pTmp->GetRefCounter();
448 }
449 
450 } // end namespace UMC
451 
452 #endif // __UMC_H264_FRAME_H__
453 #endif // MFX_ENABLE_H264_VIDEO_DECODE
454