annotate h264_refs.c @ 12530:63edd10ad4bc libavcodec tip

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