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