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