ffmpeg / libavcodec / h264_refs.c @ 3d542120
History | View | Annotate | Download (25.3 KB)
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 |
/**
|
23 |
* @file
|
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 |
|
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]; |
320 |
for(j=0; j<2; j++){ |
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]; |
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 |
|
477 |
void ff_generate_sliding_window_mmcos(H264Context *h) {
|
478 |
MpegEncContext * const s = &h->s;
|
479 |
assert(h->long_ref_count + h->short_ref_count <= h->sps.ref_frame_count); |
480 |
|
481 |
h->mmco_index= 0;
|
482 |
if(h->short_ref_count && h->long_ref_count + h->short_ref_count == h->sps.ref_frame_count &&
|
483 |
!(FIELD_PICTURE && !s->first_field && s->current_picture_ptr->reference)) { |
484 |
h->mmco[0].opcode= MMCO_SHORT2UNUSED;
|
485 |
h->mmco[0].short_pic_num= h->short_ref[ h->short_ref_count - 1 ]->frame_num; |
486 |
h->mmco_index= 1;
|
487 |
if (FIELD_PICTURE) {
|
488 |
h->mmco[0].short_pic_num *= 2; |
489 |
h->mmco[1].opcode= MMCO_SHORT2UNUSED;
|
490 |
h->mmco[1].short_pic_num= h->mmco[0].short_pic_num + 1; |
491 |
h->mmco_index= 2;
|
492 |
} |
493 |
} |
494 |
} |
495 |
|
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{
|
695 |
ff_generate_sliding_window_mmcos(h); |
696 |
} |
697 |
} |
698 |
|
699 |
return 0; |
700 |
} |