1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
18 #include "avclib_common.h"
20 /** see subclause 8.2.4 Decoding process for reference picture lists construction. */
21 OSCL_EXPORT_REF void RefListInit(AVCCommonObj *video)
23 AVCSliceHeader *sliceHdr = video->sliceHdr;
24 AVCDecPicBuffer *dpb = video->decPicBuf;
25 int slice_type = video->slice_type;
28 AVCPictureData *tmp_s;
32 if (slice_type == AVC_I_SLICE)
34 video->refList0Size = 0;
35 video->refList1Size = 0;
37 /* we still have to calculate FrameNumWrap to make sure that all I-slice clip
38 can perform sliding_window_operation properly. */
40 for (i = 0; i < dpb->num_fs; i++)
42 if ((dpb->fs[i]->IsReference == 3) && (!dpb->fs[i]->IsLongTerm))
44 /* subclause 8.2.4.1 Decoding process for picture numbers. */
45 if (dpb->fs[i]->FrameNum > (int)sliceHdr->frame_num)
47 dpb->fs[i]->FrameNumWrap = dpb->fs[i]->FrameNum - video->MaxFrameNum;
51 dpb->fs[i]->FrameNumWrap = dpb->fs[i]->FrameNum;
53 dpb->fs[i]->frame.PicNum = dpb->fs[i]->FrameNumWrap;
60 if (slice_type == AVC_P_SLICE)
62 /* Calculate FrameNumWrap and PicNum */
64 for (i = 0; i < dpb->num_fs; i++)
66 if ((dpb->fs[i]->IsReference == 3) && (!dpb->fs[i]->IsLongTerm))
68 /* subclause 8.2.4.1 Decoding process for picture numbers. */
69 if (dpb->fs[i]->FrameNum > (int)sliceHdr->frame_num)
71 dpb->fs[i]->FrameNumWrap = dpb->fs[i]->FrameNum - video->MaxFrameNum;
75 dpb->fs[i]->FrameNumWrap = dpb->fs[i]->FrameNum;
77 dpb->fs[i]->frame.PicNum = dpb->fs[i]->FrameNumWrap;
78 video->RefPicList0[list0idx++] = &(dpb->fs[i]->frame);
84 dpb->fs[0]->IsReference = 3;
85 video->RefPicList0[0] = &(dpb->fs[0]->frame);
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;
92 /* long term handling */
93 for (i = 0; i < dpb->num_fs; i++)
95 if (dpb->fs[i]->IsLongTerm == 3)
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);
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;
108 video->refList1Size = 0;
112 if ((video->refList0Size == video->refList1Size) && (video->refList0Size > 1))
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 */
117 for (i = 0; i < video->refList0Size; i++)
119 if (video->RefPicList0[i] != video->RefPicList1[i])
124 if (i == video->refList0Size)
126 tmp_s = video->RefPicList1[0];
127 video->RefPicList1[0] = video->RefPicList1[1];
128 video->RefPicList1[1] = tmp_s;
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);
138 /* see subclause 8.2.4.3 */
139 OSCL_EXPORT_REF AVCStatus ReOrderList(AVCCommonObj *video)
141 AVCSliceHeader *sliceHdr = video->sliceHdr;
142 AVCStatus status = AVC_SUCCESS;
143 int slice_type = video->slice_type;
145 if (slice_type != AVC_I_SLICE)
147 if (sliceHdr->ref_pic_list_reordering_flag_l0)
149 status = ReorderRefPicList(video, 0);
150 if (status != AVC_SUCCESS)
153 if (video->refList0Size == 0)
161 AVCStatus ReorderRefPicList(AVCCommonObj *video, int isL1)
163 AVCSliceHeader *sliceHdr = video->sliceHdr;
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;
172 int maxPicNum, currPicNum, picNumLXNoWrap, picNumLXPred, picNumLX;
176 if (!isL1) /* list 0 */
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;
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;
197 maxPicNum = video->MaxPicNum;
198 currPicNum = video->CurrPicNum;
200 picNumLXPred = currPicNum; /* initial value */
202 for (i = 0; remapping_of_pic_nums_idc[i] != 3; i++)
204 if ((remapping_of_pic_nums_idc[i] > 3) || (i >= MAX_REF_PIC_LIST_REORDERING))
206 return AVC_FAIL; /* out of range */
208 /* see subclause 8.2.4.3.1 */
209 if (remapping_of_pic_nums_idc[i] < 2)
211 if (remapping_of_pic_nums_idc[i] == 0)
213 if (picNumLXPred - (abs_diff_pic_num_minus1[i] + 1) < 0)
214 picNumLXNoWrap = picNumLXPred - (abs_diff_pic_num_minus1[i] + 1) + maxPicNum;
216 picNumLXNoWrap = picNumLXPred - (abs_diff_pic_num_minus1[i] + 1);
218 else /* (remapping_of_pic_nums_idc[i] == 1) */
220 if (picNumLXPred + (abs_diff_pic_num_minus1[i] + 1) >= maxPicNum)
221 picNumLXNoWrap = picNumLXPred + (abs_diff_pic_num_minus1[i] + 1) - maxPicNum;
223 picNumLXNoWrap = picNumLXPred + (abs_diff_pic_num_minus1[i] + 1);
225 picNumLXPred = picNumLXNoWrap; /* prediction for the next one */
227 if (picNumLXNoWrap > currPicNum)
228 picNumLX = picNumLXNoWrap - maxPicNum;
230 picNumLX = picNumLXNoWrap;
232 status = ReorderShortTerm(video, picNumLX, &refIdxLX, isL1);
233 if (status != AVC_SUCCESS)
238 else /* (remapping_of_pic_nums_idc[i] == 2), subclause 8.2.4.3.2 */
240 status = ReorderLongTerm(video, long_term_pic_idx[i], &refIdxLX, isL1);
241 if (status != AVC_SUCCESS)
247 /* that's a definition */
248 *list_size = num_ref_idx_lX_active_minus1 + 1;
253 /* see subclause 8.2.4.3.1 */
254 AVCStatus ReorderShortTerm(AVCCommonObj *video, int picNumLX, int *refIdxLX, int isL1)
257 int num_ref_idx_lX_active_minus1;
258 AVCPictureData *picLX, **RefPicListX;
260 if (!isL1) /* list 0 */
262 RefPicListX = video->RefPicList0;
263 num_ref_idx_lX_active_minus1 = video->sliceHdr->num_ref_idx_l0_active_minus1;
267 RefPicListX = video->RefPicList1;
268 num_ref_idx_lX_active_minus1 = video->sliceHdr->num_ref_idx_l1_active_minus1;
271 picLX = GetShortTermPic(video, picNumLX);
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)
284 for (cIdx = num_ref_idx_lX_active_minus1 + 1; cIdx > *refIdxLX; cIdx--)
286 RefPicListX[ cIdx ] = RefPicListX[ cIdx - 1];
289 RefPicListX[(*refIdxLX)++ ] = picLX;
293 for (cIdx = *refIdxLX; cIdx <= num_ref_idx_lX_active_minus1 + 1; cIdx++)
295 if (RefPicListX[ cIdx ])
297 if ((RefPicListX[ cIdx ]->isLongTerm) || ((int)RefPicListX[ cIdx ]->PicNum != picNumLX))
299 RefPicListX[ nIdx++ ] = RefPicListX[ cIdx ];
306 /* see subclause 8.2.4.3.2 */
307 AVCStatus ReorderLongTerm(AVCCommonObj *video, int LongTermPicNum, int *refIdxLX, int isL1)
309 AVCPictureData **RefPicListX;
310 int num_ref_idx_lX_active_minus1;
312 AVCPictureData *picLX;
314 if (!isL1) /* list 0 */
316 RefPicListX = video->RefPicList0;
317 num_ref_idx_lX_active_minus1 = video->sliceHdr->num_ref_idx_l0_active_minus1;
321 RefPicListX = video->RefPicList1;
322 num_ref_idx_lX_active_minus1 = video->sliceHdr->num_ref_idx_l1_active_minus1;
325 picLX = GetLongTermPic(video, LongTermPicNum);
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)
336 for (cIdx = num_ref_idx_lX_active_minus1 + 1; cIdx > *refIdxLX; cIdx--)
337 RefPicListX[ cIdx ] = RefPicListX[ cIdx - 1];
339 RefPicListX[(*refIdxLX)++ ] = picLX;
343 for (cIdx = *refIdxLX; cIdx <= num_ref_idx_lX_active_minus1 + 1; cIdx++)
345 if ((!RefPicListX[ cIdx ]->isLongTerm) || ((int)RefPicListX[ cIdx ]->LongTermPicNum != LongTermPicNum))
347 RefPicListX[ nIdx++ ] = RefPicListX[ cIdx ];
354 AVCPictureData* GetShortTermPic(AVCCommonObj *video, int picNum)
357 AVCDecPicBuffer *dpb = video->decPicBuf;
359 for (i = 0; i < dpb->num_fs; i++)
362 if (dpb->fs[i]->IsReference == 3)
364 if ((dpb->fs[i]->frame.isLongTerm == FALSE) && (dpb->fs[i]->frame.PicNum == picNum))
366 return &(dpb->fs[i]->frame);
375 AVCPictureData* GetLongTermPic(AVCCommonObj *video, int LongtermPicNum)
377 AVCDecPicBuffer *dpb = video->decPicBuf;
380 for (i = 0; i < dpb->num_fs; i++)
383 if (dpb->fs[i]->IsReference == 3)
385 if ((dpb->fs[i]->frame.isLongTerm == TRUE) && (dpb->fs[i]->frame.LongTermPicNum == LongtermPicNum))
387 return &(dpb->fs[i]->frame);
395 int is_short_ref(AVCPictureData *s)
397 return ((s->isReference) && !(s->isLongTerm));
400 int is_long_ref(AVCPictureData *s)
402 return ((s->isReference) && (s->isLongTerm));
406 /* sort by PicNum, descending order */
407 void SortPicByPicNum(AVCPictureData *data[], int num)
410 AVCPictureData *temp;
412 for (i = 0; i < num - 1; i++)
414 for (j = i + 1; j < num; j++)
416 if (data[j]->PicNum > data[i]->PicNum)
428 /* sort by PicNum, ascending order */
429 void SortPicByPicNumLongTerm(AVCPictureData *data[], int num)
432 AVCPictureData *temp;
434 for (i = 0; i < num - 1; i++)
436 for (j = i + 1; j < num; j++)
438 if (data[j]->LongTermPicNum < data[i]->LongTermPicNum)
451 /* sort by FrameNumWrap, descending order */
452 void SortFrameByFrameNumWrap(AVCFrameStore *data[], int num)
457 for (i = 0; i < num - 1; i++)
459 for (j = i + 1; j < num; j++)
461 if (data[j]->FrameNumWrap > data[i]->FrameNumWrap)
473 /* sort frames by LongTermFrameIdx, ascending order */
474 void SortFrameByLTFrameIdx(AVCFrameStore *data[], int num)
479 for (i = 0; i < num - 1; i++)
481 for (j = i + 1; j < num; j++)
483 if (data[j]->LongTermFrameIdx < data[i]->LongTermFrameIdx)
495 /* sort PictureData by POC in descending order */
496 void SortPicByPOC(AVCPictureData *data[], int num, int descending)
499 AVCPictureData *temp;
503 for (i = 0; i < num - 1; i++)
505 for (j = i + 1; j < num; j++)
507 if (data[j]->PicOrderCnt > data[i]->PicOrderCnt)
518 for (i = 0; i < num - 1; i++)
520 for (j = i + 1; j < num; j++)
522 if (data[j]->PicOrderCnt < data[i]->PicOrderCnt)
534 /* sort PictureData by LongTermPicNum in ascending order */
535 void SortPicByLTPicNum(AVCPictureData *data[], int num)
538 AVCPictureData *temp;
540 for (i = 0; i < num - 1; i++)
542 for (j = i + 1; j < num; j++)
544 if (data[j]->LongTermPicNum < data[i]->LongTermPicNum)
556 /* sort by PicOrderCnt, descending order */
557 void SortFrameByPOC(AVCFrameStore *data[], int num, int descending)
564 for (i = 0; i < num - 1; i++)
566 for (j = i + 1; j < num; j++)
568 if (data[j]->PicOrderCnt > data[i]->PicOrderCnt)
579 for (i = 0; i < num - 1; i++)
581 for (j = i + 1; j < num; j++)
583 if (data[j]->PicOrderCnt < data[i]->PicOrderCnt)