1 // Copyright (c) 2017-2020 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 #include <algorithm>
25 #include <memory>
26 
27 #include "mfx_trace.h"
28 
29 #include "umc_h264_task_supplier.h"
30 #include "umc_h264_frame_list.h"
31 #include "umc_h264_nal_spl.h"
32 #include "umc_h264_bitstream_headers.h"
33 #include "umc_h264_task_broker.h"
34 #include "umc_h264_dec_defs_dec.h"
35 #include "vm_sys_info.h"
36 #include "umc_structures.h"
37 #include "umc_frame_data.h"
38 #include "umc_h264_notify.h"
39 
40 #include "umc_h264_dec_debug.h"
41 
42 using namespace UMC_H264_DECODER;
43 
44 namespace UMC
45 {
46 
47 #if (MFX_VERSION >= 1025)
SetDecodeErrorTypes(NAL_Unit_Type nalUnit,mfxExtDecodeErrorReport * pDecodeErrorReport)48 inline void SetDecodeErrorTypes(NAL_Unit_Type nalUnit, mfxExtDecodeErrorReport *pDecodeErrorReport)
49 {
50     switch (nalUnit)
51     {
52         case NAL_UT_SPS: pDecodeErrorReport->ErrorTypes |= MFX_ERROR_SPS; break;
53         case NAL_UT_PPS: pDecodeErrorReport->ErrorTypes |= MFX_ERROR_PPS; break;
54         default: break;
55     };
56 }
57 #endif
58 
59 /****************************************************************************************************/
60 // DPBOutput class routine
61 /****************************************************************************************************/
DPBOutput()62 DPBOutput::DPBOutput()
63 {
64     Reset();
65 }
66 
Reset(bool disableDelayFeature)67 void DPBOutput::Reset(bool disableDelayFeature)
68 {
69     m_isUseFlags.use_payload_sei_delay = 1;
70     m_isUseFlags.use_pic_order_cnt_type = 1;
71 
72     if (disableDelayFeature)
73     {
74         m_isUseFlags.use_payload_sei_delay = 0;
75         m_isUseFlags.use_pic_order_cnt_type = 0;
76     }
77 }
78 
IsUseDelayOutputValue() const79 bool DPBOutput::IsUseDelayOutputValue() const
80 {
81     return IsUseSEIDelayOutputValue() || IsUsePicOrderCnt();
82 }
83 
IsUseSEIDelayOutputValue() const84 bool DPBOutput::IsUseSEIDelayOutputValue() const
85 {
86     return m_isUseFlags.use_payload_sei_delay != 0;
87 }
88 
IsUsePicOrderCnt() const89 bool DPBOutput::IsUsePicOrderCnt() const
90 {
91     return m_isUseFlags.use_pic_order_cnt_type != 0;
92 }
93 
OnNewSps(H264SeqParamSet * sps)94 void DPBOutput::OnNewSps(H264SeqParamSet * sps)
95 {
96     if (sps && sps->pic_order_cnt_type != 2)
97     {
98         m_isUseFlags.use_pic_order_cnt_type = 0;
99     }
100 }
101 
GetDPBOutputDelay(H264SEIPayLoad * payload)102 int32_t DPBOutput::GetDPBOutputDelay(H264SEIPayLoad * payload)
103 {
104     if (IsUsePicOrderCnt())
105         return 0;
106 
107     if (!payload)
108     {
109         m_isUseFlags.use_payload_sei_delay = 0;
110         return INVALID_DPB_OUTPUT_DELAY;
111     }
112 
113     if (IsUseSEIDelayOutputValue())
114     {
115         if (payload->SEI_messages.pic_timing.dpb_output_delay != 0)
116             m_isUseFlags.use_payload_sei_delay = 0;
117 
118         return payload->SEI_messages.pic_timing.dpb_output_delay;
119     }
120 
121     return INVALID_DPB_OUTPUT_DELAY;
122 }
123 
124 /****************************************************************************************************/
125 // SVC extension class routine
126 /****************************************************************************************************/
SVC_Extension()127 SVC_Extension::SVC_Extension()
128     : MVC_Extension()
129     , m_dependency_id(H264_MAX_DEPENDENCY_ID)
130     , m_quality_id(H264_MAX_QUALITY_ID)
131 {
132 }
133 
~SVC_Extension()134 SVC_Extension::~SVC_Extension()
135 {
136     Reset();
137 }
138 
Reset()139 void SVC_Extension::Reset()
140 {
141     MVC_Extension::Reset();
142 
143     m_quality_id = 15;
144     m_dependency_id = 7;
145 }
146 
Close()147 void SVC_Extension::Close()
148 {
149     SVC_Extension::Reset();
150     MVC_Extension::Close();
151 }
152 
SetSVCTargetLayer(uint32_t dependency_id,uint32_t quality_id,uint32_t temporal_id)153 void SVC_Extension::SetSVCTargetLayer(uint32_t dependency_id, uint32_t quality_id, uint32_t temporal_id)
154 {
155     m_dependency_id = dependency_id;
156     m_quality_id = quality_id;
157     m_temporal_id = temporal_id;
158 }
159 
IsShouldSkipSlice(H264NalExtension * nal_ext)160 bool SVC_Extension::IsShouldSkipSlice(H264NalExtension *nal_ext)
161 {
162     if (!nal_ext)
163         return true;
164 
165     if (!nal_ext->svc_extension_flag)
166         return MVC_Extension::IsShouldSkipSlice(nal_ext);
167 
168     //if (nal_ext->svc.discardable_flag)
169       //  return true;
170 
171     if (nal_ext->svc.temporal_id > m_temporal_id)
172         return true;
173 
174     if (nal_ext->svc.priority_id > m_priority_id)
175         return true;
176 
177     if (nal_ext->svc.quality_id > m_quality_id)
178         return true;
179 
180     if (nal_ext->svc.dependency_id > m_dependency_id)
181         return true;
182 
183     return false;
184 }
185 
IsShouldSkipSlice(H264Slice * slice)186 bool SVC_Extension::IsShouldSkipSlice(H264Slice * slice)
187 {
188     return IsShouldSkipSlice(&slice->GetSliceHeader()->nal_ext);
189 }
190 
ChooseLevelIdc(const H264SeqParamSetSVCExtension * extension,uint8_t baseViewLevelIDC,uint8_t extensionLevelIdc)191 void SVC_Extension::ChooseLevelIdc(const H264SeqParamSetSVCExtension * extension, uint8_t baseViewLevelIDC, uint8_t extensionLevelIdc)
192 {
193     if (m_level_idc)
194         return;
195 
196     m_level_idc = std::max({baseViewLevelIDC, extensionLevelIdc, extension->level_idc});
197 
198     assert(m_level_idc != 0);
199 }
200 
201 /****************************************************************************************************/
202 // DecReferencePictureMarking
203 /****************************************************************************************************/
DecReferencePictureMarking()204 DecReferencePictureMarking::DecReferencePictureMarking()
205     : m_isDPBErrorFound(0)
206     , m_frameCount(0)
207 {
208 }
209 
Reset()210 void DecReferencePictureMarking::Reset()
211 {
212     m_frameCount = 0;
213     m_isDPBErrorFound = 0;
214     m_commandsList.clear();
215 }
216 
ResetError()217 void DecReferencePictureMarking::ResetError()
218 {
219     m_isDPBErrorFound = 0;
220 }
221 
GetDPBError() const222 uint32_t DecReferencePictureMarking::GetDPBError() const
223 {
224     return m_isDPBErrorFound;
225 }
226 
IsDecRefPicMarkingEquals(const H264SEIPayLoadBase::SEIMessages::DecRefPicMarkingRepetition * decRefPicMarking1,const H264SEIPayLoadBase::SEIMessages::DecRefPicMarkingRepetition * decRefPicMarking2)227 bool IsDecRefPicMarkingEquals(const H264SEIPayLoadBase::SEIMessages::DecRefPicMarkingRepetition *decRefPicMarking1, const H264SEIPayLoadBase::SEIMessages::DecRefPicMarkingRepetition *decRefPicMarking2)
228 {
229     if (!decRefPicMarking1 || !decRefPicMarking2)
230         return true;
231 
232     if (decRefPicMarking1->original_idr_flag            != decRefPicMarking2->original_idr_flag ||
233         decRefPicMarking1->original_frame_num           != decRefPicMarking2->original_frame_num ||
234         decRefPicMarking1->original_field_pic_flag      != decRefPicMarking2->original_field_pic_flag ||
235         decRefPicMarking1->original_bottom_field_flag   != decRefPicMarking2->original_bottom_field_flag ||
236         decRefPicMarking1->long_term_reference_flag     != decRefPicMarking2->long_term_reference_flag)
237         return false;
238 
239     if (decRefPicMarking1->adaptiveMarkingInfo.num_entries != decRefPicMarking2->adaptiveMarkingInfo.num_entries)
240         return false;
241 
242     for (uint32_t i = 0; i < decRefPicMarking1->adaptiveMarkingInfo.num_entries; i++)
243     {
244         if (decRefPicMarking1->adaptiveMarkingInfo.value[i] != decRefPicMarking2->adaptiveMarkingInfo.value[i] ||
245             decRefPicMarking1->adaptiveMarkingInfo.mmco[i]  != decRefPicMarking2->adaptiveMarkingInfo.mmco[i])
246             return false;
247     }
248 
249     return true;
250 }
251 
CheckSEIRepetition(ViewItem & view,H264SEIPayLoad * payload)252 Status DecReferencePictureMarking::CheckSEIRepetition(ViewItem &view, H264SEIPayLoad *payload)
253 {
254     Status umcRes = UMC_OK;
255     if (!payload || payload->payLoadType != SEI_DEC_REF_PIC_MARKING_TYPE)
256         return UMC_OK;
257 
258     H264DecoderFrame * pFrame = 0;
259 
260     for (H264DecoderFrame *pCurr = view.GetDPBList(0)->head(); pCurr; pCurr = pCurr->future())
261     {
262         if (pCurr->FrameNum() == payload->SEI_messages.dec_ref_pic_marking_repetition.original_frame_num)
263         {
264             pFrame = pCurr;
265             break;
266         }
267     }
268 
269     if (!pFrame)
270         return UMC_OK;
271 
272     const H264SEIPayLoadBase::SEIMessages::DecRefPicMarkingRepetition *forCheck = pFrame->GetAU(0)->GetDecRefPicMarking();
273     if (payload->SEI_messages.dec_ref_pic_marking_repetition.original_field_pic_flag)
274     {
275         forCheck = pFrame->GetAU(pFrame->GetNumberByParity(payload->SEI_messages.dec_ref_pic_marking_repetition.original_bottom_field_flag))->GetDecRefPicMarking();
276     }
277 
278     if (!IsDecRefPicMarkingEquals(&payload->SEI_messages.dec_ref_pic_marking_repetition, forCheck))
279     {
280         pFrame->SetErrorFlagged(ERROR_FRAME_DPB);
281         m_isDPBErrorFound = 1;
282         return UMC_ERR_FAILED;
283     }
284 
285     return umcRes;
286 }
287 
CheckSEIRepetition(ViewItem & view,H264DecoderFrame * frame)288 void DecReferencePictureMarking::CheckSEIRepetition(ViewItem &view, H264DecoderFrame * frame)
289 {
290     bool isEqual = false;
291 
292     if (isEqual)
293         return;
294 
295     DPBCommandsList::iterator end_iter = m_commandsList.end();
296     H264DecoderFrame * temp = 0;
297 
298     bool wasFrame = false;
299 
300     for (H264DecoderFrame *pCurr = view.GetDPBList(0)->head(); pCurr; pCurr = pCurr->future())
301     {
302         pCurr->IncrementReference();
303         pCurr->IncrementReference();
304     }
305 
306     {
307     DPBCommandsList::reverse_iterator rev_iter = m_commandsList.rbegin();
308     DPBCommandsList::reverse_iterator rev_end_iter = m_commandsList.rend();
309 
310     for (; rev_iter != rev_end_iter; ++rev_iter)
311     {
312         DPBChangeItem& item = *rev_iter;
313 
314         if (item.m_pCurrentFrame == frame)
315         {
316             wasFrame = true;
317             Undo(frame);
318             break;
319         }
320 
321         if (temp != item.m_pCurrentFrame)
322         {
323             temp = 0;
324         }
325 
326         if (!temp)
327         {
328             temp = item.m_pCurrentFrame;
329             Undo(temp);
330         }
331     }
332     }
333 
334     bool start = false;
335     temp = 0;
336     DPBCommandsList::iterator iter = m_commandsList.begin(); // stl issue. we can't reuse iterator
337     for (; iter != end_iter; ++iter)
338     {
339         DPBChangeItem& item = *iter;
340 
341         if (item.m_pCurrentFrame == frame)
342         {
343             Redo(frame);
344             start = true;
345             break;
346         }
347 
348         if (!start && wasFrame)
349             continue;
350 
351         if (temp != item.m_pCurrentFrame)
352         {
353             temp = 0;
354         }
355 
356         if (!temp)
357         {
358             temp = item.m_pCurrentFrame;
359             Redo(temp);
360         }
361     }
362 
363     for (H264DecoderFrame *pCurr = view.GetDPBList(0)->head(); pCurr; pCurr = pCurr->future())
364     {
365         pCurr->DecrementReference();
366         pCurr->DecrementReference();
367     }
368 }
369 
Undo(const H264DecoderFrame * frame)370 void DecReferencePictureMarking::Undo(const H264DecoderFrame * frame)
371 {
372     MakeChange(true, frame);
373 }
374 
Redo(const H264DecoderFrame * frame)375 void DecReferencePictureMarking::Redo(const H264DecoderFrame * frame)
376 {
377     MakeChange(false, frame);
378 }
379 
MakeChange(bool isUndo,const H264DecoderFrame * frame)380 void DecReferencePictureMarking::MakeChange(bool isUndo, const H264DecoderFrame * frame)
381 {
382     DPBCommandsList::iterator iter = m_commandsList.begin();
383     DPBCommandsList::iterator end_iter = m_commandsList.end();
384 
385     for (; iter != end_iter; ++iter)
386     {
387         DPBChangeItem& item = *iter;
388 
389         if (item.m_pCurrentFrame == frame)
390         {
391             MakeChange(isUndo, &item);
392         }
393     }
394 }
395 
RemoveOld()396 void DecReferencePictureMarking::RemoveOld()
397 {
398     if (!m_commandsList.size())
399     {
400         m_frameCount = 0;
401         return;
402     }
403 
404     Remove(m_commandsList.front().m_pCurrentFrame);
405 }
406 
407 #ifdef _DEBUG
DebugPrintItems()408 void DecReferencePictureMarking::DebugPrintItems()
409 {
410     printf("==================================\n");
411 
412     DPBCommandsList::iterator iter = m_commandsList.begin(); // stl issue. we can't reuse iterator
413     for (; iter != m_commandsList.end(); ++iter)
414     {
415         DPBChangeItem& item = *iter;
416         printf("current - %d, ref - %d\n", item.m_pCurrentFrame->m_PicOrderCnt[0], item.m_pRefFrame->m_PicOrderCnt[0]);
417     }
418 
419     printf("==================================\n");
420 }
421 #endif
422 
Remove(H264DecoderFrame * frame)423 void DecReferencePictureMarking::Remove(H264DecoderFrame * frame)
424 {
425     //printf("remove frame - %d\n", frame->m_PicOrderCnt[0]);
426     //DebugPrintItems();
427 
428     DPBCommandsList::iterator iter = m_commandsList.begin();
429     DPBCommandsList::iterator end_iter = m_commandsList.end();
430 
431     DPBCommandsList::iterator start = m_commandsList.end();
432     DPBCommandsList::iterator end = m_commandsList.end();
433 
434     for (; iter != end_iter; ++iter)
435     {
436         DPBChangeItem& item = *iter;
437 
438         if (start == m_commandsList.end())
439         {
440             if (item.m_pCurrentFrame == frame)
441             {
442                 m_frameCount--;
443                 start = iter;
444             }
445         }
446         else
447         {
448             if (item.m_pCurrentFrame != frame)
449             {
450                 end = iter;
451                 break;
452             }
453         }
454     }
455 
456     if (start != m_commandsList.end())
457         m_commandsList.erase(m_commandsList.begin(), end);
458 
459 
460     iter = m_commandsList.begin();
461 
462     for (; iter != m_commandsList.end(); ++iter)
463     {
464         DPBChangeItem& item = *iter;
465 
466         if (item.m_pRefFrame == frame)
467         {
468             m_commandsList.erase(iter);
469             iter = m_commandsList.begin();
470             if (iter == m_commandsList.end()) // avoid ++iter operation
471                 break;
472         }
473     }
474 
475 
476     //DebugPrintItems();
477 }
478 
AddItemAndRun(H264DecoderFrame * currentFrame,H264DecoderFrame * refFrame,uint32_t flags)479 DecReferencePictureMarking::DPBChangeItem* DecReferencePictureMarking::AddItemAndRun(H264DecoderFrame * currentFrame, H264DecoderFrame * refFrame, uint32_t flags)
480 {
481     DPBChangeItem* item = AddItem(m_commandsList, currentFrame, refFrame, flags);
482     if (!item)
483         return 0;
484 
485     Redo(item);
486     return item;
487 }
488 
AddItem(DPBCommandsList & list,H264DecoderFrame * currentFrame,H264DecoderFrame * refFrame,uint32_t flags)489 DecReferencePictureMarking::DPBChangeItem* DecReferencePictureMarking::AddItem(DPBCommandsList & list, H264DecoderFrame * currentFrame, H264DecoderFrame * refFrame, uint32_t flags)
490 {
491     if (!currentFrame || !refFrame)
492         return 0;
493 
494     DPBChangeItem item;
495     item.m_pCurrentFrame = currentFrame;
496     item.m_pRefFrame = refFrame;
497 
498     item.m_type.isShortTerm = (flags & SHORT_TERM) ? 1 : 0;
499     item.m_type.isFrame     = (flags & FULL_FRAME) ? 1 : 0;
500     item.m_type.isSet       = (flags & SET_REFERENCE) ? 1 : 0;
501     item.m_type.isBottom    = (flags & BOTTOM_FIELD) ? 1 : 0;
502 
503     if (CheckUseless(&item))
504         return 0;
505 
506     list.push_back(item);
507     return &list.back();
508 }
509 
CheckUseless(DPBChangeItem * item)510 bool DecReferencePictureMarking::CheckUseless(DPBChangeItem * item)
511 {
512     if (!item)
513         return true;
514 
515     if (item->m_type.isShortTerm)
516     {
517         if (item->m_type.isFrame)
518         {
519             return item->m_type.isSet ? (item->m_pRefFrame->isShortTermRef() == 3) : (!item->m_pRefFrame->isShortTermRef());
520         }
521         else
522         {
523             return item->m_type.isSet ? item->m_pRefFrame->isShortTermRef(item->m_type.isBottom) : !item->m_pRefFrame->isShortTermRef(item->m_type.isBottom);
524         }
525     }
526     else
527     {
528         if (item->m_type.isFrame)
529         {
530             return item->m_type.isSet ? item->m_pRefFrame->isLongTermRef() == 3 : !item->m_pRefFrame->isLongTermRef();
531         }
532         else
533         {
534             return item->m_type.isSet ? item->m_pRefFrame->isLongTermRef(item->m_type.isBottom) : !item->m_pRefFrame->isLongTermRef(item->m_type.isBottom);
535         }
536     }
537 }
538 
MakeChange(bool isUndo,const DPBChangeItem * item)539 void DecReferencePictureMarking::MakeChange(bool isUndo, const DPBChangeItem * item)
540 {
541     if (!item)
542         return;
543 
544     DPBChangeItem temp = *item;
545 
546     if (isUndo)
547     {
548         temp.m_type.isSet ^= 1;
549     }
550 
551     item = &temp;
552 
553     int32_t savePSRef = item->m_pRefFrame->m_PictureStructureForRef;
554     item->m_pRefFrame->m_PictureStructureForRef = item->m_pCurrentFrame->m_PictureStructureForDec;
555 
556     if (item->m_type.isFrame)
557     {
558         if (item->m_type.isShortTerm)
559         {
560             item->m_pRefFrame->SetisShortTermRef(item->m_type.isSet == 1, 0);
561             item->m_pRefFrame->SetisShortTermRef(item->m_type.isSet == 1, 1);
562         }
563         else
564         {
565             item->m_pRefFrame->SetisLongTermRef(item->m_type.isSet == 1, 0);
566             item->m_pRefFrame->SetisLongTermRef(item->m_type.isSet == 1, 1);
567         }
568     }
569     else
570     {
571         if (item->m_type.isShortTerm)
572         {
573             item->m_pRefFrame->SetisShortTermRef(item->m_type.isSet == 1, item->m_type.isBottom);
574         }
575         else
576         {
577             item->m_pRefFrame->SetisLongTermRef(item->m_type.isSet == 1, item->m_type.isBottom);
578         }
579     }
580 
581     item->m_pRefFrame->m_PictureStructureForRef = savePSRef;
582 }
583 
Undo(const DPBChangeItem * item)584 void DecReferencePictureMarking::Undo(const DPBChangeItem * item)
585 {
586     MakeChange(true, item);
587 }
588 
Redo(const DPBChangeItem * item)589 void DecReferencePictureMarking::Redo(const DPBChangeItem * item)
590 {
591     MakeChange(false, item);
592 }
593 
SlideWindow(ViewItem & view,H264Slice * pSlice,int32_t field_index)594 void DecReferencePictureMarking::SlideWindow(ViewItem &view, H264Slice * pSlice, int32_t field_index)
595 {
596     uint32_t NumShortTermRefs, NumLongTermRefs;
597     const H264SeqParamSet* sps = pSlice->GetSeqParam();
598 
599     // find out how many active reference frames currently in decoded
600     // frames buffer
601     view.GetDPBList(0)->countActiveRefs(NumShortTermRefs, NumLongTermRefs);
602     while (NumShortTermRefs > 0 &&
603         (NumShortTermRefs + NumLongTermRefs >= sps->num_ref_frames) &&
604         !field_index)
605     {
606         // mark oldest short-term reference as unused
607         assert(NumShortTermRefs > 0);
608 
609         H264DecoderFrame * pFrame = view.GetDPBList(0)->findOldestShortTermRef();
610 
611         if (!pFrame)
612             break;
613 
614         AddItemAndRun(pSlice->GetCurrentFrame(), pFrame, UNSET_REFERENCE | FULL_FRAME | SHORT_TERM);
615         NumShortTermRefs--;
616     }
617 }
618 
UpdateRefPicMarking(ViewItem & view,H264DecoderFrame * pFrame,H264Slice * pSlice,int32_t field_index)619 Status DecReferencePictureMarking::UpdateRefPicMarking(ViewItem &view, H264DecoderFrame * pFrame, H264Slice * pSlice, int32_t field_index)
620 {
621     Status umcRes = UMC_OK;
622     bool bCurrentisST = true;
623 
624     m_frameCount++;
625 
626     H264SliceHeader  * sliceHeader = pSlice->GetSliceHeader();
627 
628     // set MVC 'inter view flag'
629     pFrame->SetInterViewRef(0 != sliceHeader->nal_ext.mvc.inter_view_flag, field_index);
630 
631     // corruption recovery
632     if (pFrame->m_bIFlag)
633     {
634         for (H264DecoderFrame *pCurr = view.GetDPBList(0)->head(); pCurr; pCurr = pCurr->future())
635         {
636             if (pCurr->GetError() & ERROR_FRAME_SHORT_TERM_STUCK)
637             {
638                 AddItemAndRun(pFrame, pCurr, UNSET_REFERENCE | FULL_FRAME | SHORT_TERM);
639             }
640         }
641     }
642 
643     if (pFrame->m_bIDRFlag)
644     {
645         // mark all reference pictures as unused
646         for (H264DecoderFrame *pCurr = view.GetDPBList(0)->head(); pCurr; pCurr = pCurr->future())
647         {
648             if (pCurr->isShortTermRef() || pCurr->isLongTermRef())
649             {
650                 AddItemAndRun(pFrame, pCurr, UNSET_REFERENCE | FULL_FRAME | SHORT_TERM);
651                 AddItemAndRun(pFrame, pCurr, UNSET_REFERENCE | FULL_FRAME | LONG_TERM);
652             }
653         }
654 
655         if (sliceHeader->long_term_reference_flag)
656         {
657             AddItemAndRun(pFrame, pFrame, SET_REFERENCE | LONG_TERM | (field_index ? BOTTOM_FIELD : TOP_FIELD));
658             //pFrame->SetisLongTermRef(true, field_index);
659             pFrame->setLongTermFrameIdx(0);
660             view.MaxLongTermFrameIdx[0] = 0;
661         }
662         else
663         {
664             AddItemAndRun(pFrame, pFrame, SET_REFERENCE | SHORT_TERM | (field_index ? BOTTOM_FIELD : TOP_FIELD));
665             //pFrame->SetisShortTermRef(true, field_index);
666             view.MaxLongTermFrameIdx[0] = -1;        // no long term frame indices
667         }
668 
669         bCurrentisST = false;
670     }
671     else
672     {
673         AdaptiveMarkingInfo* pAdaptiveMarkingInfo = pSlice->GetAdaptiveMarkingInfo();
674         // adaptive ref pic marking
675         if (pAdaptiveMarkingInfo && pAdaptiveMarkingInfo->num_entries > 0)
676         {
677             for (uint32_t arpmmf_idx = 0; arpmmf_idx < pAdaptiveMarkingInfo->num_entries; arpmmf_idx++)
678             {
679                 int32_t LongTermFrameIdx;
680                 int32_t picNum;
681                 H264DecoderFrame * pRefFrame = 0;
682                 int32_t field = 0;
683 
684                 switch (pAdaptiveMarkingInfo->mmco[arpmmf_idx])
685                 {
686                 case 1:
687                     // mark a short-term picture as unused for reference
688                     // Value is difference_of_pic_nums_minus1
689                     picNum = pFrame->PicNum(field_index) -
690                         (pAdaptiveMarkingInfo->value[arpmmf_idx*2] + 1);
691 
692                     pRefFrame = view.GetDPBList(0)->findShortTermPic(picNum, &field);
693                     AddItemAndRun(pFrame, pRefFrame, UNSET_REFERENCE | SHORT_TERM | (field ? BOTTOM_FIELD : TOP_FIELD));
694                     break;
695                 case 2:
696                     // mark a long-term picture as unused for reference
697                     // value is long_term_pic_num
698                     picNum = pAdaptiveMarkingInfo->value[arpmmf_idx*2];
699                     pRefFrame = view.GetDPBList(0)->findLongTermPic(picNum, &field);
700                     AddItemAndRun(pFrame, pRefFrame, UNSET_REFERENCE | LONG_TERM | (field ? BOTTOM_FIELD : TOP_FIELD));
701                     break;
702                 case 3:
703 
704                     // Assign a long-term frame idx to a short-term picture
705                     // Value is difference_of_pic_nums_minus1 followed by
706                     // long_term_frame_idx. Only this case uses 2 value entries.
707                     picNum = pFrame->PicNum(field_index) -
708                         (pAdaptiveMarkingInfo->value[arpmmf_idx*2] + 1);
709                     LongTermFrameIdx = pAdaptiveMarkingInfo->value[arpmmf_idx*2+1];
710 
711                     pRefFrame = view.GetDPBList(0)->findShortTermPic(picNum, &field);
712                     if (!pRefFrame)
713                         break;
714 
715                     {
716                         H264DecoderFrame * longTerm = view.GetDPBList(0)->findLongTermRefIdx(LongTermFrameIdx);
717                         if (longTerm != pRefFrame)
718                             AddItemAndRun(pFrame, longTerm, UNSET_REFERENCE | LONG_TERM | FULL_FRAME);
719                     }
720 
721                     AddItemAndRun(pFrame, pRefFrame, SET_REFERENCE | LONG_TERM | (field ? BOTTOM_FIELD : TOP_FIELD));
722                     AddItemAndRun(pFrame, pRefFrame, UNSET_REFERENCE | SHORT_TERM | (field ? BOTTOM_FIELD : TOP_FIELD));
723 
724                     pRefFrame->setLongTermFrameIdx(LongTermFrameIdx);
725                     pRefFrame->UpdateLongTermPicNum(pRefFrame->m_PictureStructureForRef >= FRM_STRUCTURE ? 2 : pRefFrame->m_bottom_field_flag[field]);
726                     break;
727                 case 4:
728                     // Specify max long term frame idx
729                     // Value is max_long_term_frame_idx_plus1
730                     // Set to "no long-term frame indices" (-1) when value == 0.
731                     view.MaxLongTermFrameIdx[0] = pAdaptiveMarkingInfo->value[arpmmf_idx*2] - 1;
732 
733                     pRefFrame = view.GetDPBList(0)->findOldLongTermRef(view.MaxLongTermFrameIdx[0]);
734                     while (pRefFrame)
735                     {
736                         AddItemAndRun(pFrame, pRefFrame, UNSET_REFERENCE | LONG_TERM | FULL_FRAME);
737                         pRefFrame = view.GetDPBList(0)->findOldLongTermRef(view.MaxLongTermFrameIdx[0]);
738                     }
739                     break;
740                 case 5:
741                     // Mark all as unused for reference
742                     // no value
743                     for (H264DecoderFrame *pCurr = view.GetDPBList(0)->head(); pCurr; pCurr = pCurr->future())
744                     {
745                         if (pCurr->isShortTermRef() || pCurr->isLongTermRef())
746                         {
747                             AddItemAndRun(pFrame, pCurr, UNSET_REFERENCE | FULL_FRAME | SHORT_TERM);
748                             AddItemAndRun(pFrame, pCurr, UNSET_REFERENCE | FULL_FRAME | LONG_TERM);
749                         }
750                     }
751 
752                     view.GetDPBList(0)->IncreaseRefPicListResetCount(pFrame);
753                     view.MaxLongTermFrameIdx[0] = -1;        // no long term frame indices
754                     // set "previous" picture order count vars for future
755 
756                     if (pFrame->m_PictureStructureForDec < FRM_STRUCTURE)
757                     {
758                         pFrame->setPicOrderCnt(0, field_index);
759                         pFrame->setPicNum(0, field_index);
760                     }
761                     else
762                     {
763                         int32_t poc = pFrame->PicOrderCnt(0, 3);
764                         pFrame->setPicOrderCnt(pFrame->PicOrderCnt(0, 1) - poc, 0);
765                         pFrame->setPicOrderCnt(pFrame->PicOrderCnt(1, 1) - poc, 1);
766                         pFrame->setPicNum(0, 0);
767                         pFrame->setPicNum(0, 1);
768                     }
769 
770                     pFrame->m_bIDRFlag = true;
771                     view.GetPOCDecoder(0)->Reset(0);
772                     // set frame_num to zero for this picture, for correct
773                     // FrameNumWrap
774                     pFrame->setFrameNum(0);
775                     sliceHeader->frame_num = 0;
776                     break;
777                 case 6:
778                     // Assign long term frame idx to current picture
779                     // Value is long_term_frame_idx
780                     LongTermFrameIdx = pAdaptiveMarkingInfo->value[arpmmf_idx*2];
781                     bCurrentisST = false;
782                     pRefFrame = view.GetDPBList(0)->findLongTermRefIdx(LongTermFrameIdx);
783                     if (pRefFrame != pFrame)
784                         AddItemAndRun(pFrame, pRefFrame, UNSET_REFERENCE | LONG_TERM | FULL_FRAME);
785 
786                     AddItemAndRun(pFrame, pFrame, SET_REFERENCE | LONG_TERM | (field_index ? BOTTOM_FIELD : TOP_FIELD));
787                     pFrame->setLongTermFrameIdx(LongTermFrameIdx);
788                     break;
789                 case 0:
790                 default:
791                     // invalid mmco command in bitstream
792                     assert(0);
793                     umcRes = UMC_ERR_INVALID_STREAM;
794                 }    // switch
795             }    // for arpmmf_idx
796         }
797     }    // not IDR picture
798 
799     if (bCurrentisST)
800     {
801         AdaptiveMarkingInfo* pAdaptiveMarkingInfo = pSlice->GetAdaptiveMarkingInfo();
802         if (pAdaptiveMarkingInfo && pAdaptiveMarkingInfo->num_entries > 0 && !field_index)
803         {
804             //with MMCO we could overflow DPB after we add current picture as short term
805             //this case is not valid but could occure in broken streams and we try to handle it
806 
807             uint32_t NumShortTermRefs, NumLongTermRefs;
808             view.GetDPBList(0)->countActiveRefs(NumShortTermRefs, NumLongTermRefs);
809             const H264SeqParamSet* sps = pSlice->GetSeqParam();
810 
811             if (NumShortTermRefs + NumLongTermRefs + 1 > sps->num_ref_frames)
812             {
813                 DPBCommandsList::iterator
814                     f = m_commandsList.begin(),
815                     l = m_commandsList.end();
816                 for (; f != l; ++f)
817                     if ((*f).m_type.isSet && !(*f).m_type.isShortTerm)
818                         break;
819 
820                 if (f != l)
821                 {
822                     Undo(&(*f));
823                     m_commandsList.erase(f);
824                 }
825             }
826         }
827 
828         if (sliceHeader->field_pic_flag && field_index)
829         {
830         }
831         else
832         {
833             SlideWindow(view, pSlice, field_index);
834         }
835 
836         AddItemAndRun(pFrame, pFrame, SET_REFERENCE | SHORT_TERM | (field_index ? BOTTOM_FIELD : TOP_FIELD));
837     }
838 
839     return umcRes;
840 }
841 
842 /****************************************************************************************************/
843 //
844 /****************************************************************************************************/
845 static
IsNeedSPSInvalidate(const H264SeqParamSet * old_sps,const H264SeqParamSet * new_sps)846 bool IsNeedSPSInvalidate(const H264SeqParamSet *old_sps, const H264SeqParamSet *new_sps)
847 {
848     if (!old_sps || !new_sps)
849         return false;
850 
851     //if (new_sps->no_output_of_prior_pics_flag)
852       //  return true;
853 
854     if (old_sps->frame_width_in_mbs != new_sps->frame_width_in_mbs)
855         return true;
856 
857     if (old_sps->frame_height_in_mbs != new_sps->frame_height_in_mbs)
858         return true;
859 
860     if (old_sps->vui.max_dec_frame_buffering < new_sps->vui.max_dec_frame_buffering)
861         return true;
862 
863     if (old_sps->chroma_format_idc != new_sps->chroma_format_idc)
864         return true;
865 
866     if (old_sps->profile_idc != new_sps->profile_idc)
867         return true;
868 
869     if (old_sps->bit_depth_luma != new_sps->bit_depth_luma)
870         return true;
871 
872     if (old_sps->bit_depth_chroma != new_sps->bit_depth_chroma)
873         return true;
874 
875     return false;
876 }
877 
878 /****************************************************************************************************/
879 // MVC_Extension class routine
880 /****************************************************************************************************/
MVC_Extension()881 MVC_Extension::MVC_Extension()
882     : m_temporal_id(H264_MAX_TEMPORAL_ID)
883     , m_priority_id(63)
884     , m_level_idc(0)
885     , m_currentDisplayView(BASE_VIEW)
886     , m_currentView((uint32_t)INVALID_VIEW_ID)
887     , m_decodingMode(UNKNOWN_DECODING_MODE)
888 {
889     Reset();
890 }
891 
~MVC_Extension()892 MVC_Extension::~MVC_Extension()
893 {
894     Close();
895 }
896 
IsExtension() const897 bool MVC_Extension::IsExtension() const
898 {
899     return m_decodingMode != AVC_DECODING_MODE;
900 }
901 
Init()902 Status MVC_Extension::Init()
903 {
904     MVC_Extension::Close();
905 
906     Status umcRes = AllocateView((uint32_t)INVALID_VIEW_ID);
907     if (UMC_OK != umcRes)
908     {
909         return umcRes;
910     }
911 
912     return UMC_OK;
913 }
914 
Close()915 void MVC_Extension::Close()
916 {
917     MVC_Extension::Reset();
918     m_viewIDsList.clear();
919     m_views.clear();
920 }
921 
Reset()922 void MVC_Extension::Reset()
923 {
924     m_temporal_id = H264_MAX_TEMPORAL_ID;
925     m_priority_id = 63;
926     m_level_idc = 0;
927     m_currentDisplayView = BASE_VIEW;
928     m_currentView = (uint32_t)INVALID_VIEW_ID;
929     m_decodingMode = UNKNOWN_DECODING_MODE;
930 
931     ViewList::iterator iter = m_views.begin();
932     ViewList::iterator iter_end = m_views.end();
933     for (; iter != iter_end; ++iter)
934     {
935         iter->Reset();
936     }
937 }
938 
FindView(int32_t viewId)939 ViewItem * MVC_Extension::FindView(int32_t viewId)
940 {
941     ViewList::iterator iter = m_views.begin();
942     ViewList::iterator iter_end = m_views.end();
943 
944     // run over the list and try to find the corresponding view
945     for (; iter != iter_end; ++iter)
946     {
947         ViewItem & item = *iter;
948         if (item.viewId == viewId)
949         {
950             return &item;
951         }
952     }
953 
954     return NULL;
955 }
956 
GetView(int32_t viewId)957 ViewItem & MVC_Extension::GetView(int32_t viewId)
958 {
959     ViewList::iterator iter = m_views.begin();
960     ViewList::iterator iter_end = m_views.end();
961 
962     // run over the list and try to find the corresponding view
963     for (; iter != iter_end; ++iter)
964     {
965         ViewItem & item = *iter;
966 
967         //if (viewId == INVALID_VIEW_ID && item.m_isDisplayable)
968           //  return &item;
969 
970         if (item.viewId == viewId)
971         {
972             return item;
973         }
974     }
975 
976     throw h264_exception(UMC_ERR_FAILED);
977     //return NULL;
978 }
979 
MoveViewToHead(int32_t view_id)980 void MVC_Extension::MoveViewToHead(int32_t view_id)
981 {
982     ViewList::iterator iter = m_views.begin();
983     ViewList::iterator iter_end = m_views.end();
984 
985     // run over the list and try to find the corresponding view
986     for (; iter != iter_end; ++iter)
987     {
988         if (iter->viewId == view_id)
989         {
990             ViewItem item = *iter;
991             ViewItem &front = m_views.front();
992             *iter = front;
993             front = item;
994             break;
995         }
996     }
997 }
998 
GetViewByNumber(int32_t viewNum)999 ViewItem & MVC_Extension::GetViewByNumber(int32_t viewNum)
1000 {
1001     ViewList::iterator iter = m_views.begin();
1002     ViewList::iterator iter_end = m_views.end();
1003 
1004     // run over the list and try to find the corresponding view
1005     for (int32_t i = 0; iter != iter_end; ++iter, i++)
1006     {
1007         ViewItem & item = *iter;
1008         if (i == viewNum)
1009             return item;
1010     }
1011 
1012     throw h264_exception(UMC_ERR_FAILED);
1013     //return NULL;
1014 }
1015 
GetBaseViewId() const1016 int32_t MVC_Extension::GetBaseViewId() const
1017 {
1018     return BASE_VIEW;
1019 }
1020 
GetViewCount() const1021 int32_t MVC_Extension::GetViewCount() const
1022 {
1023     return (int32_t)m_views.size();
1024 }
1025 
IncreaseCurrentView()1026 bool MVC_Extension::IncreaseCurrentView()
1027 {
1028     bool isWrapped = false;
1029     for (size_t i = 0; i < m_views.size(); ++i)
1030     {
1031         m_currentDisplayView++;
1032         if (m_views.size() == m_currentDisplayView)
1033         {
1034             m_currentDisplayView = BASE_VIEW;
1035             isWrapped = true;
1036         }
1037 
1038         ViewItem & view = GetViewByNumber(m_currentDisplayView);
1039         if (view.m_isDisplayable)
1040             break;
1041     }
1042 
1043     return isWrapped;
1044 }
1045 
SetTemporalId(uint32_t temporalId)1046 void MVC_Extension::SetTemporalId(uint32_t temporalId)
1047 {
1048     m_temporal_id = temporalId;
1049 }
1050 
SetViewList(const std::vector<uint32_t> & targetView,const std::vector<uint32_t> & dependencyList)1051 Status MVC_Extension::SetViewList(const std::vector<uint32_t> & targetView, const std::vector<uint32_t> & dependencyList)
1052 {
1053     for (size_t i = 0; i < targetView.size(); i++)
1054     {
1055         m_viewIDsList.push_back(targetView[i]);
1056     }
1057 
1058     for (size_t i = 0; i < dependencyList.size(); i++)
1059     {
1060         Status umcRes = AllocateView(dependencyList[i]);
1061         if (UMC_OK != umcRes)
1062         {
1063             return umcRes;
1064         }
1065 
1066         ViewItem & viewItem = GetView(dependencyList[i]);
1067         viewItem.m_isDisplayable = false;
1068         m_viewIDsList.push_back(dependencyList[i]);
1069     }
1070 
1071     m_viewIDsList.sort();
1072     m_viewIDsList.unique();
1073 
1074     return UMC_OK;
1075 }
1076 
GetLevelIDC() const1077 uint32_t MVC_Extension::GetLevelIDC() const
1078 {
1079     return m_level_idc;
1080 }
1081 
AllocateAndInitializeView(H264Slice * slice)1082 ViewItem & MVC_Extension::AllocateAndInitializeView(H264Slice * slice)
1083 {
1084     if (slice == nullptr)
1085     {
1086         throw h264_exception(UMC_ERR_NULL_PTR);
1087     }
1088     ViewItem * view = FindView(slice->GetSliceHeader()->nal_ext.mvc.view_id);
1089     if (view)
1090         return *view;
1091 
1092     Status umcRes = AllocateView(slice->GetSliceHeader()->nal_ext.mvc.view_id);
1093     if (UMC_OK != umcRes)
1094     {
1095         throw h264_exception(umcRes);
1096     }
1097 
1098     ViewItem &viewRef = GetView(slice->GetSliceHeader()->nal_ext.mvc.view_id);
1099     viewRef.SetDPBSize(const_cast<H264SeqParamSet*>(slice->m_pSeqParamSet), m_level_idc);
1100     return viewRef;
1101 }
1102 
AllocateView(int32_t view_id)1103 Status MVC_Extension::AllocateView(int32_t view_id)
1104 {
1105     // check error(s)
1106     if (((int32_t)H264_MAX_NUM_VIEW <= view_id) && (view_id != (int32_t)INVALID_VIEW_ID) )
1107     {
1108         return UMC_ERR_INVALID_PARAMS;
1109     }
1110 
1111     // already allocated
1112     if (FindView(view_id))
1113     {
1114         return UMC_OK;
1115     }
1116 
1117     if (FindView(INVALID_VIEW_ID))
1118     {
1119         ViewItem &view = GetView((uint32_t)INVALID_VIEW_ID);
1120         view.viewId = view_id;
1121         return UMC_OK;
1122     }
1123 
1124     ViewItem view;
1125     try
1126     {
1127         // allocate DPB and POC counter
1128         for (uint32_t i = 0; i < MAX_NUM_LAYERS; i++)
1129         {
1130             view.pDPB[i].reset(new H264DBPList());
1131             view.pPOCDec[i].reset(new POCDecoder());
1132         }
1133         view.viewId = view_id;
1134         view.maxDecFrameBuffering = 16;
1135     }
1136     catch(...)
1137     {
1138         return UMC_ERR_ALLOC;
1139     }
1140 
1141     // reset the variables
1142     m_views.push_back(view);
1143 
1144     return UMC_OK;
1145 
1146 } // Status AllocateView(uint32_t view_id)
1147 
IsShouldSkipSlice(H264NalExtension * nal_ext)1148 bool MVC_Extension::IsShouldSkipSlice(H264NalExtension *nal_ext)
1149 {
1150     // check is view at view_list;
1151     ViewIDsList::const_iterator iter = std::find(m_viewIDsList.begin(), m_viewIDsList.end(), nal_ext->mvc.view_id);
1152     if (iter == m_viewIDsList.end() && m_viewIDsList.size())
1153         return true;
1154 
1155     if (nal_ext->mvc.temporal_id > m_temporal_id)
1156         return true;
1157 
1158     if (nal_ext->mvc.priority_id > m_priority_id)
1159         return true;
1160 
1161     return false;
1162 }
1163 
IsShouldSkipSlice(H264Slice * slice)1164 bool MVC_Extension::IsShouldSkipSlice(H264Slice * slice)
1165 {
1166     bool isMVC = slice->GetSeqMVCParam() != 0;
1167 
1168     if (!isMVC)
1169         return false;
1170 
1171     return IsShouldSkipSlice(&slice->GetSliceHeader()->nal_ext);
1172 }
1173 
AnalyzeDependencies(const H264SeqParamSetMVCExtension *)1174 void MVC_Extension::AnalyzeDependencies(const H264SeqParamSetMVCExtension *)
1175 {
1176 }
1177 
ChooseLevelIdc(const H264SeqParamSetMVCExtension * extension,uint8_t baseViewLevelIDC,uint8_t extensionLevelIdc)1178 void MVC_Extension::ChooseLevelIdc(const H264SeqParamSetMVCExtension * extension, uint8_t baseViewLevelIDC, uint8_t extensionLevelIdc)
1179 {
1180     if (m_level_idc)
1181         return;
1182 
1183     assert(extension->viewInfo.size() == extension->num_views_minus1 + 1);
1184 
1185     if (m_viewIDsList.empty())
1186     {
1187         for (const auto & viewInfo : extension->viewInfo)
1188         {
1189             m_viewIDsList.push_back(viewInfo.view_id);
1190         }
1191 
1192         ViewIDsList::iterator iter = m_viewIDsList.begin();
1193         ViewIDsList::iterator iter_end = m_viewIDsList.end();
1194         for (; iter != iter_end; ++iter)
1195         {
1196             uint32_t targetView = *iter;
1197             ViewItem * view = FindView(targetView);
1198             if (!view)
1199                 continue;
1200 
1201             view->m_isDisplayable = true;
1202         }
1203     }
1204 
1205     AnalyzeDependencies(extension);
1206 
1207     m_level_idc = 0;
1208 
1209     for (const auto & levelInfo : extension->levelInfo)
1210     {
1211         for (const auto & operationPoint : levelInfo.opsInfo)
1212         {
1213             bool foundAll = true;
1214 
1215             for (const auto & targetView : m_viewIDsList)
1216             {
1217                 auto it = std::find_if(operationPoint.applicable_op_target_view_id.begin(), operationPoint.applicable_op_target_view_id.end(),
1218                                        [targetView](const uint16_t & item){ return item == targetView; });
1219 
1220                 if (it == operationPoint.applicable_op_target_view_id.end())
1221                 {
1222                     foundAll = false;
1223                     break;
1224                 }
1225             }
1226 
1227             if (!foundAll)
1228                 break;
1229 
1230             if (!m_level_idc || m_level_idc > levelInfo.level_idc)
1231             {
1232                 m_level_idc = levelInfo.level_idc;
1233             }
1234         }
1235     }
1236 
1237     m_level_idc = std::max({baseViewLevelIDC, extensionLevelIdc, m_level_idc});
1238 
1239     assert(m_level_idc != 0);
1240 }
1241 
1242 /****************************************************************************************************/
1243 // Skipping class routine
1244 /****************************************************************************************************/
Skipping()1245 Skipping::Skipping()
1246     : m_VideoDecodingSpeed(0)
1247     , m_SkipCycle(1)
1248     , m_ModSkipCycle(1)
1249     , m_PermanentTurnOffDeblocking(0)
1250     , m_SkipFlag(0)
1251     , m_NumberOfSkippedFrames(0)
1252 {
1253 }
1254 
~Skipping()1255 Skipping::~Skipping()
1256 {
1257 }
1258 
Reset()1259 void Skipping::Reset()
1260 {
1261     m_VideoDecodingSpeed = 0;
1262     m_SkipCycle = 0;
1263     m_ModSkipCycle = 0;
1264     m_PermanentTurnOffDeblocking = 0;
1265     m_NumberOfSkippedFrames = 0;
1266 }
1267 
PermanentDisableDeblocking(bool disable)1268 void Skipping::PermanentDisableDeblocking(bool disable)
1269 {
1270     m_PermanentTurnOffDeblocking = disable ? 3 : 0;
1271 }
1272 
IsShouldSkipDeblocking(H264DecoderFrame * pFrame,int32_t field)1273 bool Skipping::IsShouldSkipDeblocking(H264DecoderFrame * pFrame, int32_t field)
1274 {
1275     return (IS_SKIP_DEBLOCKING_MODE_PREVENTIVE || IS_SKIP_DEBLOCKING_MODE_PERMANENT ||
1276         (IS_SKIP_DEBLOCKING_MODE_NON_REF && !pFrame->GetAU(field)->IsReference()));
1277 }
1278 
IsShouldSkipFrame(H264DecoderFrame * pFrame,int32_t)1279 bool Skipping::IsShouldSkipFrame(H264DecoderFrame * pFrame, int32_t /*field*/)
1280 {
1281     bool isShouldSkip = false;
1282 
1283     //bool isReference = pFrame->GetAU(field)->IsReference();
1284 
1285     bool isReference0 = pFrame->GetAU(0)->IsReference();
1286     bool isReference1 = pFrame->GetAU(1)->IsReference();
1287 
1288     bool isReference = isReference0 || isReference1;
1289 
1290     if ((m_VideoDecodingSpeed > 0) && !isReference)
1291     {
1292         if ((m_SkipFlag % m_ModSkipCycle) == 0)
1293         {
1294             isShouldSkip = true;
1295         }
1296 
1297         m_SkipFlag++;
1298 
1299         if (m_SkipFlag >= m_SkipCycle)
1300             m_SkipFlag = 0;
1301     }
1302 
1303     if (isShouldSkip)
1304         m_NumberOfSkippedFrames++;
1305 
1306     return isShouldSkip;
1307 }
1308 
ChangeVideoDecodingSpeed(int32_t & num)1309 void Skipping::ChangeVideoDecodingSpeed(int32_t & num)
1310 {
1311     m_VideoDecodingSpeed += num;
1312 
1313     if (m_VideoDecodingSpeed < 0)
1314         m_VideoDecodingSpeed = 0;
1315     if (m_VideoDecodingSpeed > 7)
1316         m_VideoDecodingSpeed = 7;
1317 
1318     num = m_VideoDecodingSpeed;
1319 
1320     int32_t deblocking_off = m_PermanentTurnOffDeblocking;
1321 
1322     if (m_VideoDecodingSpeed > 6)
1323     {
1324         m_SkipCycle = 1;
1325         m_ModSkipCycle = 1;
1326         m_PermanentTurnOffDeblocking = 2;
1327     }
1328     else if (m_VideoDecodingSpeed > 5)
1329     {
1330         m_SkipCycle = 1;
1331         m_ModSkipCycle = 1;
1332         m_PermanentTurnOffDeblocking = 0;
1333     }
1334     else if (m_VideoDecodingSpeed > 4)
1335     {
1336         m_SkipCycle = 3;
1337         m_ModSkipCycle = 2;
1338         m_PermanentTurnOffDeblocking = 1;
1339     }
1340     else if (m_VideoDecodingSpeed > 3)
1341     {
1342         m_SkipCycle = 3;
1343         m_ModSkipCycle = 2;
1344         m_PermanentTurnOffDeblocking = 0;
1345     }
1346     else if (m_VideoDecodingSpeed > 2)
1347     {
1348         m_SkipCycle = 2;
1349         m_ModSkipCycle = 2;
1350         m_PermanentTurnOffDeblocking = 0;
1351     }
1352     else if (m_VideoDecodingSpeed > 1)
1353     {
1354         m_SkipCycle = 3;
1355         m_ModSkipCycle = 3;
1356         m_PermanentTurnOffDeblocking = 0;
1357     }
1358     else if (m_VideoDecodingSpeed == 1)
1359     {
1360         m_SkipCycle = 4;
1361         m_ModSkipCycle = 4;
1362         m_PermanentTurnOffDeblocking = 0;
1363     }
1364     else
1365     {
1366         m_PermanentTurnOffDeblocking = 0;
1367     }
1368 
1369     if (deblocking_off == 3)
1370         m_PermanentTurnOffDeblocking = 3;
1371 }
1372 
GetSkipInfo() const1373 Skipping::SkipInfo Skipping::GetSkipInfo() const
1374 {
1375     Skipping::SkipInfo info;
1376     info.isDeblockingTurnedOff = (m_VideoDecodingSpeed == 5) || (m_VideoDecodingSpeed == 7);
1377     info.numberOfSkippedFrames = m_NumberOfSkippedFrames;
1378     return info;
1379 }
1380 
1381 /****************************************************************************************************/
1382 // POCDecoder
1383 /****************************************************************************************************/
POCDecoder()1384 POCDecoder::POCDecoder()
1385 {
1386     Reset();
1387 }
1388 
~POCDecoder()1389 POCDecoder::~POCDecoder()
1390 {
1391 }
1392 
Reset(int32_t IDRFrameNum)1393 void POCDecoder::Reset(int32_t IDRFrameNum)
1394 {
1395     m_PicOrderCnt = 0;
1396     m_PicOrderCntMsb = 0;
1397     m_PicOrderCntLsb = 0;
1398     m_FrameNum = IDRFrameNum;
1399     m_PrevFrameRefNum = IDRFrameNum;
1400     m_FrameNumOffset = 0;
1401     m_TopFieldPOC = 0;
1402     m_BottomFieldPOC = 0;
1403 }
1404 
DecodePictureOrderCount(const H264Slice * slice,int32_t frame_num)1405 void POCDecoder::DecodePictureOrderCount(const H264Slice *slice, int32_t frame_num)
1406 {
1407     const H264SliceHeader *sliceHeader = slice->GetSliceHeader();
1408     const H264SeqParamSet* sps = slice->GetSeqParam();
1409 
1410     int32_t uMaxFrameNum = (1<<sps->log2_max_frame_num);
1411 
1412     if (sps->pic_order_cnt_type == 0)
1413     {
1414         // pic_order_cnt type 0
1415         int32_t CurrPicOrderCntMsb;
1416         int32_t MaxPicOrderCntLsb = sps->MaxPicOrderCntLsb;
1417 
1418         if ((sliceHeader->pic_order_cnt_lsb < m_PicOrderCntLsb) &&
1419              ((m_PicOrderCntLsb - sliceHeader->pic_order_cnt_lsb) >= (MaxPicOrderCntLsb >> 1)))
1420             CurrPicOrderCntMsb = m_PicOrderCntMsb + MaxPicOrderCntLsb;
1421         else if ((sliceHeader->pic_order_cnt_lsb > m_PicOrderCntLsb) &&
1422                 ((sliceHeader->pic_order_cnt_lsb - m_PicOrderCntLsb) > (MaxPicOrderCntLsb >> 1)))
1423             CurrPicOrderCntMsb = m_PicOrderCntMsb - MaxPicOrderCntLsb;
1424         else
1425             CurrPicOrderCntMsb = m_PicOrderCntMsb;
1426 
1427         if (sliceHeader->nal_ref_idc)
1428         {
1429             // reference picture
1430             m_PicOrderCntMsb = CurrPicOrderCntMsb & (~(MaxPicOrderCntLsb - 1));
1431             m_PicOrderCntLsb = sliceHeader->pic_order_cnt_lsb;
1432         }
1433         m_PicOrderCnt = CurrPicOrderCntMsb + sliceHeader->pic_order_cnt_lsb;
1434         if (sliceHeader->field_pic_flag == 0)
1435         {
1436              m_TopFieldPOC = CurrPicOrderCntMsb + sliceHeader->pic_order_cnt_lsb;
1437              m_BottomFieldPOC = m_TopFieldPOC + sliceHeader->delta_pic_order_cnt_bottom;
1438         }
1439 
1440     }    // pic_order_cnt type 0
1441     else if (sps->pic_order_cnt_type == 1)
1442     {
1443         // pic_order_cnt type 1
1444         uint32_t i;
1445         uint32_t uAbsFrameNum;    // frame # relative to last IDR pic
1446         uint32_t uPicOrderCycleCnt = 0;
1447         uint32_t uFrameNuminPicOrderCntCycle = 0;
1448         int32_t ExpectedPicOrderCnt = 0;
1449         int32_t ExpectedDeltaPerPicOrderCntCycle;
1450         uint32_t uNumRefFramesinPicOrderCntCycle = sps->num_ref_frames_in_pic_order_cnt_cycle;
1451 
1452         if (frame_num < m_FrameNum)
1453             m_FrameNumOffset += uMaxFrameNum;
1454 
1455         if (uNumRefFramesinPicOrderCntCycle != 0)
1456             uAbsFrameNum = m_FrameNumOffset + frame_num;
1457         else
1458             uAbsFrameNum = 0;
1459 
1460         if ((sliceHeader->nal_ref_idc == false)  && (uAbsFrameNum > 0))
1461             uAbsFrameNum--;
1462 
1463         if (uAbsFrameNum)
1464         {
1465             uPicOrderCycleCnt = (uAbsFrameNum - 1) /
1466                     uNumRefFramesinPicOrderCntCycle;
1467             uFrameNuminPicOrderCntCycle = (uAbsFrameNum - 1) %
1468                     uNumRefFramesinPicOrderCntCycle;
1469         }
1470 
1471         ExpectedDeltaPerPicOrderCntCycle = 0;
1472         for (i=0; i < uNumRefFramesinPicOrderCntCycle; i++)
1473         {
1474             ExpectedDeltaPerPicOrderCntCycle +=
1475                 sps->poffset_for_ref_frame[i];
1476         }
1477 
1478         if (uAbsFrameNum)
1479         {
1480             ExpectedPicOrderCnt = uPicOrderCycleCnt * ExpectedDeltaPerPicOrderCntCycle;
1481             for (i=0; i<=uFrameNuminPicOrderCntCycle; i++)
1482             {
1483                 ExpectedPicOrderCnt +=
1484                     sps->poffset_for_ref_frame[i];
1485             }
1486         }
1487         else
1488             ExpectedPicOrderCnt = 0;
1489 
1490         if (sliceHeader->nal_ref_idc == false)
1491             ExpectedPicOrderCnt += sps->offset_for_non_ref_pic;
1492         m_PicOrderCnt = ExpectedPicOrderCnt + sliceHeader->delta_pic_order_cnt[0];
1493         if( sliceHeader->field_pic_flag==0)
1494         {
1495             m_TopFieldPOC = ExpectedPicOrderCnt + sliceHeader->delta_pic_order_cnt[ 0 ];
1496             m_BottomFieldPOC = m_TopFieldPOC +
1497                 sps->offset_for_top_to_bottom_field + sliceHeader->delta_pic_order_cnt[ 1 ];
1498         }
1499         else if( ! sliceHeader->bottom_field_flag)
1500             m_PicOrderCnt = ExpectedPicOrderCnt + sliceHeader->delta_pic_order_cnt[ 0 ];
1501         else
1502             m_PicOrderCnt  = ExpectedPicOrderCnt + sps->offset_for_top_to_bottom_field + sliceHeader->delta_pic_order_cnt[ 0 ];
1503     }    // pic_order_cnt type 1
1504     else if (sps->pic_order_cnt_type == 2)
1505     {
1506         // pic_order_cnt type 2
1507         int32_t iMaxFrameNum = (1<<sps->log2_max_frame_num);
1508         uint32_t uAbsFrameNum;    // frame # relative to last IDR pic
1509 
1510         if (frame_num < m_FrameNum)
1511             m_FrameNumOffset += iMaxFrameNum;
1512         uAbsFrameNum = frame_num + m_FrameNumOffset;
1513         m_PicOrderCnt = uAbsFrameNum*2;
1514         if (sliceHeader->nal_ref_idc == false)
1515             m_PicOrderCnt--;
1516         m_TopFieldPOC = m_PicOrderCnt;
1517         m_BottomFieldPOC = m_PicOrderCnt;
1518 
1519     }    // pic_order_cnt type 2
1520 
1521     if (sliceHeader->nal_ref_idc)
1522     {
1523         m_PrevFrameRefNum = frame_num;
1524     }
1525 
1526     m_FrameNum = frame_num;
1527 }    // decodePictureOrderCount
1528 
DetectFrameNumGap(const H264Slice * slice,bool ignore_gaps_allowed_flag)1529 int32_t POCDecoder::DetectFrameNumGap(const H264Slice *slice, bool ignore_gaps_allowed_flag)
1530 {
1531     const H264SeqParamSet* sps = slice->GetSeqParam();
1532 
1533     if (!ignore_gaps_allowed_flag && sps->gaps_in_frame_num_value_allowed_flag != 1)
1534         return 0;
1535 
1536     const H264SliceHeader *sliceHeader = slice->GetSliceHeader();
1537 
1538     int32_t uMaxFrameNum = (1<<sps->log2_max_frame_num);
1539     int32_t frameNumGap;
1540 
1541     if (sliceHeader->IdrPicFlag)
1542         return 0;
1543 
1544     // Capture any frame_num gap
1545     if (sliceHeader->frame_num != m_PrevFrameRefNum &&
1546         sliceHeader->frame_num != (m_PrevFrameRefNum + 1) % uMaxFrameNum)
1547     {
1548         // note this could be negative if frame num wrapped
1549 
1550         if (sliceHeader->frame_num > m_PrevFrameRefNum - 1)
1551         {
1552             frameNumGap = (sliceHeader->frame_num - m_PrevFrameRefNum - 1) % uMaxFrameNum;
1553         }
1554         else
1555         {
1556             frameNumGap = (uMaxFrameNum - (m_PrevFrameRefNum + 1 - sliceHeader->frame_num)) % uMaxFrameNum;
1557         }
1558     }
1559     else
1560     {
1561         frameNumGap = 0;
1562     }
1563 
1564     return frameNumGap;
1565 }
1566 
DecodePictureOrderCountFrameGap(H264DecoderFrame * pFrame,const H264SliceHeader * pSliceHeader,int32_t frameNum)1567 void POCDecoder::DecodePictureOrderCountFrameGap(H264DecoderFrame *pFrame,
1568                                                  const H264SliceHeader *pSliceHeader,
1569                                                  int32_t frameNum)
1570 {
1571     m_PrevFrameRefNum = frameNum;
1572     m_FrameNum = frameNum;
1573 
1574     if (pSliceHeader->field_pic_flag)
1575     {
1576         pFrame->setPicOrderCnt(m_PicOrderCnt, 0);
1577         pFrame->setPicOrderCnt(m_PicOrderCnt, 1);
1578     }
1579     else
1580     {
1581         pFrame->setPicOrderCnt(m_TopFieldPOC, 0);
1582         pFrame->setPicOrderCnt(m_BottomFieldPOC, 1);
1583     }
1584 }
1585 
DecodePictureOrderCountFakeFrames(H264DecoderFrame * pFrame,const H264SliceHeader * pSliceHeader)1586 void POCDecoder::DecodePictureOrderCountFakeFrames(H264DecoderFrame *pFrame,
1587                                                    const H264SliceHeader *pSliceHeader)
1588 {
1589     if (pSliceHeader->field_pic_flag)
1590     {
1591         pFrame->setPicOrderCnt(m_PicOrderCnt, 0);
1592         pFrame->setPicOrderCnt(m_PicOrderCnt, 1);
1593     }
1594     else
1595     {
1596         pFrame->setPicOrderCnt(m_TopFieldPOC, 0);
1597         pFrame->setPicOrderCnt(m_BottomFieldPOC, 1);
1598     }
1599 
1600 }
1601 
DecodePictureOrderCountInitFrame(H264DecoderFrame * pFrame,int32_t fieldIdx)1602 void POCDecoder::DecodePictureOrderCountInitFrame(H264DecoderFrame *pFrame,
1603                                                   int32_t fieldIdx)
1604 {
1605     //transfer previosly calculated PicOrdeCnts into current Frame
1606     if (pFrame->m_PictureStructureForRef < FRM_STRUCTURE)
1607     {
1608         pFrame->setPicOrderCnt(m_PicOrderCnt, fieldIdx);
1609         if (!fieldIdx) // temporally set same POC for second field
1610             pFrame->setPicOrderCnt(m_PicOrderCnt, 1);
1611     }
1612     else
1613     {
1614         pFrame->setPicOrderCnt(m_TopFieldPOC, 0);
1615         pFrame->setPicOrderCnt(m_BottomFieldPOC, 1);
1616     }
1617 }
1618 /****************************************************************************************************/
1619 // SEI_Storer
1620 /****************************************************************************************************/
SEI_Storer()1621 SEI_Storer::SEI_Storer()
1622 {
1623     m_offset = 0;
1624     Reset();
1625 }
1626 
~SEI_Storer()1627 SEI_Storer::~SEI_Storer()
1628 {
1629     Close();
1630 }
1631 
Init()1632 void SEI_Storer::Init()
1633 {
1634     Close();
1635     m_data.resize(MAX_BUFFERED_SIZE);
1636     m_payloads.resize(START_ELEMENTS);
1637     m_offset = 0;
1638     m_lastUsed = 2;
1639 }
1640 
Close()1641 void SEI_Storer::Close()
1642 {
1643     Reset();
1644     m_data.clear();
1645     m_payloads.clear();
1646 }
1647 
Reset()1648 void SEI_Storer::Reset()
1649 {
1650     m_lastUsed = 2;
1651     for (uint32_t i = 0; i < m_payloads.size(); i++)
1652     {
1653         m_payloads[i].isUsed = 0;
1654     }
1655 }
1656 
SetFrame(H264DecoderFrame * frame,int32_t auIndex)1657 void SEI_Storer::SetFrame(H264DecoderFrame * frame, int32_t auIndex)
1658 {
1659     assert(frame);
1660     for (uint32_t i = 0; i < m_payloads.size(); i++)
1661     {
1662         if (m_payloads[i].frame == 0 && m_payloads[i].isUsed && m_payloads[i].auID == auIndex)
1663         {
1664             m_payloads[i].frame = frame;
1665         }
1666     }
1667 }
1668 
SetAUID(int32_t auIndex)1669 void SEI_Storer::SetAUID(int32_t auIndex)
1670 {
1671     for (uint32_t i = 0; i < m_payloads.size(); i++)
1672     {
1673         if (m_payloads[i].isUsed && m_payloads[i].auID == -1)
1674         {
1675             m_payloads[i].auID = auIndex;
1676         }
1677     }
1678 }
1679 
SetTimestamp(H264DecoderFrame * frame)1680 void SEI_Storer::SetTimestamp(H264DecoderFrame * frame)
1681 {
1682     assert(frame);
1683     double ts = frame->m_dFrameTime;
1684 
1685     for (uint32_t i = 0; i < m_payloads.size(); i++)
1686     {
1687         if (m_payloads[i].frame == frame)
1688         {
1689             m_payloads[i].timestamp = ts;
1690             if (m_payloads[i].isUsed)
1691                 m_payloads[i].isUsed = m_lastUsed;
1692         }
1693     }
1694 
1695     m_lastUsed++;
1696 }
1697 
GetPayloadMessage()1698 const SEI_Storer::SEI_Message * SEI_Storer::GetPayloadMessage()
1699 {
1700     SEI_Storer::SEI_Message * msg = 0;
1701 
1702     for (uint32_t i = 0; i < m_payloads.size(); i++)
1703     {
1704         if (m_payloads[i].isUsed > 1)
1705         {
1706             if (!msg || msg->isUsed > m_payloads[i].isUsed || msg->inputID > m_payloads[i].inputID)
1707             {
1708                 msg = &m_payloads[i];
1709             }
1710         }
1711     }
1712 
1713     if (msg)
1714     {
1715         msg->isUsed = 0;
1716         msg->frame = 0;
1717         msg->auID = 0;
1718         msg->inputID = 0;
1719     }
1720 
1721     return msg;
1722 }
1723 
AddMessage(UMC::MediaDataEx * nalUnit,SEI_TYPE type,int32_t auIndex)1724 SEI_Storer::SEI_Message* SEI_Storer::AddMessage(UMC::MediaDataEx *nalUnit, SEI_TYPE type, int32_t auIndex)
1725 {
1726     size_t sz = nalUnit->GetDataSize();
1727 
1728     if (sz > (m_data.size() >> 2))
1729         return 0;
1730 
1731     if (m_offset + sz > m_data.size())
1732     {
1733         m_offset = 0;
1734     }
1735 
1736     // clear overwriting messages:
1737     for (uint32_t i = 0; i < m_payloads.size(); i++)
1738     {
1739         if (!m_payloads[i].isUsed)
1740             continue;
1741 
1742         SEI_Message & mmsg = m_payloads[i];
1743 
1744         if ((m_offset + sz > mmsg.offset) &&
1745             (m_offset < mmsg.offset + mmsg.msg_size))
1746         {
1747             m_payloads[i].isUsed = 0;
1748             return 0;
1749         }
1750     }
1751 
1752     size_t freeSlot = 0;
1753     for (uint32_t i = 0; i < m_payloads.size(); i++)
1754     {
1755         if (!m_payloads[i].isUsed)
1756         {
1757             freeSlot = i;
1758             break;
1759         }
1760     }
1761 
1762     if (m_payloads[freeSlot].isUsed)
1763     {
1764         if (m_payloads.size() >= MAX_ELEMENTS)
1765             return 0;
1766 
1767         m_payloads.push_back(SEI_Message());
1768         freeSlot = m_payloads.size() - 1;
1769     }
1770 
1771     m_payloads[freeSlot].msg_size = sz;
1772     m_payloads[freeSlot].offset = m_offset;
1773     m_payloads[freeSlot].timestamp = 0;
1774     m_payloads[freeSlot].frame = 0;
1775     m_payloads[freeSlot].isUsed = 1;
1776     m_payloads[freeSlot].inputID = m_lastUsed++;
1777     m_payloads[freeSlot].data = &(m_data.front()) + m_offset;
1778     m_payloads[freeSlot].type = type;
1779     m_payloads[freeSlot].auID = auIndex;
1780 
1781     MFX_INTERNAL_CPY(&m_data[m_offset], (uint8_t*)nalUnit->GetDataPointer(), (uint32_t)sz);
1782 
1783     m_offset += sz;
1784     return &m_payloads[freeSlot];
1785 }
1786 
ViewItem()1787 ViewItem::ViewItem()
1788 {
1789     viewId = 0;
1790     maxDecFrameBuffering = 0;
1791     maxNumReorderFrames  = 16; // Max DPB size
1792 
1793     Reset();
1794 
1795 } // ViewItem::ViewItem(void)
1796 
ViewItem(const ViewItem & src)1797 ViewItem::ViewItem(const ViewItem &src)
1798 {
1799     Reset();
1800 
1801     viewId = src.viewId;
1802     for (uint32_t i = 0; i < MAX_NUM_LAYERS; i++) {
1803         pDPB[i].reset(src.pDPB[i].release());
1804         pPOCDec[i].reset(src.pPOCDec[i].release());
1805         MaxLongTermFrameIdx[i] = src.MaxLongTermFrameIdx[i];
1806     }
1807     maxDecFrameBuffering = src.maxDecFrameBuffering;
1808     maxNumReorderFrames  = src.maxNumReorderFrames;
1809 
1810 } // ViewItem::ViewItem(const ViewItem &src)
1811 
operator =(const ViewItem & src)1812 ViewItem &ViewItem::operator =(const ViewItem &src)
1813 {
1814     Reset();
1815 
1816     viewId = src.viewId;
1817     for (uint32_t i = 0; i < MAX_NUM_LAYERS; i++) {
1818         pDPB[i].reset(src.pDPB[i].release());
1819         pPOCDec[i].reset(src.pPOCDec[i].release());
1820         MaxLongTermFrameIdx[i] = src.MaxLongTermFrameIdx[i];
1821     }
1822     maxDecFrameBuffering = src.maxDecFrameBuffering;
1823     maxNumReorderFrames  = src.maxNumReorderFrames;
1824 
1825     return *this;
1826 }
1827 
~ViewItem()1828 ViewItem::~ViewItem()
1829 {
1830     Close();
1831 
1832 } // ViewItem::ViewItem(void)
1833 
Init(uint32_t view_id)1834 Status ViewItem::Init(uint32_t view_id)
1835 {
1836     // release the object before initialization
1837     Close();
1838 
1839     try
1840     {
1841         for (uint32_t i = 0; i < MAX_NUM_LAYERS; i++) {
1842             // allocate DPB and POC counter
1843             pDPB[i].reset(new H264DBPList());
1844             pPOCDec[i].reset(new POCDecoder());
1845         }
1846     }
1847     catch(...)
1848     {
1849         return UMC_ERR_ALLOC;
1850     }
1851 
1852     // save the ID
1853     viewId = view_id;
1854     localFrameTime = 0;
1855     pCurFrame = 0;
1856     return UMC_OK;
1857 
1858 } // Status ViewItem::Init(uint32_t view_id)
1859 
Close(void)1860 void ViewItem::Close(void)
1861 {
1862     // Reset the parameters before close
1863     Reset();
1864 
1865     for (int32_t i = MAX_NUM_LAYERS - 1; i >= 0; i--) {
1866         if (pDPB[i].get())
1867         {
1868             pDPB[i].reset();
1869         }
1870 
1871         if (pPOCDec[i].get())
1872         {
1873             pPOCDec[i].reset();
1874         }
1875 
1876         MaxLongTermFrameIdx[i] = 0;
1877     }
1878 
1879     viewId = (uint32_t)INVALID_VIEW_ID;
1880     maxDecFrameBuffering = 1;
1881 } // void ViewItem::Close(void)
1882 
Reset(void)1883 void ViewItem::Reset(void)
1884 {
1885     for (int32_t i = MAX_NUM_LAYERS - 1; i >= 0; i--)
1886     {
1887         if (pDPB[i].get())
1888         {
1889             pDPB[i]->Reset();
1890         }
1891 
1892         if (pPOCDec[i].get())
1893         {
1894             pPOCDec[i]->Reset();
1895         }
1896     }
1897 
1898     pCurFrame = 0;
1899     localFrameTime = 0;
1900     m_isDisplayable = true;
1901 
1902 } // void ViewItem::Reset(void)
1903 
SetDPBSize(H264SeqParamSet * pSps,uint8_t & level_idc)1904 void ViewItem::SetDPBSize(H264SeqParamSet *pSps, uint8_t & level_idc)
1905 {
1906     // calculate the new DPB size value
1907     maxDecFrameBuffering = CalculateDPBSize(level_idc ? level_idc : pSps->level_idc,
1908                                pSps->frame_width_in_mbs * 16,
1909                                pSps->frame_height_in_mbs * 16,
1910                                pSps->num_ref_frames);
1911 
1912     maxDecFrameBuffering = pSps->vui.max_dec_frame_buffering ? pSps->vui.max_dec_frame_buffering : maxDecFrameBuffering;
1913     if (pSps->vui.max_dec_frame_buffering > maxDecFrameBuffering)
1914         pSps->vui.max_dec_frame_buffering = (uint8_t)maxDecFrameBuffering;
1915 
1916     // provide the new value to the DPBList
1917     for (uint32_t i = 0; i < MAX_NUM_LAYERS; i++)
1918     {
1919         if (pDPB[i].get())
1920         {
1921             pDPB[i]->SetDPBSize(maxDecFrameBuffering);
1922         }
1923     }
1924 
1925     if (pSps->vui.bitstream_restriction_flag)
1926     {
1927         maxNumReorderFrames = pSps->vui.num_reorder_frames;
1928     }
1929     else
1930     {
1931         // Regarding H264 Specification - E.2.1 VUI parameters semantics :
1932         // When the max_num_reorder_frames syntax element is not present,
1933         // the value of max_num_reorder_frames value shall be inferred as follows:
1934         if ((1 == pSps->constraint_set3_flag) &&
1935             (H264VideoDecoderParams::H264_PROFILE_CAVLC444_INTRA == pSps->profile_idc ||
1936              H264VideoDecoderParams::H264_PROFILE_SCALABLE_HIGH  == pSps->profile_idc ||
1937              H264VideoDecoderParams::H264_PROFILE_HIGH           == pSps->profile_idc ||
1938              H264VideoDecoderParams::H264_PROFILE_HIGH10         == pSps->profile_idc ||
1939              H264VideoDecoderParams::H264_PROFILE_HIGH422        == pSps->profile_idc ||
1940              H264VideoDecoderParams::H264_PROFILE_HIGH444_PRED   == pSps->profile_idc)
1941         )
1942         {
1943             maxNumReorderFrames = 0;
1944         }
1945         else
1946         {
1947             maxNumReorderFrames = maxDecFrameBuffering;
1948         }
1949     }
1950 } // void ViewItem::SetDPBSize(const H264SeqParamSet *pSps)
1951 
1952 /****************************************************************************************************/
1953 // TaskSupplier
1954 /****************************************************************************************************/
TaskSupplier()1955 TaskSupplier::TaskSupplier()
1956     : AU_Splitter(&m_ObjHeap)
1957 
1958     , m_pSegmentDecoder(0)
1959     , m_iThreadNum(0)
1960     , m_local_delta_frame_time(0)
1961     , m_use_external_framerate(false)
1962 
1963     , m_pLastSlice(0)
1964     , m_pLastDisplayed(0)
1965     , m_pMemoryAllocator(0)
1966     , m_pFrameAllocator(0)
1967     , m_WaitForIDR(false)
1968     , m_DPBSizeEx(0)
1969     , m_frameOrder(0)
1970     , m_pTaskBroker(0)
1971     , m_UIDFrameCounter(0)
1972     , m_sei_messages(0)
1973     , m_isInitialized(false)
1974     , m_ignoreLevelConstrain(false)
1975 {
1976 }
1977 
~TaskSupplier()1978 TaskSupplier::~TaskSupplier()
1979 {
1980     Close();
1981 }
1982 
Init(VideoDecoderParams * init)1983 Status TaskSupplier::Init(VideoDecoderParams *init)
1984 {
1985     if (NULL == init)
1986         return UMC_ERR_NULL_PTR;
1987 
1988     Close();
1989 
1990     m_DPBSizeEx = 0;
1991 
1992     m_initializationParams = *init;
1993 
1994     int32_t nAllowedThreadNumber = init->numThreads;
1995     if(nAllowedThreadNumber < 0) nAllowedThreadNumber = 0;
1996 
1997     // calculate number of slice decoders.
1998     // It should be equal to CPU number
1999     m_iThreadNum = (0 == nAllowedThreadNumber) ? (vm_sys_info_get_cpu_num()) : (nAllowedThreadNumber);
2000 
2001     DPBOutput::Reset(m_iThreadNum != 1);
2002     AU_Splitter::Init();
2003     Status umcRes = SVC_Extension::Init();
2004     if (UMC_OK != umcRes)
2005     {
2006         return umcRes;
2007     }
2008 
2009     switch (m_initializationParams.info.profile) // after MVC_Extension::Init()
2010     {
2011     case 0:
2012         m_decodingMode = UNKNOWN_DECODING_MODE;
2013         break;
2014     case H264VideoDecoderParams::H264_PROFILE_MULTIVIEW_HIGH:
2015     case H264VideoDecoderParams::H264_PROFILE_STEREO_HIGH:
2016         m_decodingMode = MVC_DECODING_MODE;
2017         break;
2018     default:
2019         m_decodingMode = AVC_DECODING_MODE;
2020         break;
2021     }
2022 
2023     // create slice decoder(s)
2024     m_pSegmentDecoder = new H264SegmentDecoderBase *[m_iThreadNum];
2025     if (NULL == m_pSegmentDecoder)
2026         return UMC_ERR_ALLOC;
2027     memset(m_pSegmentDecoder, 0, sizeof(H264SegmentDecoderBase *) * m_iThreadNum);
2028 
2029     CreateTaskBroker();
2030     m_pTaskBroker->Init(m_iThreadNum);
2031 
2032     for (uint32_t i = 0; i < m_iThreadNum; i += 1)
2033     {
2034         if (UMC_OK != m_pSegmentDecoder[i]->Init(i))
2035             return UMC_ERR_INIT;
2036     }
2037 
2038     m_local_delta_frame_time = 1.0/30;
2039     m_frameOrder = 0;
2040     m_use_external_framerate = 0 < init->info.framerate;
2041 
2042     if (m_use_external_framerate)
2043     {
2044         m_local_delta_frame_time = 1 / init->info.framerate;
2045     }
2046 
2047     m_DPBSizeEx = m_iThreadNum;
2048 
2049     m_isInitialized = true;
2050 
2051     m_ignoreLevelConstrain = ((H264VideoDecoderParams *)init)->m_ignore_level_constrain;
2052 
2053     return UMC_OK;
2054 }
2055 
PreInit(VideoDecoderParams * init)2056 Status TaskSupplier::PreInit(VideoDecoderParams *init)
2057 {
2058     if (m_isInitialized)
2059         return UMC_OK;
2060 
2061     if (NULL == init)
2062         return UMC_ERR_NULL_PTR;
2063 
2064     Close();
2065 
2066     m_DPBSizeEx = 0;
2067 
2068     SVC_Extension::Init();
2069 
2070     int32_t nAllowedThreadNumber = init->numThreads;
2071     if(nAllowedThreadNumber < 0) nAllowedThreadNumber = 0;
2072 
2073     // calculate number of slice decoders.
2074     // It should be equal to CPU number
2075     m_iThreadNum = (0 == nAllowedThreadNumber) ? (vm_sys_info_get_cpu_num()) : (nAllowedThreadNumber);
2076 
2077     AU_Splitter::Init();
2078     DPBOutput::Reset(m_iThreadNum != 1);
2079 
2080     m_local_delta_frame_time = 1.0/30;
2081     m_frameOrder             = 0;
2082     m_use_external_framerate = 0 < init->info.framerate;
2083 
2084     if (m_use_external_framerate)
2085     {
2086         m_local_delta_frame_time = 1 / init->info.framerate;
2087     }
2088 
2089     m_DPBSizeEx = m_iThreadNum;
2090 
2091     m_ignoreLevelConstrain = ((H264VideoDecoderParams *)init)->m_ignore_level_constrain;
2092 
2093     return UMC_OK;
2094 }
2095 
Close()2096 void TaskSupplier::Close()
2097 {
2098     if (m_pTaskBroker)
2099     {
2100         m_pTaskBroker->Release();
2101     }
2102 
2103 // from reset
2104 
2105     {
2106     ViewList::iterator iter = m_views.begin();
2107     ViewList::iterator iter_end = m_views.end();
2108     for (; iter != iter_end; ++iter)
2109     {
2110         for (H264DecoderFrame *pFrame = iter->GetDPBList(0)->head(); pFrame; pFrame = pFrame->future())
2111         {
2112             pFrame->FreeResources();
2113         }
2114     }
2115     }
2116 
2117     if (m_pSegmentDecoder)
2118     {
2119         for (uint32_t i = 0; i < m_iThreadNum; i += 1)
2120         {
2121             delete m_pSegmentDecoder[i];
2122             m_pSegmentDecoder[i] = 0;
2123         }
2124     }
2125 
2126     SVC_Extension::Close();
2127     AU_Splitter::Close();
2128     DPBOutput::Reset(m_iThreadNum != 1);
2129     DecReferencePictureMarking::Reset();
2130     ErrorStatus::Reset();
2131 
2132     if (m_pLastSlice)
2133     {
2134         m_pLastSlice->Release();
2135         m_pLastSlice->DecrementReference();
2136         m_pLastSlice = 0;
2137     }
2138 
2139     m_accessUnit.Release();
2140     m_Headers.Reset(false);
2141     Skipping::Reset();
2142     m_ObjHeap.Release();
2143 
2144     m_frameOrder               = 0;
2145 
2146     m_WaitForIDR        = true;
2147 
2148     m_pLastDisplayed = 0;
2149 
2150     delete m_sei_messages;
2151     m_sei_messages = 0;
2152 
2153 // from reset
2154 
2155     delete[] m_pSegmentDecoder;
2156     m_pSegmentDecoder = 0;
2157 
2158     delete m_pTaskBroker;
2159     m_pTaskBroker = 0;
2160 
2161     m_iThreadNum = 0;
2162 
2163     m_DPBSizeEx = 1;
2164 
2165     m_isInitialized = false;
2166 
2167 } // void TaskSupplier::Close()
2168 
Reset()2169 void TaskSupplier::Reset()
2170 {
2171     if (m_pTaskBroker)
2172         m_pTaskBroker->Reset();
2173 
2174     {
2175     ViewList::iterator iter = m_views.begin();
2176     ViewList::iterator iter_end = m_views.end();
2177     for (; iter != iter_end; ++iter)
2178     {
2179         for (H264DecoderFrame *pFrame = iter->GetDPBList(0)->head(); pFrame; pFrame = pFrame->future())
2180         {
2181             pFrame->FreeResources();
2182         }
2183     }
2184     }
2185 
2186     if (m_sei_messages)
2187         m_sei_messages->Reset();
2188 
2189     SVC_Extension::Reset();
2190     AU_Splitter::Reset();
2191     DPBOutput::Reset(m_iThreadNum != 1);
2192     DecReferencePictureMarking::Reset();
2193     m_accessUnit.Release();
2194     ErrorStatus::Reset();
2195 
2196     switch (m_initializationParams.info.profile) // after MVC_Extension::Init()
2197     {
2198     case 0:
2199         m_decodingMode = UNKNOWN_DECODING_MODE;
2200         break;
2201     case H264VideoDecoderParams::H264_PROFILE_MULTIVIEW_HIGH:
2202     case H264VideoDecoderParams::H264_PROFILE_STEREO_HIGH:
2203         m_decodingMode = MVC_DECODING_MODE;
2204         break;
2205     default:
2206         m_decodingMode = AVC_DECODING_MODE;
2207         break;
2208     }
2209 
2210     if (m_pLastSlice)
2211     {
2212         m_pLastSlice->Release();
2213         m_pLastSlice->DecrementReference();
2214         m_pLastSlice = 0;
2215     }
2216 
2217     m_Headers.Reset(true);
2218     Skipping::Reset();
2219     m_ObjHeap.Release();
2220 
2221     m_frameOrder               = 0;
2222 
2223     m_WaitForIDR        = true;
2224 
2225     m_pLastDisplayed = 0;
2226 
2227     if (m_pTaskBroker)
2228         m_pTaskBroker->Init(m_iThreadNum);
2229 }
2230 
AfterErrorRestore()2231 void TaskSupplier::AfterErrorRestore()
2232 {
2233     if (m_pTaskBroker)
2234         m_pTaskBroker->Reset();
2235 
2236     {
2237     ViewList::iterator iter = m_views.begin();
2238     ViewList::iterator iter_end = m_views.end();
2239     for (; iter != iter_end; ++iter)
2240     {
2241         for (H264DecoderFrame *pFrame = iter->GetDPBList(0)->head(); pFrame; pFrame = pFrame->future())
2242         {
2243             pFrame->FreeResources();
2244         }
2245     }
2246     }
2247 
2248     if (m_sei_messages)
2249         m_sei_messages->Reset();
2250 
2251     SVC_Extension::Reset();
2252     AU_Splitter::Reset();
2253     DPBOutput::Reset(m_iThreadNum != 1);
2254     DecReferencePictureMarking::Reset();
2255     m_accessUnit.Release();
2256     ErrorStatus::Reset();
2257 
2258     switch (m_initializationParams.info.profile) // after MVC_Extension::Init()
2259     {
2260     case 0:
2261         m_decodingMode = UNKNOWN_DECODING_MODE;
2262         break;
2263     case H264VideoDecoderParams::H264_PROFILE_MULTIVIEW_HIGH:
2264     case H264VideoDecoderParams::H264_PROFILE_STEREO_HIGH:
2265         m_decodingMode = MVC_DECODING_MODE;
2266         break;
2267     default:
2268         m_decodingMode = AVC_DECODING_MODE;
2269         break;
2270     }
2271 
2272     if (m_pLastSlice)
2273     {
2274         m_pLastSlice->Release();
2275         m_pLastSlice->DecrementReference();
2276         m_pLastSlice = 0;
2277     }
2278 
2279     m_Headers.Reset(true);
2280     Skipping::Reset();
2281     m_ObjHeap.Release();
2282 
2283     m_WaitForIDR        = true;
2284     m_pLastDisplayed = 0;
2285 
2286     if (m_pTaskBroker)
2287         m_pTaskBroker->Init(m_iThreadNum);
2288 }
2289 
GetInfo(VideoDecoderParams * lpInfo)2290 Status TaskSupplier::GetInfo(VideoDecoderParams *lpInfo)
2291 {
2292     H264SeqParamSet *sps = m_Headers.m_SeqParams.GetCurrentHeader();
2293     if (!sps)
2294     {
2295         return UMC_ERR_NOT_ENOUGH_DATA;
2296     }
2297 
2298     const H264PicParamSet *pps = m_Headers.m_PicParams.GetCurrentHeader();
2299 
2300     lpInfo->info.clip_info.height = sps->frame_height_in_mbs * 16 -
2301         SubHeightC[sps->chroma_format_idc]*(2 - sps->frame_mbs_only_flag) *
2302         (sps->frame_cropping_rect_top_offset + sps->frame_cropping_rect_bottom_offset);
2303 
2304     lpInfo->info.clip_info.width = sps->frame_width_in_mbs * 16 - SubWidthC[sps->chroma_format_idc] *
2305         (sps->frame_cropping_rect_left_offset + sps->frame_cropping_rect_right_offset);
2306 
2307     if (0.0 < m_local_delta_frame_time)
2308     {
2309         lpInfo->info.framerate = 1.0 / m_local_delta_frame_time;
2310     }
2311     else
2312     {
2313         lpInfo->info.framerate = 0;
2314     }
2315 
2316     lpInfo->info.stream_type     = H264_VIDEO;
2317 
2318     lpInfo->profile = sps->profile_idc;
2319     lpInfo->level = sps->level_idc;
2320 
2321     lpInfo->numThreads = m_iThreadNum;
2322     lpInfo->info.color_format = GetUMCColorFormat(sps->chroma_format_idc);
2323 
2324     lpInfo->info.profile = sps->profile_idc;
2325     lpInfo->info.level = sps->level_idc;
2326 
2327     if (sps->vui.aspect_ratio_idc == 255)
2328     {
2329         lpInfo->info.aspect_ratio_width  = sps->vui.sar_width;
2330         lpInfo->info.aspect_ratio_height = sps->vui.sar_height;
2331     }
2332 
2333     uint32_t multiplier = 1 << (6 + sps->vui.bit_rate_scale);
2334     lpInfo->info.bitrate = sps->vui.bit_rate_value[0] * multiplier;
2335 
2336     if (sps->frame_mbs_only_flag)
2337         lpInfo->info.interlace_type = PROGRESSIVE;
2338     else
2339     {
2340         if (0 <= sps->offset_for_top_to_bottom_field)
2341             lpInfo->info.interlace_type = INTERLEAVED_TOP_FIELD_FIRST;
2342         else
2343             lpInfo->info.interlace_type = INTERLEAVED_BOTTOM_FIELD_FIRST;
2344     }
2345 
2346     H264VideoDecoderParams *lpH264Info = DynamicCast<H264VideoDecoderParams> (lpInfo);
2347     if (lpH264Info)
2348     {
2349         // calculate the new DPB size value
2350         lpH264Info->m_DPBSize = CalculateDPBSize(sps->level_idc,
2351                                    sps->frame_width_in_mbs * 16,
2352                                    sps->frame_height_in_mbs * 16,
2353                                    sps->num_ref_frames) + m_DPBSizeEx;
2354 
2355         mfxSize sz;
2356         sz.width    = sps->frame_width_in_mbs * 16;
2357         sz.height   = sps->frame_height_in_mbs * 16;
2358         lpH264Info->m_fullSize = sz;
2359 
2360         if (pps)
2361         {
2362            lpH264Info->m_entropy_coding_type = pps->entropy_coding_mode;
2363         }
2364 
2365         lpH264Info->m_cropArea.top = (int16_t)(SubHeightC[sps->chroma_format_idc] * sps->frame_cropping_rect_top_offset * (2 - sps->frame_mbs_only_flag));
2366         lpH264Info->m_cropArea.bottom = (int16_t)(SubHeightC[sps->chroma_format_idc] * sps->frame_cropping_rect_bottom_offset * (2 - sps->frame_mbs_only_flag));
2367         lpH264Info->m_cropArea.left = (int16_t)(SubWidthC[sps->chroma_format_idc] * sps->frame_cropping_rect_left_offset);
2368         lpH264Info->m_cropArea.right = (int16_t)(SubWidthC[sps->chroma_format_idc] * sps->frame_cropping_rect_right_offset);
2369     }
2370 
2371     return UMC_OK;
2372 }
2373 
DecodeSEI(NalUnit * nalUnit)2374 Status TaskSupplier::DecodeSEI(NalUnit *nalUnit)
2375 {
2376     H264HeadersBitstream bitStream;
2377 
2378     try
2379     {
2380         H264MemoryPiece mem;
2381         mem.SetData(nalUnit);
2382 
2383         H264MemoryPiece swappedMem;
2384         swappedMem.Allocate(nalUnit->GetDataSize() + DEFAULT_NU_TAIL_SIZE);
2385 
2386         SwapperBase * swapper = m_pNALSplitter->GetSwapper();
2387         swapper->SwapMemory(&swappedMem, &mem, DEFAULT_NU_HEADER_TAIL_VALUE);
2388 
2389         bitStream.Reset((uint8_t*)swappedMem.GetPointer(), (uint32_t)swappedMem.GetDataSize());
2390 
2391         NAL_Unit_Type nal_unit_type;
2392         uint32_t nal_ref_idc;
2393 
2394         bitStream.GetNALUnitType(nal_unit_type, nal_ref_idc);
2395 
2396         do
2397         {
2398             H264SEIPayLoad    m_SEIPayLoads;
2399 
2400             bitStream.ParseSEI(m_Headers, &m_SEIPayLoads);
2401 
2402             DEBUG_PRINT((VM_STRING("debug headers SEI - %d\n"), m_SEIPayLoads.payLoadType));
2403 
2404             if (m_SEIPayLoads.payLoadType == SEI_USER_DATA_REGISTERED_TYPE)
2405             {
2406                 m_UserData = m_SEIPayLoads;
2407             }
2408             else
2409             {
2410                 m_Headers.m_SEIParams.AddHeader(&m_SEIPayLoads);
2411             }
2412 
2413         } while (bitStream.More_RBSP_Data());
2414 
2415     } catch(...)
2416     {
2417         // nothing to do just catch it
2418     }
2419 
2420     return UMC_OK;
2421 }
2422 
DecodeHeaders(NalUnit * nalUnit)2423 Status TaskSupplier::DecodeHeaders(NalUnit *nalUnit)
2424 {
2425     ViewItem *view = GetViewCount() ? &GetViewByNumber(BASE_VIEW) : 0;
2426     Status umcRes = UMC_OK;
2427 
2428     H264HeadersBitstream bitStream;
2429 
2430     try
2431     {
2432         H264MemoryPiece mem;
2433         mem.SetData(nalUnit);
2434 
2435         H264MemoryPiece swappedMem;
2436 
2437         swappedMem.Allocate(nalUnit->GetDataSize() + DEFAULT_NU_TAIL_SIZE);
2438 
2439         SwapperBase * swapper = m_pNALSplitter->GetSwapper();
2440         swapper->SwapMemory(&swappedMem, &mem);
2441 
2442         bitStream.Reset((uint8_t*)swappedMem.GetPointer(), (uint32_t)swappedMem.GetDataSize());
2443 
2444         NAL_Unit_Type nal_unit_type;
2445         uint32_t nal_ref_idc;
2446 
2447         bitStream.GetNALUnitType(nal_unit_type, nal_ref_idc);
2448 
2449         switch(nal_unit_type)
2450         {
2451         // sequence parameter set
2452         case NAL_UT_SPS:
2453             {
2454                 H264SeqParamSet sps;
2455                 sps.seq_parameter_set_id = MAX_NUM_SEQ_PARAM_SETS;
2456                 umcRes = bitStream.GetSequenceParamSet(&sps, m_ignoreLevelConstrain);
2457                 if (umcRes != UMC_OK)
2458                 {
2459                     H264SeqParamSet * old_sps = m_Headers.m_SeqParams.GetHeader(sps.seq_parameter_set_id);
2460                     if (old_sps)
2461                         old_sps->errorFlags = 1;
2462                     return UMC_ERR_INVALID_STREAM;
2463                 }
2464 
2465                 uint8_t newDPBsize = (uint8_t)CalculateDPBSize(sps.level_idc,
2466                                             sps.frame_width_in_mbs * 16,
2467                                             sps.frame_height_in_mbs * 16,
2468                                             sps.num_ref_frames);
2469 
2470                 bool isNeedClean = sps.vui.max_dec_frame_buffering == 0;
2471                 sps.vui.max_dec_frame_buffering = sps.vui.max_dec_frame_buffering ? sps.vui.max_dec_frame_buffering : newDPBsize;
2472                 if (sps.vui.max_dec_frame_buffering > newDPBsize)
2473                     sps.vui.max_dec_frame_buffering = newDPBsize;
2474 
2475                 if (sps.num_ref_frames > newDPBsize)
2476                     sps.num_ref_frames = newDPBsize;
2477 
2478                 const H264SeqParamSet * old_sps = m_Headers.m_SeqParams.GetCurrentHeader();
2479                 bool newResolution = false;
2480                 if (IsNeedSPSInvalidate(old_sps, &sps))
2481                 {
2482                     newResolution = true;
2483                 }
2484 
2485                 if (isNeedClean)
2486                     sps.vui.max_dec_frame_buffering = 0;
2487 
2488                 DEBUG_PRINT((VM_STRING("debug headers SPS - %d, num_ref_frames - %d \n"), sps.seq_parameter_set_id, sps.num_ref_frames));
2489 
2490                 H264SeqParamSet * temp = m_Headers.m_SeqParams.GetHeader(sps.seq_parameter_set_id);
2491                 m_Headers.m_SeqParams.AddHeader(&sps);
2492 
2493                 // Validate the incoming bitstream's image dimensions.
2494                 temp = m_Headers.m_SeqParams.GetHeader(sps.seq_parameter_set_id);
2495                 if (!temp)
2496                 {
2497                     return UMC_ERR_NULL_PTR;
2498                 }
2499                 if (view)
2500                 {
2501                     uint8_t newDPBsizeL = (uint8_t)CalculateDPBSize(m_level_idc ? m_level_idc : temp->level_idc,
2502                                                                 sps.frame_width_in_mbs * 16,
2503                                                                 sps.frame_height_in_mbs * 16,
2504                                                                 sps.num_ref_frames);
2505 
2506                     temp->vui.max_dec_frame_buffering = temp->vui.max_dec_frame_buffering ? temp->vui.max_dec_frame_buffering : newDPBsizeL;
2507                     if (temp->vui.max_dec_frame_buffering > newDPBsizeL)
2508                         temp->vui.max_dec_frame_buffering = newDPBsizeL;
2509                 }
2510 
2511                 m_pNALSplitter->SetSuggestedSize(CalculateSuggestedSize(&sps));
2512 
2513                 if (!temp->vui.timing_info_present_flag || m_use_external_framerate)
2514                 {
2515                     temp->vui.num_units_in_tick = 90000;
2516                     temp->vui.time_scale = (uint32_t)(2*90000 / m_local_delta_frame_time);
2517                 }
2518 
2519                 m_local_delta_frame_time = 1 / ((0.5 * temp->vui.time_scale) / temp->vui.num_units_in_tick);
2520 
2521                 ErrorStatus::isSPSError = 0;
2522 
2523                 if (newResolution)
2524                     return UMC_NTF_NEW_RESOLUTION;
2525             }
2526             break;
2527 
2528         case NAL_UT_SPS_EX:
2529             {
2530                 H264SeqParamSetExtension sps_ex;
2531                 umcRes = bitStream.GetSequenceParamSetExtension(&sps_ex);
2532 
2533                 if (umcRes != UMC_OK)
2534                     return UMC_ERR_INVALID_STREAM;
2535 
2536                 m_Headers.m_SeqExParams.AddHeader(&sps_ex);
2537             }
2538             break;
2539 
2540             // picture parameter set
2541         case NAL_UT_PPS:
2542             {
2543                 H264PicParamSet pps;
2544                 // set illegal id
2545                 pps.pic_parameter_set_id = MAX_NUM_PIC_PARAM_SETS;
2546 
2547                 // Get id
2548                 umcRes = bitStream.GetPictureParamSetPart1(&pps);
2549                 if (UMC_OK != umcRes)
2550                 {
2551                     H264PicParamSet * old_pps = m_Headers.m_PicParams.GetHeader(pps.pic_parameter_set_id);
2552                     if (old_pps)
2553                         old_pps->errorFlags = 1;
2554                     return UMC_ERR_INVALID_STREAM;
2555                 }
2556 
2557                 H264SeqParamSet *refSps = m_Headers.m_SeqParams.GetHeader(pps.seq_parameter_set_id);
2558                 uint32_t prevActivePPS = m_Headers.m_PicParams.GetCurrentID();
2559 
2560                 if (!refSps || refSps->seq_parameter_set_id >= MAX_NUM_SEQ_PARAM_SETS)
2561                 {
2562                     refSps = m_Headers.m_SeqParamsMvcExt.GetHeader(pps.seq_parameter_set_id);
2563                     if (!refSps || refSps->seq_parameter_set_id >= MAX_NUM_SEQ_PARAM_SETS)
2564                     {
2565                         refSps = m_Headers.m_SeqParamsSvcExt.GetHeader(pps.seq_parameter_set_id);
2566                         if (!refSps || refSps->seq_parameter_set_id >= MAX_NUM_SEQ_PARAM_SETS)
2567                             return UMC_ERR_INVALID_STREAM;
2568                     }
2569                 }
2570 
2571                 // Get rest of pic param set
2572                 umcRes = bitStream.GetPictureParamSetPart2(&pps, refSps);
2573                 if (UMC_OK != umcRes)
2574                 {
2575                     H264PicParamSet * old_pps = m_Headers.m_PicParams.GetHeader(pps.pic_parameter_set_id);
2576                     if (old_pps)
2577                         old_pps->errorFlags = 1;
2578                     return UMC_ERR_INVALID_STREAM;
2579                 }
2580 
2581                 DEBUG_PRINT((VM_STRING("debug headers PPS - %d - SPS - %d\n"), pps.pic_parameter_set_id, pps.seq_parameter_set_id));
2582                 m_Headers.m_PicParams.AddHeader(&pps);
2583 
2584                 //m_Headers.m_SeqParams.SetCurrentID(pps.seq_parameter_set_id);
2585                 // in case of MVC restore previous active PPS
2586                 if ((H264VideoDecoderParams::H264_PROFILE_MULTIVIEW_HIGH == refSps->profile_idc) ||
2587                     (H264VideoDecoderParams::H264_PROFILE_STEREO_HIGH == refSps->profile_idc))
2588                 {
2589                     m_Headers.m_PicParams.SetCurrentID(prevActivePPS);
2590                 }
2591 
2592                 ErrorStatus::isPPSError = 0;
2593             }
2594             break;
2595 
2596         // subset sequence parameter set
2597         case NAL_UT_SUBSET_SPS:
2598             {
2599                 if (!IsExtension())
2600                     break;
2601 
2602                 H264SeqParamSet sps;
2603                 umcRes = bitStream.GetSequenceParamSet(&sps);
2604                 if (UMC_OK != umcRes)
2605                 {
2606                     return UMC_ERR_INVALID_STREAM;
2607                 }
2608 
2609                 m_pNALSplitter->SetSuggestedSize(CalculateSuggestedSize(&sps));
2610 
2611                 DEBUG_PRINT((VM_STRING("debug headers SUBSET SPS - %d, profile_idc - %d, level_idc - %d, num_ref_frames - %d \n"), sps.seq_parameter_set_id, sps.profile_idc, sps.level_idc, sps.num_ref_frames));
2612 
2613                 if ((sps.profile_idc == H264VideoDecoderParams::H264_PROFILE_SCALABLE_BASELINE) ||
2614                     (sps.profile_idc == H264VideoDecoderParams::H264_PROFILE_SCALABLE_HIGH))
2615                 {
2616                     H264SeqParamSetSVCExtension spsSvcExt;
2617                     H264SeqParamSet * sps_temp = &spsSvcExt;
2618 
2619                     *sps_temp = sps;
2620 
2621                     umcRes = bitStream.GetSequenceParamSetSvcExt(&spsSvcExt);
2622                     if (UMC_OK != umcRes)
2623                     {
2624                         return UMC_ERR_INVALID_STREAM;
2625                     }
2626 
2627                     const H264SeqParamSetSVCExtension * old_sps = m_Headers.m_SeqParamsSvcExt.GetCurrentHeader();
2628                     bool newResolution = false;
2629                     if (old_sps && old_sps->profile_idc != spsSvcExt.profile_idc)
2630                     {
2631                         newResolution = true;
2632                     }
2633 
2634                     m_Headers.m_SeqParamsSvcExt.AddHeader(&spsSvcExt);
2635 
2636                     SVC_Extension::ChooseLevelIdc(&spsSvcExt, sps.level_idc, sps.level_idc);
2637 
2638                     if (view)
2639                     {
2640                         view->SetDPBSize(&sps, m_level_idc);
2641                     }
2642 
2643                     if (newResolution)
2644                         return UMC_NTF_NEW_RESOLUTION;
2645                 }
2646 
2647                 // decode additional parameters
2648                 if ((H264VideoDecoderParams::H264_PROFILE_MULTIVIEW_HIGH == sps.profile_idc) ||
2649                     (H264VideoDecoderParams::H264_PROFILE_STEREO_HIGH == sps.profile_idc))
2650                 {
2651                     H264SeqParamSetMVCExtension spsMvcExt;
2652                     H264SeqParamSet * sps_temp = &spsMvcExt;
2653 
2654                     *sps_temp = sps;
2655 
2656                     // skip one bit
2657                     bitStream.Get1Bit();
2658                     // decode  MVC extension
2659                     umcRes = bitStream.GetSequenceParamSetMvcExt(&spsMvcExt);
2660                     if (UMC_OK != umcRes)
2661                     {
2662                         return UMC_ERR_INVALID_STREAM;
2663                     }
2664 
2665                     const H264SeqParamSetMVCExtension * old_sps = m_Headers.m_SeqParamsMvcExt.GetCurrentHeader();
2666                     bool newResolution = false;
2667                     if (old_sps && old_sps->profile_idc != spsMvcExt.profile_idc)
2668                     {
2669                         newResolution = true;
2670                     }
2671 
2672                     DEBUG_PRINT((VM_STRING("debug headers SUBSET SPS MVC ext - %d \n"), sps.seq_parameter_set_id));
2673                     m_Headers.m_SeqParamsMvcExt.AddHeader(&spsMvcExt);
2674 
2675                     MVC_Extension::ChooseLevelIdc(&spsMvcExt, sps.level_idc, sps.level_idc);
2676 
2677                     if (view)
2678                     {
2679                         view->SetDPBSize(&sps, m_level_idc);
2680                     }
2681 
2682                     if (newResolution)
2683                         return UMC_NTF_NEW_RESOLUTION;
2684                 }
2685             }
2686             break;
2687 
2688         // decode a prefix nal unit
2689         case NAL_UT_PREFIX:
2690             {
2691                 umcRes = bitStream.GetNalUnitPrefix(&m_Headers.m_nalExtension, nal_ref_idc);
2692                 if (UMC_OK != umcRes)
2693                 {
2694                     m_Headers.m_nalExtension.extension_present = 0;
2695                     return UMC_ERR_INVALID_STREAM;
2696                 }
2697             }
2698             break;
2699 
2700         default:
2701             break;
2702         }
2703     }
2704     catch(const h264_exception & ex)
2705     {
2706         return ex.GetStatus();
2707     }
2708     catch(...)
2709     {
2710         return UMC_ERR_INVALID_STREAM;
2711     }
2712 
2713     return UMC_OK;
2714 
2715 } // Status TaskSupplier::DecodeHeaders(MediaDataEx::_MediaDataEx *pSource, H264MemoryPiece * pMem)
2716 
2717 //////////////////////////////////////////////////////////////////////////////
2718 // ProcessFrameNumGap
2719 //
2720 // A non-sequential frame_num has been detected. If the sequence parameter
2721 // set field gaps_in_frame_num_value_allowed_flag is non-zero then the gap
2722 // is OK and "non-existing" frames will be created to correctly fill the
2723 // gap. Otherwise the gap is an indication of lost frames and the need to
2724 // handle in a reasonable way.
2725 //////////////////////////////////////////////////////////////////////////////
ProcessFrameNumGap(H264Slice * pSlice,int32_t field,int32_t dId,int32_t maxDId)2726 Status TaskSupplier::ProcessFrameNumGap(H264Slice *pSlice, int32_t field, int32_t dId, int32_t maxDId)
2727 {
2728     ViewItem &view = GetView(pSlice->GetSliceHeader()->nal_ext.mvc.view_id);
2729     Status umcRes = UMC_OK;
2730     const H264SeqParamSet* sps = pSlice->GetSeqParam();
2731     H264SliceHeader *sliceHeader = pSlice->GetSliceHeader();
2732 
2733     uint32_t frameNumGap = view.GetPOCDecoder(0)->DetectFrameNumGap(pSlice);
2734 
2735     if (!frameNumGap)
2736         return UMC_OK;
2737 
2738     if (dId == maxDId)
2739     {
2740         if (frameNumGap > view.maxDecFrameBuffering)
2741         {
2742             frameNumGap = view.maxDecFrameBuffering;
2743         }
2744     }
2745     else
2746     {
2747         if (frameNumGap > sps->num_ref_frames)
2748         {
2749             frameNumGap = sps->num_ref_frames;
2750         }
2751     }
2752 
2753     int32_t uMaxFrameNum = (1<<sps->log2_max_frame_num);
2754 
2755     DEBUG_PRINT((VM_STRING("frame gap - %d\n"), frameNumGap));
2756 
2757     // Fill the frame_num gap with non-existing frames. For each missing
2758     // frame:
2759     //  - allocate a frame
2760     //  - set frame num and pic num
2761     //  - update FrameNumWrap for all reference frames
2762     //  - use sliding window frame marking to free oldest reference
2763     //  - mark the frame as short-term reference
2764     // The picture part of the generated frames is unimportant -- it will
2765     // not be used for reference.
2766 
2767     // set to first missing frame. Note that if frame number wrapped during
2768     // the gap, the first missing frame_num could be larger than the
2769     // current frame_num. If that happened, FrameNumGap will be negative.
2770     //VM_ASSERT((int32_t)sliceHeader->frame_num > frameNumGap);
2771     int32_t frame_num = sliceHeader->frame_num - frameNumGap;
2772 
2773     while ((frame_num != sliceHeader->frame_num) && (umcRes == UMC_OK))
2774     {
2775         H264DecoderFrame *pFrame;
2776 
2777         {
2778             // allocate a frame
2779             // Traverse list for next disposable frame
2780             pFrame = GetFreeFrame(pSlice);
2781 
2782             // Did we find one?
2783             if (!pFrame)
2784             {
2785                 return UMC_ERR_NOT_ENOUGH_BUFFER;
2786             }
2787 
2788             pFrame->IncrementReference();
2789             m_UIDFrameCounter++;
2790             pFrame->m_UID = m_UIDFrameCounter;
2791         }
2792 
2793         frameNumGap--;
2794 
2795         if (sps->pic_order_cnt_type != 0)
2796         {
2797             int32_t tmp1 = sliceHeader->delta_pic_order_cnt[0];
2798             int32_t tmp2 = sliceHeader->delta_pic_order_cnt[1];
2799             sliceHeader->delta_pic_order_cnt[0] = sliceHeader->delta_pic_order_cnt[1] = 0;
2800 
2801             view.GetPOCDecoder(0)->DecodePictureOrderCount(pSlice, frame_num);
2802 
2803             sliceHeader->delta_pic_order_cnt[0] = tmp1;
2804             sliceHeader->delta_pic_order_cnt[1] = tmp2;
2805         }
2806 
2807         // Set frame num and pic num for the missing frame
2808         pFrame->setFrameNum(frame_num);
2809         view.GetPOCDecoder(0)->DecodePictureOrderCountFrameGap(pFrame, sliceHeader, frame_num);
2810         DEBUG_PRINT((VM_STRING("frame gap - frame_num = %d, poc = %d,%d added\n"), frame_num, pFrame->m_PicOrderCnt[0], pFrame->m_PicOrderCnt[1]));
2811 
2812         if (sliceHeader->field_pic_flag == 0)
2813         {
2814             pFrame->setPicNum(frame_num, 0);
2815         }
2816         else
2817         {
2818             pFrame->setPicNum(frame_num*2+1, 0);
2819             pFrame->setPicNum(frame_num*2+1, 1);
2820         }
2821 
2822         // Update frameNumWrap and picNum for all decoded frames
2823 
2824         H264DecoderFrame *pFrm;
2825         H264DecoderFrame * pHead = view.GetDPBList(0)->head();
2826         for (pFrm = pHead; pFrm; pFrm = pFrm->future())
2827         {
2828             // TBD: modify for fields
2829             pFrm->UpdateFrameNumWrap(frame_num,
2830                 uMaxFrameNum,
2831                 pFrame->m_PictureStructureForRef+
2832                 pFrame->m_bottom_field_flag[field]);
2833         }
2834 
2835         // sliding window ref pic marking
2836         // view2 below inicialized exacly as view above.
2837         // why we need view2 & may it be defferent from view?
2838         ViewItem &view2 = GetView(pSlice->GetSliceHeader()->nal_ext.mvc.view_id);
2839         H264DecoderFrame * saveFrame = pFrame;
2840         std::swap(pSlice->m_pCurrentFrame, saveFrame);
2841         DecReferencePictureMarking::SlideWindow(view2, pSlice, 0);
2842         std::swap(pSlice->m_pCurrentFrame, saveFrame);
2843 
2844         pFrame->SetisShortTermRef(true, 0);
2845         pFrame->SetisShortTermRef(true, 1);
2846 
2847         // next missing frame
2848         frame_num++;
2849         if (frame_num >= uMaxFrameNum)
2850             frame_num = 0;
2851 
2852         pFrame->SetFrameAsNonExist();
2853         pFrame->DecrementReference();
2854     }   // while
2855 
2856     return UMC_OK;
2857 }   // ProcessFrameNumGap
2858 
PostProcessDisplayFrame(H264DecoderFrame * pFrame)2859 void TaskSupplier::PostProcessDisplayFrame(H264DecoderFrame *pFrame)
2860 {
2861     if (!pFrame || pFrame->post_procces_complete)
2862         return;
2863 
2864     ViewItem &view = GetView(pFrame->m_viewId);
2865 
2866     pFrame->post_procces_complete = true;
2867 
2868     DEBUG_PRINT((VM_STRING("Outputted POC - %d, busyState - %d, uid - %d, viewId - %d, pppp - %d\n"), pFrame->m_PicOrderCnt[0], pFrame->GetRefCounter(), pFrame->m_UID, pFrame->m_viewId, pppp++));
2869 
2870     if (!pFrame->IsFrameExist())
2871         return;
2872 
2873     pFrame->m_isOriginalPTS = pFrame->m_dFrameTime > -1.0;
2874     if (pFrame->m_isOriginalPTS)
2875     {
2876         view.localFrameTime = pFrame->m_dFrameTime;
2877     }
2878     else
2879     {
2880         pFrame->m_dFrameTime = view.localFrameTime;
2881     }
2882 
2883     pFrame->m_frameOrder = m_frameOrder;
2884     switch (pFrame->m_displayPictureStruct)
2885     {
2886     case UMC::DPS_TOP_BOTTOM_TOP:
2887     case UMC::DPS_BOTTOM_TOP_BOTTOM:
2888         if (m_initializationParams.lFlags & UMC::FLAG_VDEC_TELECINE_PTS)
2889         {
2890             view.localFrameTime += (m_local_delta_frame_time / 2);
2891         }
2892         break;
2893 
2894     case UMC::DPS_FRAME_DOUBLING:
2895     case UMC::DPS_FRAME_TRIPLING:
2896     case UMC::DPS_TOP:
2897     case UMC::DPS_BOTTOM:
2898     case UMC::DPS_TOP_BOTTOM:
2899     case UMC::DPS_BOTTOM_TOP:
2900     case UMC::DPS_FRAME:
2901     default:
2902         break;
2903     }
2904 
2905     view.localFrameTime += m_local_delta_frame_time;
2906 
2907     bool wasWrapped = IncreaseCurrentView();
2908     if (wasWrapped)
2909         m_frameOrder++;
2910 
2911     if (view.GetDPBList(0)->GetRecoveryFrameCnt() != -1)
2912         view.GetDPBList(0)->SetRecoveryFrameCnt(-1);
2913 }
2914 
GetFrameToDisplayInternal(bool force)2915 H264DecoderFrame *TaskSupplier::GetFrameToDisplayInternal(bool force)
2916 {
2917     H264DecoderFrame *pFrame = GetAnyFrameToDisplay(force);
2918     return pFrame;
2919 }
2920 
GetAnyFrameToDisplay(bool force)2921 H264DecoderFrame *TaskSupplier::GetAnyFrameToDisplay(bool force)
2922 {
2923     ViewList::iterator iter = m_views.begin();
2924     ViewList::iterator iter_end = m_views.end();
2925 
2926     for (uint32_t i = 0; iter != iter_end; ++i, ++iter)
2927     {
2928         ViewItem &view = *iter;
2929 
2930         if (i != m_currentDisplayView || !view.m_isDisplayable)
2931         {
2932             if (i == m_currentDisplayView)
2933             {
2934                 IncreaseCurrentView();
2935             }
2936             continue;
2937         }
2938 
2939         for (;;)
2940         {
2941             // show oldest frame
2942 
2943             // Flag SPS.VUI.max_num_reorder_frames may be presented in bitstream headers
2944             // (if SPS.VUI.bitstream_restriction_flag == 1) and may be used to reduce
2945             // latency on outputting decoded frames.
2946             //
2947             // Due to h264 is a legacy codec and flag SPS.VUI.max_num_reorder_frames
2948             // is not necessary - there are existed some old encoders and coded videos
2949             // where flag max_num_reorder_frames is set to 0 by default, but reordering
2950             // actually exists. For this reason Media SDK ignores this flag by default,
2951             // because there is a risk to break decoding some old videos.
2952             //
2953             // Enabling define ENABLE_MAX_NUM_REORDER_FRAMES_OUTPUT allows to reduce latency
2954             // (ex: max_num_reorder_frames == 0 -> output frame immediately)
2955 
2956             uint32_t countNumDisplayable = view.GetDPBList(0)->countNumDisplayable();
2957             if (   countNumDisplayable > view.maxDecFrameBuffering
2958 #ifdef ENABLE_MAX_NUM_REORDER_FRAMES_OUTPUT
2959                 || countNumDisplayable > view.maxNumReorderFrames
2960 #endif
2961                 || force)
2962             {
2963                 H264DecoderFrame *pTmp = view.GetDPBList(0)->findOldestDisplayable(view.maxDecFrameBuffering);
2964 
2965                 if (pTmp)
2966                 {
2967                     int32_t recovery_frame_cnt = view.GetDPBList(0)->GetRecoveryFrameCnt(); // DEBUG !!! need to think about recovery and MVC
2968 
2969                     if (!pTmp->IsFrameExist() || (recovery_frame_cnt != -1 && pTmp->m_FrameNum != recovery_frame_cnt))
2970                     {
2971                         pTmp->SetErrorFlagged(ERROR_FRAME_RECOVERY);
2972                     }
2973 
2974                     return pTmp;
2975                 }
2976 
2977                 break;
2978             }
2979             else
2980             {
2981                 if (DPBOutput::IsUseDelayOutputValue())
2982                 {
2983                     H264DecoderFrame *pTmp = view.GetDPBList(0)->findDisplayableByDPBDelay();
2984                     if (pTmp)
2985                         return pTmp;
2986                 }
2987                 break;
2988             }
2989         }
2990     }
2991 
2992     return 0;
2993 }
2994 
SetMBMap(const H264Slice *,H264DecoderFrame *,LocalResources *)2995 void TaskSupplier::SetMBMap(const H264Slice * , H264DecoderFrame *, LocalResources * )
2996 {
2997 }
2998 
PreventDPBFullness()2999 void TaskSupplier::PreventDPBFullness()
3000 {
3001     ViewList::iterator iter = m_views.begin();
3002     ViewList::iterator iter_end = m_views.end();
3003 
3004     for (; iter != iter_end; ++iter)
3005     {
3006         ViewItem &view = *iter;
3007         H264DBPList *pDPB = view.GetDPBList(0);
3008 
3009     try
3010     {
3011         for (;;)
3012         {
3013             // force Display or ... delete long term
3014             const H264SeqParamSet* sps = m_Headers.m_SeqParams.GetCurrentHeader();
3015             if (sps)
3016             {
3017                 uint32_t NumShortTermRefs, NumLongTermRefs;
3018 
3019                 // find out how many active reference frames currently in decoded
3020                 // frames buffer
3021                 pDPB->countActiveRefs(NumShortTermRefs, NumLongTermRefs);
3022 
3023                 if (NumLongTermRefs == sps->num_ref_frames)
3024                 {
3025                     H264DecoderFrame *pFrame = pDPB->findOldestLongTermRef();
3026                     if (pFrame)
3027                     {
3028                         pFrame->SetisLongTermRef(false, 0);
3029                         pFrame->SetisLongTermRef(false, 1);
3030                         pFrame->Reset();
3031                     }
3032                 }
3033 
3034                 if (pDPB->IsDisposableExist())
3035                     break;
3036 
3037                 /*while (NumShortTermRefs > 0 &&
3038                     (NumShortTermRefs + NumLongTermRefs >= (int32_t)sps->num_ref_frames))
3039                 {
3040                     H264DecoderFrame * pFrame = view.pDPB->findOldestShortTermRef();
3041 
3042                     if (!pFrame)
3043                         break;
3044 
3045                     pFrame->SetisShortTermRef(false, 0);
3046                     pFrame->SetisShortTermRef(false, 1);
3047 
3048                     NumShortTermRefs--;
3049                 };*/
3050 
3051                 if (pDPB->IsDisposableExist())
3052                     break;
3053             }
3054 
3055             break;
3056         }
3057     } catch(...)
3058     {
3059     }
3060 
3061     if (!pDPB->IsDisposableExist())
3062         AfterErrorRestore();
3063 
3064     }
3065 }
3066 
CompleteDecodedFrames(H264DecoderFrame ** decoded)3067 Status TaskSupplier::CompleteDecodedFrames(H264DecoderFrame ** decoded)
3068 {
3069     H264DecoderFrame* completed = 0;
3070     Status sts = UMC_OK;
3071 
3072     ViewList::iterator iter = m_views.begin();
3073     ViewList::iterator iter_end = m_views.end();
3074     for (; iter != iter_end; ++iter)
3075     {
3076         ViewItem &view = *iter;
3077         H264DBPList *pDPB = view.GetDPBList(0);
3078 
3079         for (;;) //add all ready to decoding
3080         {
3081             bool isOneToAdd = true;
3082             H264DecoderFrame * frameToAdd = 0;
3083 
3084             for (H264DecoderFrame * frame = pDPB->head(); frame; frame = frame->future())
3085             {
3086                 int32_t const frm_error = frame->GetError();
3087 
3088                 //we don't overwrite an error if we already got it
3089                 if (sts == UMC_OK && frm_error < 0)
3090                     //if we have ERROR_FRAME_DEVICE_FAILURE  bit is set then this error is  UMC::Status code
3091                     sts = static_cast<Status>(frm_error);
3092 
3093                 if (frame->IsFrameExist() && !frame->IsDecoded())
3094                 {
3095                     if (!frame->IsDecodingStarted() && frame->IsFullFrame())
3096                     {
3097                         if (frameToAdd)
3098                         {
3099                             isOneToAdd = false;
3100                             if (frameToAdd->m_UID < frame->m_UID) // add first with min UID
3101                                 continue;
3102                         }
3103 
3104                         frameToAdd = frame;
3105                     }
3106 
3107                     if (!frame->IsDecodingCompleted())
3108                     {
3109                         continue;
3110                     }
3111 
3112                     frame->OnDecodingCompleted();
3113                     completed = frame;
3114                 }
3115             }
3116 
3117             if (sts != UMC_OK)
3118                 break;
3119 
3120             if (frameToAdd)
3121             {
3122                 if (!m_pTaskBroker->AddFrameToDecoding(frameToAdd))
3123                     break;
3124             }
3125 
3126             if (isOneToAdd)
3127                 break;
3128         }
3129     }
3130 
3131     if (decoded)
3132         *decoded = completed;
3133 
3134     return sts;
3135 }
3136 
AddSource(MediaData * pSource)3137 Status TaskSupplier::AddSource(MediaData * pSource)
3138 {
3139     MFX_AUTO_LTRACE(MFX_TRACE_LEVEL_HOTSPOTS, "TaskSupplier::AddSource");
3140 
3141     H264DecoderFrame* completed = 0;
3142     Status umcRes = CompleteDecodedFrames(&completed);
3143     if (umcRes != UMC_OK)
3144         return pSource || !completed ? umcRes : UMC_OK;
3145 
3146     umcRes = AddOneFrame(pSource); // construct frame
3147 
3148     if (UMC_ERR_NOT_ENOUGH_BUFFER == umcRes)
3149     {
3150         ViewItem &view = GetView(m_currentView);
3151         H264DBPList *pDPB = view.GetDPBList(0);
3152 
3153         // in the following case(s) we can lay on the base view only,
3154         // because the buffers are managed synchronously.
3155 
3156         // frame is being processed. Wait for asynchronous end of operation.
3157         if (pDPB->IsDisposableExist())
3158         {
3159             return UMC_WRN_INFO_NOT_READY;
3160         }
3161 
3162         // frame is finished, but still referenced.
3163         // Wait for asynchronous complete.
3164         if (pDPB->IsAlmostDisposableExist())
3165         {
3166             return UMC_WRN_INFO_NOT_READY;
3167         }
3168 
3169         // some more hard reasons of frame lacking.
3170         if (!m_pTaskBroker->IsEnoughForStartDecoding(true))
3171         {
3172             umcRes = CompleteDecodedFrames(&completed);
3173             if (umcRes != UMC_OK)
3174                 return umcRes;
3175             else if (completed)
3176                 return UMC_WRN_INFO_NOT_READY;
3177 
3178             if (GetFrameToDisplayInternal(true))
3179                 return UMC_ERR_NEED_FORCE_OUTPUT;
3180 
3181             PreventDPBFullness();
3182             return UMC_WRN_INFO_NOT_READY;
3183         }
3184     }
3185 
3186     return umcRes;
3187 }
3188 
3189 #if (MFX_VERSION >= 1025)
ProcessNalUnit(NalUnit * nalUnit,mfxExtDecodeErrorReport * pDecodeErrorReport)3190 Status TaskSupplier::ProcessNalUnit(NalUnit *nalUnit, mfxExtDecodeErrorReport * pDecodeErrorReport)
3191 #else
3192 Status TaskSupplier::ProcessNalUnit(NalUnit *nalUnit)
3193 #endif
3194 {
3195     Status umcRes = UMC_OK;
3196 
3197     switch (nalUnit->GetNalUnitType())
3198     {
3199     case NAL_UT_IDR_SLICE:
3200     case NAL_UT_SLICE:
3201     case NAL_UT_AUXILIARY:
3202     case NAL_UT_CODED_SLICE_EXTENSION:
3203         {
3204             H264Slice * pSlice = DecodeSliceHeader(nalUnit);
3205             if (pSlice)
3206             {
3207                 umcRes = AddSlice(pSlice, false);
3208             }
3209         }
3210         break;
3211 
3212     case NAL_UT_SPS:
3213     case NAL_UT_PPS:
3214     case NAL_UT_SPS_EX:
3215     case NAL_UT_SUBSET_SPS:
3216     case NAL_UT_PREFIX:
3217         umcRes = DecodeHeaders(nalUnit);
3218 
3219 #if (MFX_VERSION >= 1025)
3220         if (pDecodeErrorReport && umcRes == UMC_ERR_INVALID_STREAM)
3221            SetDecodeErrorTypes(nalUnit->GetNalUnitType(), pDecodeErrorReport);
3222 #endif
3223 
3224         break;
3225 
3226     case NAL_UT_SEI:
3227         umcRes = DecodeSEI(nalUnit);
3228         break;
3229     case NAL_UT_AUD:
3230         m_accessUnit.CompleteLastLayer();
3231         break;
3232 
3233     case NAL_UT_DPA: //ignore it
3234     case NAL_UT_DPB:
3235     case NAL_UT_DPC:
3236     case NAL_UT_FD:
3237     case NAL_UT_UNSPECIFIED:
3238         break;
3239 
3240     case NAL_UT_END_OF_STREAM:
3241     case NAL_UT_END_OF_SEQ:
3242         {
3243             m_accessUnit.CompleteLastLayer();
3244             m_WaitForIDR = true;
3245         }
3246         break;
3247 
3248     default:
3249         break;
3250     };
3251 
3252     return umcRes;
3253 }
3254 
AddOneFrame(MediaData * pSource)3255 Status TaskSupplier::AddOneFrame(MediaData * pSource)
3256 {
3257     Status umsRes = UMC_OK;
3258 
3259     if (m_pLastSlice)
3260     {
3261         Status sts = AddSlice(m_pLastSlice, !pSource);
3262         if (sts == UMC_ERR_NOT_ENOUGH_BUFFER || sts == UMC_ERR_ALLOC)
3263         {
3264             return sts;
3265         }
3266 
3267         if (sts == UMC_OK)
3268             return sts;
3269     }
3270 
3271     do
3272     {
3273 #if (MFX_VERSION >= 1025)
3274         MediaData::AuxInfo* aux = (pSource) ? pSource->GetAuxInfo(MFX_EXTBUFF_DECODE_ERROR_REPORT) : NULL;
3275         mfxExtDecodeErrorReport* pDecodeErrorReport = (aux) ? reinterpret_cast<mfxExtDecodeErrorReport*>(aux->ptr) : NULL;
3276 #endif
3277 
3278         NalUnit *nalUnit = m_pNALSplitter->GetNalUnits(pSource);
3279 
3280         if (!nalUnit && pSource)
3281         {
3282             uint32_t flags = pSource->GetFlags();
3283 
3284             if (!(flags & MediaData::FLAG_VIDEO_DATA_NOT_FULL_FRAME))
3285             {
3286                 assert(!m_pLastSlice);
3287                 return AddSlice(0, true);
3288             }
3289 
3290             return UMC_ERR_SYNC;
3291         }
3292 
3293         if (!nalUnit)
3294         {
3295             if (!pSource)
3296                 return AddSlice(0, true);
3297 
3298             return UMC_ERR_NOT_ENOUGH_DATA;
3299         }
3300 
3301         if ((NAL_UT_IDR_SLICE != nalUnit->GetNalUnitType()) &&
3302             (NAL_UT_SLICE != nalUnit->GetNalUnitType()))
3303         {
3304             // Reset last prefix NAL unit
3305             m_Headers.m_nalExtension.extension_present = 0;
3306         }
3307 
3308         switch ((NAL_Unit_Type)nalUnit->GetNalUnitType())
3309         {
3310         case NAL_UT_IDR_SLICE:
3311         case NAL_UT_SLICE:
3312         case NAL_UT_AUXILIARY:
3313         case NAL_UT_CODED_SLICE_EXTENSION:
3314             {
3315             H264Slice * pSlice = DecodeSliceHeader(nalUnit);
3316             if (pSlice)
3317             {
3318                 umsRes = AddSlice(pSlice, !pSource);
3319                 if (umsRes == UMC_ERR_NOT_ENOUGH_BUFFER || umsRes == UMC_OK || umsRes == UMC_ERR_ALLOC)
3320                 {
3321 
3322                     return umsRes;
3323                 }
3324             }
3325             }
3326             break;
3327 
3328         case NAL_UT_SPS:
3329         case NAL_UT_PPS:
3330         case NAL_UT_SPS_EX:
3331         case NAL_UT_SUBSET_SPS:
3332         case NAL_UT_PREFIX:
3333             umsRes = DecodeHeaders(nalUnit);
3334             if (umsRes != UMC_OK)
3335             {
3336                 if (umsRes == UMC_NTF_NEW_RESOLUTION && pSource)
3337                 {
3338                     int32_t size = (int32_t)nalUnit->GetDataSize();
3339                     pSource->MoveDataPointer(- size - 3);
3340                 }
3341 
3342 #if (MFX_VERSION >= 1025)
3343                 if (pDecodeErrorReport && umsRes == UMC_ERR_INVALID_STREAM)
3344                     SetDecodeErrorTypes(nalUnit->GetNalUnitType(), pDecodeErrorReport);
3345 #endif
3346 
3347                 return umsRes;
3348             }
3349 
3350             if (nalUnit->GetNalUnitType() == NAL_UT_SPS || nalUnit->GetNalUnitType() == NAL_UT_PPS)
3351             {
3352                 m_accessUnit.CompleteLastLayer();
3353             }
3354             break;
3355 
3356         case NAL_UT_SEI:
3357             m_accessUnit.CompleteLastLayer();
3358             DecodeSEI(nalUnit);
3359             break;
3360         case NAL_UT_AUD:  //ignore it
3361             m_accessUnit.CompleteLastLayer();
3362             break;
3363 
3364         case NAL_UT_END_OF_STREAM:
3365         case NAL_UT_END_OF_SEQ:
3366             {
3367                 m_accessUnit.CompleteLastLayer();
3368                 m_WaitForIDR = true;
3369             }
3370             break;
3371 
3372         case NAL_UT_DPA: //ignore it
3373         case NAL_UT_DPB:
3374         case NAL_UT_DPC:
3375         case NAL_UT_FD:
3376         default:
3377             break;
3378         };
3379 
3380     } while ((pSource) && (MINIMAL_DATA_SIZE < pSource->GetDataSize()));
3381 
3382     if (!pSource)
3383     {
3384         return AddSlice(0, true);
3385     }
3386     else
3387     {
3388         uint32_t flags = pSource->GetFlags();
3389 
3390         if (!(flags & MediaData::FLAG_VIDEO_DATA_NOT_FULL_FRAME))
3391         {
3392             assert(!m_pLastSlice);
3393             return AddSlice(0, true);
3394         }
3395     }
3396 
3397     return UMC_ERR_NOT_ENOUGH_DATA;
3398 }
3399 
3400 static
IsFieldOfOneFrame(const H264DecoderFrame * pFrame,const H264Slice * pSlice1,const H264Slice * pSlice2)3401 bool IsFieldOfOneFrame(const H264DecoderFrame *pFrame, const H264Slice * pSlice1, const H264Slice *pSlice2)
3402 {
3403     if (!pFrame)
3404         return false;
3405 
3406     if (pFrame && pFrame->GetAU(0)->GetStatus() > H264DecoderFrameInfo::STATUS_NOT_FILLED
3407         && pFrame->GetAU(1)->GetStatus() > H264DecoderFrameInfo::STATUS_NOT_FILLED)
3408         return false;
3409 
3410     if ((pSlice1->GetSliceHeader()->nal_ref_idc && !pSlice2->GetSliceHeader()->nal_ref_idc) ||
3411         (!pSlice1->GetSliceHeader()->nal_ref_idc && pSlice2->GetSliceHeader()->nal_ref_idc))
3412         return false;
3413 
3414     if (pSlice1->GetSliceHeader()->field_pic_flag != pSlice2->GetSliceHeader()->field_pic_flag)
3415         return false;
3416 
3417     if (pSlice1->GetSliceHeader()->frame_num != pSlice2->GetSliceHeader()->frame_num)
3418         return false;
3419 
3420     if (pSlice1->GetSliceHeader()->bottom_field_flag == pSlice2->GetSliceHeader()->bottom_field_flag)
3421         return false;
3422 
3423     return true;
3424 }
3425 
CreateSlice()3426 H264Slice * TaskSupplier::CreateSlice()
3427 {
3428     return m_ObjHeap.AllocateObject<H264Slice>();
3429 }
3430 
DecodeSliceHeader(NalUnit * nalUnit)3431 H264Slice * TaskSupplier::DecodeSliceHeader(NalUnit *nalUnit)
3432 {
3433     if ((0 > m_Headers.m_SeqParams.GetCurrentID()) ||
3434         (0 > m_Headers.m_PicParams.GetCurrentID()))
3435     {
3436         return 0;
3437     }
3438 
3439     if (m_Headers.m_nalExtension.extension_present)
3440     {
3441         if (SVC_Extension::IsShouldSkipSlice(&m_Headers.m_nalExtension))
3442         {
3443             m_Headers.m_nalExtension.extension_present = 0;
3444             return 0;
3445         }
3446     }
3447 
3448     H264Slice * pSlice = CreateSlice();
3449     if (!pSlice)
3450     {
3451         return 0;
3452     }
3453     pSlice->SetHeap(&m_ObjHeap);
3454     pSlice->IncrementReference();
3455 
3456     notifier0<H264Slice> memory_leak_preventing_slice(pSlice, &H264Slice::DecrementReference);
3457 
3458     H264MemoryPiece memCopy;
3459     memCopy.SetData(nalUnit);
3460 
3461     pSlice->m_pSource.Allocate(nalUnit->GetDataSize() + DEFAULT_NU_SLICE_TAIL_SIZE);
3462 
3463     notifier0<H264MemoryPiece> memory_leak_preventing(&pSlice->m_pSource, &H264MemoryPiece::Release);
3464 
3465     SwapperBase * swapper = m_pNALSplitter->GetSwapper();
3466     swapper->SwapMemory(&pSlice->m_pSource, &memCopy);
3467 
3468     int32_t pps_pid = pSlice->RetrievePicParamSetNumber();
3469     if (pps_pid == -1)
3470     {
3471         ErrorStatus::isPPSError = 1;
3472         return 0;
3473     }
3474 
3475     H264SEIPayLoad * spl = m_Headers.m_SEIParams.GetHeader(SEI_RECOVERY_POINT_TYPE);
3476 
3477     if (m_WaitForIDR)
3478     {
3479         if (pSlice->GetSliceHeader()->slice_type != INTRASLICE && !spl)
3480         {
3481             return 0;
3482         }
3483     }
3484 
3485     pSlice->m_pPicParamSet = m_Headers.m_PicParams.GetHeader(pps_pid);
3486     if (!pSlice->m_pPicParamSet)
3487     {
3488         return 0;
3489     }
3490 
3491     int32_t seq_parameter_set_id = pSlice->m_pPicParamSet->seq_parameter_set_id;
3492 
3493     if (NAL_UT_CODED_SLICE_EXTENSION == pSlice->GetSliceHeader()->nal_unit_type)
3494     {
3495         if (pSlice->GetSliceHeader()->nal_ext.svc_extension_flag == 0)
3496         {
3497             pSlice->m_pSeqParamSetSvcEx = 0;
3498             pSlice->m_pSeqParamSet = pSlice->m_pSeqParamSetMvcEx = m_Headers.m_SeqParamsMvcExt.GetHeader(seq_parameter_set_id);
3499 
3500             if (NULL == pSlice->m_pSeqParamSet)
3501             {
3502                 return 0;
3503             }
3504 
3505             m_Headers.m_SeqParamsMvcExt.SetCurrentID(pSlice->m_pSeqParamSetMvcEx->seq_parameter_set_id);
3506             m_Headers.m_PicParams.SetCurrentID(pSlice->m_pPicParamSet->pic_parameter_set_id);
3507         }
3508         else
3509         {
3510             pSlice->m_pSeqParamSetMvcEx = 0;
3511             pSlice->m_pSeqParamSet = pSlice->m_pSeqParamSetSvcEx = m_Headers.m_SeqParamsSvcExt.GetHeader(seq_parameter_set_id);
3512 
3513             if (NULL == pSlice->m_pSeqParamSet)
3514             {
3515                 return 0;
3516             }
3517 
3518             m_Headers.m_SeqParamsSvcExt.SetCurrentID(pSlice->m_pSeqParamSetSvcEx->seq_parameter_set_id);
3519             m_Headers.m_PicParams.SetCurrentID(pSlice->m_pPicParamSet->pic_parameter_set_id);
3520         }
3521     }
3522     else
3523     {
3524         pSlice->m_pSeqParamSetSvcEx = m_Headers.m_SeqParamsSvcExt.GetCurrentHeader();
3525         pSlice->m_pSeqParamSetMvcEx = m_Headers.m_SeqParamsMvcExt.GetCurrentHeader();
3526         pSlice->m_pSeqParamSet = m_Headers.m_SeqParams.GetHeader(seq_parameter_set_id);
3527 
3528         if (!pSlice->m_pSeqParamSet)
3529         {
3530             ErrorStatus::isSPSError = 0;
3531             return 0;
3532         }
3533 
3534         m_Headers.m_SeqParams.SetCurrentID(pSlice->m_pPicParamSet->seq_parameter_set_id);
3535         m_Headers.m_PicParams.SetCurrentID(pSlice->m_pPicParamSet->pic_parameter_set_id);
3536     }
3537 
3538     if (pSlice->m_pSeqParamSet->errorFlags)
3539         ErrorStatus::isSPSError = 1;
3540 
3541     if (pSlice->m_pPicParamSet->errorFlags)
3542         ErrorStatus::isPPSError = 1;
3543 
3544     Status sts = InitializePictureParamSet(m_Headers.m_PicParams.GetHeader(pps_pid), pSlice->m_pSeqParamSet, NAL_UT_CODED_SLICE_EXTENSION == pSlice->GetSliceHeader()->nal_unit_type);
3545     if (sts != UMC_OK)
3546     {
3547         return 0;
3548     }
3549 
3550     pSlice->m_pSeqParamSetEx = m_Headers.m_SeqExParams.GetHeader(seq_parameter_set_id);
3551     pSlice->m_pCurrentFrame = 0;
3552 
3553     memory_leak_preventing.ClearNotification();
3554     pSlice->m_dTime = pSlice->m_pSource.GetTime();
3555 
3556     if (!pSlice->Reset(&m_Headers.m_nalExtension))
3557     {
3558         return 0;
3559     }
3560 
3561     if (IsShouldSkipSlice(pSlice))
3562         return 0;
3563 
3564     if (!IsExtension())
3565     {
3566         memset(&pSlice->GetSliceHeader()->nal_ext, 0, sizeof(H264NalExtension));
3567     }
3568 
3569     if (spl)
3570     {
3571         if (m_WaitForIDR)
3572         {
3573             AllocateAndInitializeView(pSlice);
3574             ViewItem &view = GetView(pSlice->GetSliceHeader()->nal_ext.mvc.view_id);
3575             uint32_t recoveryFrameNum = (spl->SEI_messages.recovery_point.recovery_frame_cnt + pSlice->GetSliceHeader()->frame_num) % (1 << pSlice->m_pSeqParamSet->log2_max_frame_num);
3576             view.GetDPBList(0)->SetRecoveryFrameCnt(recoveryFrameNum);
3577         }
3578 
3579         if ((pSlice->GetSliceHeader()->slice_type != INTRASLICE))
3580         {
3581             H264SEIPayLoad * splToRemove = m_Headers.m_SEIParams.GetHeader(SEI_RECOVERY_POINT_TYPE);
3582             m_Headers.m_SEIParams.RemoveHeader(splToRemove);
3583         }
3584     }
3585 
3586     m_WaitForIDR = false;
3587     memory_leak_preventing_slice.ClearNotification();
3588 
3589     //DEBUG_PRINT((VM_STRING("debug headers slice - view - %d \n"), pSlice->GetSliceHeader()->nal_ext.mvc.view_id));
3590 
3591     return pSlice;
3592 }
3593 
DPBSanitize(H264DecoderFrame * pDPBHead,const H264DecoderFrame * pFrame)3594 void TaskSupplier::DPBSanitize(H264DecoderFrame * pDPBHead, const H264DecoderFrame * pFrame)
3595 {
3596     for (H264DecoderFrame *pFrm = pDPBHead; pFrm; pFrm = pFrm->future())
3597     {
3598         if ((pFrm != pFrame) &&
3599             (pFrm->FrameNum() == pFrame->FrameNum()) &&
3600              pFrm->isShortTermRef())
3601         {
3602             pFrm->SetErrorFlagged(ERROR_FRAME_SHORT_TERM_STUCK);
3603             AddItemAndRun(pFrm, pFrm, UNSET_REFERENCE | FULL_FRAME | SHORT_TERM);
3604         }
3605     }
3606 }
3607 
AddSlice(H264Slice * pSlice,bool force)3608 Status TaskSupplier::AddSlice(H264Slice * pSlice, bool force)
3609 {
3610     if (!m_accessUnit.GetLayersCount() && pSlice)
3611     {
3612         if (m_sei_messages)
3613             m_sei_messages->SetAUID(m_accessUnit.GetAUIndentifier());
3614     }
3615 
3616     if (!pSlice)
3617     {
3618         m_accessUnit.AddSlice(0); // full AU
3619     }
3620 
3621     if ((!pSlice || m_accessUnit.IsFullAU() || !m_accessUnit.AddSlice(pSlice)) && m_accessUnit.GetLayersCount())
3622     {
3623         m_pLastSlice = pSlice;
3624         if (!m_accessUnit.m_isInitialized)
3625         {
3626             InitializeLayers(&m_accessUnit, 0, 0);
3627 
3628             size_t layersCount = m_accessUnit.GetLayersCount();
3629             uint32_t maxDId = 0;
3630             if (layersCount && m_accessUnit.GetLayer(layersCount - 1)->GetSliceCount())
3631             {
3632                 maxDId = m_accessUnit.GetLayer(layersCount - 1)->GetSlice(0)->GetSliceHeader()->nal_ext.svc.dependency_id;
3633             }
3634             for (size_t i = 0; i < layersCount; i++)
3635             {
3636                 SetOfSlices * setOfSlices = m_accessUnit.GetLayer(i);
3637                 H264Slice * slice = setOfSlices->GetSlice(0);
3638                 if (slice == nullptr)
3639                     continue;
3640 
3641                 AllocateAndInitializeView(slice);
3642 
3643                 ViewItem &view = GetView(slice->GetSliceHeader()->nal_ext.mvc.view_id);
3644 
3645                 if (view.pCurFrame && view.pCurFrame->m_PictureStructureForDec < FRM_STRUCTURE)
3646                 {
3647                     H264Slice * pFirstFrameSlice = view.pCurFrame->GetAU(0)->GetSlice(0);
3648                     if (!pFirstFrameSlice || !IsFieldOfOneFrame(view.pCurFrame, pFirstFrameSlice, slice))
3649                     {
3650                         ProcessNonPairedField(view.pCurFrame);
3651                         OnFullFrame(view.pCurFrame);
3652                         view.pCurFrame = 0;
3653                     }
3654                 }
3655 
3656                 if (view.GetPOCDecoder(0)->DetectFrameNumGap(slice))
3657                 {
3658                     view.pCurFrame = 0;
3659 
3660                     Status umsRes = ProcessFrameNumGap(slice, 0, 0, maxDId);
3661                     if (umsRes != UMC_OK)
3662                         return umsRes;
3663                 }
3664             }
3665 
3666             m_accessUnit.m_isInitialized = true;
3667         }
3668 
3669         size_t layersCount = m_accessUnit.GetLayersCount();
3670 
3671         {
3672             for (size_t i = 0; i < layersCount; i++)
3673             {
3674                 SetOfSlices * setOfSlices = m_accessUnit.GetLayer(i);
3675                 H264Slice * slice = setOfSlices->GetSlice(0);
3676 
3677                 if (setOfSlices->m_frame)
3678                     continue;
3679 
3680                 Status sts = AllocateNewFrame(slice, &setOfSlices->m_frame);
3681                 if (sts != UMC_OK)
3682                     return sts;
3683 
3684                 if (!setOfSlices->m_frame)
3685                     return UMC_ERR_NOT_ENOUGH_BUFFER;
3686 
3687                 setOfSlices->m_frame->m_auIndex = m_accessUnit.GetAUIndentifier();
3688                 ApplyPayloadsToFrame(setOfSlices->m_frame, slice, &setOfSlices->m_payloads);
3689 
3690                 if (layersCount == 1)
3691                     break;
3692 
3693                 return UMC_OK;
3694             }
3695         }
3696 
3697         for (size_t i = 0; i < layersCount; i++)
3698         {
3699             SetOfSlices * setOfSlices = m_accessUnit.GetLayer(i);
3700             if (setOfSlices->m_isCompleted)
3701                 continue;
3702 
3703             H264Slice * lastSlice = setOfSlices->GetSlice(setOfSlices->GetSliceCount() - 1);
3704 
3705             FrameType Frame_type = SliceTypeToFrameType(lastSlice->GetSliceHeader()->slice_type);
3706             m_currentView = lastSlice->GetSliceHeader()->nal_ext.mvc.view_id;
3707             ViewItem &view = GetView(m_currentView);
3708             view.pCurFrame = setOfSlices->m_frame;
3709 
3710             //1)If frame_num has gap in a stream, for a kind of cases that the frame_num has a jump, the frame_num
3711             //gap will cause a reference frame to stay in DPB buffer constantly. Need to unmark the reference frame
3712             //in DPB buffer when the future frame with the same frame_num is coming.
3713             //2)If a stream has a wrong way to calculate the B frame's frame_num, this will cause DPB buffer confusion.
3714             //For example: The B frame's frame_num equals to the previous reference frame's frame_num.
3715             //For these cases, add an another condition (Frame_type != B_PICTURE) that unmark the reference frame when
3716             //decoding the P frame or I frame rather than B frame.
3717             if (lastSlice->GetSeqParam()->gaps_in_frame_num_value_allowed_flag != 1 && Frame_type != B_PICTURE)
3718             {
3719                 // Check if DPB has ST frames with frame_num duplicating frame_num of new slice_type
3720                 // If so, unmark such frames as ST.
3721                 H264DecoderFrame * pHead = view.GetDPBList(0)->head();
3722                 DPBSanitize(pHead, view.pCurFrame);
3723             }
3724 
3725             const H264SliceHeader *sliceHeader = lastSlice->GetSliceHeader();
3726             uint32_t field_index = setOfSlices->m_frame->GetNumberByParity(sliceHeader->bottom_field_flag);
3727             if (!setOfSlices->m_frame->GetAU(field_index)->GetSliceCount())
3728             {
3729                 size_t count = setOfSlices->GetSliceCount();
3730                 for (size_t sliceId = 0; sliceId < count; sliceId++)
3731                 {
3732                     H264Slice * slice = setOfSlices->GetSlice(sliceId);
3733                     slice->m_pCurrentFrame = setOfSlices->m_frame;
3734                     AddSliceToFrame(setOfSlices->m_frame, slice);
3735 
3736                     if (slice->GetSliceHeader()->slice_type != INTRASLICE)
3737                     {
3738                         uint32_t NumShortTermRefs, NumLongTermRefs, NumInterViewRefs = 0;
3739                         view.GetDPBList(0)->countActiveRefs(NumShortTermRefs, NumLongTermRefs);
3740                         // calculate number of inter-view references
3741                         if (slice->GetSliceHeader()->nal_ext.mvc.view_id)
3742                         {
3743                             NumInterViewRefs = GetInterViewFrameRefs(m_views,
3744                                                                      slice->GetSliceHeader()->nal_ext.mvc.view_id,
3745                                                                      setOfSlices->m_frame->m_auIndex,
3746                                                                      slice->GetSliceHeader()->bottom_field_flag);
3747                         }
3748 
3749                         if (NumShortTermRefs + NumLongTermRefs + NumInterViewRefs == 0)
3750                             AddFakeReferenceFrame(slice);
3751                     }
3752 
3753                     slice->UpdateReferenceList(m_views, 0);
3754                 }
3755 
3756                 if (count && !setOfSlices->GetSlice(0)->IsSliceGroups())
3757                 {
3758                     H264Slice * slice = setOfSlices->GetSlice(0);
3759                     if (slice->m_iFirstMB)
3760                     {
3761                         m_pSegmentDecoder[0]->RestoreErrorRect(0, slice->m_iFirstMB, slice);
3762                     }
3763                 }
3764             }
3765 
3766             Status umcRes;
3767             if ((umcRes = CompleteFrame(setOfSlices->m_frame, field_index)) != UMC_OK)
3768             {
3769                 return umcRes;
3770             }
3771 
3772             if (setOfSlices->m_frame->m_PictureStructureForDec < FRM_STRUCTURE && force && !pSlice)
3773             {
3774                 if (ProcessNonPairedField(setOfSlices->m_frame))
3775                 {
3776                     OnFullFrame(setOfSlices->m_frame);
3777                     view.pCurFrame = 0;
3778                 }
3779             }
3780 
3781             if (setOfSlices->m_frame->m_PictureStructureForDec >= FRM_STRUCTURE || field_index)
3782             {
3783                 OnFullFrame(setOfSlices->m_frame);
3784                 view.pCurFrame = 0;
3785             }
3786 
3787             setOfSlices->m_isCompleted = true;
3788         }
3789 
3790         m_accessUnit.Reset();
3791         return layersCount ? UMC_OK : UMC_ERR_NOT_ENOUGH_DATA;
3792     }
3793 
3794     m_pLastSlice = 0;
3795     return UMC_ERR_NOT_ENOUGH_DATA;
3796 }
3797 
AddFakeReferenceFrame(H264Slice *)3798 void TaskSupplier::AddFakeReferenceFrame(H264Slice * )
3799 {
3800 }
3801 
OnFullFrame(H264DecoderFrame * pFrame)3802 void TaskSupplier::OnFullFrame(H264DecoderFrame * pFrame)
3803 {
3804     pFrame->SetFullFrame(true);
3805 
3806     ViewItem &view = GetView(pFrame->m_viewId);
3807 
3808     if (!view.m_isDisplayable)
3809     {
3810         pFrame->setWasOutputted();
3811         pFrame->setWasDisplayed();
3812     }
3813 
3814     if (pFrame->IsSkipped())
3815         return;
3816 
3817     if (pFrame->m_bIDRFlag && !(pFrame->GetError() & ERROR_FRAME_DPB))
3818     {
3819         DecReferencePictureMarking::ResetError();
3820     }
3821 
3822     if (DecReferencePictureMarking::GetDPBError())
3823     {
3824         pFrame->SetErrorFlagged(ERROR_FRAME_DPB);
3825     }
3826 }
3827 
InitializeLayers(AccessUnit * accessUnit,H264DecoderFrame *,int32_t)3828 Status TaskSupplier::InitializeLayers(AccessUnit *accessUnit, H264DecoderFrame * /*pFrame*/, int32_t /*field*/)
3829 {
3830     accessUnit->SortforASO();
3831     size_t layersCount = accessUnit->GetLayersCount();
3832 
3833     if (!layersCount)
3834         return UMC_OK;
3835 
3836     if ((m_decodingMode == MVC_DECODING_MODE) && layersCount > 1)
3837     {
3838         H264Slice * sliceExtension = 0;
3839         for (size_t i = layersCount - 1; i >= 1; i--)
3840         {
3841             SetOfSlices * setOfSlices = accessUnit->GetLayer(i);
3842             size_t sliceCount = setOfSlices->GetSliceCount();
3843             for (size_t sliceId = 0; sliceId < sliceCount; sliceId++)
3844             {
3845                 H264Slice * slice = setOfSlices->GetSlice(sliceId);
3846                 if (NAL_UT_CODED_SLICE_EXTENSION == slice->GetSliceHeader()->nal_unit_type)
3847                 {
3848                     sliceExtension = slice;
3849                     break;
3850                 }
3851             }
3852 
3853             if (sliceExtension)
3854                 break;
3855         }
3856 
3857         if (sliceExtension)
3858         {
3859             SetOfSlices * setOfSlices = accessUnit->GetLayer(0);
3860             size_t sliceCount = setOfSlices->GetSliceCount();
3861             for (size_t sliceId = 0; sliceId < sliceCount; sliceId++)
3862             {
3863                 H264Slice * slice = setOfSlices->GetSlice(sliceId);
3864                 if (NAL_UT_CODED_SLICE_EXTENSION != slice->GetSliceHeader()->nal_unit_type)
3865                 {
3866                     if (!slice->m_pSeqParamSetMvcEx)
3867                         slice->SetSeqMVCParam(sliceExtension->m_pSeqParamSetMvcEx);
3868                     if (!slice->m_pSeqParamSetSvcEx)
3869                         slice->SetSeqSVCParam(sliceExtension->m_pSeqParamSetSvcEx);
3870                 }
3871             }
3872         }
3873     }
3874 
3875     return UMC_OK;
3876 }
3877 
CompleteFrame(H264DecoderFrame * pFrame,int32_t field)3878 Status TaskSupplier::CompleteFrame(H264DecoderFrame * pFrame, int32_t field)
3879 {
3880     if (!pFrame)
3881         return UMC_OK;
3882 
3883     H264DecoderFrameInfo * slicesInfo = pFrame->GetAU(field);
3884 
3885     if (slicesInfo->GetStatus() > H264DecoderFrameInfo::STATUS_NOT_FILLED)
3886         return UMC_OK;
3887 
3888     DEBUG_PRINT((VM_STRING("Complete frame POC - (%d,%d) type - %d, picStruct - %d, field - %d, count - %d, m_uid - %d, IDR - %d, viewId - %d\n"), pFrame->m_PicOrderCnt[0], pFrame->m_PicOrderCnt[1], pFrame->m_FrameType, pFrame->m_displayPictureStruct, field, pFrame->GetAU(field)->GetSliceCount(), pFrame->m_UID, pFrame->m_bIDRFlag, pFrame->m_viewId));
3889 
3890     DBPUpdate(pFrame, field);
3891 
3892     // skipping algorithm
3893     {
3894         if (((slicesInfo->IsField() && field) || !slicesInfo->IsField()) &&
3895             IsShouldSkipFrame(pFrame, field))
3896         {
3897             if (slicesInfo->IsField())
3898             {
3899                 pFrame->GetAU(0)->SetStatus(H264DecoderFrameInfo::STATUS_COMPLETED);
3900                 pFrame->GetAU(1)->SetStatus(H264DecoderFrameInfo::STATUS_COMPLETED);
3901             }
3902             else
3903             {
3904                 pFrame->GetAU(0)->SetStatus(H264DecoderFrameInfo::STATUS_COMPLETED);
3905             }
3906 
3907             pFrame->SetisShortTermRef(false, 0);
3908             pFrame->SetisShortTermRef(false, 1);
3909             pFrame->SetisLongTermRef(false, 0);
3910             pFrame->SetisLongTermRef(false, 1);
3911             pFrame->SetSkipped(true);
3912             pFrame->OnDecodingCompleted();
3913             return UMC_OK;
3914         }
3915         else
3916         {
3917             if (IsShouldSkipDeblocking(pFrame, field))
3918             {
3919                 pFrame->GetAU(field)->SkipDeblocking();
3920             }
3921         }
3922     }
3923 
3924     slicesInfo->SetStatus(H264DecoderFrameInfo::STATUS_FILLED);
3925     return UMC_OK;
3926 }
3927 
InitFreeFrame(H264DecoderFrame * pFrame,const H264Slice * pSlice)3928 void TaskSupplier::InitFreeFrame(H264DecoderFrame * pFrame, const H264Slice *pSlice)
3929 {
3930     const H264SeqParamSet *pSeqParam = pSlice->GetSeqParam();
3931 
3932     pFrame->m_FrameType = SliceTypeToFrameType(pSlice->GetSliceHeader()->slice_type);
3933     pFrame->m_dFrameTime = pSlice->m_dTime;
3934     pFrame->m_crop_left = SubWidthC[pSeqParam->chroma_format_idc] * pSeqParam->frame_cropping_rect_left_offset;
3935     pFrame->m_crop_right = SubWidthC[pSeqParam->chroma_format_idc] * pSeqParam->frame_cropping_rect_right_offset;
3936     pFrame->m_crop_top = SubHeightC[pSeqParam->chroma_format_idc] * pSeqParam->frame_cropping_rect_top_offset * (2 - pSeqParam->frame_mbs_only_flag);
3937     pFrame->m_crop_bottom = SubHeightC[pSeqParam->chroma_format_idc] * pSeqParam->frame_cropping_rect_bottom_offset * (2 - pSeqParam->frame_mbs_only_flag);
3938     pFrame->m_crop_flag = pSeqParam->frame_cropping_flag;
3939 
3940     pFrame->setFrameNum(pSlice->GetSliceHeader()->frame_num);
3941     if (pSlice->GetSliceHeader()->nal_ext.extension_present &&
3942         0 == pSlice->GetSliceHeader()->nal_ext.svc_extension_flag)
3943     {
3944         pFrame->setViewId(pSlice->GetSliceHeader()->nal_ext.mvc.view_id);
3945     }
3946 
3947     pFrame->m_aspect_width  = pSeqParam->vui.sar_width;
3948     pFrame->m_aspect_height = pSeqParam->vui.sar_height;
3949 
3950     if (pSlice->GetSliceHeader()->field_pic_flag)
3951     {
3952         pFrame->m_bottom_field_flag[0] = pSlice->GetSliceHeader()->bottom_field_flag;
3953         pFrame->m_bottom_field_flag[1] = !pSlice->GetSliceHeader()->bottom_field_flag;
3954 
3955         pFrame->m_PictureStructureForRef =
3956         pFrame->m_PictureStructureForDec = FLD_STRUCTURE;
3957     }
3958     else
3959     {
3960         pFrame->m_bottom_field_flag[0] = 0;
3961         pFrame->m_bottom_field_flag[1] = 1;
3962 
3963         if (pSlice->GetSliceHeader()->MbaffFrameFlag)
3964         {
3965             pFrame->m_PictureStructureForRef =
3966             pFrame->m_PictureStructureForDec = AFRM_STRUCTURE;
3967         }
3968         else
3969         {
3970             pFrame->m_PictureStructureForRef =
3971             pFrame->m_PictureStructureForDec = FRM_STRUCTURE;
3972         }
3973     }
3974 
3975     int32_t iMBCount = pSeqParam->frame_width_in_mbs * pSeqParam->frame_height_in_mbs;
3976     pFrame->totalMBs = iMBCount;
3977     if (pFrame->m_PictureStructureForDec < FRM_STRUCTURE)
3978         pFrame->totalMBs /= 2;
3979 
3980     int32_t chroma_format_idc = pSeqParam->chroma_format_idc;
3981 
3982     uint8_t bit_depth_luma = pSeqParam->bit_depth_luma;
3983     uint8_t bit_depth_chroma = pSeqParam->bit_depth_chroma;
3984 
3985     int32_t bit_depth = std::max(bit_depth_luma, bit_depth_chroma);
3986 
3987     int32_t iMBWidth = pSeqParam->frame_width_in_mbs;
3988     int32_t iMBHeight = pSeqParam->frame_height_in_mbs;
3989     mfxSize dimensions = {iMBWidth * 16, iMBHeight * 16};
3990 
3991     ColorFormat cf = GetUMCColorFormat(chroma_format_idc);
3992 
3993     VideoDataInfo info;
3994     info.Init(dimensions.width, dimensions.height, cf, bit_depth);
3995 
3996     pFrame->Init(&info);
3997 }
3998 
InitFrameCounter(H264DecoderFrame * pFrame,const H264Slice * pSlice)3999 void TaskSupplier::InitFrameCounter(H264DecoderFrame * pFrame, const H264Slice *pSlice)
4000 {
4001     const H264SliceHeader *sliceHeader = pSlice->GetSliceHeader();
4002     ViewItem &view = GetView(sliceHeader->nal_ext.mvc.view_id);
4003 
4004     if (view.GetPOCDecoder(0)->DetectFrameNumGap(pSlice, true))
4005     {
4006         H264DBPList* dpb = view.GetDPBList(0);
4007         assert(dpb);
4008 
4009         uint32_t NumShortTerm, NumLongTerm;
4010         dpb->countActiveRefs(NumShortTerm, NumLongTerm);
4011 
4012         if ((NumShortTerm + NumLongTerm > 0))
4013         {
4014             // set error flag only we have some references in DPB
4015             pFrame->SetErrorFlagged(ERROR_FRAME_REFERENCE_FRAME);
4016 
4017             // Leaving aside a legal frame_num wrapping cases, when a rapid _decrease_ of frame_num occurs due to frame gaps,
4018             // frames marked as short-term prior the gap may get stuck in DPB for a very long sequence (up to '(1 << log2_max_frame_num) - 1').
4019             // Reference lists are generated incorrectly. A potential recovery point can be at next I frame (if GOP is closed).
4020             // So let's mark these potentially dangereous ST frames
4021             // to remove them later from DPB in UpdateRefPicMarking() (if they're still there) at next I frame or SEI recovery point.
4022             for (H264DecoderFrame *pFrm = view.GetDPBList(0)->head(); pFrm; pFrm = pFrm->future())
4023             {
4024                 if ((pFrm->FrameNum() > sliceHeader->frame_num) && pFrm->isShortTermRef())
4025                 {
4026                     pFrm->SetErrorFlagged(ERROR_FRAME_SHORT_TERM_STUCK);
4027                 }
4028             }
4029         }
4030     }
4031 
4032     if (sliceHeader->IdrPicFlag)
4033     {
4034         view.GetPOCDecoder(0)->Reset(sliceHeader->frame_num);
4035     }
4036 
4037     view.GetPOCDecoder(0)->DecodePictureOrderCount(pSlice, sliceHeader->frame_num);
4038 
4039     pFrame->m_bIDRFlag = (sliceHeader->IdrPicFlag != 0);
4040 
4041     const int32_t recoveryFrameNum = view.GetDPBList(0)->GetRecoveryFrameCnt();
4042     pFrame->m_bIFlag = (sliceHeader->slice_type == INTRASLICE) || (recoveryFrameNum != -1 && pFrame->FrameNum() == recoveryFrameNum);
4043 
4044     if (pFrame->m_bIDRFlag)
4045     {
4046         view.GetDPBList(0)->IncreaseRefPicListResetCount(pFrame);
4047     }
4048 
4049     pFrame->setFrameNum(sliceHeader->frame_num);
4050 
4051     uint32_t field_index = pFrame->GetNumberByParity(sliceHeader->bottom_field_flag);
4052 
4053     if (sliceHeader->field_pic_flag == 0)
4054         pFrame->setPicNum(sliceHeader->frame_num, 0);
4055     else
4056         pFrame->setPicNum(sliceHeader->frame_num*2+1, field_index);
4057 
4058     view.GetPOCDecoder(0)->DecodePictureOrderCountInitFrame(pFrame, field_index);
4059 
4060     DEBUG_PRINT((VM_STRING("Init frame POC - %d, %d, field - %d, uid - %d, frame_num - %d, viewId - %d\n"), pFrame->m_PicOrderCnt[0], pFrame->m_PicOrderCnt[1], field_index, pFrame->m_UID, pFrame->m_FrameNum, pFrame->m_viewId));
4061 
4062     pFrame->SetInterViewRef(0 != pSlice->GetSliceHeader()->nal_ext.mvc.inter_view_flag, field_index);
4063     pFrame->InitRefPicListResetCount(field_index);
4064 
4065 } // void TaskSupplier::InitFrameCounter(H264DecoderFrame * pFrame, const H264Slice *pSlice)
4066 
AddSliceToFrame(H264DecoderFrame * pFrame,H264Slice * pSlice)4067 void TaskSupplier::AddSliceToFrame(H264DecoderFrame *pFrame, H264Slice *pSlice)
4068 {
4069     const H264SliceHeader *sliceHeader = pSlice->GetSliceHeader();
4070 
4071     if (pFrame->m_FrameType < SliceTypeToFrameType(pSlice->GetSliceHeader()->slice_type))
4072         pFrame->m_FrameType = SliceTypeToFrameType(pSlice->GetSliceHeader()->slice_type);
4073 
4074     uint32_t field_index = pFrame->GetNumberByParity(sliceHeader->bottom_field_flag);
4075 
4076     H264DecoderFrameInfo * au_info = pFrame->GetAU(field_index);
4077     int32_t iSliceNumber = au_info->GetSliceCount() + 1;
4078 
4079     if (field_index)
4080     {
4081         iSliceNumber += pFrame->m_TopSliceCount;
4082     }
4083     else
4084     {
4085         pFrame->m_TopSliceCount++;
4086     }
4087 
4088     pFrame->m_iNumberOfSlices++;
4089 
4090     pSlice->SetSliceNumber(iSliceNumber);
4091     pSlice->m_pCurrentFrame = pFrame;
4092     au_info->AddSlice(pSlice);
4093 }
4094 
DBPUpdate(H264DecoderFrame * pFrame,int32_t field)4095 void TaskSupplier::DBPUpdate(H264DecoderFrame * pFrame, int32_t field)
4096 {
4097     H264DecoderFrameInfo *slicesInfo = pFrame->GetAU(field);
4098 
4099     uint32_t count = slicesInfo->GetSliceCount();
4100     for (uint32_t i = 0; i < count; i++)
4101     {
4102         H264Slice * slice = slicesInfo->GetSlice(i);
4103         if (!slice->IsReference())
4104             continue;
4105 
4106         ViewItem &view = GetView(slice->GetSliceHeader()->nal_ext.mvc.view_id);
4107 
4108         DecReferencePictureMarking::UpdateRefPicMarking(view, pFrame, slice, field);
4109         break;
4110     }
4111 }
4112 
FindSurface(FrameMemID id)4113 H264DecoderFrame * TaskSupplier::FindSurface(FrameMemID id)
4114 {
4115     AutomaticUMCMutex guard(m_mGuard);
4116 
4117     ViewList::iterator iter = m_views.begin();
4118     ViewList::iterator iter_end = m_views.end();
4119 
4120     for (; iter != iter_end; ++iter)
4121     {
4122         H264DecoderFrame *pFrame = iter->GetDPBList(0)->head();
4123         for (; pFrame; pFrame = pFrame->future())
4124         {
4125             if (pFrame->GetFrameData()->GetFrameMID() == id)
4126                 return pFrame;
4127         }
4128     }
4129 
4130     return 0;
4131 }
4132 
RunDecoding()4133 Status TaskSupplier::RunDecoding()
4134 {
4135     Status umcRes = CompleteDecodedFrames(0);
4136     if (umcRes != UMC_OK)
4137         return umcRes;
4138 
4139     ViewList::iterator iter = m_views.begin();
4140     ViewList::iterator iter_end = m_views.end();
4141 
4142     H264DecoderFrame *pFrame = 0;
4143     for (; iter != iter_end; ++iter)
4144     {
4145         pFrame = iter->GetDPBList(0)->head();
4146 
4147         for (; pFrame; pFrame = pFrame->future())
4148         {
4149             if (!pFrame->IsDecodingCompleted())
4150             {
4151                 break;
4152             }
4153         }
4154 
4155         if (pFrame)
4156             break;
4157     }
4158 
4159     m_pTaskBroker->Start();
4160 
4161     if (!pFrame)
4162         return UMC_OK;
4163 
4164     //DEBUG_PRINT((VM_STRING("Decode POC - %d\n"), pFrame->m_PicOrderCnt[0]));
4165 
4166     return UMC_OK;
4167 }
4168 
GetUserData(MediaData * pUD)4169 Status TaskSupplier::GetUserData(MediaData * pUD)
4170 {
4171     if(!pUD)
4172         return UMC_ERR_NULL_PTR;
4173 
4174     if (!m_pLastDisplayed)
4175         return UMC_ERR_NOT_ENOUGH_DATA;
4176 
4177     if (m_pLastDisplayed->m_UserData.user_data.size() && m_pLastDisplayed->m_UserData.payLoadSize &&
4178         m_pLastDisplayed->m_UserData.payLoadType == SEI_USER_DATA_REGISTERED_TYPE)
4179     {
4180         pUD->SetTime(m_pLastDisplayed->m_dFrameTime);
4181         pUD->SetBufferPointer(&m_pLastDisplayed->m_UserData.user_data[0],
4182             m_pLastDisplayed->m_UserData.payLoadSize);
4183         pUD->SetDataSize(m_pLastDisplayed->m_UserData.payLoadSize);
4184         //m_pLastDisplayed->m_UserData.Reset();
4185         return UMC_OK;
4186     }
4187 
4188     return UMC_ERR_NOT_ENOUGH_DATA;
4189 }
4190 
ApplyPayloadsToFrame(H264DecoderFrame * frame,H264Slice * slice,SeiPayloadArray * payloads)4191 void TaskSupplier::ApplyPayloadsToFrame(H264DecoderFrame * frame, H264Slice *slice, SeiPayloadArray * payloads)
4192 {
4193     if (!payloads || !frame)
4194         return;
4195 
4196     if (m_sei_messages)
4197     {
4198         m_sei_messages->SetFrame(frame, frame->m_auIndex);
4199     }
4200 
4201     H264SEIPayLoad * payload = payloads->FindPayload(SEI_PIC_TIMING_TYPE);
4202 
4203     if (frame->m_displayPictureStruct == DPS_UNKNOWN)
4204     {
4205         if (payload && slice->GetSeqParam()->vui.pic_struct_present_flag)
4206         {
4207             frame->m_displayPictureStruct = payload->SEI_messages.pic_timing.pic_struct;
4208         }
4209         else
4210         {
4211             if (frame->m_PictureStructureForDec == FLD_STRUCTURE)
4212             {
4213                 frame->m_displayPictureStruct = frame->GetNumberByParity(0) ? DPS_BOTTOM : DPS_TOP;
4214             }
4215             else
4216             {
4217                 if (frame->PicOrderCnt(0, 1) == frame->PicOrderCnt(1, 1))
4218                 {
4219                     frame->m_displayPictureStruct = DPS_FRAME;
4220                 }
4221                 else
4222                 {
4223                     frame->m_displayPictureStruct = (frame->PicOrderCnt(0, 1) < frame->PicOrderCnt(1, 1)) ? DPS_TOP_BOTTOM : DPS_BOTTOM_TOP;
4224                 }
4225             }
4226         }
4227     }
4228 
4229     frame->m_dpb_output_delay = DPBOutput::GetDPBOutputDelay(payload);
4230 
4231     if (frame->GetAU(0)->m_isBExist || frame->GetAU(1)->m_isBExist)
4232         DPBOutput::GetDPBOutputDelay(0);
4233 
4234     payload = payloads->FindPayload(SEI_DEC_REF_PIC_MARKING_TYPE);
4235     if (payload)
4236     {
4237         ViewItem &view = GetViewByNumber(BASE_VIEW);
4238         DecReferencePictureMarking::CheckSEIRepetition(view, payload);
4239     }
4240 }
4241 
AllocateNewFrame(const H264Slice * slice,H264DecoderFrame ** frame)4242 Status TaskSupplier::AllocateNewFrame(const H264Slice *slice, H264DecoderFrame **frame)
4243 {
4244     if (!frame || !slice)
4245     {
4246         return UMC_ERR_NULL_PTR;
4247     }
4248 
4249     *frame = 0;
4250 
4251     m_currentView = slice->GetSliceHeader()->nal_ext.mvc.view_id;
4252     ViewItem &view = GetView(m_currentView);
4253 
4254     if (view.pCurFrame && view.pCurFrame->m_PictureStructureForDec < FRM_STRUCTURE)
4255     {
4256         H264Slice * pFirstFrameSlice = view.pCurFrame->GetAU(0)->GetSlice(0);
4257         if (pFirstFrameSlice && IsFieldOfOneFrame(view.pCurFrame, pFirstFrameSlice, slice))
4258         {
4259             *frame = view.pCurFrame;
4260             InitFrameCounter(*frame, slice);
4261         }
4262 
4263         view.pCurFrame = 0;
4264     }
4265 
4266     if (*frame)
4267         return UMC_OK;
4268 
4269     H264DecoderFrame *pFrame = GetFreeFrame(slice);
4270     if (!pFrame)
4271     {
4272         return UMC_ERR_NOT_ENOUGH_BUFFER;
4273     }
4274 
4275     Status umcRes = AllocateFrameData(pFrame);
4276     if (umcRes != UMC_OK)
4277     {
4278         return umcRes;
4279     }
4280 
4281     *frame = pFrame;
4282 
4283     if (slice->IsField())
4284     {
4285         pFrame->GetAU(1)->SetStatus(H264DecoderFrameInfo::STATUS_NOT_FILLED);
4286     }
4287 
4288     InitFrameCounter(pFrame, slice);
4289 
4290     return UMC_OK;
4291 } // H264DecoderFrame * TaskSupplier::AddFrame(H264Slice *pSlice)
4292 
4293 } // namespace UMC
4294 #endif // MFX_ENABLE_H264_VIDEO_DECODE
4295