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