1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 #include "avclib_common.h"
19 
20 /** see subclause 8.2.4 Decoding process for reference picture lists construction. */
RefListInit(AVCCommonObj * video)21 OSCL_EXPORT_REF void RefListInit(AVCCommonObj *video)
22 {
23     AVCSliceHeader *sliceHdr = video->sliceHdr;
24     AVCDecPicBuffer *dpb = video->decPicBuf;
25     int slice_type = video->slice_type;
26     int i, list0idx;
27 
28     AVCPictureData *tmp_s;
29 
30     list0idx = 0;
31 
32     if (slice_type == AVC_I_SLICE)
33     {
34         video->refList0Size = 0;
35         video->refList1Size = 0;
36 
37         /* we still have to calculate FrameNumWrap to make sure that all I-slice clip
38         can perform sliding_window_operation properly. */
39 
40         for (i = 0; i < dpb->num_fs; i++)
41         {
42             if ((dpb->fs[i]->IsReference == 3) && (!dpb->fs[i]->IsLongTerm))
43             {
44                 /* subclause 8.2.4.1 Decoding process for picture numbers. */
45                 if (dpb->fs[i]->FrameNum > (int)sliceHdr->frame_num)
46                 {
47                     dpb->fs[i]->FrameNumWrap = dpb->fs[i]->FrameNum - video->MaxFrameNum;
48                 }
49                 else
50                 {
51                     dpb->fs[i]->FrameNumWrap = dpb->fs[i]->FrameNum;
52                 }
53                 dpb->fs[i]->frame.PicNum = dpb->fs[i]->FrameNumWrap;
54             }
55         }
56 
57 
58         return ;
59     }
60     if (slice_type == AVC_P_SLICE)
61     {
62         /* Calculate FrameNumWrap and PicNum */
63 
64         for (i = 0; i < dpb->num_fs; i++)
65         {
66             if ((dpb->fs[i]->IsReference == 3) && (!dpb->fs[i]->IsLongTerm))
67             {
68                 /* subclause 8.2.4.1 Decoding process for picture numbers. */
69                 if (dpb->fs[i]->FrameNum > (int)sliceHdr->frame_num)
70                 {
71                     dpb->fs[i]->FrameNumWrap = dpb->fs[i]->FrameNum - video->MaxFrameNum;
72                 }
73                 else
74                 {
75                     dpb->fs[i]->FrameNumWrap = dpb->fs[i]->FrameNum;
76                 }
77                 dpb->fs[i]->frame.PicNum = dpb->fs[i]->FrameNumWrap;
78                 video->RefPicList0[list0idx++] = &(dpb->fs[i]->frame);
79             }
80         }
81 
82         if (list0idx == 0)
83         {
84             dpb->fs[0]->IsReference = 3;
85             video->RefPicList0[0] = &(dpb->fs[0]->frame);
86             list0idx = 1;
87         }
88         /* order list 0 by PicNum from max to min, see subclause 8.2.4.2.1 */
89         SortPicByPicNum(video->RefPicList0, list0idx);
90         video->refList0Size = list0idx;
91 
92         /* long term handling */
93         for (i = 0; i < dpb->num_fs; i++)
94         {
95             if (dpb->fs[i]->IsLongTerm == 3)
96             {
97                 /* subclause 8.2.4.1 Decoding process for picture numbers. */
98                 dpb->fs[i]->frame.LongTermPicNum = dpb->fs[i]->LongTermFrameIdx;
99                 video->RefPicList0[list0idx++] = &(dpb->fs[i]->frame);
100             }
101         }
102 
103         /* order PicNum from min to max, see subclause 8.2.4.2.1  */
104         SortPicByPicNumLongTerm(&(video->RefPicList0[video->refList0Size]), list0idx - video->refList0Size);
105         video->refList0Size = list0idx;
106 
107 
108         video->refList1Size = 0;
109     }
110 
111 
112     if ((video->refList0Size == video->refList1Size) && (video->refList0Size > 1))
113     {
114         /* check if lists are identical, if yes swap first two elements of listX[1] */
115         /* last paragraph of subclause 8.2.4.2.4 */
116 
117         for (i = 0; i < video->refList0Size; i++)
118         {
119             if (video->RefPicList0[i] != video->RefPicList1[i])
120             {
121                 break;
122             }
123         }
124         if (i == video->refList0Size)
125         {
126             tmp_s = video->RefPicList1[0];
127             video->RefPicList1[0] = video->RefPicList1[1];
128             video->RefPicList1[1] = tmp_s;
129         }
130     }
131 
132     /* set max size */
133     video->refList0Size = AVC_MIN(video->refList0Size, (int)video->sliceHdr->num_ref_idx_l0_active_minus1 + 1);
134     video->refList1Size = AVC_MIN(video->refList1Size, (int)video->sliceHdr->num_ref_idx_l1_active_minus1 + 1);
135 
136     return ;
137 }
138 /* see subclause 8.2.4.3 */
ReOrderList(AVCCommonObj * video)139 OSCL_EXPORT_REF AVCStatus ReOrderList(AVCCommonObj *video)
140 {
141     AVCSliceHeader *sliceHdr = video->sliceHdr;
142     AVCStatus status = AVC_SUCCESS;
143     int slice_type = video->slice_type;
144 
145     if (slice_type != AVC_I_SLICE)
146     {
147         if (sliceHdr->ref_pic_list_reordering_flag_l0)
148         {
149             status = ReorderRefPicList(video, 0);
150             if (status != AVC_SUCCESS)
151                 return status;
152         }
153         if (video->refList0Size == 0)
154         {
155             return AVC_FAIL;
156         }
157     }
158     return status;
159 }
160 
ReorderRefPicList(AVCCommonObj * video,int isL1)161 AVCStatus ReorderRefPicList(AVCCommonObj *video, int isL1)
162 {
163     AVCSliceHeader *sliceHdr = video->sliceHdr;
164     AVCStatus status;
165 
166     int *list_size;
167     int num_ref_idx_lX_active_minus1;
168     uint *remapping_of_pic_nums_idc;
169     int *abs_diff_pic_num_minus1;
170     int *long_term_pic_idx;
171     int i;
172     int maxPicNum, currPicNum, picNumLXNoWrap, picNumLXPred, picNumLX;
173     int refIdxLX = 0;
174     void* tmp;
175 
176     if (!isL1) /* list 0 */
177     {
178         list_size = &(video->refList0Size);
179         num_ref_idx_lX_active_minus1 = sliceHdr->num_ref_idx_l0_active_minus1;
180         remapping_of_pic_nums_idc = sliceHdr->reordering_of_pic_nums_idc_l0;
181         tmp = (void*)sliceHdr->abs_diff_pic_num_minus1_l0;
182         abs_diff_pic_num_minus1 = (int*) tmp;
183         tmp = (void*)sliceHdr->long_term_pic_num_l0;
184         long_term_pic_idx = (int*) tmp;
185     }
186     else
187     {
188         list_size = &(video->refList1Size);
189         num_ref_idx_lX_active_minus1 = sliceHdr->num_ref_idx_l1_active_minus1;
190         remapping_of_pic_nums_idc = sliceHdr->reordering_of_pic_nums_idc_l1;
191         tmp = (void*) sliceHdr->abs_diff_pic_num_minus1_l1;
192         abs_diff_pic_num_minus1 = (int*) tmp;
193         tmp = (void*) sliceHdr->long_term_pic_num_l1;
194         long_term_pic_idx = (int*)tmp;
195     }
196 
197     maxPicNum = video->MaxPicNum;
198     currPicNum = video->CurrPicNum;
199 
200     picNumLXPred = currPicNum; /* initial value */
201 
202     for (i = 0; remapping_of_pic_nums_idc[i] != 3; i++)
203     {
204         if ((remapping_of_pic_nums_idc[i] > 3) || (i >= MAX_REF_PIC_LIST_REORDERING))
205         {
206             return AVC_FAIL; /* out of range */
207         }
208         /* see subclause 8.2.4.3.1 */
209         if (remapping_of_pic_nums_idc[i] < 2)
210         {
211             if (remapping_of_pic_nums_idc[i] == 0)
212             {
213                 if (picNumLXPred - (abs_diff_pic_num_minus1[i] + 1) < 0)
214                     picNumLXNoWrap = picNumLXPred - (abs_diff_pic_num_minus1[i] + 1) + maxPicNum;
215                 else
216                     picNumLXNoWrap = picNumLXPred - (abs_diff_pic_num_minus1[i] + 1);
217             }
218             else /* (remapping_of_pic_nums_idc[i] == 1) */
219             {
220                 if (picNumLXPred + (abs_diff_pic_num_minus1[i] + 1)  >=  maxPicNum)
221                     picNumLXNoWrap = picNumLXPred + (abs_diff_pic_num_minus1[i] + 1) - maxPicNum;
222                 else
223                     picNumLXNoWrap = picNumLXPred + (abs_diff_pic_num_minus1[i] + 1);
224             }
225             picNumLXPred = picNumLXNoWrap; /* prediction for the next one */
226 
227             if (picNumLXNoWrap > currPicNum)
228                 picNumLX = picNumLXNoWrap - maxPicNum;
229             else
230                 picNumLX = picNumLXNoWrap;
231 
232             status = ReorderShortTerm(video, picNumLX, &refIdxLX, isL1);
233             if (status != AVC_SUCCESS)
234             {
235                 return status;
236             }
237         }
238         else /* (remapping_of_pic_nums_idc[i] == 2), subclause 8.2.4.3.2 */
239         {
240             status = ReorderLongTerm(video, long_term_pic_idx[i], &refIdxLX, isL1);
241             if (status != AVC_SUCCESS)
242             {
243                 return status;
244             }
245         }
246     }
247     /* that's a definition */
248     *list_size = num_ref_idx_lX_active_minus1 + 1;
249 
250     return AVC_SUCCESS;
251 }
252 
253 /* see subclause 8.2.4.3.1 */
ReorderShortTerm(AVCCommonObj * video,int picNumLX,int * refIdxLX,int isL1)254 AVCStatus ReorderShortTerm(AVCCommonObj *video, int picNumLX, int *refIdxLX, int isL1)
255 {
256     int cIdx, nIdx;
257     int num_ref_idx_lX_active_minus1;
258     AVCPictureData *picLX, **RefPicListX;
259 
260     if (!isL1) /* list 0 */
261     {
262         RefPicListX = video->RefPicList0;
263         num_ref_idx_lX_active_minus1 = video->sliceHdr->num_ref_idx_l0_active_minus1;
264     }
265     else
266     {
267         RefPicListX = video->RefPicList1;
268         num_ref_idx_lX_active_minus1 = video->sliceHdr->num_ref_idx_l1_active_minus1;
269     }
270 
271     picLX = GetShortTermPic(video, picNumLX);
272 
273     if (picLX == NULL)
274     {
275         return AVC_FAIL;
276     }
277     /* Note RefPicListX has to access element number num_ref_idx_lX_active */
278     /* There could be access violation here. */
279     if (num_ref_idx_lX_active_minus1 + 1 >= MAX_REF_PIC_LIST)
280     {
281         return AVC_FAIL;
282     }
283 
284     for (cIdx = num_ref_idx_lX_active_minus1 + 1; cIdx > *refIdxLX; cIdx--)
285     {
286         RefPicListX[ cIdx ] = RefPicListX[ cIdx - 1];
287     }
288 
289     RefPicListX[(*refIdxLX)++ ] = picLX;
290 
291     nIdx = *refIdxLX;
292 
293     for (cIdx = *refIdxLX; cIdx <= num_ref_idx_lX_active_minus1 + 1; cIdx++)
294     {
295         if (RefPicListX[ cIdx ])
296         {
297             if ((RefPicListX[ cIdx ]->isLongTerm) || ((int)RefPicListX[ cIdx ]->PicNum != picNumLX))
298             {
299                 RefPicListX[ nIdx++ ] = RefPicListX[ cIdx ];
300             }
301         }
302     }
303     return AVC_SUCCESS;
304 }
305 
306 /* see subclause 8.2.4.3.2 */
ReorderLongTerm(AVCCommonObj * video,int LongTermPicNum,int * refIdxLX,int isL1)307 AVCStatus ReorderLongTerm(AVCCommonObj *video, int LongTermPicNum, int *refIdxLX, int isL1)
308 {
309     AVCPictureData **RefPicListX;
310     int num_ref_idx_lX_active_minus1;
311     int cIdx, nIdx;
312     AVCPictureData *picLX;
313 
314     if (!isL1) /* list 0 */
315     {
316         RefPicListX = video->RefPicList0;
317         num_ref_idx_lX_active_minus1 = video->sliceHdr->num_ref_idx_l0_active_minus1;
318     }
319     else
320     {
321         RefPicListX = video->RefPicList1;
322         num_ref_idx_lX_active_minus1 = video->sliceHdr->num_ref_idx_l1_active_minus1;
323     }
324 
325     picLX = GetLongTermPic(video, LongTermPicNum);
326     if (picLX == NULL)
327     {
328         return AVC_FAIL;
329     }
330     /* Note RefPicListX has to access element number num_ref_idx_lX_active */
331     /* There could be access violation here. */
332     if (num_ref_idx_lX_active_minus1 + 1 >= MAX_REF_PIC_LIST)
333     {
334         return AVC_FAIL;
335     }
336     for (cIdx = num_ref_idx_lX_active_minus1 + 1; cIdx > *refIdxLX; cIdx--)
337         RefPicListX[ cIdx ] = RefPicListX[ cIdx - 1];
338 
339     RefPicListX[(*refIdxLX)++ ] = picLX;
340 
341     nIdx = *refIdxLX;
342 
343     for (cIdx = *refIdxLX; cIdx <= num_ref_idx_lX_active_minus1 + 1; cIdx++)
344     {
345         if ((!RefPicListX[ cIdx ]->isLongTerm) || ((int)RefPicListX[ cIdx ]->LongTermPicNum != LongTermPicNum))
346         {
347             RefPicListX[ nIdx++ ] = RefPicListX[ cIdx ];
348         }
349     }
350     return AVC_SUCCESS;
351 }
352 
353 
GetShortTermPic(AVCCommonObj * video,int picNum)354 AVCPictureData*  GetShortTermPic(AVCCommonObj *video, int picNum)
355 {
356     int i;
357     AVCDecPicBuffer *dpb = video->decPicBuf;
358 
359     for (i = 0; i < dpb->num_fs; i++)
360     {
361 
362         if (dpb->fs[i]->IsReference == 3)
363         {
364             if ((dpb->fs[i]->frame.isLongTerm == FALSE) && (dpb->fs[i]->frame.PicNum == picNum))
365             {
366                 return &(dpb->fs[i]->frame);
367             }
368         }
369 
370     }
371 
372     return NULL;
373 }
374 
GetLongTermPic(AVCCommonObj * video,int LongtermPicNum)375 AVCPictureData*  GetLongTermPic(AVCCommonObj *video, int LongtermPicNum)
376 {
377     AVCDecPicBuffer *dpb = video->decPicBuf;
378     int i;
379 
380     for (i = 0; i < dpb->num_fs; i++)
381     {
382 
383         if (dpb->fs[i]->IsReference == 3)
384         {
385             if ((dpb->fs[i]->frame.isLongTerm == TRUE) && (dpb->fs[i]->frame.LongTermPicNum == LongtermPicNum))
386             {
387                 return &(dpb->fs[i]->frame);
388             }
389         }
390 
391     }
392     return NULL;
393 }
394 
is_short_ref(AVCPictureData * s)395 int is_short_ref(AVCPictureData *s)
396 {
397     return ((s->isReference) && !(s->isLongTerm));
398 }
399 
is_long_ref(AVCPictureData * s)400 int is_long_ref(AVCPictureData *s)
401 {
402     return ((s->isReference) && (s->isLongTerm));
403 }
404 
405 
406 /* sort by PicNum, descending order */
SortPicByPicNum(AVCPictureData * data[],int num)407 void SortPicByPicNum(AVCPictureData *data[], int num)
408 {
409     int i, j;
410     AVCPictureData *temp;
411 
412     for (i = 0; i < num - 1; i++)
413     {
414         for (j = i + 1; j < num; j++)
415         {
416             if (data[j]->PicNum > data[i]->PicNum)
417             {
418                 temp = data[j];
419                 data[j] = data[i];
420                 data[i] = temp;
421             }
422         }
423     }
424 
425     return ;
426 }
427 
428 /* sort by PicNum, ascending order */
SortPicByPicNumLongTerm(AVCPictureData * data[],int num)429 void SortPicByPicNumLongTerm(AVCPictureData *data[], int num)
430 {
431     int i, j;
432     AVCPictureData *temp;
433 
434     for (i = 0; i < num - 1; i++)
435     {
436         for (j = i + 1; j < num; j++)
437         {
438             if (data[j]->LongTermPicNum < data[i]->LongTermPicNum)
439             {
440                 temp = data[j];
441                 data[j] = data[i];
442                 data[i] = temp;
443             }
444         }
445     }
446 
447     return ;
448 }
449 
450 
451 /* sort by FrameNumWrap, descending order */
SortFrameByFrameNumWrap(AVCFrameStore * data[],int num)452 void SortFrameByFrameNumWrap(AVCFrameStore *data[], int num)
453 {
454     int i, j;
455     AVCFrameStore *temp;
456 
457     for (i = 0; i < num - 1; i++)
458     {
459         for (j = i + 1; j < num; j++)
460         {
461             if (data[j]->FrameNumWrap > data[i]->FrameNumWrap)
462             {
463                 temp = data[j];
464                 data[j] = data[i];
465                 data[i] = temp;
466             }
467         }
468     }
469 
470     return ;
471 }
472 
473 /* sort frames by LongTermFrameIdx, ascending order */
SortFrameByLTFrameIdx(AVCFrameStore * data[],int num)474 void SortFrameByLTFrameIdx(AVCFrameStore *data[], int num)
475 {
476     int i, j;
477     AVCFrameStore *temp;
478 
479     for (i = 0; i < num - 1; i++)
480     {
481         for (j = i + 1; j < num; j++)
482         {
483             if (data[j]->LongTermFrameIdx < data[i]->LongTermFrameIdx)
484             {
485                 temp = data[j];
486                 data[j] = data[i];
487                 data[i] = temp;
488             }
489         }
490     }
491 
492     return ;
493 }
494 
495 /* sort PictureData by POC in descending order */
SortPicByPOC(AVCPictureData * data[],int num,int descending)496 void SortPicByPOC(AVCPictureData *data[], int num, int descending)
497 {
498     int i, j;
499     AVCPictureData *temp;
500 
501     if (descending)
502     {
503         for (i = 0; i < num - 1; i++)
504         {
505             for (j = i + 1; j < num; j++)
506             {
507                 if (data[j]->PicOrderCnt > data[i]->PicOrderCnt)
508                 {
509                     temp = data[j];
510                     data[j] = data[i];
511                     data[i] = temp;
512                 }
513             }
514         }
515     }
516     else
517     {
518         for (i = 0; i < num - 1; i++)
519         {
520             for (j = i + 1; j < num; j++)
521             {
522                 if (data[j]->PicOrderCnt < data[i]->PicOrderCnt)
523                 {
524                     temp = data[j];
525                     data[j] = data[i];
526                     data[i] = temp;
527                 }
528             }
529         }
530     }
531     return ;
532 }
533 
534 /* sort PictureData by LongTermPicNum in ascending order */
SortPicByLTPicNum(AVCPictureData * data[],int num)535 void SortPicByLTPicNum(AVCPictureData *data[], int num)
536 {
537     int i, j;
538     AVCPictureData *temp;
539 
540     for (i = 0; i < num - 1; i++)
541     {
542         for (j = i + 1; j < num; j++)
543         {
544             if (data[j]->LongTermPicNum < data[i]->LongTermPicNum)
545             {
546                 temp = data[j];
547                 data[j] = data[i];
548                 data[i] = temp;
549             }
550         }
551     }
552 
553     return ;
554 }
555 
556 /* sort by PicOrderCnt, descending order */
SortFrameByPOC(AVCFrameStore * data[],int num,int descending)557 void SortFrameByPOC(AVCFrameStore *data[], int num, int descending)
558 {
559     int i, j;
560     AVCFrameStore *temp;
561 
562     if (descending)
563     {
564         for (i = 0; i < num - 1; i++)
565         {
566             for (j = i + 1; j < num; j++)
567             {
568                 if (data[j]->PicOrderCnt > data[i]->PicOrderCnt)
569                 {
570                     temp = data[j];
571                     data[j] = data[i];
572                     data[i] = temp;
573                 }
574             }
575         }
576     }
577     else
578     {
579         for (i = 0; i < num - 1; i++)
580         {
581             for (j = i + 1; j < num; j++)
582             {
583                 if (data[j]->PicOrderCnt < data[i]->PicOrderCnt)
584                 {
585                     temp = data[j];
586                     data[j] = data[i];
587                     data[i] = temp;
588                 }
589             }
590         }
591     }
592 
593     return ;
594 }
595 
596 
597