Mercurial > libavcodec.hg
annotate h264_refs.c @ 12501:b3f9612d4ea7 libavcodec
Remove pointless semicolon
| author | vitor |
|---|---|
| date | Fri, 17 Sep 2010 19:33:56 +0000 |
| parents | f7bedc1ce1bc |
| children |
| rev | line source |
|---|---|
| 10862 | 1 /* |
| 2 * H.26L/H.264/AVC/JVT/14496-10/... reference picture handling | |
| 3 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> | |
| 4 * | |
| 5 * This file is part of FFmpeg. | |
| 6 * | |
| 7 * FFmpeg is free software; you can redistribute it and/or | |
| 8 * modify it under the terms of the GNU Lesser General Public | |
| 9 * License as published by the Free Software Foundation; either | |
| 10 * version 2.1 of the License, or (at your option) any later version. | |
| 11 * | |
| 12 * FFmpeg is distributed in the hope that it will be useful, | |
| 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 15 * Lesser General Public License for more details. | |
| 16 * | |
| 17 * You should have received a copy of the GNU Lesser General Public | |
| 18 * License along with FFmpeg; if not, write to the Free Software | |
| 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 20 */ | |
| 21 | |
| 22 /** | |
|
11644
7dd2a45249a9
Remove explicit filename from Doxygen @file commands.
diego
parents:
11558
diff
changeset
|
23 * @file |
| 10862 | 24 * H.264 / AVC / MPEG4 part10 reference picture handling. |
| 25 * @author Michael Niedermayer <michaelni@gmx.at> | |
| 26 */ | |
| 27 | |
| 28 #include "internal.h" | |
| 29 #include "dsputil.h" | |
| 30 #include "avcodec.h" | |
| 31 #include "h264.h" | |
| 32 #include "golomb.h" | |
| 33 | |
| 34 //#undef NDEBUG | |
| 35 #include <assert.h> | |
| 36 | |
| 37 | |
| 38 static void pic_as_field(Picture *pic, const int parity){ | |
| 39 int i; | |
| 40 for (i = 0; i < 4; ++i) { | |
| 41 if (parity == PICT_BOTTOM_FIELD) | |
| 42 pic->data[i] += pic->linesize[i]; | |
| 43 pic->reference = parity; | |
| 44 pic->linesize[i] *= 2; | |
| 45 } | |
| 46 pic->poc= pic->field_poc[parity == PICT_BOTTOM_FIELD]; | |
| 47 } | |
| 48 | |
| 49 static int split_field_copy(Picture *dest, Picture *src, | |
| 50 int parity, int id_add){ | |
| 51 int match = !!(src->reference & parity); | |
| 52 | |
| 53 if (match) { | |
| 54 *dest = *src; | |
| 55 if(parity != PICT_FRAME){ | |
| 56 pic_as_field(dest, parity); | |
| 57 dest->pic_id *= 2; | |
| 58 dest->pic_id += id_add; | |
| 59 } | |
| 60 } | |
| 61 | |
| 62 return match; | |
| 63 } | |
| 64 | |
| 65 static int build_def_list(Picture *def, Picture **in, int len, int is_long, int sel){ | |
| 66 int i[2]={0}; | |
| 67 int index=0; | |
| 68 | |
| 69 while(i[0]<len || i[1]<len){ | |
| 70 while(i[0]<len && !(in[ i[0] ] && (in[ i[0] ]->reference & sel))) | |
| 71 i[0]++; | |
| 72 while(i[1]<len && !(in[ i[1] ] && (in[ i[1] ]->reference & (sel^3)))) | |
| 73 i[1]++; | |
| 74 if(i[0] < len){ | |
| 75 in[ i[0] ]->pic_id= is_long ? i[0] : in[ i[0] ]->frame_num; | |
| 76 split_field_copy(&def[index++], in[ i[0]++ ], sel , 1); | |
| 77 } | |
| 78 if(i[1] < len){ | |
| 79 in[ i[1] ]->pic_id= is_long ? i[1] : in[ i[1] ]->frame_num; | |
| 80 split_field_copy(&def[index++], in[ i[1]++ ], sel^3, 0); | |
| 81 } | |
| 82 } | |
| 83 | |
| 84 return index; | |
| 85 } | |
| 86 | |
| 87 static int add_sorted(Picture **sorted, Picture **src, int len, int limit, int dir){ | |
| 88 int i, best_poc; | |
| 89 int out_i= 0; | |
| 90 | |
| 91 for(;;){ | |
| 92 best_poc= dir ? INT_MIN : INT_MAX; | |
| 93 | |
| 94 for(i=0; i<len; i++){ | |
| 95 const int poc= src[i]->poc; | |
| 96 if(((poc > limit) ^ dir) && ((poc < best_poc) ^ dir)){ | |
| 97 best_poc= poc; | |
| 98 sorted[out_i]= src[i]; | |
| 99 } | |
| 100 } | |
| 101 if(best_poc == (dir ? INT_MIN : INT_MAX)) | |
| 102 break; | |
| 103 limit= sorted[out_i++]->poc - dir; | |
| 104 } | |
| 105 return out_i; | |
| 106 } | |
| 107 | |
| 108 int ff_h264_fill_default_ref_list(H264Context *h){ | |
| 109 MpegEncContext * const s = &h->s; | |
| 110 int i, len; | |
| 111 | |
| 112 if(h->slice_type_nos==FF_B_TYPE){ | |
| 113 Picture *sorted[32]; | |
| 114 int cur_poc, list; | |
| 115 int lens[2]; | |
| 116 | |
| 117 if(FIELD_PICTURE) | |
| 118 cur_poc= s->current_picture_ptr->field_poc[ s->picture_structure == PICT_BOTTOM_FIELD ]; | |
| 119 else | |
| 120 cur_poc= s->current_picture_ptr->poc; | |
| 121 | |
| 122 for(list= 0; list<2; list++){ | |
| 123 len= add_sorted(sorted , h->short_ref, h->short_ref_count, cur_poc, 1^list); | |
| 124 len+=add_sorted(sorted+len, h->short_ref, h->short_ref_count, cur_poc, 0^list); | |
| 125 assert(len<=32); | |
| 126 len= build_def_list(h->default_ref_list[list] , sorted , len, 0, s->picture_structure); | |
| 127 len+=build_def_list(h->default_ref_list[list]+len, h->long_ref, 16 , 1, s->picture_structure); | |
| 128 assert(len<=32); | |
| 129 | |
| 130 if(len < h->ref_count[list]) | |
| 131 memset(&h->default_ref_list[list][len], 0, sizeof(Picture)*(h->ref_count[list] - len)); | |
| 132 lens[list]= len; | |
| 133 } | |
| 134 | |
| 135 if(lens[0] == lens[1] && lens[1] > 1){ | |
| 136 for(i=0; h->default_ref_list[0][i].data[0] == h->default_ref_list[1][i].data[0] && i<lens[0]; i++); | |
| 137 if(i == lens[0]) | |
| 138 FFSWAP(Picture, h->default_ref_list[1][0], h->default_ref_list[1][1]); | |
| 139 } | |
| 140 }else{ | |
| 141 len = build_def_list(h->default_ref_list[0] , h->short_ref, h->short_ref_count, 0, s->picture_structure); | |
| 142 len+= build_def_list(h->default_ref_list[0]+len, h-> long_ref, 16 , 1, s->picture_structure); | |
| 143 assert(len <= 32); | |
| 144 if(len < h->ref_count[0]) | |
| 145 memset(&h->default_ref_list[0][len], 0, sizeof(Picture)*(h->ref_count[0] - len)); | |
| 146 } | |
| 147 #ifdef TRACE | |
| 148 for (i=0; i<h->ref_count[0]; i++) { | |
| 149 tprintf(h->s.avctx, "List0: %s fn:%d 0x%p\n", (h->default_ref_list[0][i].long_ref ? "LT" : "ST"), h->default_ref_list[0][i].pic_id, h->default_ref_list[0][i].data[0]); | |
| 150 } | |
| 151 if(h->slice_type_nos==FF_B_TYPE){ | |
| 152 for (i=0; i<h->ref_count[1]; i++) { | |
| 153 tprintf(h->s.avctx, "List1: %s fn:%d 0x%p\n", (h->default_ref_list[1][i].long_ref ? "LT" : "ST"), h->default_ref_list[1][i].pic_id, h->default_ref_list[1][i].data[0]); | |
| 154 } | |
| 155 } | |
| 156 #endif | |
| 157 return 0; | |
| 158 } | |
| 159 | |
| 160 static void print_short_term(H264Context *h); | |
| 161 static void print_long_term(H264Context *h); | |
| 162 | |
| 163 /** | |
| 164 * Extract structure information about the picture described by pic_num in | |
| 165 * the current decoding context (frame or field). Note that pic_num is | |
| 166 * picture number without wrapping (so, 0<=pic_num<max_pic_num). | |
| 167 * @param pic_num picture number for which to extract structure information | |
| 168 * @param structure one of PICT_XXX describing structure of picture | |
| 169 * with pic_num | |
| 170 * @return frame number (short term) or long term index of picture | |
| 171 * described by pic_num | |
| 172 */ | |
| 173 static int pic_num_extract(H264Context *h, int pic_num, int *structure){ | |
| 174 MpegEncContext * const s = &h->s; | |
| 175 | |
| 176 *structure = s->picture_structure; | |
| 177 if(FIELD_PICTURE){ | |
| 178 if (!(pic_num & 1)) | |
| 179 /* opposite field */ | |
| 180 *structure ^= PICT_FRAME; | |
| 181 pic_num >>= 1; | |
| 182 } | |
| 183 | |
| 184 return pic_num; | |
| 185 } | |
| 186 | |
| 187 int ff_h264_decode_ref_pic_list_reordering(H264Context *h){ | |
| 188 MpegEncContext * const s = &h->s; | |
| 189 int list, index, pic_structure; | |
| 190 | |
| 191 print_short_term(h); | |
| 192 print_long_term(h); | |
| 193 | |
| 194 for(list=0; list<h->list_count; list++){ | |
| 195 memcpy(h->ref_list[list], h->default_ref_list[list], sizeof(Picture)*h->ref_count[list]); | |
| 196 | |
| 197 if(get_bits1(&s->gb)){ | |
| 198 int pred= h->curr_pic_num; | |
| 199 | |
| 200 for(index=0; ; index++){ | |
| 201 unsigned int reordering_of_pic_nums_idc= get_ue_golomb_31(&s->gb); | |
| 202 unsigned int pic_id; | |
| 203 int i; | |
| 204 Picture *ref = NULL; | |
| 205 | |
| 206 if(reordering_of_pic_nums_idc==3) | |
| 207 break; | |
| 208 | |
| 209 if(index >= h->ref_count[list]){ | |
| 210 av_log(h->s.avctx, AV_LOG_ERROR, "reference count overflow\n"); | |
| 211 return -1; | |
| 212 } | |
| 213 | |
| 214 if(reordering_of_pic_nums_idc<3){ | |
| 215 if(reordering_of_pic_nums_idc<2){ | |
| 216 const unsigned int abs_diff_pic_num= get_ue_golomb(&s->gb) + 1; | |
| 217 int frame_num; | |
| 218 | |
| 219 if(abs_diff_pic_num > h->max_pic_num){ | |
| 220 av_log(h->s.avctx, AV_LOG_ERROR, "abs_diff_pic_num overflow\n"); | |
| 221 return -1; | |
| 222 } | |
| 223 | |
| 224 if(reordering_of_pic_nums_idc == 0) pred-= abs_diff_pic_num; | |
| 225 else pred+= abs_diff_pic_num; | |
| 226 pred &= h->max_pic_num - 1; | |
| 227 | |
| 228 frame_num = pic_num_extract(h, pred, &pic_structure); | |
| 229 | |
| 230 for(i= h->short_ref_count-1; i>=0; i--){ | |
| 231 ref = h->short_ref[i]; | |
| 232 assert(ref->reference); | |
| 233 assert(!ref->long_ref); | |
| 234 if( | |
| 235 ref->frame_num == frame_num && | |
| 236 (ref->reference & pic_structure) | |
| 237 ) | |
| 238 break; | |
| 239 } | |
| 240 if(i>=0) | |
| 241 ref->pic_id= pred; | |
| 242 }else{ | |
| 243 int long_idx; | |
| 244 pic_id= get_ue_golomb(&s->gb); //long_term_pic_idx | |
| 245 | |
| 246 long_idx= pic_num_extract(h, pic_id, &pic_structure); | |
| 247 | |
| 248 if(long_idx>31){ | |
| 249 av_log(h->s.avctx, AV_LOG_ERROR, "long_term_pic_idx overflow\n"); | |
| 250 return -1; | |
| 251 } | |
| 252 ref = h->long_ref[long_idx]; | |
| 253 assert(!(ref && !ref->reference)); | |
| 254 if(ref && (ref->reference & pic_structure)){ | |
| 255 ref->pic_id= pic_id; | |
| 256 assert(ref->long_ref); | |
| 257 i=0; | |
| 258 }else{ | |
| 259 i=-1; | |
| 260 } | |
| 261 } | |
| 262 | |
| 263 if (i < 0) { | |
| 264 av_log(h->s.avctx, AV_LOG_ERROR, "reference picture missing during reorder\n"); | |
| 265 memset(&h->ref_list[list][index], 0, sizeof(Picture)); //FIXME | |
| 266 } else { | |
| 267 for(i=index; i+1<h->ref_count[list]; i++){ | |
| 268 if(ref->long_ref == h->ref_list[list][i].long_ref && ref->pic_id == h->ref_list[list][i].pic_id) | |
| 269 break; | |
| 270 } | |
| 271 for(; i > index; i--){ | |
| 272 h->ref_list[list][i]= h->ref_list[list][i-1]; | |
| 273 } | |
| 274 h->ref_list[list][index]= *ref; | |
| 275 if (FIELD_PICTURE){ | |
| 276 pic_as_field(&h->ref_list[list][index], pic_structure); | |
| 277 } | |
| 278 } | |
| 279 }else{ | |
| 280 av_log(h->s.avctx, AV_LOG_ERROR, "illegal reordering_of_pic_nums_idc\n"); | |
| 281 return -1; | |
| 282 } | |
| 283 } | |
| 284 } | |
| 285 } | |
| 286 for(list=0; list<h->list_count; list++){ | |
| 287 for(index= 0; index < h->ref_count[list]; index++){ | |
| 288 if(!h->ref_list[list][index].data[0]){ | |
| 289 av_log(h->s.avctx, AV_LOG_ERROR, "Missing reference picture\n"); | |
| 290 if(h->default_ref_list[list][0].data[0]) | |
| 291 h->ref_list[list][index]= h->default_ref_list[list][0]; | |
| 292 else | |
| 293 return -1; | |
| 294 } | |
| 295 } | |
| 296 } | |
| 297 | |
| 298 return 0; | |
| 299 } | |
| 300 | |
| 301 void ff_h264_fill_mbaff_ref_list(H264Context *h){ | |
| 302 int list, i, j; | |
| 303 for(list=0; list<2; list++){ //FIXME try list_count | |
| 304 for(i=0; i<h->ref_count[list]; i++){ | |
| 305 Picture *frame = &h->ref_list[list][i]; | |
| 306 Picture *field = &h->ref_list[list][16+2*i]; | |
| 307 field[0] = *frame; | |
| 308 for(j=0; j<3; j++) | |
| 309 field[0].linesize[j] <<= 1; | |
| 310 field[0].reference = PICT_TOP_FIELD; | |
| 311 field[0].poc= field[0].field_poc[0]; | |
| 312 field[1] = field[0]; | |
| 313 for(j=0; j<3; j++) | |
| 314 field[1].data[j] += frame->linesize[j]; | |
| 315 field[1].reference = PICT_BOTTOM_FIELD; | |
| 316 field[1].poc= field[1].field_poc[1]; | |
| 317 | |
| 11349 | 318 h->luma_weight[16+2*i][list][0] = h->luma_weight[16+2*i+1][list][0] = h->luma_weight[i][list][0]; |
| 319 h->luma_weight[16+2*i][list][1] = h->luma_weight[16+2*i+1][list][1] = h->luma_weight[i][list][1]; | |
| 10862 | 320 for(j=0; j<2; j++){ |
| 11349 | 321 h->chroma_weight[16+2*i][list][j][0] = h->chroma_weight[16+2*i+1][list][j][0] = h->chroma_weight[i][list][j][0]; |
| 322 h->chroma_weight[16+2*i][list][j][1] = h->chroma_weight[16+2*i+1][list][j][1] = h->chroma_weight[i][list][j][1]; | |
| 10862 | 323 } |
| 324 } | |
| 325 } | |
| 326 } | |
| 327 | |
| 328 /** | |
| 329 * Mark a picture as no longer needed for reference. The refmask | |
| 330 * argument allows unreferencing of individual fields or the whole frame. | |
| 331 * If the picture becomes entirely unreferenced, but is being held for | |
| 332 * display purposes, it is marked as such. | |
| 333 * @param refmask mask of fields to unreference; the mask is bitwise | |
| 334 * anded with the reference marking of pic | |
| 335 * @return non-zero if pic becomes entirely unreferenced (except possibly | |
| 336 * for display purposes) zero if one of the fields remains in | |
| 337 * reference | |
| 338 */ | |
| 339 static inline int unreference_pic(H264Context *h, Picture *pic, int refmask){ | |
| 340 int i; | |
| 341 if (pic->reference &= refmask) { | |
| 342 return 0; | |
| 343 } else { | |
| 344 for(i = 0; h->delayed_pic[i]; i++) | |
| 345 if(pic == h->delayed_pic[i]){ | |
| 346 pic->reference=DELAYED_PIC_REF; | |
| 347 break; | |
| 348 } | |
| 349 return 1; | |
| 350 } | |
| 351 } | |
| 352 | |
| 353 /** | |
| 354 * Find a Picture in the short term reference list by frame number. | |
| 355 * @param frame_num frame number to search for | |
| 356 * @param idx the index into h->short_ref where returned picture is found | |
| 357 * undefined if no picture found. | |
| 358 * @return pointer to the found picture, or NULL if no pic with the provided | |
| 359 * frame number is found | |
| 360 */ | |
| 361 static Picture * find_short(H264Context *h, int frame_num, int *idx){ | |
| 362 MpegEncContext * const s = &h->s; | |
| 363 int i; | |
| 364 | |
| 365 for(i=0; i<h->short_ref_count; i++){ | |
| 366 Picture *pic= h->short_ref[i]; | |
| 367 if(s->avctx->debug&FF_DEBUG_MMCO) | |
| 368 av_log(h->s.avctx, AV_LOG_DEBUG, "%d %d %p\n", i, pic->frame_num, pic); | |
| 369 if(pic->frame_num == frame_num) { | |
| 370 *idx = i; | |
| 371 return pic; | |
| 372 } | |
| 373 } | |
| 374 return NULL; | |
| 375 } | |
| 376 | |
| 377 /** | |
| 378 * Remove a picture from the short term reference list by its index in | |
| 379 * that list. This does no checking on the provided index; it is assumed | |
| 380 * to be valid. Other list entries are shifted down. | |
| 381 * @param i index into h->short_ref of picture to remove. | |
| 382 */ | |
| 383 static void remove_short_at_index(H264Context *h, int i){ | |
| 384 assert(i >= 0 && i < h->short_ref_count); | |
| 385 h->short_ref[i]= NULL; | |
| 386 if (--h->short_ref_count) | |
| 387 memmove(&h->short_ref[i], &h->short_ref[i+1], (h->short_ref_count - i)*sizeof(Picture*)); | |
| 388 } | |
| 389 | |
| 390 /** | |
| 391 * | |
| 392 * @return the removed picture or NULL if an error occurs | |
| 393 */ | |
| 394 static Picture * remove_short(H264Context *h, int frame_num, int ref_mask){ | |
| 395 MpegEncContext * const s = &h->s; | |
| 396 Picture *pic; | |
| 397 int i; | |
| 398 | |
| 399 if(s->avctx->debug&FF_DEBUG_MMCO) | |
| 400 av_log(h->s.avctx, AV_LOG_DEBUG, "remove short %d count %d\n", frame_num, h->short_ref_count); | |
| 401 | |
| 402 pic = find_short(h, frame_num, &i); | |
| 403 if (pic){ | |
| 404 if(unreference_pic(h, pic, ref_mask)) | |
| 405 remove_short_at_index(h, i); | |
| 406 } | |
| 407 | |
| 408 return pic; | |
| 409 } | |
| 410 | |
| 411 /** | |
| 412 * Remove a picture from the long term reference list by its index in | |
| 413 * that list. | |
| 414 * @return the removed picture or NULL if an error occurs | |
| 415 */ | |
| 416 static Picture * remove_long(H264Context *h, int i, int ref_mask){ | |
| 417 Picture *pic; | |
| 418 | |
| 419 pic= h->long_ref[i]; | |
| 420 if (pic){ | |
| 421 if(unreference_pic(h, pic, ref_mask)){ | |
| 422 assert(h->long_ref[i]->long_ref == 1); | |
| 423 h->long_ref[i]->long_ref= 0; | |
| 424 h->long_ref[i]= NULL; | |
| 425 h->long_ref_count--; | |
| 426 } | |
| 427 } | |
| 428 | |
| 429 return pic; | |
| 430 } | |
| 431 | |
| 432 void ff_h264_remove_all_refs(H264Context *h){ | |
| 433 int i; | |
| 434 | |
| 435 for(i=0; i<16; i++){ | |
| 436 remove_long(h, i, 0); | |
| 437 } | |
| 438 assert(h->long_ref_count==0); | |
| 439 | |
| 440 for(i=0; i<h->short_ref_count; i++){ | |
| 441 unreference_pic(h, h->short_ref[i], 0); | |
| 442 h->short_ref[i]= NULL; | |
| 443 } | |
| 444 h->short_ref_count=0; | |
| 445 } | |
| 446 | |
| 447 /** | |
| 448 * print short term list | |
| 449 */ | |
| 450 static void print_short_term(H264Context *h) { | |
| 451 uint32_t i; | |
| 452 if(h->s.avctx->debug&FF_DEBUG_MMCO) { | |
| 453 av_log(h->s.avctx, AV_LOG_DEBUG, "short term list:\n"); | |
| 454 for(i=0; i<h->short_ref_count; i++){ | |
| 455 Picture *pic= h->short_ref[i]; | |
| 456 av_log(h->s.avctx, AV_LOG_DEBUG, "%d fn:%d poc:%d %p\n", i, pic->frame_num, pic->poc, pic->data[0]); | |
| 457 } | |
| 458 } | |
| 459 } | |
| 460 | |
| 461 /** | |
| 462 * print long term list | |
| 463 */ | |
| 464 static void print_long_term(H264Context *h) { | |
| 465 uint32_t i; | |
| 466 if(h->s.avctx->debug&FF_DEBUG_MMCO) { | |
| 467 av_log(h->s.avctx, AV_LOG_DEBUG, "long term list:\n"); | |
| 468 for(i = 0; i < 16; i++){ | |
| 469 Picture *pic= h->long_ref[i]; | |
| 470 if (pic) { | |
| 471 av_log(h->s.avctx, AV_LOG_DEBUG, "%d fn:%d poc:%d %p\n", i, pic->frame_num, pic->poc, pic->data[0]); | |
| 472 } | |
| 473 } | |
| 474 } | |
| 475 } | |
| 476 | |
|
12093
05f91a88f986
Factorize ff_generate_sliding_window_mmcos() out.
michael
parents:
11644
diff
changeset
|
477 void ff_generate_sliding_window_mmcos(H264Context *h) { |
|
05f91a88f986
Factorize ff_generate_sliding_window_mmcos() out.
michael
parents:
11644
diff
changeset
|
478 MpegEncContext * const s = &h->s; |
|
05f91a88f986
Factorize ff_generate_sliding_window_mmcos() out.
michael
parents:
11644
diff
changeset
|
479 assert(h->long_ref_count + h->short_ref_count <= h->sps.ref_frame_count); |
|
05f91a88f986
Factorize ff_generate_sliding_window_mmcos() out.
michael
parents:
11644
diff
changeset
|
480 |
|
12094
f7bedc1ce1bc
Perform sliding window operation during frame gap handling.
michael
parents:
12093
diff
changeset
|
481 h->mmco_index= 0; |
|
12093
05f91a88f986
Factorize ff_generate_sliding_window_mmcos() out.
michael
parents:
11644
diff
changeset
|
482 if(h->short_ref_count && h->long_ref_count + h->short_ref_count == h->sps.ref_frame_count && |
|
05f91a88f986
Factorize ff_generate_sliding_window_mmcos() out.
michael
parents:
11644
diff
changeset
|
483 !(FIELD_PICTURE && !s->first_field && s->current_picture_ptr->reference)) { |
|
05f91a88f986
Factorize ff_generate_sliding_window_mmcos() out.
michael
parents:
11644
diff
changeset
|
484 h->mmco[0].opcode= MMCO_SHORT2UNUSED; |
|
05f91a88f986
Factorize ff_generate_sliding_window_mmcos() out.
michael
parents:
11644
diff
changeset
|
485 h->mmco[0].short_pic_num= h->short_ref[ h->short_ref_count - 1 ]->frame_num; |
|
05f91a88f986
Factorize ff_generate_sliding_window_mmcos() out.
michael
parents:
11644
diff
changeset
|
486 h->mmco_index= 1; |
|
05f91a88f986
Factorize ff_generate_sliding_window_mmcos() out.
michael
parents:
11644
diff
changeset
|
487 if (FIELD_PICTURE) { |
|
05f91a88f986
Factorize ff_generate_sliding_window_mmcos() out.
michael
parents:
11644
diff
changeset
|
488 h->mmco[0].short_pic_num *= 2; |
|
05f91a88f986
Factorize ff_generate_sliding_window_mmcos() out.
michael
parents:
11644
diff
changeset
|
489 h->mmco[1].opcode= MMCO_SHORT2UNUSED; |
|
05f91a88f986
Factorize ff_generate_sliding_window_mmcos() out.
michael
parents:
11644
diff
changeset
|
490 h->mmco[1].short_pic_num= h->mmco[0].short_pic_num + 1; |
|
05f91a88f986
Factorize ff_generate_sliding_window_mmcos() out.
michael
parents:
11644
diff
changeset
|
491 h->mmco_index= 2; |
|
05f91a88f986
Factorize ff_generate_sliding_window_mmcos() out.
michael
parents:
11644
diff
changeset
|
492 } |
|
05f91a88f986
Factorize ff_generate_sliding_window_mmcos() out.
michael
parents:
11644
diff
changeset
|
493 } |
|
05f91a88f986
Factorize ff_generate_sliding_window_mmcos() out.
michael
parents:
11644
diff
changeset
|
494 } |
|
05f91a88f986
Factorize ff_generate_sliding_window_mmcos() out.
michael
parents:
11644
diff
changeset
|
495 |
| 10862 | 496 int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ |
| 497 MpegEncContext * const s = &h->s; | |
| 498 int i, av_uninit(j); | |
| 499 int current_ref_assigned=0; | |
| 500 Picture *av_uninit(pic); | |
| 501 | |
| 502 if((s->avctx->debug&FF_DEBUG_MMCO) && mmco_count==0) | |
| 503 av_log(h->s.avctx, AV_LOG_DEBUG, "no mmco here\n"); | |
| 504 | |
| 505 for(i=0; i<mmco_count; i++){ | |
| 506 int av_uninit(structure), av_uninit(frame_num); | |
| 507 if(s->avctx->debug&FF_DEBUG_MMCO) | |
| 508 av_log(h->s.avctx, AV_LOG_DEBUG, "mmco:%d %d %d\n", h->mmco[i].opcode, h->mmco[i].short_pic_num, h->mmco[i].long_arg); | |
| 509 | |
| 510 if( mmco[i].opcode == MMCO_SHORT2UNUSED | |
| 511 || mmco[i].opcode == MMCO_SHORT2LONG){ | |
| 512 frame_num = pic_num_extract(h, mmco[i].short_pic_num, &structure); | |
| 513 pic = find_short(h, frame_num, &j); | |
| 514 if(!pic){ | |
| 515 if(mmco[i].opcode != MMCO_SHORT2LONG || !h->long_ref[mmco[i].long_arg] | |
| 516 || h->long_ref[mmco[i].long_arg]->frame_num != frame_num) | |
| 517 av_log(h->s.avctx, AV_LOG_ERROR, "mmco: unref short failure\n"); | |
| 518 continue; | |
| 519 } | |
| 520 } | |
| 521 | |
| 522 switch(mmco[i].opcode){ | |
| 523 case MMCO_SHORT2UNUSED: | |
| 524 if(s->avctx->debug&FF_DEBUG_MMCO) | |
| 525 av_log(h->s.avctx, AV_LOG_DEBUG, "mmco: unref short %d count %d\n", h->mmco[i].short_pic_num, h->short_ref_count); | |
| 526 remove_short(h, frame_num, structure ^ PICT_FRAME); | |
| 527 break; | |
| 528 case MMCO_SHORT2LONG: | |
| 529 if (h->long_ref[mmco[i].long_arg] != pic) | |
| 530 remove_long(h, mmco[i].long_arg, 0); | |
| 531 | |
| 532 remove_short_at_index(h, j); | |
| 533 h->long_ref[ mmco[i].long_arg ]= pic; | |
| 534 if (h->long_ref[ mmco[i].long_arg ]){ | |
| 535 h->long_ref[ mmco[i].long_arg ]->long_ref=1; | |
| 536 h->long_ref_count++; | |
| 537 } | |
| 538 break; | |
| 539 case MMCO_LONG2UNUSED: | |
| 540 j = pic_num_extract(h, mmco[i].long_arg, &structure); | |
| 541 pic = h->long_ref[j]; | |
| 542 if (pic) { | |
| 543 remove_long(h, j, structure ^ PICT_FRAME); | |
| 544 } else if(s->avctx->debug&FF_DEBUG_MMCO) | |
| 545 av_log(h->s.avctx, AV_LOG_DEBUG, "mmco: unref long failure\n"); | |
| 546 break; | |
| 547 case MMCO_LONG: | |
| 548 // Comment below left from previous code as it is an interresting note. | |
| 549 /* First field in pair is in short term list or | |
| 550 * at a different long term index. | |
| 551 * This is not allowed; see 7.4.3.3, notes 2 and 3. | |
| 552 * Report the problem and keep the pair where it is, | |
| 553 * and mark this field valid. | |
| 554 */ | |
| 555 | |
| 556 if (h->long_ref[mmco[i].long_arg] != s->current_picture_ptr) { | |
| 557 remove_long(h, mmco[i].long_arg, 0); | |
| 558 | |
| 559 h->long_ref[ mmco[i].long_arg ]= s->current_picture_ptr; | |
| 560 h->long_ref[ mmco[i].long_arg ]->long_ref=1; | |
| 561 h->long_ref_count++; | |
| 562 } | |
| 563 | |
| 564 s->current_picture_ptr->reference |= s->picture_structure; | |
| 565 current_ref_assigned=1; | |
| 566 break; | |
| 567 case MMCO_SET_MAX_LONG: | |
| 568 assert(mmco[i].long_arg <= 16); | |
| 569 // just remove the long term which index is greater than new max | |
| 570 for(j = mmco[i].long_arg; j<16; j++){ | |
| 571 remove_long(h, j, 0); | |
| 572 } | |
| 573 break; | |
| 574 case MMCO_RESET: | |
| 575 while(h->short_ref_count){ | |
| 576 remove_short(h, h->short_ref[0]->frame_num, 0); | |
| 577 } | |
| 578 for(j = 0; j < 16; j++) { | |
| 579 remove_long(h, j, 0); | |
| 580 } | |
| 581 s->current_picture_ptr->poc= | |
| 582 s->current_picture_ptr->field_poc[0]= | |
| 583 s->current_picture_ptr->field_poc[1]= | |
| 584 h->poc_lsb= | |
| 585 h->poc_msb= | |
| 586 h->frame_num= | |
| 587 s->current_picture_ptr->frame_num= 0; | |
| 588 s->current_picture_ptr->mmco_reset=1; | |
| 589 break; | |
| 590 default: assert(0); | |
| 591 } | |
| 592 } | |
| 593 | |
| 594 if (!current_ref_assigned) { | |
| 595 /* Second field of complementary field pair; the first field of | |
| 596 * which is already referenced. If short referenced, it | |
| 597 * should be first entry in short_ref. If not, it must exist | |
| 598 * in long_ref; trying to put it on the short list here is an | |
| 599 * error in the encoded bit stream (ref: 7.4.3.3, NOTE 2 and 3). | |
| 600 */ | |
| 601 if (h->short_ref_count && h->short_ref[0] == s->current_picture_ptr) { | |
| 602 /* Just mark the second field valid */ | |
| 603 s->current_picture_ptr->reference = PICT_FRAME; | |
| 604 } else if (s->current_picture_ptr->long_ref) { | |
| 605 av_log(h->s.avctx, AV_LOG_ERROR, "illegal short term reference " | |
| 606 "assignment for second field " | |
| 607 "in complementary field pair " | |
| 608 "(first field is long term)\n"); | |
| 609 } else { | |
| 610 pic= remove_short(h, s->current_picture_ptr->frame_num, 0); | |
| 611 if(pic){ | |
| 612 av_log(h->s.avctx, AV_LOG_ERROR, "illegal short term buffer state detected\n"); | |
| 613 } | |
| 614 | |
| 615 if(h->short_ref_count) | |
| 616 memmove(&h->short_ref[1], &h->short_ref[0], h->short_ref_count*sizeof(Picture*)); | |
| 617 | |
| 618 h->short_ref[0]= s->current_picture_ptr; | |
| 619 h->short_ref_count++; | |
| 620 s->current_picture_ptr->reference |= s->picture_structure; | |
| 621 } | |
| 622 } | |
| 623 | |
| 624 if (h->long_ref_count + h->short_ref_count > h->sps.ref_frame_count){ | |
| 625 | |
| 626 /* We have too many reference frames, probably due to corrupted | |
| 627 * stream. Need to discard one frame. Prevents overrun of the | |
| 628 * short_ref and long_ref buffers. | |
| 629 */ | |
| 630 av_log(h->s.avctx, AV_LOG_ERROR, | |
| 631 "number of reference frames exceeds max (probably " | |
| 632 "corrupt input), discarding one\n"); | |
| 633 | |
| 634 if (h->long_ref_count && !h->short_ref_count) { | |
| 635 for (i = 0; i < 16; ++i) | |
| 636 if (h->long_ref[i]) | |
| 637 break; | |
| 638 | |
| 639 assert(i < 16); | |
| 640 remove_long(h, i, 0); | |
| 641 } else { | |
| 642 pic = h->short_ref[h->short_ref_count - 1]; | |
| 643 remove_short(h, pic->frame_num, 0); | |
| 644 } | |
| 645 } | |
| 646 | |
| 647 print_short_term(h); | |
| 648 print_long_term(h); | |
| 649 return 0; | |
| 650 } | |
| 651 | |
| 652 int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb){ | |
| 653 MpegEncContext * const s = &h->s; | |
| 654 int i; | |
| 655 | |
| 656 h->mmco_index= 0; | |
| 657 if(h->nal_unit_type == NAL_IDR_SLICE){ //FIXME fields | |
| 658 s->broken_link= get_bits1(gb) -1; | |
| 659 if(get_bits1(gb)){ | |
| 660 h->mmco[0].opcode= MMCO_LONG; | |
| 661 h->mmco[0].long_arg= 0; | |
| 662 h->mmco_index= 1; | |
| 663 } | |
| 664 }else{ | |
| 665 if(get_bits1(gb)){ // adaptive_ref_pic_marking_mode_flag | |
| 666 for(i= 0; i<MAX_MMCO_COUNT; i++) { | |
| 667 MMCOOpcode opcode= get_ue_golomb_31(gb); | |
| 668 | |
| 669 h->mmco[i].opcode= opcode; | |
| 670 if(opcode==MMCO_SHORT2UNUSED || opcode==MMCO_SHORT2LONG){ | |
| 671 h->mmco[i].short_pic_num= (h->curr_pic_num - get_ue_golomb(gb) - 1) & (h->max_pic_num - 1); | |
| 672 /* if(h->mmco[i].short_pic_num >= h->short_ref_count || h->short_ref[ h->mmco[i].short_pic_num ] == NULL){ | |
| 673 av_log(s->avctx, AV_LOG_ERROR, "illegal short ref in memory management control operation %d\n", mmco); | |
| 674 return -1; | |
| 675 }*/ | |
| 676 } | |
| 677 if(opcode==MMCO_SHORT2LONG || opcode==MMCO_LONG2UNUSED || opcode==MMCO_LONG || opcode==MMCO_SET_MAX_LONG){ | |
| 678 unsigned int long_arg= get_ue_golomb_31(gb); | |
| 679 if(long_arg >= 32 || (long_arg >= 16 && !(opcode == MMCO_LONG2UNUSED && FIELD_PICTURE))){ | |
| 680 av_log(h->s.avctx, AV_LOG_ERROR, "illegal long ref in memory management control operation %d\n", opcode); | |
| 681 return -1; | |
| 682 } | |
| 683 h->mmco[i].long_arg= long_arg; | |
| 684 } | |
| 685 | |
| 686 if(opcode > (unsigned)MMCO_LONG){ | |
| 687 av_log(h->s.avctx, AV_LOG_ERROR, "illegal memory management control operation %d\n", opcode); | |
| 688 return -1; | |
| 689 } | |
| 690 if(opcode == MMCO_END) | |
| 691 break; | |
| 692 } | |
| 693 h->mmco_index= i; | |
| 694 }else{ | |
|
12093
05f91a88f986
Factorize ff_generate_sliding_window_mmcos() out.
michael
parents:
11644
diff
changeset
|
695 ff_generate_sliding_window_mmcos(h); |
| 10862 | 696 } |
| 697 } | |
| 698 | |
| 699 return 0; | |
| 700 } |
