1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * H.26L/H.264/AVC/JVT/14496-10/... reference picture handling 3cabdff1aSopenharmony_ci * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> 4cabdff1aSopenharmony_ci * 5cabdff1aSopenharmony_ci * This file is part of FFmpeg. 6cabdff1aSopenharmony_ci * 7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 11cabdff1aSopenharmony_ci * 12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15cabdff1aSopenharmony_ci * Lesser General Public License for more details. 16cabdff1aSopenharmony_ci * 17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20cabdff1aSopenharmony_ci */ 21cabdff1aSopenharmony_ci 22cabdff1aSopenharmony_ci/** 23cabdff1aSopenharmony_ci * @file 24cabdff1aSopenharmony_ci * H.264 / AVC / MPEG-4 part10 reference picture handling. 25cabdff1aSopenharmony_ci * @author Michael Niedermayer <michaelni@gmx.at> 26cabdff1aSopenharmony_ci */ 27cabdff1aSopenharmony_ci 28cabdff1aSopenharmony_ci#include <inttypes.h> 29cabdff1aSopenharmony_ci 30cabdff1aSopenharmony_ci#include "libavutil/avassert.h" 31cabdff1aSopenharmony_ci#include "avcodec.h" 32cabdff1aSopenharmony_ci#include "h264.h" 33cabdff1aSopenharmony_ci#include "h264dec.h" 34cabdff1aSopenharmony_ci#include "golomb.h" 35cabdff1aSopenharmony_ci#include "mpegutils.h" 36cabdff1aSopenharmony_ci 37cabdff1aSopenharmony_ci#include <assert.h> 38cabdff1aSopenharmony_ci 39cabdff1aSopenharmony_cistatic void pic_as_field(H264Ref *pic, const int parity) 40cabdff1aSopenharmony_ci{ 41cabdff1aSopenharmony_ci int i; 42cabdff1aSopenharmony_ci for (i = 0; i < FF_ARRAY_ELEMS(pic->data); ++i) { 43cabdff1aSopenharmony_ci if (parity == PICT_BOTTOM_FIELD) 44cabdff1aSopenharmony_ci pic->data[i] += pic->linesize[i]; 45cabdff1aSopenharmony_ci pic->reference = parity; 46cabdff1aSopenharmony_ci pic->linesize[i] *= 2; 47cabdff1aSopenharmony_ci } 48cabdff1aSopenharmony_ci pic->poc = pic->parent->field_poc[parity == PICT_BOTTOM_FIELD]; 49cabdff1aSopenharmony_ci} 50cabdff1aSopenharmony_ci 51cabdff1aSopenharmony_cistatic void ref_from_h264pic(H264Ref *dst, H264Picture *src) 52cabdff1aSopenharmony_ci{ 53cabdff1aSopenharmony_ci memcpy(dst->data, src->f->data, sizeof(dst->data)); 54cabdff1aSopenharmony_ci memcpy(dst->linesize, src->f->linesize, sizeof(dst->linesize)); 55cabdff1aSopenharmony_ci dst->reference = src->reference; 56cabdff1aSopenharmony_ci dst->poc = src->poc; 57cabdff1aSopenharmony_ci dst->pic_id = src->pic_id; 58cabdff1aSopenharmony_ci dst->parent = src; 59cabdff1aSopenharmony_ci} 60cabdff1aSopenharmony_ci 61cabdff1aSopenharmony_cistatic int split_field_copy(H264Ref *dest, H264Picture *src, int parity, int id_add) 62cabdff1aSopenharmony_ci{ 63cabdff1aSopenharmony_ci int match = !!(src->reference & parity); 64cabdff1aSopenharmony_ci 65cabdff1aSopenharmony_ci if (match) { 66cabdff1aSopenharmony_ci ref_from_h264pic(dest, src); 67cabdff1aSopenharmony_ci if (parity != PICT_FRAME) { 68cabdff1aSopenharmony_ci pic_as_field(dest, parity); 69cabdff1aSopenharmony_ci dest->pic_id *= 2; 70cabdff1aSopenharmony_ci dest->pic_id += id_add; 71cabdff1aSopenharmony_ci } 72cabdff1aSopenharmony_ci } 73cabdff1aSopenharmony_ci 74cabdff1aSopenharmony_ci return match; 75cabdff1aSopenharmony_ci} 76cabdff1aSopenharmony_ci 77cabdff1aSopenharmony_cistatic int build_def_list(H264Ref *def, int def_len, 78cabdff1aSopenharmony_ci H264Picture * const *in, int len, int is_long, int sel) 79cabdff1aSopenharmony_ci{ 80cabdff1aSopenharmony_ci int i[2] = { 0 }; 81cabdff1aSopenharmony_ci int index = 0; 82cabdff1aSopenharmony_ci 83cabdff1aSopenharmony_ci while (i[0] < len || i[1] < len) { 84cabdff1aSopenharmony_ci while (i[0] < len && !(in[i[0]] && (in[i[0]]->reference & sel))) 85cabdff1aSopenharmony_ci i[0]++; 86cabdff1aSopenharmony_ci while (i[1] < len && !(in[i[1]] && (in[i[1]]->reference & (sel ^ 3)))) 87cabdff1aSopenharmony_ci i[1]++; 88cabdff1aSopenharmony_ci if (i[0] < len) { 89cabdff1aSopenharmony_ci av_assert0(index < def_len); 90cabdff1aSopenharmony_ci in[i[0]]->pic_id = is_long ? i[0] : in[i[0]]->frame_num; 91cabdff1aSopenharmony_ci split_field_copy(&def[index++], in[i[0]++], sel, 1); 92cabdff1aSopenharmony_ci } 93cabdff1aSopenharmony_ci if (i[1] < len) { 94cabdff1aSopenharmony_ci av_assert0(index < def_len); 95cabdff1aSopenharmony_ci in[i[1]]->pic_id = is_long ? i[1] : in[i[1]]->frame_num; 96cabdff1aSopenharmony_ci split_field_copy(&def[index++], in[i[1]++], sel ^ 3, 0); 97cabdff1aSopenharmony_ci } 98cabdff1aSopenharmony_ci } 99cabdff1aSopenharmony_ci 100cabdff1aSopenharmony_ci return index; 101cabdff1aSopenharmony_ci} 102cabdff1aSopenharmony_ci 103cabdff1aSopenharmony_cistatic int add_sorted(H264Picture **sorted, H264Picture * const *src, 104cabdff1aSopenharmony_ci int len, int limit, int dir) 105cabdff1aSopenharmony_ci{ 106cabdff1aSopenharmony_ci int i, best_poc; 107cabdff1aSopenharmony_ci int out_i = 0; 108cabdff1aSopenharmony_ci 109cabdff1aSopenharmony_ci for (;;) { 110cabdff1aSopenharmony_ci best_poc = dir ? INT_MIN : INT_MAX; 111cabdff1aSopenharmony_ci 112cabdff1aSopenharmony_ci for (i = 0; i < len; i++) { 113cabdff1aSopenharmony_ci const int poc = src[i]->poc; 114cabdff1aSopenharmony_ci if (((poc > limit) ^ dir) && ((poc < best_poc) ^ dir)) { 115cabdff1aSopenharmony_ci best_poc = poc; 116cabdff1aSopenharmony_ci sorted[out_i] = src[i]; 117cabdff1aSopenharmony_ci } 118cabdff1aSopenharmony_ci } 119cabdff1aSopenharmony_ci if (best_poc == (dir ? INT_MIN : INT_MAX)) 120cabdff1aSopenharmony_ci break; 121cabdff1aSopenharmony_ci limit = sorted[out_i++]->poc - dir; 122cabdff1aSopenharmony_ci } 123cabdff1aSopenharmony_ci return out_i; 124cabdff1aSopenharmony_ci} 125cabdff1aSopenharmony_ci 126cabdff1aSopenharmony_cistatic int mismatches_ref(const H264Context *h, const H264Picture *pic) 127cabdff1aSopenharmony_ci{ 128cabdff1aSopenharmony_ci const AVFrame *f = pic->f; 129cabdff1aSopenharmony_ci return (h->cur_pic_ptr->f->width != f->width || 130cabdff1aSopenharmony_ci h->cur_pic_ptr->f->height != f->height || 131cabdff1aSopenharmony_ci h->cur_pic_ptr->f->format != f->format); 132cabdff1aSopenharmony_ci} 133cabdff1aSopenharmony_ci 134cabdff1aSopenharmony_cistatic void h264_initialise_ref_list(H264Context *h, H264SliceContext *sl) 135cabdff1aSopenharmony_ci{ 136cabdff1aSopenharmony_ci int i, len; 137cabdff1aSopenharmony_ci int j; 138cabdff1aSopenharmony_ci 139cabdff1aSopenharmony_ci if (sl->slice_type_nos == AV_PICTURE_TYPE_B) { 140cabdff1aSopenharmony_ci H264Picture *sorted[32]; 141cabdff1aSopenharmony_ci int cur_poc, list; 142cabdff1aSopenharmony_ci int lens[2]; 143cabdff1aSopenharmony_ci 144cabdff1aSopenharmony_ci if (FIELD_PICTURE(h)) 145cabdff1aSopenharmony_ci cur_poc = h->cur_pic_ptr->field_poc[h->picture_structure == PICT_BOTTOM_FIELD]; 146cabdff1aSopenharmony_ci else 147cabdff1aSopenharmony_ci cur_poc = h->cur_pic_ptr->poc; 148cabdff1aSopenharmony_ci 149cabdff1aSopenharmony_ci for (list = 0; list < 2; list++) { 150cabdff1aSopenharmony_ci len = add_sorted(sorted, h->short_ref, h->short_ref_count, cur_poc, 1 ^ list); 151cabdff1aSopenharmony_ci len += add_sorted(sorted + len, h->short_ref, h->short_ref_count, cur_poc, 0 ^ list); 152cabdff1aSopenharmony_ci av_assert0(len <= 32); 153cabdff1aSopenharmony_ci 154cabdff1aSopenharmony_ci len = build_def_list(sl->ref_list[list], FF_ARRAY_ELEMS(sl->ref_list[0]), 155cabdff1aSopenharmony_ci sorted, len, 0, h->picture_structure); 156cabdff1aSopenharmony_ci len += build_def_list(sl->ref_list[list] + len, 157cabdff1aSopenharmony_ci FF_ARRAY_ELEMS(sl->ref_list[0]) - len, 158cabdff1aSopenharmony_ci h->long_ref, 16, 1, h->picture_structure); 159cabdff1aSopenharmony_ci av_assert0(len <= 32); 160cabdff1aSopenharmony_ci 161cabdff1aSopenharmony_ci if (len < sl->ref_count[list]) 162cabdff1aSopenharmony_ci memset(&sl->ref_list[list][len], 0, sizeof(H264Ref) * (sl->ref_count[list] - len)); 163cabdff1aSopenharmony_ci lens[list] = len; 164cabdff1aSopenharmony_ci } 165cabdff1aSopenharmony_ci 166cabdff1aSopenharmony_ci if (lens[0] == lens[1] && lens[1] > 1) { 167cabdff1aSopenharmony_ci for (i = 0; i < lens[0] && 168cabdff1aSopenharmony_ci sl->ref_list[0][i].parent->f->buf[0]->buffer == 169cabdff1aSopenharmony_ci sl->ref_list[1][i].parent->f->buf[0]->buffer; i++); 170cabdff1aSopenharmony_ci if (i == lens[0]) { 171cabdff1aSopenharmony_ci FFSWAP(H264Ref, sl->ref_list[1][0], sl->ref_list[1][1]); 172cabdff1aSopenharmony_ci } 173cabdff1aSopenharmony_ci } 174cabdff1aSopenharmony_ci } else { 175cabdff1aSopenharmony_ci len = build_def_list(sl->ref_list[0], FF_ARRAY_ELEMS(sl->ref_list[0]), 176cabdff1aSopenharmony_ci h->short_ref, h->short_ref_count, 0, h->picture_structure); 177cabdff1aSopenharmony_ci len += build_def_list(sl->ref_list[0] + len, 178cabdff1aSopenharmony_ci FF_ARRAY_ELEMS(sl->ref_list[0]) - len, 179cabdff1aSopenharmony_ci h-> long_ref, 16, 1, h->picture_structure); 180cabdff1aSopenharmony_ci av_assert0(len <= 32); 181cabdff1aSopenharmony_ci 182cabdff1aSopenharmony_ci if (len < sl->ref_count[0]) 183cabdff1aSopenharmony_ci memset(&sl->ref_list[0][len], 0, sizeof(H264Ref) * (sl->ref_count[0] - len)); 184cabdff1aSopenharmony_ci } 185cabdff1aSopenharmony_ci#ifdef TRACE 186cabdff1aSopenharmony_ci for (i = 0; i < sl->ref_count[0]; i++) { 187cabdff1aSopenharmony_ci ff_tlog(h->avctx, "List0: %s fn:%d 0x%p\n", 188cabdff1aSopenharmony_ci (sl->ref_list[0][i].parent ? (sl->ref_list[0][i].parent->long_ref ? "LT" : "ST") : "??"), 189cabdff1aSopenharmony_ci sl->ref_list[0][i].pic_id, 190cabdff1aSopenharmony_ci sl->ref_list[0][i].data[0]); 191cabdff1aSopenharmony_ci } 192cabdff1aSopenharmony_ci if (sl->slice_type_nos == AV_PICTURE_TYPE_B) { 193cabdff1aSopenharmony_ci for (i = 0; i < sl->ref_count[1]; i++) { 194cabdff1aSopenharmony_ci ff_tlog(h->avctx, "List1: %s fn:%d 0x%p\n", 195cabdff1aSopenharmony_ci (sl->ref_list[1][i].parent ? (sl->ref_list[1][i].parent->long_ref ? "LT" : "ST") : "??"), 196cabdff1aSopenharmony_ci sl->ref_list[1][i].pic_id, 197cabdff1aSopenharmony_ci sl->ref_list[1][i].data[0]); 198cabdff1aSopenharmony_ci } 199cabdff1aSopenharmony_ci } 200cabdff1aSopenharmony_ci#endif 201cabdff1aSopenharmony_ci 202cabdff1aSopenharmony_ci for (j = 0; j<1+(sl->slice_type_nos == AV_PICTURE_TYPE_B); j++) { 203cabdff1aSopenharmony_ci for (i = 0; i < sl->ref_count[j]; i++) { 204cabdff1aSopenharmony_ci if (sl->ref_list[j][i].parent) { 205cabdff1aSopenharmony_ci if (mismatches_ref(h, sl->ref_list[j][i].parent)) { 206cabdff1aSopenharmony_ci av_log(h->avctx, AV_LOG_ERROR, "Discarding mismatching reference\n"); 207cabdff1aSopenharmony_ci memset(&sl->ref_list[j][i], 0, sizeof(sl->ref_list[j][i])); 208cabdff1aSopenharmony_ci } 209cabdff1aSopenharmony_ci } 210cabdff1aSopenharmony_ci } 211cabdff1aSopenharmony_ci } 212cabdff1aSopenharmony_ci for (i = 0; i < sl->list_count; i++) 213cabdff1aSopenharmony_ci h->default_ref[i] = sl->ref_list[i][0]; 214cabdff1aSopenharmony_ci} 215cabdff1aSopenharmony_ci 216cabdff1aSopenharmony_ci/** 217cabdff1aSopenharmony_ci * print short term list 218cabdff1aSopenharmony_ci */ 219cabdff1aSopenharmony_cistatic void print_short_term(const H264Context *h) 220cabdff1aSopenharmony_ci{ 221cabdff1aSopenharmony_ci uint32_t i; 222cabdff1aSopenharmony_ci if (h->avctx->debug & FF_DEBUG_MMCO) { 223cabdff1aSopenharmony_ci av_log(h->avctx, AV_LOG_DEBUG, "short term list:\n"); 224cabdff1aSopenharmony_ci for (i = 0; i < h->short_ref_count; i++) { 225cabdff1aSopenharmony_ci H264Picture *pic = h->short_ref[i]; 226cabdff1aSopenharmony_ci av_log(h->avctx, AV_LOG_DEBUG, "%"PRIu32" fn:%d poc:%d %p\n", 227cabdff1aSopenharmony_ci i, pic->frame_num, pic->poc, pic->f->data[0]); 228cabdff1aSopenharmony_ci } 229cabdff1aSopenharmony_ci } 230cabdff1aSopenharmony_ci} 231cabdff1aSopenharmony_ci 232cabdff1aSopenharmony_ci/** 233cabdff1aSopenharmony_ci * print long term list 234cabdff1aSopenharmony_ci */ 235cabdff1aSopenharmony_cistatic void print_long_term(const H264Context *h) 236cabdff1aSopenharmony_ci{ 237cabdff1aSopenharmony_ci uint32_t i; 238cabdff1aSopenharmony_ci if (h->avctx->debug & FF_DEBUG_MMCO) { 239cabdff1aSopenharmony_ci av_log(h->avctx, AV_LOG_DEBUG, "long term list:\n"); 240cabdff1aSopenharmony_ci for (i = 0; i < 16; i++) { 241cabdff1aSopenharmony_ci H264Picture *pic = h->long_ref[i]; 242cabdff1aSopenharmony_ci if (pic) { 243cabdff1aSopenharmony_ci av_log(h->avctx, AV_LOG_DEBUG, "%"PRIu32" fn:%d poc:%d %p\n", 244cabdff1aSopenharmony_ci i, pic->frame_num, pic->poc, pic->f->data[0]); 245cabdff1aSopenharmony_ci } 246cabdff1aSopenharmony_ci } 247cabdff1aSopenharmony_ci } 248cabdff1aSopenharmony_ci} 249cabdff1aSopenharmony_ci 250cabdff1aSopenharmony_ci/** 251cabdff1aSopenharmony_ci * Extract structure information about the picture described by pic_num in 252cabdff1aSopenharmony_ci * the current decoding context (frame or field). Note that pic_num is 253cabdff1aSopenharmony_ci * picture number without wrapping (so, 0<=pic_num<max_pic_num). 254cabdff1aSopenharmony_ci * @param pic_num picture number for which to extract structure information 255cabdff1aSopenharmony_ci * @param structure one of PICT_XXX describing structure of picture 256cabdff1aSopenharmony_ci * with pic_num 257cabdff1aSopenharmony_ci * @return frame number (short term) or long term index of picture 258cabdff1aSopenharmony_ci * described by pic_num 259cabdff1aSopenharmony_ci */ 260cabdff1aSopenharmony_cistatic int pic_num_extract(const H264Context *h, int pic_num, int *structure) 261cabdff1aSopenharmony_ci{ 262cabdff1aSopenharmony_ci *structure = h->picture_structure; 263cabdff1aSopenharmony_ci if (FIELD_PICTURE(h)) { 264cabdff1aSopenharmony_ci if (!(pic_num & 1)) 265cabdff1aSopenharmony_ci /* opposite field */ 266cabdff1aSopenharmony_ci *structure ^= PICT_FRAME; 267cabdff1aSopenharmony_ci pic_num >>= 1; 268cabdff1aSopenharmony_ci } 269cabdff1aSopenharmony_ci 270cabdff1aSopenharmony_ci return pic_num; 271cabdff1aSopenharmony_ci} 272cabdff1aSopenharmony_ci 273cabdff1aSopenharmony_cistatic void h264_fill_mbaff_ref_list(H264SliceContext *sl) 274cabdff1aSopenharmony_ci{ 275cabdff1aSopenharmony_ci int list, i, j; 276cabdff1aSopenharmony_ci for (list = 0; list < sl->list_count; list++) { 277cabdff1aSopenharmony_ci for (i = 0; i < sl->ref_count[list]; i++) { 278cabdff1aSopenharmony_ci H264Ref *frame = &sl->ref_list[list][i]; 279cabdff1aSopenharmony_ci H264Ref *field = &sl->ref_list[list][16 + 2 * i]; 280cabdff1aSopenharmony_ci 281cabdff1aSopenharmony_ci field[0] = *frame; 282cabdff1aSopenharmony_ci 283cabdff1aSopenharmony_ci for (j = 0; j < 3; j++) 284cabdff1aSopenharmony_ci field[0].linesize[j] <<= 1; 285cabdff1aSopenharmony_ci field[0].reference = PICT_TOP_FIELD; 286cabdff1aSopenharmony_ci field[0].poc = field[0].parent->field_poc[0]; 287cabdff1aSopenharmony_ci 288cabdff1aSopenharmony_ci field[1] = field[0]; 289cabdff1aSopenharmony_ci 290cabdff1aSopenharmony_ci for (j = 0; j < 3; j++) 291cabdff1aSopenharmony_ci field[1].data[j] += frame->parent->f->linesize[j]; 292cabdff1aSopenharmony_ci field[1].reference = PICT_BOTTOM_FIELD; 293cabdff1aSopenharmony_ci field[1].poc = field[1].parent->field_poc[1]; 294cabdff1aSopenharmony_ci } 295cabdff1aSopenharmony_ci } 296cabdff1aSopenharmony_ci} 297cabdff1aSopenharmony_ci 298cabdff1aSopenharmony_ciint ff_h264_build_ref_list(H264Context *h, H264SliceContext *sl) 299cabdff1aSopenharmony_ci{ 300cabdff1aSopenharmony_ci int list, index, pic_structure; 301cabdff1aSopenharmony_ci 302cabdff1aSopenharmony_ci print_short_term(h); 303cabdff1aSopenharmony_ci print_long_term(h); 304cabdff1aSopenharmony_ci 305cabdff1aSopenharmony_ci h264_initialise_ref_list(h, sl); 306cabdff1aSopenharmony_ci 307cabdff1aSopenharmony_ci for (list = 0; list < sl->list_count; list++) { 308cabdff1aSopenharmony_ci int pred = sl->curr_pic_num; 309cabdff1aSopenharmony_ci 310cabdff1aSopenharmony_ci for (index = 0; index < sl->nb_ref_modifications[list]; index++) { 311cabdff1aSopenharmony_ci unsigned int modification_of_pic_nums_idc = sl->ref_modifications[list][index].op; 312cabdff1aSopenharmony_ci unsigned int val = sl->ref_modifications[list][index].val; 313cabdff1aSopenharmony_ci unsigned int pic_id; 314cabdff1aSopenharmony_ci int i; 315cabdff1aSopenharmony_ci H264Picture *ref = NULL; 316cabdff1aSopenharmony_ci 317cabdff1aSopenharmony_ci switch (modification_of_pic_nums_idc) { 318cabdff1aSopenharmony_ci case 0: 319cabdff1aSopenharmony_ci case 1: { 320cabdff1aSopenharmony_ci const unsigned int abs_diff_pic_num = val + 1; 321cabdff1aSopenharmony_ci int frame_num; 322cabdff1aSopenharmony_ci 323cabdff1aSopenharmony_ci if (abs_diff_pic_num > sl->max_pic_num) { 324cabdff1aSopenharmony_ci av_log(h->avctx, AV_LOG_ERROR, 325cabdff1aSopenharmony_ci "abs_diff_pic_num overflow\n"); 326cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 327cabdff1aSopenharmony_ci } 328cabdff1aSopenharmony_ci 329cabdff1aSopenharmony_ci if (modification_of_pic_nums_idc == 0) 330cabdff1aSopenharmony_ci pred -= abs_diff_pic_num; 331cabdff1aSopenharmony_ci else 332cabdff1aSopenharmony_ci pred += abs_diff_pic_num; 333cabdff1aSopenharmony_ci pred &= sl->max_pic_num - 1; 334cabdff1aSopenharmony_ci 335cabdff1aSopenharmony_ci frame_num = pic_num_extract(h, pred, &pic_structure); 336cabdff1aSopenharmony_ci 337cabdff1aSopenharmony_ci for (i = h->short_ref_count - 1; i >= 0; i--) { 338cabdff1aSopenharmony_ci ref = h->short_ref[i]; 339cabdff1aSopenharmony_ci assert(ref->reference); 340cabdff1aSopenharmony_ci assert(!ref->long_ref); 341cabdff1aSopenharmony_ci if (ref->frame_num == frame_num && 342cabdff1aSopenharmony_ci (ref->reference & pic_structure)) 343cabdff1aSopenharmony_ci break; 344cabdff1aSopenharmony_ci } 345cabdff1aSopenharmony_ci if (i >= 0) 346cabdff1aSopenharmony_ci ref->pic_id = pred; 347cabdff1aSopenharmony_ci break; 348cabdff1aSopenharmony_ci } 349cabdff1aSopenharmony_ci case 2: { 350cabdff1aSopenharmony_ci int long_idx; 351cabdff1aSopenharmony_ci pic_id = val; // long_term_pic_idx 352cabdff1aSopenharmony_ci 353cabdff1aSopenharmony_ci long_idx = pic_num_extract(h, pic_id, &pic_structure); 354cabdff1aSopenharmony_ci 355cabdff1aSopenharmony_ci if (long_idx > 31U) { 356cabdff1aSopenharmony_ci av_log(h->avctx, AV_LOG_ERROR, 357cabdff1aSopenharmony_ci "long_term_pic_idx overflow\n"); 358cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 359cabdff1aSopenharmony_ci } 360cabdff1aSopenharmony_ci ref = h->long_ref[long_idx]; 361cabdff1aSopenharmony_ci assert(!(ref && !ref->reference)); 362cabdff1aSopenharmony_ci if (ref && (ref->reference & pic_structure)) { 363cabdff1aSopenharmony_ci ref->pic_id = pic_id; 364cabdff1aSopenharmony_ci assert(ref->long_ref); 365cabdff1aSopenharmony_ci i = 0; 366cabdff1aSopenharmony_ci } else { 367cabdff1aSopenharmony_ci i = -1; 368cabdff1aSopenharmony_ci } 369cabdff1aSopenharmony_ci break; 370cabdff1aSopenharmony_ci } 371cabdff1aSopenharmony_ci default: 372cabdff1aSopenharmony_ci av_assert0(0); 373cabdff1aSopenharmony_ci } 374cabdff1aSopenharmony_ci 375cabdff1aSopenharmony_ci if (i < 0 || mismatches_ref(h, ref)) { 376cabdff1aSopenharmony_ci av_log(h->avctx, AV_LOG_ERROR, 377cabdff1aSopenharmony_ci i < 0 ? "reference picture missing during reorder\n" : 378cabdff1aSopenharmony_ci "mismatching reference\n" 379cabdff1aSopenharmony_ci ); 380cabdff1aSopenharmony_ci memset(&sl->ref_list[list][index], 0, sizeof(sl->ref_list[0][0])); // FIXME 381cabdff1aSopenharmony_ci } else { 382cabdff1aSopenharmony_ci for (i = index; i + 1 < sl->ref_count[list]; i++) { 383cabdff1aSopenharmony_ci if (sl->ref_list[list][i].parent && 384cabdff1aSopenharmony_ci ref->long_ref == sl->ref_list[list][i].parent->long_ref && 385cabdff1aSopenharmony_ci ref->pic_id == sl->ref_list[list][i].pic_id) 386cabdff1aSopenharmony_ci break; 387cabdff1aSopenharmony_ci } 388cabdff1aSopenharmony_ci for (; i > index; i--) { 389cabdff1aSopenharmony_ci sl->ref_list[list][i] = sl->ref_list[list][i - 1]; 390cabdff1aSopenharmony_ci } 391cabdff1aSopenharmony_ci ref_from_h264pic(&sl->ref_list[list][index], ref); 392cabdff1aSopenharmony_ci if (FIELD_PICTURE(h)) { 393cabdff1aSopenharmony_ci pic_as_field(&sl->ref_list[list][index], pic_structure); 394cabdff1aSopenharmony_ci } 395cabdff1aSopenharmony_ci } 396cabdff1aSopenharmony_ci } 397cabdff1aSopenharmony_ci } 398cabdff1aSopenharmony_ci for (list = 0; list < sl->list_count; list++) { 399cabdff1aSopenharmony_ci for (index = 0; index < sl->ref_count[list]; index++) { 400cabdff1aSopenharmony_ci if ( !sl->ref_list[list][index].parent 401cabdff1aSopenharmony_ci || (!FIELD_PICTURE(h) && (sl->ref_list[list][index].reference&3) != 3)) { 402cabdff1aSopenharmony_ci int i; 403cabdff1aSopenharmony_ci av_log(h->avctx, AV_LOG_ERROR, "Missing reference picture, default is %d\n", h->default_ref[list].poc); 404cabdff1aSopenharmony_ci for (i = 0; i < FF_ARRAY_ELEMS(h->last_pocs); i++) 405cabdff1aSopenharmony_ci h->last_pocs[i] = INT_MIN; 406cabdff1aSopenharmony_ci if (h->default_ref[list].parent 407cabdff1aSopenharmony_ci && !(!FIELD_PICTURE(h) && (h->default_ref[list].reference&3) != 3)) 408cabdff1aSopenharmony_ci sl->ref_list[list][index] = h->default_ref[list]; 409cabdff1aSopenharmony_ci else 410cabdff1aSopenharmony_ci return -1; 411cabdff1aSopenharmony_ci } 412cabdff1aSopenharmony_ci av_assert0(av_buffer_get_ref_count(sl->ref_list[list][index].parent->f->buf[0]) > 0); 413cabdff1aSopenharmony_ci } 414cabdff1aSopenharmony_ci } 415cabdff1aSopenharmony_ci 416cabdff1aSopenharmony_ci if (FRAME_MBAFF(h)) 417cabdff1aSopenharmony_ci h264_fill_mbaff_ref_list(sl); 418cabdff1aSopenharmony_ci 419cabdff1aSopenharmony_ci return 0; 420cabdff1aSopenharmony_ci} 421cabdff1aSopenharmony_ci 422cabdff1aSopenharmony_ciint ff_h264_decode_ref_pic_list_reordering(H264SliceContext *sl, void *logctx) 423cabdff1aSopenharmony_ci{ 424cabdff1aSopenharmony_ci int list, index; 425cabdff1aSopenharmony_ci 426cabdff1aSopenharmony_ci sl->nb_ref_modifications[0] = 0; 427cabdff1aSopenharmony_ci sl->nb_ref_modifications[1] = 0; 428cabdff1aSopenharmony_ci 429cabdff1aSopenharmony_ci for (list = 0; list < sl->list_count; list++) { 430cabdff1aSopenharmony_ci if (!get_bits1(&sl->gb)) // ref_pic_list_modification_flag_l[01] 431cabdff1aSopenharmony_ci continue; 432cabdff1aSopenharmony_ci 433cabdff1aSopenharmony_ci for (index = 0; ; index++) { 434cabdff1aSopenharmony_ci unsigned int op = get_ue_golomb_31(&sl->gb); 435cabdff1aSopenharmony_ci 436cabdff1aSopenharmony_ci if (op == 3) 437cabdff1aSopenharmony_ci break; 438cabdff1aSopenharmony_ci 439cabdff1aSopenharmony_ci if (index >= sl->ref_count[list]) { 440cabdff1aSopenharmony_ci av_log(logctx, AV_LOG_ERROR, "reference count overflow\n"); 441cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 442cabdff1aSopenharmony_ci } else if (op > 2) { 443cabdff1aSopenharmony_ci av_log(logctx, AV_LOG_ERROR, 444cabdff1aSopenharmony_ci "illegal modification_of_pic_nums_idc %u\n", 445cabdff1aSopenharmony_ci op); 446cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 447cabdff1aSopenharmony_ci } 448cabdff1aSopenharmony_ci sl->ref_modifications[list][index].val = get_ue_golomb_long(&sl->gb); 449cabdff1aSopenharmony_ci sl->ref_modifications[list][index].op = op; 450cabdff1aSopenharmony_ci sl->nb_ref_modifications[list]++; 451cabdff1aSopenharmony_ci } 452cabdff1aSopenharmony_ci } 453cabdff1aSopenharmony_ci 454cabdff1aSopenharmony_ci return 0; 455cabdff1aSopenharmony_ci} 456cabdff1aSopenharmony_ci 457cabdff1aSopenharmony_ci/** 458cabdff1aSopenharmony_ci * Mark a picture as no longer needed for reference. The refmask 459cabdff1aSopenharmony_ci * argument allows unreferencing of individual fields or the whole frame. 460cabdff1aSopenharmony_ci * If the picture becomes entirely unreferenced, but is being held for 461cabdff1aSopenharmony_ci * display purposes, it is marked as such. 462cabdff1aSopenharmony_ci * @param refmask mask of fields to unreference; the mask is bitwise 463cabdff1aSopenharmony_ci * anded with the reference marking of pic 464cabdff1aSopenharmony_ci * @return non-zero if pic becomes entirely unreferenced (except possibly 465cabdff1aSopenharmony_ci * for display purposes) zero if one of the fields remains in 466cabdff1aSopenharmony_ci * reference 467cabdff1aSopenharmony_ci */ 468cabdff1aSopenharmony_cistatic inline int unreference_pic(H264Context *h, H264Picture *pic, int refmask) 469cabdff1aSopenharmony_ci{ 470cabdff1aSopenharmony_ci int i; 471cabdff1aSopenharmony_ci if (pic->reference &= refmask) { 472cabdff1aSopenharmony_ci return 0; 473cabdff1aSopenharmony_ci } else { 474cabdff1aSopenharmony_ci for(i = 0; h->delayed_pic[i]; i++) 475cabdff1aSopenharmony_ci if(pic == h->delayed_pic[i]){ 476cabdff1aSopenharmony_ci pic->reference = DELAYED_PIC_REF; 477cabdff1aSopenharmony_ci break; 478cabdff1aSopenharmony_ci } 479cabdff1aSopenharmony_ci return 1; 480cabdff1aSopenharmony_ci } 481cabdff1aSopenharmony_ci} 482cabdff1aSopenharmony_ci 483cabdff1aSopenharmony_ci/** 484cabdff1aSopenharmony_ci * Find a H264Picture in the short term reference list by frame number. 485cabdff1aSopenharmony_ci * @param frame_num frame number to search for 486cabdff1aSopenharmony_ci * @param idx the index into h->short_ref where returned picture is found 487cabdff1aSopenharmony_ci * undefined if no picture found. 488cabdff1aSopenharmony_ci * @return pointer to the found picture, or NULL if no pic with the provided 489cabdff1aSopenharmony_ci * frame number is found 490cabdff1aSopenharmony_ci */ 491cabdff1aSopenharmony_cistatic H264Picture *find_short(H264Context *h, int frame_num, int *idx) 492cabdff1aSopenharmony_ci{ 493cabdff1aSopenharmony_ci int i; 494cabdff1aSopenharmony_ci 495cabdff1aSopenharmony_ci for (i = 0; i < h->short_ref_count; i++) { 496cabdff1aSopenharmony_ci H264Picture *pic = h->short_ref[i]; 497cabdff1aSopenharmony_ci if (h->avctx->debug & FF_DEBUG_MMCO) 498cabdff1aSopenharmony_ci av_log(h->avctx, AV_LOG_DEBUG, "%d %d %p\n", i, pic->frame_num, pic); 499cabdff1aSopenharmony_ci if (pic->frame_num == frame_num) { 500cabdff1aSopenharmony_ci *idx = i; 501cabdff1aSopenharmony_ci return pic; 502cabdff1aSopenharmony_ci } 503cabdff1aSopenharmony_ci } 504cabdff1aSopenharmony_ci return NULL; 505cabdff1aSopenharmony_ci} 506cabdff1aSopenharmony_ci 507cabdff1aSopenharmony_ci/** 508cabdff1aSopenharmony_ci * Remove a picture from the short term reference list by its index in 509cabdff1aSopenharmony_ci * that list. This does no checking on the provided index; it is assumed 510cabdff1aSopenharmony_ci * to be valid. Other list entries are shifted down. 511cabdff1aSopenharmony_ci * @param i index into h->short_ref of picture to remove. 512cabdff1aSopenharmony_ci */ 513cabdff1aSopenharmony_cistatic void remove_short_at_index(H264Context *h, int i) 514cabdff1aSopenharmony_ci{ 515cabdff1aSopenharmony_ci assert(i >= 0 && i < h->short_ref_count); 516cabdff1aSopenharmony_ci h->short_ref[i] = NULL; 517cabdff1aSopenharmony_ci if (--h->short_ref_count) 518cabdff1aSopenharmony_ci memmove(&h->short_ref[i], &h->short_ref[i + 1], 519cabdff1aSopenharmony_ci (h->short_ref_count - i) * sizeof(H264Picture*)); 520cabdff1aSopenharmony_ci} 521cabdff1aSopenharmony_ci 522cabdff1aSopenharmony_ci/** 523cabdff1aSopenharmony_ci * @return the removed picture or NULL if an error occurs 524cabdff1aSopenharmony_ci */ 525cabdff1aSopenharmony_cistatic H264Picture *remove_short(H264Context *h, int frame_num, int ref_mask) 526cabdff1aSopenharmony_ci{ 527cabdff1aSopenharmony_ci H264Picture *pic; 528cabdff1aSopenharmony_ci int i; 529cabdff1aSopenharmony_ci 530cabdff1aSopenharmony_ci if (h->avctx->debug & FF_DEBUG_MMCO) 531cabdff1aSopenharmony_ci av_log(h->avctx, AV_LOG_DEBUG, "remove short %d count %d\n", frame_num, h->short_ref_count); 532cabdff1aSopenharmony_ci 533cabdff1aSopenharmony_ci pic = find_short(h, frame_num, &i); 534cabdff1aSopenharmony_ci if (pic) { 535cabdff1aSopenharmony_ci if (unreference_pic(h, pic, ref_mask)) 536cabdff1aSopenharmony_ci remove_short_at_index(h, i); 537cabdff1aSopenharmony_ci } 538cabdff1aSopenharmony_ci 539cabdff1aSopenharmony_ci return pic; 540cabdff1aSopenharmony_ci} 541cabdff1aSopenharmony_ci 542cabdff1aSopenharmony_ci/** 543cabdff1aSopenharmony_ci * Remove a picture from the long term reference list by its index in 544cabdff1aSopenharmony_ci * that list. 545cabdff1aSopenharmony_ci * @return the removed picture or NULL if an error occurs 546cabdff1aSopenharmony_ci */ 547cabdff1aSopenharmony_cistatic H264Picture *remove_long(H264Context *h, int i, int ref_mask) 548cabdff1aSopenharmony_ci{ 549cabdff1aSopenharmony_ci H264Picture *pic; 550cabdff1aSopenharmony_ci 551cabdff1aSopenharmony_ci pic = h->long_ref[i]; 552cabdff1aSopenharmony_ci if (pic) { 553cabdff1aSopenharmony_ci if (unreference_pic(h, pic, ref_mask)) { 554cabdff1aSopenharmony_ci assert(h->long_ref[i]->long_ref == 1); 555cabdff1aSopenharmony_ci h->long_ref[i]->long_ref = 0; 556cabdff1aSopenharmony_ci h->long_ref[i] = NULL; 557cabdff1aSopenharmony_ci h->long_ref_count--; 558cabdff1aSopenharmony_ci } 559cabdff1aSopenharmony_ci } 560cabdff1aSopenharmony_ci 561cabdff1aSopenharmony_ci return pic; 562cabdff1aSopenharmony_ci} 563cabdff1aSopenharmony_ci 564cabdff1aSopenharmony_civoid ff_h264_remove_all_refs(H264Context *h) 565cabdff1aSopenharmony_ci{ 566cabdff1aSopenharmony_ci int i; 567cabdff1aSopenharmony_ci 568cabdff1aSopenharmony_ci for (i = 0; i < 16; i++) { 569cabdff1aSopenharmony_ci remove_long(h, i, 0); 570cabdff1aSopenharmony_ci } 571cabdff1aSopenharmony_ci assert(h->long_ref_count == 0); 572cabdff1aSopenharmony_ci 573cabdff1aSopenharmony_ci if (h->short_ref_count && !h->last_pic_for_ec.f->data[0]) { 574cabdff1aSopenharmony_ci ff_h264_unref_picture(h, &h->last_pic_for_ec); 575cabdff1aSopenharmony_ci ff_h264_ref_picture(h, &h->last_pic_for_ec, h->short_ref[0]); 576cabdff1aSopenharmony_ci } 577cabdff1aSopenharmony_ci 578cabdff1aSopenharmony_ci for (i = 0; i < h->short_ref_count; i++) { 579cabdff1aSopenharmony_ci unreference_pic(h, h->short_ref[i], 0); 580cabdff1aSopenharmony_ci h->short_ref[i] = NULL; 581cabdff1aSopenharmony_ci } 582cabdff1aSopenharmony_ci h->short_ref_count = 0; 583cabdff1aSopenharmony_ci 584cabdff1aSopenharmony_ci memset(h->default_ref, 0, sizeof(h->default_ref)); 585cabdff1aSopenharmony_ci} 586cabdff1aSopenharmony_ci 587cabdff1aSopenharmony_cistatic void generate_sliding_window_mmcos(H264Context *h) 588cabdff1aSopenharmony_ci{ 589cabdff1aSopenharmony_ci MMCO *mmco = h->mmco; 590cabdff1aSopenharmony_ci int nb_mmco = 0; 591cabdff1aSopenharmony_ci 592cabdff1aSopenharmony_ci if (h->short_ref_count && 593cabdff1aSopenharmony_ci h->long_ref_count + h->short_ref_count >= h->ps.sps->ref_frame_count && 594cabdff1aSopenharmony_ci !(FIELD_PICTURE(h) && !h->first_field && h->cur_pic_ptr->reference)) { 595cabdff1aSopenharmony_ci mmco[0].opcode = MMCO_SHORT2UNUSED; 596cabdff1aSopenharmony_ci mmco[0].short_pic_num = h->short_ref[h->short_ref_count - 1]->frame_num; 597cabdff1aSopenharmony_ci nb_mmco = 1; 598cabdff1aSopenharmony_ci if (FIELD_PICTURE(h)) { 599cabdff1aSopenharmony_ci mmco[0].short_pic_num *= 2; 600cabdff1aSopenharmony_ci mmco[1].opcode = MMCO_SHORT2UNUSED; 601cabdff1aSopenharmony_ci mmco[1].short_pic_num = mmco[0].short_pic_num + 1; 602cabdff1aSopenharmony_ci nb_mmco = 2; 603cabdff1aSopenharmony_ci } 604cabdff1aSopenharmony_ci } 605cabdff1aSopenharmony_ci 606cabdff1aSopenharmony_ci h->nb_mmco = nb_mmco; 607cabdff1aSopenharmony_ci} 608cabdff1aSopenharmony_ci 609cabdff1aSopenharmony_ciint ff_h264_execute_ref_pic_marking(H264Context *h) 610cabdff1aSopenharmony_ci{ 611cabdff1aSopenharmony_ci MMCO *mmco = h->mmco; 612cabdff1aSopenharmony_ci int mmco_count; 613cabdff1aSopenharmony_ci int i, av_uninit(j); 614cabdff1aSopenharmony_ci int pps_ref_count[2] = {0}; 615cabdff1aSopenharmony_ci int current_ref_assigned = 0, err = 0; 616cabdff1aSopenharmony_ci H264Picture *av_uninit(pic); 617cabdff1aSopenharmony_ci 618cabdff1aSopenharmony_ci if (!h->ps.sps) { 619cabdff1aSopenharmony_ci av_log(h->avctx, AV_LOG_ERROR, "SPS is unset\n"); 620cabdff1aSopenharmony_ci err = AVERROR_INVALIDDATA; 621cabdff1aSopenharmony_ci goto out; 622cabdff1aSopenharmony_ci } 623cabdff1aSopenharmony_ci 624cabdff1aSopenharmony_ci if (!h->explicit_ref_marking) 625cabdff1aSopenharmony_ci generate_sliding_window_mmcos(h); 626cabdff1aSopenharmony_ci mmco_count = h->nb_mmco; 627cabdff1aSopenharmony_ci 628cabdff1aSopenharmony_ci if ((h->avctx->debug & FF_DEBUG_MMCO) && mmco_count == 0) 629cabdff1aSopenharmony_ci av_log(h->avctx, AV_LOG_DEBUG, "no mmco here\n"); 630cabdff1aSopenharmony_ci 631cabdff1aSopenharmony_ci for (i = 0; i < mmco_count; i++) { 632cabdff1aSopenharmony_ci int av_uninit(structure), av_uninit(frame_num); 633cabdff1aSopenharmony_ci if (h->avctx->debug & FF_DEBUG_MMCO) 634cabdff1aSopenharmony_ci av_log(h->avctx, AV_LOG_DEBUG, "mmco:%d %d %d\n", h->mmco[i].opcode, 635cabdff1aSopenharmony_ci h->mmco[i].short_pic_num, h->mmco[i].long_arg); 636cabdff1aSopenharmony_ci 637cabdff1aSopenharmony_ci if (mmco[i].opcode == MMCO_SHORT2UNUSED || 638cabdff1aSopenharmony_ci mmco[i].opcode == MMCO_SHORT2LONG) { 639cabdff1aSopenharmony_ci frame_num = pic_num_extract(h, mmco[i].short_pic_num, &structure); 640cabdff1aSopenharmony_ci pic = find_short(h, frame_num, &j); 641cabdff1aSopenharmony_ci if (!pic) { 642cabdff1aSopenharmony_ci if (mmco[i].opcode != MMCO_SHORT2LONG || 643cabdff1aSopenharmony_ci !h->long_ref[mmco[i].long_arg] || 644cabdff1aSopenharmony_ci h->long_ref[mmco[i].long_arg]->frame_num != frame_num) { 645cabdff1aSopenharmony_ci av_log(h->avctx, h->short_ref_count ? AV_LOG_ERROR : AV_LOG_DEBUG, "mmco: unref short failure\n"); 646cabdff1aSopenharmony_ci err = AVERROR_INVALIDDATA; 647cabdff1aSopenharmony_ci } 648cabdff1aSopenharmony_ci continue; 649cabdff1aSopenharmony_ci } 650cabdff1aSopenharmony_ci } 651cabdff1aSopenharmony_ci 652cabdff1aSopenharmony_ci switch (mmco[i].opcode) { 653cabdff1aSopenharmony_ci case MMCO_SHORT2UNUSED: 654cabdff1aSopenharmony_ci if (h->avctx->debug & FF_DEBUG_MMCO) 655cabdff1aSopenharmony_ci av_log(h->avctx, AV_LOG_DEBUG, "mmco: unref short %d count %d\n", 656cabdff1aSopenharmony_ci h->mmco[i].short_pic_num, h->short_ref_count); 657cabdff1aSopenharmony_ci remove_short(h, frame_num, structure ^ PICT_FRAME); 658cabdff1aSopenharmony_ci break; 659cabdff1aSopenharmony_ci case MMCO_SHORT2LONG: 660cabdff1aSopenharmony_ci if (h->long_ref[mmco[i].long_arg] != pic) 661cabdff1aSopenharmony_ci remove_long(h, mmco[i].long_arg, 0); 662cabdff1aSopenharmony_ci 663cabdff1aSopenharmony_ci remove_short_at_index(h, j); 664cabdff1aSopenharmony_ci h->long_ref[ mmco[i].long_arg ] = pic; 665cabdff1aSopenharmony_ci if (h->long_ref[mmco[i].long_arg]) { 666cabdff1aSopenharmony_ci h->long_ref[mmco[i].long_arg]->long_ref = 1; 667cabdff1aSopenharmony_ci h->long_ref_count++; 668cabdff1aSopenharmony_ci } 669cabdff1aSopenharmony_ci break; 670cabdff1aSopenharmony_ci case MMCO_LONG2UNUSED: 671cabdff1aSopenharmony_ci j = pic_num_extract(h, mmco[i].long_arg, &structure); 672cabdff1aSopenharmony_ci pic = h->long_ref[j]; 673cabdff1aSopenharmony_ci if (pic) { 674cabdff1aSopenharmony_ci remove_long(h, j, structure ^ PICT_FRAME); 675cabdff1aSopenharmony_ci } else if (h->avctx->debug & FF_DEBUG_MMCO) 676cabdff1aSopenharmony_ci av_log(h->avctx, AV_LOG_DEBUG, "mmco: unref long failure\n"); 677cabdff1aSopenharmony_ci break; 678cabdff1aSopenharmony_ci case MMCO_LONG: 679cabdff1aSopenharmony_ci // Comment below left from previous code as it is an interesting note. 680cabdff1aSopenharmony_ci /* First field in pair is in short term list or 681cabdff1aSopenharmony_ci * at a different long term index. 682cabdff1aSopenharmony_ci * This is not allowed; see 7.4.3.3, notes 2 and 3. 683cabdff1aSopenharmony_ci * Report the problem and keep the pair where it is, 684cabdff1aSopenharmony_ci * and mark this field valid. 685cabdff1aSopenharmony_ci */ 686cabdff1aSopenharmony_ci if (h->short_ref[0] == h->cur_pic_ptr) { 687cabdff1aSopenharmony_ci av_log(h->avctx, AV_LOG_ERROR, "mmco: cannot assign current picture to short and long at the same time\n"); 688cabdff1aSopenharmony_ci remove_short_at_index(h, 0); 689cabdff1aSopenharmony_ci } 690cabdff1aSopenharmony_ci 691cabdff1aSopenharmony_ci /* make sure the current picture is not already assigned as a long ref */ 692cabdff1aSopenharmony_ci if (h->cur_pic_ptr->long_ref) { 693cabdff1aSopenharmony_ci for (j = 0; j < FF_ARRAY_ELEMS(h->long_ref); j++) { 694cabdff1aSopenharmony_ci if (h->long_ref[j] == h->cur_pic_ptr) { 695cabdff1aSopenharmony_ci if (j != mmco[i].long_arg) 696cabdff1aSopenharmony_ci av_log(h->avctx, AV_LOG_ERROR, "mmco: cannot assign current picture to 2 long term references\n"); 697cabdff1aSopenharmony_ci remove_long(h, j, 0); 698cabdff1aSopenharmony_ci } 699cabdff1aSopenharmony_ci } 700cabdff1aSopenharmony_ci } 701cabdff1aSopenharmony_ci 702cabdff1aSopenharmony_ci if (h->long_ref[mmco[i].long_arg] != h->cur_pic_ptr) { 703cabdff1aSopenharmony_ci av_assert0(!h->cur_pic_ptr->long_ref); 704cabdff1aSopenharmony_ci remove_long(h, mmco[i].long_arg, 0); 705cabdff1aSopenharmony_ci 706cabdff1aSopenharmony_ci h->long_ref[mmco[i].long_arg] = h->cur_pic_ptr; 707cabdff1aSopenharmony_ci h->long_ref[mmco[i].long_arg]->long_ref = 1; 708cabdff1aSopenharmony_ci h->long_ref_count++; 709cabdff1aSopenharmony_ci } 710cabdff1aSopenharmony_ci 711cabdff1aSopenharmony_ci h->cur_pic_ptr->reference |= h->picture_structure; 712cabdff1aSopenharmony_ci current_ref_assigned = 1; 713cabdff1aSopenharmony_ci break; 714cabdff1aSopenharmony_ci case MMCO_SET_MAX_LONG: 715cabdff1aSopenharmony_ci assert(mmco[i].long_arg <= 16); 716cabdff1aSopenharmony_ci // just remove the long term which index is greater than new max 717cabdff1aSopenharmony_ci for (j = mmco[i].long_arg; j < 16; j++) { 718cabdff1aSopenharmony_ci remove_long(h, j, 0); 719cabdff1aSopenharmony_ci } 720cabdff1aSopenharmony_ci break; 721cabdff1aSopenharmony_ci case MMCO_RESET: 722cabdff1aSopenharmony_ci while (h->short_ref_count) { 723cabdff1aSopenharmony_ci remove_short(h, h->short_ref[0]->frame_num, 0); 724cabdff1aSopenharmony_ci } 725cabdff1aSopenharmony_ci for (j = 0; j < 16; j++) { 726cabdff1aSopenharmony_ci remove_long(h, j, 0); 727cabdff1aSopenharmony_ci } 728cabdff1aSopenharmony_ci h->poc.frame_num = h->cur_pic_ptr->frame_num = 0; 729cabdff1aSopenharmony_ci h->mmco_reset = 1; 730cabdff1aSopenharmony_ci h->cur_pic_ptr->mmco_reset = 1; 731cabdff1aSopenharmony_ci for (j = 0; j < FF_ARRAY_ELEMS(h->last_pocs); j++) 732cabdff1aSopenharmony_ci h->last_pocs[j] = INT_MIN; 733cabdff1aSopenharmony_ci break; 734cabdff1aSopenharmony_ci default: av_assert0(0); 735cabdff1aSopenharmony_ci } 736cabdff1aSopenharmony_ci } 737cabdff1aSopenharmony_ci 738cabdff1aSopenharmony_ci if (!current_ref_assigned) { 739cabdff1aSopenharmony_ci /* Second field of complementary field pair; the first field of 740cabdff1aSopenharmony_ci * which is already referenced. If short referenced, it 741cabdff1aSopenharmony_ci * should be first entry in short_ref. If not, it must exist 742cabdff1aSopenharmony_ci * in long_ref; trying to put it on the short list here is an 743cabdff1aSopenharmony_ci * error in the encoded bit stream (ref: 7.4.3.3, NOTE 2 and 3). 744cabdff1aSopenharmony_ci */ 745cabdff1aSopenharmony_ci if (h->short_ref_count && h->short_ref[0] == h->cur_pic_ptr) { 746cabdff1aSopenharmony_ci /* Just mark the second field valid */ 747cabdff1aSopenharmony_ci h->cur_pic_ptr->reference |= h->picture_structure; 748cabdff1aSopenharmony_ci } else if (h->cur_pic_ptr->long_ref) { 749cabdff1aSopenharmony_ci av_log(h->avctx, AV_LOG_ERROR, "illegal short term reference " 750cabdff1aSopenharmony_ci "assignment for second field " 751cabdff1aSopenharmony_ci "in complementary field pair " 752cabdff1aSopenharmony_ci "(first field is long term)\n"); 753cabdff1aSopenharmony_ci err = AVERROR_INVALIDDATA; 754cabdff1aSopenharmony_ci } else { 755cabdff1aSopenharmony_ci pic = remove_short(h, h->cur_pic_ptr->frame_num, 0); 756cabdff1aSopenharmony_ci if (pic) { 757cabdff1aSopenharmony_ci av_log(h->avctx, AV_LOG_ERROR, "illegal short term buffer state detected\n"); 758cabdff1aSopenharmony_ci err = AVERROR_INVALIDDATA; 759cabdff1aSopenharmony_ci } 760cabdff1aSopenharmony_ci 761cabdff1aSopenharmony_ci if (h->short_ref_count) 762cabdff1aSopenharmony_ci memmove(&h->short_ref[1], &h->short_ref[0], 763cabdff1aSopenharmony_ci h->short_ref_count * sizeof(H264Picture*)); 764cabdff1aSopenharmony_ci 765cabdff1aSopenharmony_ci h->short_ref[0] = h->cur_pic_ptr; 766cabdff1aSopenharmony_ci h->short_ref_count++; 767cabdff1aSopenharmony_ci h->cur_pic_ptr->reference |= h->picture_structure; 768cabdff1aSopenharmony_ci } 769cabdff1aSopenharmony_ci } 770cabdff1aSopenharmony_ci 771cabdff1aSopenharmony_ci if (h->long_ref_count + h->short_ref_count > FFMAX(h->ps.sps->ref_frame_count, 1)) { 772cabdff1aSopenharmony_ci 773cabdff1aSopenharmony_ci /* We have too many reference frames, probably due to corrupted 774cabdff1aSopenharmony_ci * stream. Need to discard one frame. Prevents overrun of the 775cabdff1aSopenharmony_ci * short_ref and long_ref buffers. 776cabdff1aSopenharmony_ci */ 777cabdff1aSopenharmony_ci av_log(h->avctx, AV_LOG_ERROR, 778cabdff1aSopenharmony_ci "number of reference frames (%d+%d) exceeds max (%d; probably " 779cabdff1aSopenharmony_ci "corrupt input), discarding one\n", 780cabdff1aSopenharmony_ci h->long_ref_count, h->short_ref_count, h->ps.sps->ref_frame_count); 781cabdff1aSopenharmony_ci err = AVERROR_INVALIDDATA; 782cabdff1aSopenharmony_ci 783cabdff1aSopenharmony_ci if (h->long_ref_count && !h->short_ref_count) { 784cabdff1aSopenharmony_ci for (i = 0; i < 16; ++i) 785cabdff1aSopenharmony_ci if (h->long_ref[i]) 786cabdff1aSopenharmony_ci break; 787cabdff1aSopenharmony_ci 788cabdff1aSopenharmony_ci assert(i < 16); 789cabdff1aSopenharmony_ci remove_long(h, i, 0); 790cabdff1aSopenharmony_ci } else { 791cabdff1aSopenharmony_ci pic = h->short_ref[h->short_ref_count - 1]; 792cabdff1aSopenharmony_ci remove_short(h, pic->frame_num, 0); 793cabdff1aSopenharmony_ci } 794cabdff1aSopenharmony_ci } 795cabdff1aSopenharmony_ci 796cabdff1aSopenharmony_ci for (i = 0; i<h->short_ref_count; i++) { 797cabdff1aSopenharmony_ci pic = h->short_ref[i]; 798cabdff1aSopenharmony_ci if (pic->invalid_gap) { 799cabdff1aSopenharmony_ci int d = av_mod_uintp2(h->cur_pic_ptr->frame_num - pic->frame_num, h->ps.sps->log2_max_frame_num); 800cabdff1aSopenharmony_ci if (d > h->ps.sps->ref_frame_count) 801cabdff1aSopenharmony_ci remove_short(h, pic->frame_num, 0); 802cabdff1aSopenharmony_ci } 803cabdff1aSopenharmony_ci } 804cabdff1aSopenharmony_ci 805cabdff1aSopenharmony_ci print_short_term(h); 806cabdff1aSopenharmony_ci print_long_term(h); 807cabdff1aSopenharmony_ci 808cabdff1aSopenharmony_ci for (i = 0; i < FF_ARRAY_ELEMS(h->ps.pps_list); i++) { 809cabdff1aSopenharmony_ci if (h->ps.pps_list[i]) { 810cabdff1aSopenharmony_ci const PPS *pps = (const PPS *)h->ps.pps_list[i]->data; 811cabdff1aSopenharmony_ci pps_ref_count[0] = FFMAX(pps_ref_count[0], pps->ref_count[0]); 812cabdff1aSopenharmony_ci pps_ref_count[1] = FFMAX(pps_ref_count[1], pps->ref_count[1]); 813cabdff1aSopenharmony_ci } 814cabdff1aSopenharmony_ci } 815cabdff1aSopenharmony_ci 816cabdff1aSopenharmony_ci // Detect unmarked random access points 817cabdff1aSopenharmony_ci if ( err >= 0 818cabdff1aSopenharmony_ci && h->long_ref_count==0 819cabdff1aSopenharmony_ci && ( h->short_ref_count<=2 820cabdff1aSopenharmony_ci || pps_ref_count[0] <= 2 && pps_ref_count[1] <= 1 && h->avctx->has_b_frames 821cabdff1aSopenharmony_ci || pps_ref_count[0] <= 1 + (h->picture_structure != PICT_FRAME) && pps_ref_count[1] <= 1) 822cabdff1aSopenharmony_ci && pps_ref_count[0]<=2 + (h->picture_structure != PICT_FRAME) + (2*!h->has_recovery_point) 823cabdff1aSopenharmony_ci && h->cur_pic_ptr->f->pict_type == AV_PICTURE_TYPE_I){ 824cabdff1aSopenharmony_ci h->cur_pic_ptr->recovered |= 1; 825cabdff1aSopenharmony_ci if(!h->avctx->has_b_frames) 826cabdff1aSopenharmony_ci h->frame_recovered |= FRAME_RECOVERED_SEI; 827cabdff1aSopenharmony_ci } 828cabdff1aSopenharmony_ci 829cabdff1aSopenharmony_ciout: 830cabdff1aSopenharmony_ci return (h->avctx->err_recognition & AV_EF_EXPLODE) ? err : 0; 831cabdff1aSopenharmony_ci} 832cabdff1aSopenharmony_ci 833cabdff1aSopenharmony_ciint ff_h264_decode_ref_pic_marking(H264SliceContext *sl, GetBitContext *gb, 834cabdff1aSopenharmony_ci const H2645NAL *nal, void *logctx) 835cabdff1aSopenharmony_ci{ 836cabdff1aSopenharmony_ci int i; 837cabdff1aSopenharmony_ci MMCO *mmco = sl->mmco; 838cabdff1aSopenharmony_ci int nb_mmco = 0; 839cabdff1aSopenharmony_ci 840cabdff1aSopenharmony_ci if (nal->type == H264_NAL_IDR_SLICE) { // FIXME fields 841cabdff1aSopenharmony_ci skip_bits1(gb); // broken_link 842cabdff1aSopenharmony_ci if (get_bits1(gb)) { 843cabdff1aSopenharmony_ci mmco[0].opcode = MMCO_LONG; 844cabdff1aSopenharmony_ci mmco[0].long_arg = 0; 845cabdff1aSopenharmony_ci nb_mmco = 1; 846cabdff1aSopenharmony_ci } 847cabdff1aSopenharmony_ci sl->explicit_ref_marking = 1; 848cabdff1aSopenharmony_ci } else { 849cabdff1aSopenharmony_ci sl->explicit_ref_marking = get_bits1(gb); 850cabdff1aSopenharmony_ci if (sl->explicit_ref_marking) { 851cabdff1aSopenharmony_ci for (i = 0; i < FF_ARRAY_ELEMS(sl->mmco); i++) { 852cabdff1aSopenharmony_ci MMCOOpcode opcode = get_ue_golomb_31(gb); 853cabdff1aSopenharmony_ci 854cabdff1aSopenharmony_ci mmco[i].opcode = opcode; 855cabdff1aSopenharmony_ci if (opcode == MMCO_SHORT2UNUSED || opcode == MMCO_SHORT2LONG) { 856cabdff1aSopenharmony_ci mmco[i].short_pic_num = 857cabdff1aSopenharmony_ci (sl->curr_pic_num - get_ue_golomb_long(gb) - 1) & 858cabdff1aSopenharmony_ci (sl->max_pic_num - 1); 859cabdff1aSopenharmony_ci } 860cabdff1aSopenharmony_ci if (opcode == MMCO_SHORT2LONG || opcode == MMCO_LONG2UNUSED || 861cabdff1aSopenharmony_ci opcode == MMCO_LONG || opcode == MMCO_SET_MAX_LONG) { 862cabdff1aSopenharmony_ci unsigned int long_arg = get_ue_golomb_31(gb); 863cabdff1aSopenharmony_ci if (long_arg >= 32 || 864cabdff1aSopenharmony_ci (long_arg >= 16 && !(opcode == MMCO_SET_MAX_LONG && 865cabdff1aSopenharmony_ci long_arg == 16) && 866cabdff1aSopenharmony_ci !(opcode == MMCO_LONG2UNUSED && FIELD_PICTURE(sl)))) { 867cabdff1aSopenharmony_ci av_log(logctx, AV_LOG_ERROR, 868cabdff1aSopenharmony_ci "illegal long ref in memory management control " 869cabdff1aSopenharmony_ci "operation %d\n", opcode); 870cabdff1aSopenharmony_ci sl->nb_mmco = i; 871cabdff1aSopenharmony_ci return -1; 872cabdff1aSopenharmony_ci } 873cabdff1aSopenharmony_ci mmco[i].long_arg = long_arg; 874cabdff1aSopenharmony_ci } 875cabdff1aSopenharmony_ci 876cabdff1aSopenharmony_ci if (opcode > (unsigned) MMCO_LONG) { 877cabdff1aSopenharmony_ci av_log(logctx, AV_LOG_ERROR, 878cabdff1aSopenharmony_ci "illegal memory management control operation %d\n", 879cabdff1aSopenharmony_ci opcode); 880cabdff1aSopenharmony_ci sl->nb_mmco = i; 881cabdff1aSopenharmony_ci return -1; 882cabdff1aSopenharmony_ci } 883cabdff1aSopenharmony_ci if (opcode == MMCO_END) 884cabdff1aSopenharmony_ci break; 885cabdff1aSopenharmony_ci } 886cabdff1aSopenharmony_ci nb_mmco = i; 887cabdff1aSopenharmony_ci } 888cabdff1aSopenharmony_ci } 889cabdff1aSopenharmony_ci 890cabdff1aSopenharmony_ci sl->nb_mmco = nb_mmco; 891cabdff1aSopenharmony_ci 892cabdff1aSopenharmony_ci return 0; 893cabdff1aSopenharmony_ci} 894