Home | History | Annotate | Download | only in src
      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. */
     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 */
    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 
    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 */
    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 */
    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 
    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 
    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 
    395 int is_short_ref(AVCPictureData *s)
    396 {
    397     return ((s->isReference) && !(s->isLongTerm));
    398 }
    399 
    400 int is_long_ref(AVCPictureData *s)
    401 {
    402     return ((s->isReference) && (s->isLongTerm));
    403 }
    404 
    405 
    406 /* sort by PicNum, descending order */
    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 */
    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 */
    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 */
    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 */
    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 */
    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 */
    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