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