Mercurial > libavcodec.hg
comparison h263dec.c @ 745:25d7fb7c89be libavcodec
better/cleaner error resilience (done in a 2nd pass after decoding)
h263/mpeg4 out of order slice decoding
author | michaelni |
---|---|
date | Sun, 13 Oct 2002 13:16:04 +0000 |
parents | 16dab8296293 |
children | 3d4377531f6c |
comparison
equal
deleted
inserted
replaced
744:2f7da29ede37 | 745:25d7fb7c89be |
---|---|
18 */ | 18 */ |
19 #include "avcodec.h" | 19 #include "avcodec.h" |
20 #include "dsputil.h" | 20 #include "dsputil.h" |
21 #include "mpegvideo.h" | 21 #include "mpegvideo.h" |
22 | 22 |
23 #if 1 | |
24 #define PRINT_QP(a, b) {} | |
25 #else | |
26 #define PRINT_QP(a, b) printf(a, b) | |
27 #endif | |
28 | |
23 //#define DEBUG | 29 //#define DEBUG |
24 //#define PRINT_FRAME_TIME | 30 //#define PRINT_FRAME_TIME |
25 #ifdef PRINT_FRAME_TIME | 31 #ifdef PRINT_FRAME_TIME |
26 static inline long long rdtsc() | 32 static inline long long rdtsc() |
27 { | 33 { |
32 // printf("%d\n", int(l/1000)); | 38 // printf("%d\n", int(l/1000)); |
33 return l; | 39 return l; |
34 } | 40 } |
35 #endif | 41 #endif |
36 | 42 |
43 const UINT16 ff_mpeg4_resync_prefix[8]; | |
44 | |
37 static int h263_decode_init(AVCodecContext *avctx) | 45 static int h263_decode_init(AVCodecContext *avctx) |
38 { | 46 { |
39 MpegEncContext *s = avctx->priv_data; | 47 MpegEncContext *s = avctx->priv_data; |
40 | 48 |
41 s->avctx = avctx; | 49 s->avctx = avctx; |
42 s->out_format = FMT_H263; | 50 s->out_format = FMT_H263; |
43 | 51 |
44 s->width = avctx->width; | 52 s->width = avctx->width; |
45 s->height = avctx->height; | 53 s->height = avctx->height; |
46 s->workaround_bugs= avctx->workaround_bugs; | 54 s->workaround_bugs= avctx->workaround_bugs; |
55 | |
56 // set defaults | |
57 s->quant_precision=5; | |
58 s->progressive_sequence=1; | |
59 s->decode_mb= ff_h263_decode_mb; | |
47 | 60 |
48 /* select sub codec */ | 61 /* select sub codec */ |
49 switch(avctx->codec->id) { | 62 switch(avctx->codec->id) { |
50 case CODEC_ID_H263: | 63 case CODEC_ID_H263: |
51 s->gob_number = 0; | 64 s->gob_number = 0; |
113 /** | 126 /** |
114 * retunrs the number of bytes consumed for building the current frame | 127 * retunrs the number of bytes consumed for building the current frame |
115 */ | 128 */ |
116 static int get_consumed_bytes(MpegEncContext *s, int buf_size){ | 129 static int get_consumed_bytes(MpegEncContext *s, int buf_size){ |
117 int pos= (get_bits_count(&s->gb)+7)>>3; | 130 int pos= (get_bits_count(&s->gb)+7)>>3; |
118 | |
119 if(s->divx_version>=500){ | 131 if(s->divx_version>=500){ |
120 //we would have to scan through the whole buf to handle the weird reordering ... | 132 //we would have to scan through the whole buf to handle the weird reordering ... |
121 return buf_size; | 133 return buf_size; |
122 }else{ | 134 }else{ |
123 if(pos==0) pos=1; //avoid infinite loops (i doubt thats needed but ...) | 135 if(pos==0) pos=1; //avoid infinite loops (i doubt thats needed but ...) |
125 | 137 |
126 return pos; | 138 return pos; |
127 } | 139 } |
128 } | 140 } |
129 | 141 |
142 static int decode_slice(MpegEncContext *s){ | |
143 s->last_resync_gb= s->gb; | |
144 s->first_slice_line= 1; | |
145 | |
146 s->resync_mb_x= s->mb_x; | |
147 s->resync_mb_y= s->mb_y; | |
148 | |
149 s->y_dc_scale= s->y_dc_scale_table[ s->qscale ]; | |
150 s->c_dc_scale= s->c_dc_scale_table[ s->qscale ]; | |
151 | |
152 if(s->partitioned_frame){ | |
153 const int qscale= s->qscale; | |
154 | |
155 if(s->codec_id==CODEC_ID_MPEG4){ | |
156 if(ff_mpeg4_decode_partitions(s) < 0) | |
157 return -1; | |
158 } | |
159 | |
160 /* restore variables which where modified */ | |
161 s->first_slice_line=1; | |
162 s->mb_x= s->resync_mb_x; | |
163 s->mb_y= s->resync_mb_y; | |
164 s->qscale= qscale; | |
165 s->y_dc_scale= s->y_dc_scale_table[ s->qscale ]; | |
166 s->c_dc_scale= s->c_dc_scale_table[ s->qscale ]; | |
167 } | |
168 | |
169 for(; s->mb_y < s->mb_height; s->mb_y++) { | |
170 /* per-row end of slice checks */ | |
171 if(s->msmpeg4_version){ | |
172 if(s->resync_mb_y + s->slice_height == s->mb_y){ | |
173 const int xy= s->mb_x + s->mb_y*s->mb_width; | |
174 s->error_status_table[xy-1]|= AC_END|DC_END|MV_END; | |
175 return 0; | |
176 } | |
177 } | |
178 | |
179 if(s->msmpeg4_version==1){ | |
180 s->last_dc[0]= | |
181 s->last_dc[1]= | |
182 s->last_dc[2]= 128; | |
183 } | |
184 | |
185 ff_init_block_index(s); | |
186 for(; s->mb_x < s->mb_width; s->mb_x++) { | |
187 int ret; | |
188 | |
189 ff_update_block_index(s); | |
190 | |
191 if(s->resync_mb_x == s->mb_x && s->resync_mb_y+1 == s->mb_y){ | |
192 s->first_slice_line=0; | |
193 } | |
194 | |
195 /* DCT & quantize */ | |
196 clear_blocks(s->block[0]); | |
197 | |
198 s->mv_dir = MV_DIR_FORWARD; | |
199 s->mv_type = MV_TYPE_16X16; | |
200 //printf("%d %d %06X\n", ret, get_bits_count(&s->gb), show_bits(&s->gb, 24)); | |
201 ret= s->decode_mb(s, s->block); | |
202 | |
203 PRINT_QP("%2d", s->qscale); | |
204 MPV_decode_mb(s, s->block); | |
205 | |
206 if(ret<0){ | |
207 const int xy= s->mb_x + s->mb_y*s->mb_width; | |
208 if(ret==SLICE_END){ | |
209 //printf("%d %d %06X\n", s->mb_x, s->gb.size*8 - get_bits_count(&s->gb), show_bits(&s->gb, 24)); | |
210 s->error_status_table[xy]|= AC_END; | |
211 if(!s->partitioned_frame) | |
212 s->error_status_table[xy]|= MV_END|DC_END; | |
213 | |
214 if(++s->mb_x >= s->mb_width){ | |
215 s->mb_x=0; | |
216 ff_draw_horiz_band(s); | |
217 s->mb_y++; | |
218 } | |
219 return 0; | |
220 }else if(ret==SLICE_NOEND){ | |
221 fprintf(stderr,"Slice mismatch at MB: %d\n", xy); | |
222 return -1; | |
223 } | |
224 fprintf(stderr,"Error at MB: %d\n", xy); | |
225 s->error_status_table[xy]|= AC_ERROR; | |
226 if(!s->partitioned_frame) | |
227 s->error_status_table[xy]|= DC_ERROR|MV_ERROR; | |
228 | |
229 return -1; | |
230 } | |
231 } | |
232 | |
233 ff_draw_horiz_band(s); | |
234 | |
235 PRINT_QP("%s", "\n"); | |
236 | |
237 s->mb_x= 0; | |
238 } | |
239 | |
240 assert(s->mb_x==0 && s->mb_y==s->mb_height); | |
241 | |
242 // handle formats which dont have unique end markers | |
243 if(s->msmpeg4_version || (s->workaround_bugs&FF_BUG_NO_PADDING)){ //FIXME perhaps solve this more cleanly | |
244 int left= s->gb.size*8 - get_bits_count(&s->gb); | |
245 int max_extra=7; | |
246 | |
247 /* no markers in M$ crap */ | |
248 if(s->msmpeg4_version && s->pict_type==I_TYPE) | |
249 max_extra+= 17; | |
250 | |
251 /* buggy padding but the frame should still end approximately at the bitstream end */ | |
252 if((s->workaround_bugs&FF_BUG_NO_PADDING) && s->error_resilience>=3) | |
253 max_extra+= 48; | |
254 else if((s->workaround_bugs&FF_BUG_NO_PADDING)) | |
255 max_extra+= 256*256*256*64; | |
256 | |
257 if(left>max_extra){ | |
258 fprintf(stderr, "discarding %d junk bits at end, next would be %X\n", left, show_bits(&s->gb, 24)); | |
259 } | |
260 else if(left<0){ | |
261 fprintf(stderr, "overreading %d bits\n", -left); | |
262 }else | |
263 s->error_status_table[s->mb_num-1]|= AC_END|MV_END|DC_END; | |
264 | |
265 return 0; | |
266 } | |
267 | |
268 fprintf(stderr, "slice end not reached but screenspace end (%d left %06X)\n", | |
269 s->gb.size*8 - get_bits_count(&s->gb), | |
270 show_bits(&s->gb, 24)); | |
271 return -1; | |
272 } | |
273 | |
130 static int h263_decode_frame(AVCodecContext *avctx, | 274 static int h263_decode_frame(AVCodecContext *avctx, |
131 void *data, int *data_size, | 275 void *data, int *data_size, |
132 UINT8 *buf, int buf_size) | 276 UINT8 *buf, int buf_size) |
133 { | 277 { |
134 MpegEncContext *s = avctx->priv_data; | 278 MpegEncContext *s = avctx->priv_data; |
135 int ret; | 279 int ret,i; |
136 AVPicture *pict = data; | 280 AVPicture *pict = data; |
137 #ifdef PRINT_FRAME_TIME | 281 #ifdef PRINT_FRAME_TIME |
138 uint64_t time= rdtsc(); | 282 uint64_t time= rdtsc(); |
139 #endif | 283 #endif |
140 #ifdef DEBUG | 284 #ifdef DEBUG |
142 printf("bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]); | 286 printf("bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]); |
143 #endif | 287 #endif |
144 | 288 |
145 s->hurry_up= avctx->hurry_up; | 289 s->hurry_up= avctx->hurry_up; |
146 s->error_resilience= avctx->error_resilience; | 290 s->error_resilience= avctx->error_resilience; |
147 | |
148 s->workaround_bugs= avctx->workaround_bugs; | |
149 if(s->avctx->fourcc == ff_get_fourcc("XVIX") && s->workaround_bugs==0) | |
150 s->workaround_bugs=2; | |
151 | 291 |
152 s->flags= avctx->flags; | 292 s->flags= avctx->flags; |
153 | 293 |
154 *data_size = 0; | 294 *data_size = 0; |
155 | 295 |
163 }else | 303 }else |
164 init_get_bits(&s->gb, buf, buf_size); | 304 init_get_bits(&s->gb, buf, buf_size); |
165 s->bitstream_buffer_size=0; | 305 s->bitstream_buffer_size=0; |
166 | 306 |
167 if (!s->context_initialized) { | 307 if (!s->context_initialized) { |
168 if (MPV_common_init(s) < 0) //we need the idct permutaton for reading a custom matrix | 308 if (DCT_common_init(s) < 0) //we need the idct permutaton for reading a custom matrix |
169 return -1; | 309 return -1; |
170 } | 310 } |
171 | 311 |
172 /* let's go :-) */ | 312 /* let's go :-) */ |
173 if (s->h263_msmpeg4) { | 313 if (s->h263_msmpeg4) { |
179 ret = intel_h263_decode_picture_header(s); | 319 ret = intel_h263_decode_picture_header(s); |
180 } else { | 320 } else { |
181 ret = h263_decode_picture_header(s); | 321 ret = h263_decode_picture_header(s); |
182 } | 322 } |
183 avctx->has_b_frames= s->has_b_frames; | 323 avctx->has_b_frames= s->has_b_frames; |
324 | |
325 if(s->workaround_bugs&FF_BUG_AUTODETECT){ | |
326 if(s->avctx->fourcc == ff_get_fourcc("XVIX")) | |
327 s->workaround_bugs|= FF_BUG_XVID_ILACE; | |
328 | |
329 if(s->avctx->fourcc == ff_get_fourcc("MP4S")) | |
330 s->workaround_bugs|= FF_BUG_AC_VLC; | |
331 | |
332 if(s->avctx->fourcc == ff_get_fourcc("M4S2")) | |
333 s->workaround_bugs|= FF_BUG_AC_VLC; | |
334 | |
335 if(s->avctx->fourcc == ff_get_fourcc("UMP4")){ | |
336 s->workaround_bugs|= FF_BUG_UMP4; | |
337 s->workaround_bugs|= FF_BUG_AC_VLC; | |
338 } | |
339 | |
340 if(s->divx_version==500) | |
341 s->workaround_bugs|= FF_BUG_NO_PADDING; | |
342 | |
343 /* very ugly XVID padding bug detection FIXME/XXX solve this differently | |
344 * lets hope this at least works | |
345 */ | |
346 if( s->resync_marker==0 && s->data_partitioning==0 && s->divx_version==0 | |
347 && s->codec_id==CODEC_ID_MPEG4 && s->vo_type==0) | |
348 s->workaround_bugs|= FF_BUG_NO_PADDING; | |
349 | |
350 if(s->lavc_build && s->lavc_build<4609) //FIXME not sure about the version num but a 4609 file seems ok | |
351 s->workaround_bugs|= FF_BUG_NO_PADDING; | |
352 } | |
353 | |
354 | |
184 #if 0 // dump bits per frame / qp / complexity | 355 #if 0 // dump bits per frame / qp / complexity |
185 { | 356 { |
186 static FILE *f=NULL; | 357 static FILE *f=NULL; |
187 if(!f) f=fopen("rate_qp_cplx.txt", "w"); | 358 if(!f) f=fopen("rate_qp_cplx.txt", "w"); |
188 fprintf(f, "%d %d %f\n", buf_size, s->qscale, buf_size*(double)s->qscale); | 359 fprintf(f, "%d %d %f\n", buf_size, s->qscale, buf_size*(double)s->qscale); |
208 if (s->aspect_ratio_info == FF_ASPECT_EXTENDED) | 379 if (s->aspect_ratio_info == FF_ASPECT_EXTENDED) |
209 { | 380 { |
210 avctx->aspected_width = s->aspected_width; | 381 avctx->aspected_width = s->aspected_width; |
211 avctx->aspected_height = s->aspected_height; | 382 avctx->aspected_height = s->aspected_height; |
212 } | 383 } |
384 | |
385 if (s->codec_id==CODEC_ID_H263 && s->codec_id==CODEC_ID_H263) | |
386 s->gob_index = ff_h263_get_gob_height(s); | |
387 | |
213 if (MPV_common_init(s) < 0) | 388 if (MPV_common_init(s) < 0) |
214 return -1; | 389 return -1; |
215 } | 390 } |
216 | 391 |
217 if(ret==FRAME_SKIPED) return get_consumed_bytes(s, buf_size); | 392 if(ret==FRAME_SKIPED) return get_consumed_bytes(s, buf_size); |
218 /* skip if the header was thrashed */ | 393 /* skip if the header was thrashed */ |
219 if (ret < 0){ | 394 if (ret < 0){ |
220 fprintf(stderr, "header damaged\n"); | 395 fprintf(stderr, "header damaged\n"); |
221 return -1; | 396 return -1; |
236 | 411 |
237 #ifdef DEBUG | 412 #ifdef DEBUG |
238 printf("qscale=%d\n", s->qscale); | 413 printf("qscale=%d\n", s->qscale); |
239 #endif | 414 #endif |
240 | 415 |
241 /* init resync/ error resilience specific variables */ | 416 if(s->error_resilience) |
242 s->next_resync_qscale= s->qscale; | 417 memset(s->error_status_table, MV_ERROR|AC_ERROR|DC_ERROR|VP_START|AC_END|DC_END|MV_END, s->mb_num*sizeof(UINT8)); |
243 s->next_resync_gb= s->gb; | 418 |
244 if(s->resync_marker) s->mb_num_left= 0; | |
245 else s->mb_num_left= s->mb_num; | |
246 | |
247 /* decode each macroblock */ | 419 /* decode each macroblock */ |
248 s->block_wrap[0]= | 420 s->block_wrap[0]= |
249 s->block_wrap[1]= | 421 s->block_wrap[1]= |
250 s->block_wrap[2]= | 422 s->block_wrap[2]= |
251 s->block_wrap[3]= s->mb_width*2 + 2; | 423 s->block_wrap[3]= s->mb_width*2 + 2; |
252 s->block_wrap[4]= | 424 s->block_wrap[4]= |
253 s->block_wrap[5]= s->mb_width + 2; | 425 s->block_wrap[5]= s->mb_width + 2; |
254 for(s->mb_y=0; s->mb_y < s->mb_height; s->mb_y++) { | 426 s->mb_x=0; |
255 /* Check for GOB headers on H.263 */ | 427 s->mb_y=0; |
256 /* FIXME: In the future H.263+ will have intra prediction */ | 428 |
257 /* and we are gonna need another way to detect MPEG4 */ | 429 decode_slice(s); |
258 if (s->mb_y && !s->h263_pred) { | 430 s->error_status_table[0]|= VP_START; |
259 s->first_slice_line = h263_decode_gob_header(s); | 431 while(s->mb_y<s->mb_height && s->gb.size*8 - get_bits_count(&s->gb)>32){ |
260 } | 432 if(s->msmpeg4_version){ |
261 | 433 if(s->mb_x!=0 || (s->mb_y%s->slice_height)!=0) |
262 if(s->msmpeg4_version==1){ | 434 break; |
263 s->last_dc[0]= | 435 }else{ |
264 s->last_dc[1]= | 436 if(ff_h263_resync(s)<0) |
265 s->last_dc[2]= 128; | 437 break; |
266 } | 438 } |
267 | 439 |
268 s->y_dc_scale= s->y_dc_scale_table[ s->qscale ]; | 440 if(s->msmpeg4_version!=4) |
269 s->c_dc_scale= s->c_dc_scale_table[ s->qscale ]; | 441 ff_mpeg4_clean_buffers(s); |
270 | 442 |
271 s->block_index[0]= s->block_wrap[0]*(s->mb_y*2 + 1) - 1; | 443 decode_slice(s); |
272 s->block_index[1]= s->block_wrap[0]*(s->mb_y*2 + 1); | 444 s->error_status_table[s->resync_mb_x + s->resync_mb_y*s->mb_width]|= VP_START; |
273 s->block_index[2]= s->block_wrap[0]*(s->mb_y*2 + 2) - 1; | |
274 s->block_index[3]= s->block_wrap[0]*(s->mb_y*2 + 2); | |
275 s->block_index[4]= s->block_wrap[4]*(s->mb_y + 1) + s->block_wrap[0]*(s->mb_height*2 + 2); | |
276 s->block_index[5]= s->block_wrap[4]*(s->mb_y + 1 + s->mb_height + 2) + s->block_wrap[0]*(s->mb_height*2 + 2); | |
277 for(s->mb_x=0; s->mb_x < s->mb_width; s->mb_x++) { | |
278 s->block_index[0]+=2; | |
279 s->block_index[1]+=2; | |
280 s->block_index[2]+=2; | |
281 s->block_index[3]+=2; | |
282 s->block_index[4]++; | |
283 s->block_index[5]++; | |
284 #ifdef DEBUG | |
285 printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y); | |
286 #endif | |
287 | |
288 if(s->resync_marker){ | |
289 if(s->mb_num_left<=0){ | |
290 /* except the first block */ | |
291 if(s->mb_x!=0 || s->mb_y!=0){ | |
292 /* did we miss the next resync marker without noticing an error yet */ | |
293 if(((get_bits_count(&s->gb)+8)&(~7)) != s->next_resync_pos && s->decoding_error==0){ | |
294 fprintf(stderr, "slice end missmatch x:%d y:%d %d %d\n", | |
295 s->mb_x, s->mb_y, get_bits_count(&s->gb), s->next_resync_pos); | |
296 ff_conceal_past_errors(s, 1); | |
297 } | |
298 } | |
299 s->qscale= s->next_resync_qscale; | |
300 s->y_dc_scale= s->y_dc_scale_table[ s->qscale ]; | |
301 s->c_dc_scale= s->c_dc_scale_table[ s->qscale ]; | |
302 | |
303 s->gb= s->next_resync_gb; | |
304 s->resync_mb_x= s->mb_x; //we know that the marker is here cuz mb_num_left was the distance to it | |
305 s->resync_mb_y= s->mb_y; | |
306 s->first_slice_line=1; | |
307 | |
308 if(s->codec_id==CODEC_ID_MPEG4){ | |
309 ff_mpeg4_clean_buffers(s); | |
310 ff_mpeg4_resync(s); | |
311 } | |
312 } | |
313 | |
314 if( s->resync_mb_x==s->mb_x | |
315 && s->resync_mb_y==s->mb_y && s->decoding_error!=0){ | |
316 fprintf(stderr, "resynced at %d %d\n", s->mb_x, s->mb_y); | |
317 s->decoding_error= 0; | |
318 } | |
319 } | |
320 | |
321 //fprintf(stderr,"\nFrame: %d\tMB: %d",avctx->frame_number, (s->mb_y * s->mb_width) + s->mb_x); | |
322 /* DCT & quantize */ | |
323 if(s->decoding_error!=DECODING_DESYNC){ | |
324 int last_error= s->decoding_error; | |
325 clear_blocks(s->block[0]); | |
326 | |
327 s->mv_dir = MV_DIR_FORWARD; | |
328 s->mv_type = MV_TYPE_16X16; | |
329 if (s->h263_msmpeg4) { | |
330 if (msmpeg4_decode_mb(s, s->block) < 0) { | |
331 fprintf(stderr,"Error at MB: %d\n", (s->mb_y * s->mb_width) + s->mb_x); | |
332 s->decoding_error=DECODING_DESYNC; | |
333 } | |
334 } else { | |
335 if (h263_decode_mb(s, s->block) < 0) { | |
336 fprintf(stderr,"Error at MB: %d\n", (s->mb_y * s->mb_width) + s->mb_x); | |
337 s->decoding_error=DECODING_DESYNC; | |
338 } | |
339 } | |
340 | |
341 if(s->decoding_error!=last_error){ | |
342 ff_conceal_past_errors(s, 0); | |
343 } | |
344 } | |
345 | |
346 /* conceal errors */ | |
347 if( s->decoding_error==DECODING_DESYNC | |
348 || (s->decoding_error==DECODING_ACDC_LOST && s->mb_intra)){ | |
349 s->mv_dir = MV_DIR_FORWARD; | |
350 s->mv_type = MV_TYPE_16X16; | |
351 s->mb_skiped=0; | |
352 s->mb_intra=0; | |
353 s->mv[0][0][0]=0; //FIXME this is not optimal | |
354 s->mv[0][0][1]=0; | |
355 clear_blocks(s->block[0]); | |
356 }else if(s->decoding_error && !s->mb_intra){ | |
357 clear_blocks(s->block[0]); | |
358 } | |
359 //FIXME remove AC for intra | |
360 | |
361 MPV_decode_mb(s, s->block); | |
362 | |
363 s->mb_num_left--; | |
364 } | |
365 if ( avctx->draw_horiz_band | |
366 && (s->num_available_buffers>=1 || (!s->has_b_frames)) ) { | |
367 UINT8 *src_ptr[3]; | |
368 int y, h, offset; | |
369 y = s->mb_y * 16; | |
370 h = s->height - y; | |
371 if (h > 16) | |
372 h = 16; | |
373 | |
374 if(s->pict_type==B_TYPE) | |
375 offset = 0; | |
376 else | |
377 offset = y * s->linesize; | |
378 | |
379 if(s->pict_type==B_TYPE || (!s->has_b_frames)){ | |
380 src_ptr[0] = s->current_picture[0] + offset; | |
381 src_ptr[1] = s->current_picture[1] + (offset >> 2); | |
382 src_ptr[2] = s->current_picture[2] + (offset >> 2); | |
383 } else { | |
384 src_ptr[0] = s->last_picture[0] + offset; | |
385 src_ptr[1] = s->last_picture[1] + (offset >> 2); | |
386 src_ptr[2] = s->last_picture[2] + (offset >> 2); | |
387 } | |
388 avctx->draw_horiz_band(avctx, src_ptr, s->linesize, | |
389 y, s->width, h); | |
390 } | |
391 } | 445 } |
392 | 446 |
393 if (s->h263_msmpeg4 && s->msmpeg4_version<4 && s->pict_type==I_TYPE) | 447 if (s->h263_msmpeg4 && s->msmpeg4_version<4 && s->pict_type==I_TYPE) |
394 if(msmpeg4_decode_ext_header(s, buf_size) < 0) return -1; | 448 if(msmpeg4_decode_ext_header(s, buf_size) < 0) return -1; |
395 | 449 |
412 s->bitstream_buffer_size= buf_size - current_pos; | 466 s->bitstream_buffer_size= buf_size - current_pos; |
413 } | 467 } |
414 } | 468 } |
415 } | 469 } |
416 | 470 |
417 if(s->bitstream_buffer_size==0 && s->error_resilience>0){ | 471 if(s->error_resilience){ |
418 int left= s->gb.size*8 - get_bits_count(&s->gb); | 472 int error=0, num_end_markers=0; |
419 int max_extra=8; | 473 for(i=0; i<s->mb_num; i++){ |
420 | 474 int status= s->error_status_table[i]; |
421 if(s->codec_id==CODEC_ID_MPEG4) max_extra+=32; | 475 #if 0 |
422 | 476 if(i%s->mb_width == 0) printf("\n"); |
423 if(left>max_extra){ | 477 printf("%2X ", status); |
424 fprintf(stderr, "discarding %d junk bits at end, next would be %X\n", left, show_bits(&s->gb, 24)); | 478 #endif |
425 if(s->decoding_error==0) | 479 if(status==0) continue; |
426 ff_conceal_past_errors(s, 1); | 480 |
427 } | 481 if(status&(DC_ERROR|AC_ERROR|MV_ERROR)) |
428 if(left<0){ | 482 error=1; |
429 fprintf(stderr, "overreading %d bits\n", -left); | 483 if(status&VP_START){ |
430 if(s->decoding_error==0) | 484 if(num_end_markers) |
431 ff_conceal_past_errors(s, 1); | 485 error=1; |
432 } | 486 num_end_markers=3; |
433 } | 487 } |
434 | 488 if(status&AC_END) |
489 num_end_markers--; | |
490 if(status&DC_END) | |
491 num_end_markers--; | |
492 if(status&MV_END) | |
493 num_end_markers--; | |
494 } | |
495 if(num_end_markers || error){ | |
496 fprintf(stderr, "concealing errors\n"); | |
497 //printf("type:%d\n", s->pict_type); | |
498 ff_error_resilience(s); | |
499 } | |
500 } | |
501 | |
435 MPV_frame_end(s); | 502 MPV_frame_end(s); |
436 #if 0 //dirty show MVs, we should export the MV tables and write a filter to show them | 503 #if 0 //dirty show MVs, we should export the MV tables and write a filter to show them |
437 { | 504 { |
438 int mb_y; | 505 int mb_y; |
439 s->has_b_frames=1; | 506 s->has_b_frames=1; |