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