/Show/avc/reflist.cpp
C++ | 596 lines | 471 code | 79 blank | 46 comment | 115 complexity | b2ef779b5d544860589a3ab6a577f487 MD5 | raw file
Possible License(s): BSD-3-Clause
- /* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- * -------------------------------------------------------------------
- */
- #include "avclib_common.h"
- /** see subclause 8.2.4 Decoding process for reference picture lists construction. */
- OSCL_EXPORT_REF void RefListInit(AVCCommonObj *video)
- {
- AVCSliceHeader *sliceHdr = video->sliceHdr;
- AVCDecPicBuffer *dpb = video->decPicBuf;
- int slice_type = video->slice_type;
- int i, list0idx;
- AVCPictureData *tmp_s;
- list0idx = 0;
- if (slice_type == AVC_I_SLICE)
- {
- video->refList0Size = 0;
- video->refList1Size = 0;
- /* we still have to calculate FrameNumWrap to make sure that all I-slice clip
- can perform sliding_window_operation properly. */
- for (i = 0; i < dpb->num_fs; i++)
- {
- if ((dpb->fs[i]->IsReference == 3) && (!dpb->fs[i]->IsLongTerm))
- {
- /* subclause 8.2.4.1 Decoding process for picture numbers. */
- if (dpb->fs[i]->FrameNum > (int)sliceHdr->frame_num)
- {
- dpb->fs[i]->FrameNumWrap = dpb->fs[i]->FrameNum - video->MaxFrameNum;
- }
- else
- {
- dpb->fs[i]->FrameNumWrap = dpb->fs[i]->FrameNum;
- }
- dpb->fs[i]->frame.PicNum = dpb->fs[i]->FrameNumWrap;
- }
- }
- return ;
- }
- if (slice_type == AVC_P_SLICE)
- {
- /* Calculate FrameNumWrap and PicNum */
- for (i = 0; i < dpb->num_fs; i++)
- {
- if ((dpb->fs[i]->IsReference == 3) && (!dpb->fs[i]->IsLongTerm))
- {
- /* subclause 8.2.4.1 Decoding process for picture numbers. */
- if (dpb->fs[i]->FrameNum > (int)sliceHdr->frame_num)
- {
- dpb->fs[i]->FrameNumWrap = dpb->fs[i]->FrameNum - video->MaxFrameNum;
- }
- else
- {
- dpb->fs[i]->FrameNumWrap = dpb->fs[i]->FrameNum;
- }
- dpb->fs[i]->frame.PicNum = dpb->fs[i]->FrameNumWrap;
- video->RefPicList0[list0idx++] = &(dpb->fs[i]->frame);
- }
- }
- if (list0idx == 0)
- {
- dpb->fs[0]->IsReference = 3;
- video->RefPicList0[0] = &(dpb->fs[0]->frame);
- list0idx = 1;
- }
- /* order list 0 by PicNum from max to min, see subclause 8.2.4.2.1 */
- SortPicByPicNum(video->RefPicList0, list0idx);
- video->refList0Size = list0idx;
- /* long term handling */
- for (i = 0; i < dpb->num_fs; i++)
- {
- if (dpb->fs[i]->IsLongTerm == 3)
- {
- /* subclause 8.2.4.1 Decoding process for picture numbers. */
- dpb->fs[i]->frame.LongTermPicNum = dpb->fs[i]->LongTermFrameIdx;
- video->RefPicList0[list0idx++] = &(dpb->fs[i]->frame);
- }
- }
- /* order PicNum from min to max, see subclause 8.2.4.2.1 */
- SortPicByPicNumLongTerm(&(video->RefPicList0[video->refList0Size]), list0idx - video->refList0Size);
- video->refList0Size = list0idx;
- video->refList1Size = 0;
- }
- if ((video->refList0Size == video->refList1Size) && (video->refList0Size > 1))
- {
- /* check if lists are identical, if yes swap first two elements of listX[1] */
- /* last paragraph of subclause 8.2.4.2.4 */
- for (i = 0; i < video->refList0Size; i++)
- {
- if (video->RefPicList0[i] != video->RefPicList1[i])
- {
- break;
- }
- }
- if (i == video->refList0Size)
- {
- tmp_s = video->RefPicList1[0];
- video->RefPicList1[0] = video->RefPicList1[1];
- video->RefPicList1[1] = tmp_s;
- }
- }
- /* set max size */
- video->refList0Size = AVC_MIN(video->refList0Size, (int)video->sliceHdr->num_ref_idx_l0_active_minus1 + 1);
- video->refList1Size = AVC_MIN(video->refList1Size, (int)video->sliceHdr->num_ref_idx_l1_active_minus1 + 1);
- return ;
- }
- /* see subclause 8.2.4.3 */
- OSCL_EXPORT_REF AVCStatus ReOrderList(AVCCommonObj *video)
- {
- AVCSliceHeader *sliceHdr = video->sliceHdr;
- AVCStatus status = AVC_SUCCESS;
- int slice_type = video->slice_type;
- if (slice_type != AVC_I_SLICE)
- {
- if (sliceHdr->ref_pic_list_reordering_flag_l0)
- {
- status = ReorderRefPicList(video, 0);
- if (status != AVC_SUCCESS)
- return status;
- }
- if (video->refList0Size == 0)
- {
- return AVC_FAIL;
- }
- }
- return status;
- }
- AVCStatus ReorderRefPicList(AVCCommonObj *video, int isL1)
- {
- AVCSliceHeader *sliceHdr = video->sliceHdr;
- AVCStatus status;
- int *list_size;
- int num_ref_idx_lX_active_minus1;
- uint *remapping_of_pic_nums_idc;
- int *abs_diff_pic_num_minus1;
- int *long_term_pic_idx;
- int i;
- int maxPicNum, currPicNum, picNumLXNoWrap, picNumLXPred, picNumLX;
- int refIdxLX = 0;
- void* tmp;
- if (!isL1) /* list 0 */
- {
- list_size = &(video->refList0Size);
- num_ref_idx_lX_active_minus1 = sliceHdr->num_ref_idx_l0_active_minus1;
- remapping_of_pic_nums_idc = sliceHdr->reordering_of_pic_nums_idc_l0;
- tmp = (void*)sliceHdr->abs_diff_pic_num_minus1_l0;
- abs_diff_pic_num_minus1 = (int*) tmp;
- tmp = (void*)sliceHdr->long_term_pic_num_l0;
- long_term_pic_idx = (int*) tmp;
- }
- else
- {
- list_size = &(video->refList1Size);
- num_ref_idx_lX_active_minus1 = sliceHdr->num_ref_idx_l1_active_minus1;
- remapping_of_pic_nums_idc = sliceHdr->reordering_of_pic_nums_idc_l1;
- tmp = (void*) sliceHdr->abs_diff_pic_num_minus1_l1;
- abs_diff_pic_num_minus1 = (int*) tmp;
- tmp = (void*) sliceHdr->long_term_pic_num_l1;
- long_term_pic_idx = (int*)tmp;
- }
- maxPicNum = video->MaxPicNum;
- currPicNum = video->CurrPicNum;
- picNumLXPred = currPicNum; /* initial value */
- for (i = 0; remapping_of_pic_nums_idc[i] != 3; i++)
- {
- if ((remapping_of_pic_nums_idc[i] > 3) || (i >= MAX_REF_PIC_LIST_REORDERING))
- {
- return AVC_FAIL; /* out of range */
- }
- /* see subclause 8.2.4.3.1 */
- if (remapping_of_pic_nums_idc[i] < 2)
- {
- if (remapping_of_pic_nums_idc[i] == 0)
- {
- if (picNumLXPred - (abs_diff_pic_num_minus1[i] + 1) < 0)
- picNumLXNoWrap = picNumLXPred - (abs_diff_pic_num_minus1[i] + 1) + maxPicNum;
- else
- picNumLXNoWrap = picNumLXPred - (abs_diff_pic_num_minus1[i] + 1);
- }
- else /* (remapping_of_pic_nums_idc[i] == 1) */
- {
- if (picNumLXPred + (abs_diff_pic_num_minus1[i] + 1) >= maxPicNum)
- picNumLXNoWrap = picNumLXPred + (abs_diff_pic_num_minus1[i] + 1) - maxPicNum;
- else
- picNumLXNoWrap = picNumLXPred + (abs_diff_pic_num_minus1[i] + 1);
- }
- picNumLXPred = picNumLXNoWrap; /* prediction for the next one */
- if (picNumLXNoWrap > currPicNum)
- picNumLX = picNumLXNoWrap - maxPicNum;
- else
- picNumLX = picNumLXNoWrap;
- status = ReorderShortTerm(video, picNumLX, &refIdxLX, isL1);
- if (status != AVC_SUCCESS)
- {
- return status;
- }
- }
- else /* (remapping_of_pic_nums_idc[i] == 2), subclause 8.2.4.3.2 */
- {
- status = ReorderLongTerm(video, long_term_pic_idx[i], &refIdxLX, isL1);
- if (status != AVC_SUCCESS)
- {
- return status;
- }
- }
- }
- /* that's a definition */
- *list_size = num_ref_idx_lX_active_minus1 + 1;
- return AVC_SUCCESS;
- }
- /* see subclause 8.2.4.3.1 */
- AVCStatus ReorderShortTerm(AVCCommonObj *video, int picNumLX, int *refIdxLX, int isL1)
- {
- int cIdx, nIdx;
- int num_ref_idx_lX_active_minus1;
- AVCPictureData *picLX, **RefPicListX;
- if (!isL1) /* list 0 */
- {
- RefPicListX = video->RefPicList0;
- num_ref_idx_lX_active_minus1 = video->sliceHdr->num_ref_idx_l0_active_minus1;
- }
- else
- {
- RefPicListX = video->RefPicList1;
- num_ref_idx_lX_active_minus1 = video->sliceHdr->num_ref_idx_l1_active_minus1;
- }
- picLX = GetShortTermPic(video, picNumLX);
- if (picLX == NULL)
- {
- return AVC_FAIL;
- }
- /* Note RefPicListX has to access element number num_ref_idx_lX_active */
- /* There could be access violation here. */
- if (num_ref_idx_lX_active_minus1 + 1 >= MAX_REF_PIC_LIST)
- {
- return AVC_FAIL;
- }
- for (cIdx = num_ref_idx_lX_active_minus1 + 1; cIdx > *refIdxLX; cIdx--)
- {
- RefPicListX[ cIdx ] = RefPicListX[ cIdx - 1];
- }
- RefPicListX[(*refIdxLX)++ ] = picLX;
- nIdx = *refIdxLX;
- for (cIdx = *refIdxLX; cIdx <= num_ref_idx_lX_active_minus1 + 1; cIdx++)
- {
- if (RefPicListX[ cIdx ])
- {
- if ((RefPicListX[ cIdx ]->isLongTerm) || ((int)RefPicListX[ cIdx ]->PicNum != picNumLX))
- {
- RefPicListX[ nIdx++ ] = RefPicListX[ cIdx ];
- }
- }
- }
- return AVC_SUCCESS;
- }
- /* see subclause 8.2.4.3.2 */
- AVCStatus ReorderLongTerm(AVCCommonObj *video, int LongTermPicNum, int *refIdxLX, int isL1)
- {
- AVCPictureData **RefPicListX;
- int num_ref_idx_lX_active_minus1;
- int cIdx, nIdx;
- AVCPictureData *picLX;
- if (!isL1) /* list 0 */
- {
- RefPicListX = video->RefPicList0;
- num_ref_idx_lX_active_minus1 = video->sliceHdr->num_ref_idx_l0_active_minus1;
- }
- else
- {
- RefPicListX = video->RefPicList1;
- num_ref_idx_lX_active_minus1 = video->sliceHdr->num_ref_idx_l1_active_minus1;
- }
- picLX = GetLongTermPic(video, LongTermPicNum);
- if (picLX == NULL)
- {
- return AVC_FAIL;
- }
- /* Note RefPicListX has to access element number num_ref_idx_lX_active */
- /* There could be access violation here. */
- if (num_ref_idx_lX_active_minus1 + 1 >= MAX_REF_PIC_LIST)
- {
- return AVC_FAIL;
- }
- for (cIdx = num_ref_idx_lX_active_minus1 + 1; cIdx > *refIdxLX; cIdx--)
- RefPicListX[ cIdx ] = RefPicListX[ cIdx - 1];
- RefPicListX[(*refIdxLX)++ ] = picLX;
- nIdx = *refIdxLX;
- for (cIdx = *refIdxLX; cIdx <= num_ref_idx_lX_active_minus1 + 1; cIdx++)
- {
- if ((!RefPicListX[ cIdx ]->isLongTerm) || ((int)RefPicListX[ cIdx ]->LongTermPicNum != LongTermPicNum))
- {
- RefPicListX[ nIdx++ ] = RefPicListX[ cIdx ];
- }
- }
- return AVC_SUCCESS;
- }
- AVCPictureData* GetShortTermPic(AVCCommonObj *video, int picNum)
- {
- int i;
- AVCDecPicBuffer *dpb = video->decPicBuf;
- for (i = 0; i < dpb->num_fs; i++)
- {
- if (dpb->fs[i]->IsReference == 3)
- {
- if ((dpb->fs[i]->frame.isLongTerm == FALSE) && (dpb->fs[i]->frame.PicNum == picNum))
- {
- return &(dpb->fs[i]->frame);
- }
- }
- }
- return NULL;
- }
- AVCPictureData* GetLongTermPic(AVCCommonObj *video, int LongtermPicNum)
- {
- AVCDecPicBuffer *dpb = video->decPicBuf;
- int i;
- for (i = 0; i < dpb->num_fs; i++)
- {
- if (dpb->fs[i]->IsReference == 3)
- {
- if ((dpb->fs[i]->frame.isLongTerm == TRUE) && (dpb->fs[i]->frame.LongTermPicNum == LongtermPicNum))
- {
- return &(dpb->fs[i]->frame);
- }
- }
- }
- return NULL;
- }
- int is_short_ref(AVCPictureData *s)
- {
- return ((s->isReference) && !(s->isLongTerm));
- }
- int is_long_ref(AVCPictureData *s)
- {
- return ((s->isReference) && (s->isLongTerm));
- }
- /* sort by PicNum, descending order */
- void SortPicByPicNum(AVCPictureData *data[], int num)
- {
- int i, j;
- AVCPictureData *temp;
- for (i = 0; i < num - 1; i++)
- {
- for (j = i + 1; j < num; j++)
- {
- if (data[j]->PicNum > data[i]->PicNum)
- {
- temp = data[j];
- data[j] = data[i];
- data[i] = temp;
- }
- }
- }
- return ;
- }
- /* sort by PicNum, ascending order */
- void SortPicByPicNumLongTerm(AVCPictureData *data[], int num)
- {
- int i, j;
- AVCPictureData *temp;
- for (i = 0; i < num - 1; i++)
- {
- for (j = i + 1; j < num; j++)
- {
- if (data[j]->LongTermPicNum < data[i]->LongTermPicNum)
- {
- temp = data[j];
- data[j] = data[i];
- data[i] = temp;
- }
- }
- }
- return ;
- }
- /* sort by FrameNumWrap, descending order */
- void SortFrameByFrameNumWrap(AVCFrameStore *data[], int num)
- {
- int i, j;
- AVCFrameStore *temp;
- for (i = 0; i < num - 1; i++)
- {
- for (j = i + 1; j < num; j++)
- {
- if (data[j]->FrameNumWrap > data[i]->FrameNumWrap)
- {
- temp = data[j];
- data[j] = data[i];
- data[i] = temp;
- }
- }
- }
- return ;
- }
- /* sort frames by LongTermFrameIdx, ascending order */
- void SortFrameByLTFrameIdx(AVCFrameStore *data[], int num)
- {
- int i, j;
- AVCFrameStore *temp;
- for (i = 0; i < num - 1; i++)
- {
- for (j = i + 1; j < num; j++)
- {
- if (data[j]->LongTermFrameIdx < data[i]->LongTermFrameIdx)
- {
- temp = data[j];
- data[j] = data[i];
- data[i] = temp;
- }
- }
- }
- return ;
- }
- /* sort PictureData by POC in descending order */
- void SortPicByPOC(AVCPictureData *data[], int num, int descending)
- {
- int i, j;
- AVCPictureData *temp;
- if (descending)
- {
- for (i = 0; i < num - 1; i++)
- {
- for (j = i + 1; j < num; j++)
- {
- if (data[j]->PicOrderCnt > data[i]->PicOrderCnt)
- {
- temp = data[j];
- data[j] = data[i];
- data[i] = temp;
- }
- }
- }
- }
- else
- {
- for (i = 0; i < num - 1; i++)
- {
- for (j = i + 1; j < num; j++)
- {
- if (data[j]->PicOrderCnt < data[i]->PicOrderCnt)
- {
- temp = data[j];
- data[j] = data[i];
- data[i] = temp;
- }
- }
- }
- }
- return ;
- }
- /* sort PictureData by LongTermPicNum in ascending order */
- void SortPicByLTPicNum(AVCPictureData *data[], int num)
- {
- int i, j;
- AVCPictureData *temp;
- for (i = 0; i < num - 1; i++)
- {
- for (j = i + 1; j < num; j++)
- {
- if (data[j]->LongTermPicNum < data[i]->LongTermPicNum)
- {
- temp = data[j];
- data[j] = data[i];
- data[i] = temp;
- }
- }
- }
- return ;
- }
- /* sort by PicOrderCnt, descending order */
- void SortFrameByPOC(AVCFrameStore *data[], int num, int descending)
- {
- int i, j;
- AVCFrameStore *temp;
- if (descending)
- {
- for (i = 0; i < num - 1; i++)
- {
- for (j = i + 1; j < num; j++)
- {
- if (data[j]->PicOrderCnt > data[i]->PicOrderCnt)
- {
- temp = data[j];
- data[j] = data[i];
- data[i] = temp;
- }
- }
- }
- }
- else
- {
- for (i = 0; i < num - 1; i++)
- {
- for (j = i + 1; j < num; j++)
- {
- if (data[j]->PicOrderCnt < data[i]->PicOrderCnt)
- {
- temp = data[j];
- data[j] = data[i];
- data[i] = temp;
- }
- }
- }
- }
- return ;
- }