Mercurial > libavcodec.hg
comparison mjpegdec.c @ 9913:b73796e93571 libavcodec
Add a got_picture flag to MJpegDecodeContext which indicates if its picture
element is valid. Skip the code handling SOS and EOI if not, since it can not
work without a valid AVPicture.
This fixes a crash with mjpeg/smclockmjpeg.avi.1.0 from issue 1240 where the
decoder returned an invalid AVPicture.
author | reimar |
---|---|
date | Sat, 04 Jul 2009 18:20:35 +0000 |
parents | 9502108caadf |
children | e1aaf6216769 |
comparison
equal
deleted
inserted
replaced
9912:9502108caadf | 9913:b73796e93571 |
---|---|
336 av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | 336 av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
337 return -1; | 337 return -1; |
338 } | 338 } |
339 s->picture.pict_type= FF_I_TYPE; | 339 s->picture.pict_type= FF_I_TYPE; |
340 s->picture.key_frame= 1; | 340 s->picture.key_frame= 1; |
341 s->got_picture = 1; | |
341 | 342 |
342 for(i=0; i<3; i++){ | 343 for(i=0; i<3; i++){ |
343 s->linesize[i]= s->picture.linesize[i] << s->interlaced; | 344 s->linesize[i]= s->picture.linesize[i] << s->interlaced; |
344 } | 345 } |
345 | 346 |
1247 MJpegDecodeContext *s = avctx->priv_data; | 1248 MJpegDecodeContext *s = avctx->priv_data; |
1248 const uint8_t *buf_end, *buf_ptr; | 1249 const uint8_t *buf_end, *buf_ptr; |
1249 int start_code; | 1250 int start_code; |
1250 AVFrame *picture = data; | 1251 AVFrame *picture = data; |
1251 | 1252 |
1253 s->got_picture = 0; // picture from previous image can not be reused | |
1252 buf_ptr = buf; | 1254 buf_ptr = buf; |
1253 buf_end = buf + buf_size; | 1255 buf_end = buf + buf_size; |
1254 while (buf_ptr < buf_end) { | 1256 while (buf_ptr < buf_end) { |
1255 /* find start next marker */ | 1257 /* find start next marker */ |
1256 start_code = find_marker(&buf_ptr, buf_end); | 1258 start_code = find_marker(&buf_ptr, buf_end); |
1408 case EOI: | 1410 case EOI: |
1409 s->cur_scan = 0; | 1411 s->cur_scan = 0; |
1410 if ((s->buggy_avid && !s->interlaced) || s->restart_interval) | 1412 if ((s->buggy_avid && !s->interlaced) || s->restart_interval) |
1411 break; | 1413 break; |
1412 eoi_parser: | 1414 eoi_parser: |
1415 if (!s->got_picture) { | |
1416 av_log(avctx, AV_LOG_WARNING, "Found EOI before any SOF, ignoring\n"); | |
1417 break; | |
1418 } | |
1413 { | 1419 { |
1414 if (s->interlaced) { | 1420 if (s->interlaced) { |
1415 s->bottom_field ^= 1; | 1421 s->bottom_field ^= 1; |
1416 /* if not bottom field, do not output image yet */ | 1422 /* if not bottom field, do not output image yet */ |
1417 if (s->bottom_field == !s->interlace_polarity) | 1423 if (s->bottom_field == !s->interlace_polarity) |
1432 | 1438 |
1433 goto the_end; | 1439 goto the_end; |
1434 } | 1440 } |
1435 break; | 1441 break; |
1436 case SOS: | 1442 case SOS: |
1443 if (!s->got_picture) { | |
1444 av_log(avctx, AV_LOG_WARNING, "Can not process SOS before SOF, skipping\n"); | |
1445 break; | |
1446 } | |
1437 ff_mjpeg_decode_sos(s); | 1447 ff_mjpeg_decode_sos(s); |
1438 /* buggy avid puts EOI every 10-20th frame */ | 1448 /* buggy avid puts EOI every 10-20th frame */ |
1439 /* if restart period is over process EOI */ | 1449 /* if restart period is over process EOI */ |
1440 if ((s->buggy_avid && !s->interlaced) || s->restart_interval) | 1450 if ((s->buggy_avid && !s->interlaced) || s->restart_interval) |
1441 goto eoi_parser; | 1451 goto eoi_parser; |