1 // Copyright (c) 2017-2018 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 /*  DEBUG: this file is requred to changing name
25     to umc_h264_dec_slice_decode_pic */
26 
27 #include "umc_h264_slice_decoding.h"
28 #include "umc_h264_dec.h"
29 #include "vm_debug.h"
30 #include "umc_h264_frame_list.h"
31 
32 #include "umc_h264_task_supplier.h"
33 
34 //#define ENABLE_LIST_TRACE
35 #define LIST_TRACE_FILE_NAME "d:/ipp.ref"
36 
37 namespace UMC
38 {
39 
FindLastValidReference(H264DecoderFrame ** pList,int32_t iLength)40 static H264DecoderFrame *FindLastValidReference(H264DecoderFrame **pList, int32_t iLength)
41 {
42     int32_t i;
43     H264DecoderFrame *pLast = NULL;
44 
45     for (i = 0; i < iLength; i += 1)
46     {
47         if (pList[i])
48             pLast = pList[i];
49     }
50 
51     return pLast;
52 
53 } // H264DecoderFrame *FindLastValidReference(H264DecoderFrame **pList,
54 
55 
UpdateReferenceList(ViewList & views,int32_t dIdIndex)56 Status H264Slice::UpdateReferenceList(ViewList &views,
57                                       int32_t dIdIndex)
58 {
59     UMC_H264_DECODER::RefPicListReorderInfo *pReorderInfo_L0 = &ReorderInfoL0;
60     UMC_H264_DECODER::RefPicListReorderInfo *pReorderInfo_L1 = &ReorderInfoL1;
61     const UMC_H264_DECODER::H264SeqParamSet *sps = GetSeqParam();
62     uint32_t uMaxFrameNum;
63     uint32_t uMaxPicNum;
64     H264DecoderFrame *pFrm;
65     H264DBPList *pDecoderFrameList = GetDPB(views, m_SliceHeader.nal_ext.mvc.view_id, dIdIndex);
66     H264DecoderFrame *pHead = pDecoderFrameList->head();
67     //uint32_t i;
68     H264DecoderFrame **pRefPicList0;
69     H264DecoderFrame **pRefPicList1;
70     ReferenceFlags *pFields0;
71     ReferenceFlags *pFields1;
72     uint32_t NumShortTermRefs, NumLongTermRefs;
73     H264RefListInfo rli;
74     H264DecoderFrame *pLastInList[2] = {NULL, NULL};
75 
76     if (m_pCurrentFrame == nullptr)
77         return UMC_ERR_NULL_PTR;
78 
79     const H264DecoderRefPicList* pH264DecRefPicList0 = m_pCurrentFrame->GetRefPicList(m_iNumber, 0);
80     const H264DecoderRefPicList* pH264DecRefPicList1 = m_pCurrentFrame->GetRefPicList(m_iNumber, 1);
81     if (pH264DecRefPicList0 == nullptr || pH264DecRefPicList1 == nullptr)
82         return UMC_ERR_NULL_PTR;
83 
84     pRefPicList0 = pH264DecRefPicList0->m_RefPicList;
85     pRefPicList1 = pH264DecRefPicList1->m_RefPicList;
86     pFields0 = pH264DecRefPicList0->m_Flags;
87     pFields1 = pH264DecRefPicList1->m_Flags;
88 
89     // Spec reference: 8.2.4, "Decoding process for reference picture lists
90     // construction"
91 
92     // get pointers to the picture and sequence parameter sets currently in use
93     uMaxFrameNum = (1<<sps->log2_max_frame_num);
94     uMaxPicNum = (m_SliceHeader.field_pic_flag == 0) ? uMaxFrameNum : uMaxFrameNum<<1;
95 
96     for (pFrm = pHead; pFrm; pFrm = pFrm->future())
97     {
98         // update FrameNumWrap and picNum if frame number wrap occurred,
99         // for short-term frames
100         // TBD: modify for fields
101         pFrm->UpdateFrameNumWrap((int32_t)m_SliceHeader.frame_num,
102             uMaxFrameNum,
103             m_pCurrentFrame->m_PictureStructureForDec +
104             m_SliceHeader.bottom_field_flag);
105 
106         // For long-term references, update LongTermPicNum. Note this
107         // could be done when LongTermFrameIdx is set, but this would
108         // only work for frames, not fields.
109         // TBD: modify for fields
110         pFrm->UpdateLongTermPicNum(m_pCurrentFrame->m_PictureStructureForDec +
111                                    m_SliceHeader.bottom_field_flag);
112     }
113 
114     for (uint32_t number = 0; number <= MAX_NUM_REF_FRAMES + 1; number++)
115     {
116         pRefPicList0[number] = 0;
117         pRefPicList1[number] = 0;
118         pFields0[number].field = 0;
119         pFields0[number].isShortReference = 0;
120         pFields1[number].field = 0;
121         pFields1[number].isShortReference = 0;
122     }
123 
124     if ((m_SliceHeader.slice_type != INTRASLICE) && (m_SliceHeader.slice_type != S_INTRASLICE))
125     {
126         uint32_t NumInterViewRefs = 0;
127 
128         // Detect and report no available reference frames
129         pDecoderFrameList->countActiveRefs(NumShortTermRefs, NumLongTermRefs);
130         // calculate number of inter-view references
131         if (m_SliceHeader.nal_ext.mvc.view_id != views.front().viewId)
132         {
133             NumInterViewRefs = GetInterViewFrameRefs(views, m_SliceHeader.nal_ext.mvc.view_id, m_pCurrentFrame->m_auIndex, m_SliceHeader.bottom_field_flag);
134         }
135 
136         if ((NumShortTermRefs + NumLongTermRefs + NumInterViewRefs) == 0)
137         {
138             return UMC_ERR_INVALID_STREAM;
139         }
140 
141 
142         // Initialize the reference picture lists
143         // Note the slice header get function always fills num_ref_idx_lx_active
144         // fields with a valid value; either the override from the slice
145         // header in the bitstream or the values from the pic param set when
146         // there is no override.
147 
148         if (!m_SliceHeader.IdrPicFlag)
149         {
150             if ((m_SliceHeader.slice_type == PREDSLICE) ||
151                 (m_SliceHeader.slice_type == S_PREDSLICE))
152             {
153                 pDecoderFrameList->InitPSliceRefPicList(this, pRefPicList0);
154                 pLastInList[0] = FindLastValidReference(pRefPicList0,
155                                                         m_SliceHeader.num_ref_idx_l0_active);
156             }
157             else
158             {
159                 pDecoderFrameList->InitBSliceRefPicLists(this, pRefPicList0, pRefPicList1, rli);
160                 pLastInList[0] = FindLastValidReference(pRefPicList0,
161                                                         m_SliceHeader.num_ref_idx_l0_active);
162                 pLastInList[1] = FindLastValidReference(pRefPicList1,
163                                                         m_SliceHeader.num_ref_idx_l1_active);
164             }
165 
166             // Reorder the reference picture lists
167             if (m_pCurrentFrame->m_PictureStructureForDec < FRM_STRUCTURE)
168             {
169                 rli.m_iNumFramesInL0List = AdjustRefPicListForFields(pRefPicList0, pFields0, rli);
170             }
171 
172             if (BPREDSLICE == m_SliceHeader.slice_type)
173             {
174                 if (m_pCurrentFrame->m_PictureStructureForDec < FRM_STRUCTURE)
175                 {
176                     rli.m_iNumFramesInL1List = AdjustRefPicListForFields(pRefPicList1, pFields1, rli);
177                 }
178 
179                 if ((rli.m_iNumFramesInL0List == rli.m_iNumFramesInL1List) &&
180                     (rli.m_iNumFramesInL0List > 1))
181                 {
182                     bool isNeedSwap = true;
183                     for (int32_t i = 0; i < rli.m_iNumFramesInL0List; i++)
184                     {
185                         if (pRefPicList1[i] != pRefPicList0[i] ||
186                             pFields1[i].field != pFields0[i].field)
187                         {
188                             isNeedSwap = false;
189                             break;
190                         }
191                     }
192 
193                     if (isNeedSwap)
194                     {
195                         std::swap(pRefPicList1[0], pRefPicList1[1]);
196                         std::swap(pFields1[0], pFields1[1]);
197                     }
198                 }
199             }
200         }
201 
202         // MVC extension. Add inter-view references
203         if ((H264VideoDecoderParams::H264_PROFILE_MULTIVIEW_HIGH == m_pSeqParamSet->profile_idc) ||
204             (H264VideoDecoderParams::H264_PROFILE_STEREO_HIGH == m_pSeqParamSet->profile_idc))
205         {
206             pDecoderFrameList->AddInterViewRefs(this, pRefPicList0, pFields0, LIST_0, views);
207             if (m_SliceHeader.IdrPicFlag)
208             {
209                 pLastInList[0] = FindLastValidReference(pRefPicList0, m_SliceHeader.num_ref_idx_l0_active);
210             }
211 
212             if (BPREDSLICE == m_SliceHeader.slice_type)
213             {
214                 pDecoderFrameList->AddInterViewRefs(this, pRefPicList1, pFields1, LIST_1, views);
215                 if (m_SliceHeader.IdrPicFlag)
216                     pLastInList[1] = FindLastValidReference(pRefPicList1, m_SliceHeader.num_ref_idx_l1_active);
217             }
218         }
219 
220 
221         if (pReorderInfo_L0->num_entries > 0)
222             ReOrderRefPicList(pRefPicList0, pFields0, pReorderInfo_L0, uMaxPicNum, views, dIdIndex, 0);
223 
224         pRefPicList0[m_SliceHeader.num_ref_idx_l0_active] = 0;
225 
226         if (BPREDSLICE == m_SliceHeader.slice_type)
227         {
228             if (pReorderInfo_L1->num_entries > 0)
229                 ReOrderRefPicList(pRefPicList1, pFields1, pReorderInfo_L1, uMaxPicNum, views, dIdIndex, 1);
230 
231             pRefPicList1[m_SliceHeader.num_ref_idx_l1_active] = 0;
232         }
233 
234 
235 
236         // set absent references
237         {
238             int32_t i;
239             int32_t iCurField = 1;
240 
241             if (!pLastInList[0])
242             {
243                 for (;;)
244                 {
245                     for (H264DecoderFrame *pFrame = pDecoderFrameList->head(); pFrame; pFrame = pFrame->future())
246                     {
247                         if (pFrame->isShortTermRef()==3)
248                             pLastInList[0] = pFrame;
249                     }
250 
251                     if (pLastInList[0])
252                         break;
253 
254                     for (H264DecoderFrame *pFrame = pDecoderFrameList->head(); pFrame; pFrame = pFrame->future())
255                     {
256                         if (pFrame->isLongTermRef()==3)
257                             pLastInList[0] = pFrame;
258                     }
259                     break;
260                 }
261             }
262 
263             if (BPREDSLICE == m_SliceHeader.slice_type && !pLastInList[1])
264             {
265                 pLastInList[1] = pLastInList[0];
266             }
267 
268             for (i = 0; i < m_SliceHeader.num_ref_idx_l0_active; i += 1)
269             {
270                 if (NULL == pRefPicList0[i])
271                 {
272                     pRefPicList0[i] = pLastInList[0];
273                     m_pCurrentFrame->AddReference(pLastInList[0]);
274                     pFields0[i].field = (int8_t) (iCurField ^= 1);
275                     if (pRefPicList0[i])
276                         pFields0[i].isShortReference = (pRefPicList0[i]->m_viewId == m_pCurrentFrame->m_viewId) ? 1 : 0;
277                     else
278                         pFields0[i].isShortReference = 1;
279                     pFields0[i].isLongReference = 0;
280                     m_pCurrentFrame->SetErrorFlagged(ERROR_FRAME_MAJOR);
281                 }
282                 else
283                 {
284                     m_pCurrentFrame->AddReference(pRefPicList0[i]);
285                     m_pCurrentFrame->SetErrorFlagged(pRefPicList0[i]->IsFrameExist() ? 0 : ERROR_FRAME_MAJOR);
286                     pFields0[i].isShortReference =
287                         pRefPicList0[i]->isShortTermRef(pRefPicList0[i]->GetNumberByParity(pFields0[i].field));
288                     pFields0[i].isLongReference =
289                         pRefPicList0[i]->isLongTermRef(pRefPicList0[i]->GetNumberByParity(pFields0[i].field));
290 
291                     if (pRefPicList0[i]->m_viewId != m_pCurrentFrame->m_viewId)
292                         pFields0[i].isShortReference = pFields0[i].isLongReference = 0;
293                 }
294             }
295 
296             if (BPREDSLICE == m_SliceHeader.slice_type)
297             {
298                 iCurField = 1;
299 
300                 for (i = 0; i < m_SliceHeader.num_ref_idx_l1_active; i += 1)
301                 {
302                     if (NULL == pRefPicList1[i])
303                     {
304                         pRefPicList1[i] = pLastInList[1];
305                         m_pCurrentFrame->AddReference(pLastInList[1]);
306                         pFields1[i].field = (int8_t) (iCurField ^= 1);
307                         pFields1[i].isShortReference = 1;
308                         if (pRefPicList1[i])
309                             pFields1[i].isShortReference = (pRefPicList1[i]->m_viewId == m_pCurrentFrame->m_viewId) ? 1 : 0;
310                         else
311                             pFields1[i].isShortReference = 1;
312                         pFields1[i].isLongReference = 0;
313                         m_pCurrentFrame->SetErrorFlagged(ERROR_FRAME_MAJOR);
314                     }
315                     else
316                     {
317                         m_pCurrentFrame->AddReference(pRefPicList1[i]);
318                         m_pCurrentFrame->SetErrorFlagged(pRefPicList1[i]->IsFrameExist() ? 0 : ERROR_FRAME_MAJOR);
319                         pFields1[i].isShortReference =
320                             pRefPicList1[i]->isShortTermRef(pRefPicList1[i]->GetNumberByParity(pFields1[i].field));
321                         pFields1[i].isLongReference =
322                             pRefPicList1[i]->isLongTermRef(pRefPicList1[i]->GetNumberByParity(pFields1[i].field));
323 
324                         if (pRefPicList1[i]->m_viewId != m_pCurrentFrame->m_viewId)
325                             pFields1[i].isShortReference = pFields1[i].isLongReference = 0;
326                     }
327                 }
328             }
329         }
330     }
331 
332     return UMC_OK;
333 
334 } // Status H264Slice::UpdateRefPicList(H264DecoderFrameList *pDecoderFrameList)
335 
AdjustRefPicListForFields(H264DecoderFrame ** pRefPicList,ReferenceFlags * pFields,H264RefListInfo & rli)336 int32_t H264Slice::AdjustRefPicListForFields(H264DecoderFrame **pRefPicList,
337                                           ReferenceFlags *pFields,
338                                           H264RefListInfo &rli)
339 {
340     H264DecoderFrame *TempList[MAX_NUM_REF_FRAMES+1];
341     uint8_t TempFields[MAX_NUM_REF_FRAMES+1];
342     //walk through list and set correct indices
343     int32_t i=0,j=0,numSTR=0,numLTR=0;
344     int32_t num_same_parity = 0, num_opposite_parity = 0;
345     int8_t current_parity = m_SliceHeader.bottom_field_flag;
346     //first scan the list to determine number of shortterm and longterm reference frames
347     while ((numSTR < 16) && pRefPicList[numSTR] && pRefPicList[numSTR]->isShortTermRef()) numSTR++;
348     while ((numSTR + numLTR < 16) && pRefPicList[numSTR+numLTR] && pRefPicList[numSTR+numLTR]->isLongTermRef()) numLTR++;
349 
350     while (num_same_parity < numSTR ||  num_opposite_parity < numSTR)
351     {
352         //try to fill shorttermref fields with the same parity first
353         if (num_same_parity < numSTR)
354         {
355             while (num_same_parity < numSTR)
356             {
357                 int32_t ref_field = pRefPicList[num_same_parity]->GetNumberByParity(current_parity);
358                 if (pRefPicList[num_same_parity]->isShortTermRef(ref_field))
359                     break;
360 
361                 num_same_parity++;
362 
363             }
364 
365             if (num_same_parity<numSTR)
366             {
367                 TempList[i] = pRefPicList[num_same_parity];
368                 TempFields[i] = current_parity;
369                 i++;
370                 num_same_parity++;
371             }
372         }
373         //now process opposite parity
374         if (num_opposite_parity < numSTR)
375         {
376             while (num_opposite_parity < numSTR)
377             {
378                 int32_t ref_field = pRefPicList[num_opposite_parity]->GetNumberByParity(!current_parity);
379                 if (pRefPicList[num_opposite_parity]->isShortTermRef(ref_field))
380                     break;
381                 num_opposite_parity++;
382             }
383 
384             if (num_opposite_parity<numSTR) //selected field is reference
385             {
386                 TempList[i] = pRefPicList[num_opposite_parity];
387                 TempFields[i] = !current_parity;
388                 i++;
389                 num_opposite_parity++;
390             }
391         }
392     }
393 
394     rli.m_iNumShortEntriesInList = (uint8_t) i;
395     num_same_parity = num_opposite_parity = 0;
396     //now processing LongTermRef
397     while(num_same_parity<numLTR ||  num_opposite_parity<numLTR)
398     {
399         //try to fill longtermref fields with the same parity first
400         if (num_same_parity < numLTR)
401         {
402             while (num_same_parity < numLTR)
403             {
404                 int32_t ref_field = pRefPicList[num_same_parity+numSTR]->GetNumberByParity(current_parity);
405                 if (pRefPicList[num_same_parity+numSTR]->isLongTermRef(ref_field))
406                     break;
407                 num_same_parity++;
408             }
409             if (num_same_parity<numLTR)
410             {
411                 TempList[i] = pRefPicList[num_same_parity+numSTR];
412                 TempFields[i] = current_parity;
413                 i++;
414                 num_same_parity++;
415             }
416         }
417         //now process opposite parity
418         if (num_opposite_parity<numLTR)
419         {
420             while (num_opposite_parity < numLTR)
421             {
422                 int32_t ref_field = pRefPicList[num_opposite_parity+numSTR]->GetNumberByParity(!current_parity);
423 
424                 if (pRefPicList[num_opposite_parity+numSTR]->isLongTermRef(ref_field))
425                     break;
426                 num_opposite_parity++;
427             }
428 
429             if (num_opposite_parity<numLTR) //selected field is reference
430             {
431                 TempList[i] = pRefPicList[num_opposite_parity+numSTR];
432                 TempFields[i] = !current_parity;
433                 i++;
434                 num_opposite_parity++;
435             }
436         }
437     }
438 
439     rli.m_iNumLongEntriesInList = (uint8_t) (i - rli.m_iNumShortEntriesInList);
440     j = 0;
441     while(j < i)//copy data back to list
442     {
443         pRefPicList[j] = TempList[j];
444         pFields[j].field = TempFields[j];
445         pFields[j].isShortReference = (unsigned char) (pRefPicList[j]->isShortTermRef(pRefPicList[j]->GetNumberByParity(TempFields[j])) ? 1 : 0);
446         j++;
447     }
448 
449     while(j < (int32_t)MAX_NUM_REF_FRAMES)//fill remaining entries
450     {
451         pRefPicList[j] = NULL;
452         pFields[j].field = 0;
453         pFields[j].isShortReference = 0;
454         j++;
455     }
456 
457     return i;
458 } // int32_t H264Slice::AdjustRefPicListForFields(H264DecoderFrame **pRefPicList, int8_t *pFields)
459 
ReOrderRefPicList(H264DecoderFrame ** pRefPicList,ReferenceFlags * pFields,UMC_H264_DECODER::RefPicListReorderInfo * pReorderInfo,int32_t MaxPicNum,ViewList & views,int32_t dIdIndex,uint32_t listNum)460 void H264Slice::ReOrderRefPicList(H264DecoderFrame **pRefPicList,
461                                   ReferenceFlags *pFields,
462                                   UMC_H264_DECODER::RefPicListReorderInfo *pReorderInfo,
463                                   int32_t MaxPicNum,
464                                   ViewList &views,
465                                   int32_t dIdIndex,
466                                   uint32_t listNum)
467 {
468     bool bIsFieldSlice = (m_SliceHeader.field_pic_flag != 0);
469     uint32_t NumRefActive = (0 == listNum) ?
470                           m_SliceHeader.num_ref_idx_l0_active :
471                           m_SliceHeader.num_ref_idx_l1_active;
472     uint32_t i;
473     int32_t picNumNoWrap;
474     int32_t picNum;
475     int32_t picNumPred;
476     int32_t picNumCurr;
477     int32_t picViewIdxLXPred = -1;
478     H264DBPList *pDecoderFrameList = GetDPB(views, m_SliceHeader.nal_ext.mvc.view_id, dIdIndex);
479 
480     int32_t pocForce = bIsFieldSlice ? 0 : 3;
481 
482     // Reference: Reordering process for reference picture lists, 8.2.4.3
483     picNumCurr = m_pCurrentFrame->PicNum(m_pCurrentFrame->GetNumberByParity(m_SliceHeader.bottom_field_flag), pocForce);
484     picNumPred = picNumCurr;
485 
486     for (i=0; i<pReorderInfo->num_entries; i++)
487     {
488         if (pReorderInfo->reordering_of_pic_nums_idc[i] < 2)
489         {
490             // short-term reorder
491             if (pReorderInfo->reordering_of_pic_nums_idc[i] == 0)
492             {
493                 picNumNoWrap = picNumPred - pReorderInfo->reorder_value[i];
494                 if (picNumNoWrap < 0)
495                     picNumNoWrap += MaxPicNum;
496             }
497             else
498             {
499                 picNumNoWrap = picNumPred + pReorderInfo->reorder_value[i];
500                 if (picNumNoWrap >= MaxPicNum)
501                     picNumNoWrap -= MaxPicNum;
502             }
503             picNumPred = picNumNoWrap;
504 
505             picNum = picNumNoWrap;
506             if (picNum > picNumCurr)
507                 picNum -= MaxPicNum;
508 
509             int32_t frameField;
510             H264DecoderFrame* pFrame = pDecoderFrameList->findShortTermPic(picNum, &frameField);
511 
512             for (uint32_t k = NumRefActive; k > i; k--)
513             {
514                 pRefPicList[k] = pRefPicList[k - 1];
515                 pFields[k] = pFields[k - 1];
516             }
517 
518             // Place picture with picNum on list, shifting pictures
519             // down by one while removing any duplication of picture with picNum.
520             pRefPicList[i] = pFrame;
521             pFields[i].field = (char) ((pFrame && bIsFieldSlice) ? pFrame->m_bottom_field_flag[frameField] : 0);
522             pFields[i].isShortReference = 1;
523             int32_t refIdxLX = i + 1;
524 
525             for(uint32_t kk = i + 1; kk <= NumRefActive; kk++)
526             {
527                 if (pRefPicList[kk])
528                 {
529                     if (!(pRefPicList[kk]->isShortTermRef(pRefPicList[kk]->GetNumberByParity(pFields[kk].field)) &&
530                         pRefPicList[kk]->PicNum(pRefPicList[kk]->GetNumberByParity(pFields[kk].field), 1) == picNum))
531                     {
532                         pRefPicList[refIdxLX] = pRefPicList[kk];
533                         pFields[refIdxLX] = pFields[kk];
534                         refIdxLX++;
535                     }
536                 }
537             }
538         }    // short-term reorder
539         else if (2 == pReorderInfo->reordering_of_pic_nums_idc[i])
540         {
541             // long term reorder
542             picNum = pReorderInfo->reorder_value[i];
543 
544             int32_t frameField;
545             H264DecoderFrame* pFrame = pDecoderFrameList->findLongTermPic(picNum, &frameField);
546 
547             for (uint32_t k = NumRefActive; k > i; k--)
548             {
549                 pRefPicList[k] = pRefPicList[k - 1];
550                 pFields[k] = pFields[k - 1];
551             }
552 
553             // Place picture with picNum on list, shifting pictures
554             // down by one while removing any duplication of picture with picNum.
555             pRefPicList[i] = pFrame;
556             pFields[i].field = (char) ((pFrame && bIsFieldSlice) ? pFrame->m_bottom_field_flag[frameField] : 0);
557             pFields[i].isShortReference = 0;
558             int32_t refIdxLX = i + 1;
559 
560             for(uint32_t kk = i + 1; kk <= NumRefActive; kk++)
561             {
562                 if (pRefPicList[kk])
563                 {
564                     if (!(pRefPicList[kk]->isLongTermRef(pRefPicList[kk]->GetNumberByParity(pFields[kk].field)) &&
565                         pRefPicList[kk]->LongTermPicNum(pRefPicList[kk]->GetNumberByParity(pFields[kk].field), 1) == picNum))
566                     {
567                         pRefPicList[refIdxLX] = pRefPicList[kk];
568                         pFields[refIdxLX] = pFields[kk];
569                         refIdxLX++;
570                     }
571                 }
572             }
573         }    // long term reorder
574         // MVC reordering
575         else if ((4 == pReorderInfo->reordering_of_pic_nums_idc[i]) ||
576                     (5 == pReorderInfo->reordering_of_pic_nums_idc[i]))
577         {
578             int32_t abs_diff_view_idx = pReorderInfo->reorder_value[i];
579             int32_t maxViewIdx;
580             int32_t targetViewID;
581 
582             if (!m_pSeqParamSetMvcEx)
583             {
584                 m_pCurrentFrame->SetErrorFlagged(ERROR_FRAME_MAJOR);
585                 continue;
586             }
587 
588             uint32_t picViewIdxLX;
589             H264DecoderFrame* pFrame = NULL;
590             int32_t curPOC = m_pCurrentFrame->PicOrderCnt(m_pCurrentFrame->GetNumberByParity(m_SliceHeader.bottom_field_flag), pocForce);
591 
592             // set current VO index
593             const auto currView = std::find_if(m_pSeqParamSetMvcEx->viewInfo.begin(), m_pSeqParamSetMvcEx->viewInfo.end(),
594                                          [this](const UMC_H264_DECODER::H264ViewRefInfo &item){ return item.view_id == m_SliceHeader.nal_ext.mvc.view_id; });
595             if (currView == m_pSeqParamSetMvcEx->viewInfo.end())
596             {
597                 throw h264_exception(UMC_ERR_INVALID_STREAM);
598             }
599 
600             // get the maximum number of reference
601             if (m_SliceHeader.nal_ext.mvc.anchor_pic_flag)
602             {
603                 maxViewIdx = currView->num_anchor_refs_lx[listNum];
604             }
605             else
606             {
607                 maxViewIdx = currView->num_non_anchor_refs_lx[listNum];
608             }
609 
610             // get the index of view reference
611             if (4 == pReorderInfo->reordering_of_pic_nums_idc[i])
612             {
613                 if (picViewIdxLXPred - abs_diff_view_idx < 0)
614                 {
615                     picViewIdxLX = picViewIdxLXPred - abs_diff_view_idx + maxViewIdx;
616                 }
617                 else
618                 {
619                     picViewIdxLX = picViewIdxLXPred - abs_diff_view_idx;
620                 }
621             }
622             else
623             {
624                 if (picViewIdxLXPred + abs_diff_view_idx >= maxViewIdx)
625                 {
626                     picViewIdxLX = picViewIdxLXPred + abs_diff_view_idx - maxViewIdx;
627                 }
628                 else
629                 {
630                     picViewIdxLX = picViewIdxLXPred + abs_diff_view_idx;
631                 }
632             }
633             picViewIdxLXPred = picViewIdxLX;
634             if (picViewIdxLX >= UMC::H264_MAX_NUM_VIEW_REF)
635             {
636                 m_pCurrentFrame->SetErrorFlagged(ERROR_FRAME_MAJOR);
637                 continue;
638             }
639             // get the target view
640             if (m_SliceHeader.nal_ext.mvc.anchor_pic_flag)
641             {
642                 targetViewID = currView->anchor_refs_lx[listNum][picViewIdxLX];
643             }
644             else
645             {
646                 targetViewID = currView->non_anchor_refs_lx[listNum][picViewIdxLX];
647             }
648             ViewList::iterator iter = views.begin();
649             ViewList::iterator iter_end = views.end();
650             for (; iter != iter_end; ++iter)
651             {
652                 if (targetViewID == iter->viewId)
653                 {
654                     pFrame = iter->GetDPBList(dIdIndex)->findInterViewRef(m_pCurrentFrame->m_auIndex, m_SliceHeader.bottom_field_flag);
655                     break;
656                 }
657             }
658             // corresponding frame is found
659             if (!pFrame)
660                 continue;
661 
662             // make some space to insert the reference
663             for (uint32_t k = NumRefActive; k > i; k--)
664             {
665                 pRefPicList[k] = pRefPicList[k - 1];
666                 pFields[k] = pFields[k - 1];
667             }
668 
669             // Place picture with picNum on list, shifting pictures
670             // down by one while removing any duplication of picture with cuuPOC.
671             pRefPicList[i] = pFrame;
672             pFields[i].field = m_SliceHeader.bottom_field_flag;
673             pFields[i].isShortReference = 1;
674             uint32_t refIdxLX = i + 1;
675 
676             for (uint32_t kk = i + 1; kk <= NumRefActive; kk++)
677             {
678                 if (pRefPicList[kk])
679                 {
680                     uint32_t refFieldIdx = pRefPicList[kk]->GetNumberByParity(m_SliceHeader.bottom_field_flag);
681 
682                     if ((pRefPicList[kk]->m_viewId != targetViewID) ||
683                         (pRefPicList[kk]->PicOrderCnt(refFieldIdx, pocForce) != curPOC))
684                     {
685                         pRefPicList[refIdxLX] = pRefPicList[kk];
686                         pFields[refIdxLX] = pFields[kk];
687                         refIdxLX++;
688                     }
689                 }
690             }
691         }
692     }    // for i
693 } // void H264Slice::ReOrderRefPicList(H264DecoderFrame **pRefPicList,
694 
695 } // namespace UMC
696 
697 #endif // MFX_ENABLE_H264_VIDEO_DECODE
698