@ -138,6 +138,7 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx)
s - > buffer = NULL ;
s - > start_code = - 1 ;
s - > first_picture = 1 ;
s - > seen_sof = 0 ;
s - > got_picture = 0 ;
s - > orig_height = avctx - > coded_height ;
avctx - > chroma_sample_location = AVCHROMA_LOC_CENTER ;
@ -429,6 +430,7 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
memcpy ( s - > h_count , h_count , sizeof ( h_count ) ) ;
memcpy ( s - > v_count , v_count , sizeof ( v_count ) ) ;
s - > interlaced = 0 ;
s - > seen_sof = 0 ;
s - > got_picture = 0 ;
/* test interlaced mode */
@ -681,11 +683,13 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
} else if ( s - > nb_components ! = 1 ) {
av_log ( s - > avctx , AV_LOG_ERROR , " Unsupported number of components %d \n " , s - > nb_components ) ;
return AVERROR_PATCHWELCOME ;
} else if ( s - > palette_index & & s - > bits < = 8 )
s - > avctx - > pix_fmt = AV_PIX_FMT_PAL8 ;
else if ( s - > bits < = 8 )
s - > avctx - > pix_fmt = AV_PIX_FMT_GRAY8 ;
else
} else if ( s - > bits < = 8 ) {
avpriv_set_systematic_pal2 ( s - > palette , s - > avctx - > pix_fmt ) ;
if ( s - > palette_index )
s - > avctx - > pix_fmt = AV_PIX_FMT_PAL8 ;
else
s - > avctx - > pix_fmt = AV_PIX_FMT_GRAY8 ;
} else
s - > avctx - > pix_fmt = AV_PIX_FMT_GRAY16 ;
}
@ -719,26 +723,13 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
if ( s - > avctx - > skip_frame = = AVDISCARD_ALL ) {
s - > picture_ptr - > pict_type = AV_PICTURE_TYPE_I ;
s - > picture_ptr - > key_frame = 1 ;
s - > got_picture = 1 ;
s - > seen_sof = 1 ;
return 0 ;
}
av_frame_unref ( s - > picture_ptr ) ;
if ( ff_get_buffer ( s - > avctx , s - > picture_ptr , AV_GET_BUFFER_FLAG_REF ) < 0 )
return - 1 ;
s - > picture_ptr - > pict_type = AV_PICTURE_TYPE_I ;
s - > picture_ptr - > key_frame = 1 ;
s - > got_picture = 1 ;
for ( i = 0 ; i < 4 ; i + + )
s - > linesize [ i ] = s - > picture_ptr - > linesize [ i ] < < s - > interlaced ;
ff_dlog ( s - > avctx , " %d %d %d %d %d %d \n " ,
s - > width , s - > height , s - > linesize [ 0 ] , s - > linesize [ 1 ] ,
s - > interlaced , s - > avctx - > height ) ;
}
s - > seen_sof = 1 ;
if ( ( s - > rgb & & ! s - > lossless & & ! s - > ls ) | |
( ! s - > rgb & & s - > ls & & s - > nb_components > 1 ) | |
( s - > avctx - > pix_fmt = = AV_PIX_FMT_PAL8 & & ! s - > ls )
@ -764,18 +755,6 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
memset ( s - > coefs_finished , 0 , sizeof ( s - > coefs_finished ) ) ;
}
if ( s - > avctx - > hwaccel ) {
s - > hwaccel_picture_private =
av_mallocz ( s - > avctx - > hwaccel - > frame_priv_data_size ) ;
if ( ! s - > hwaccel_picture_private )
return AVERROR ( ENOMEM ) ;
ret = s - > avctx - > hwaccel - > start_frame ( s - > avctx , s - > raw_image_buffer ,
s - > raw_image_buffer_size ) ;
if ( ret < 0 )
return ret ;
}
return 0 ;
}
@ -1630,12 +1609,44 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask,
const int block_size = s - > lossless ? 1 : 8 ;
int ilv , prev_shift ;
if ( ! s - > got_picture ) {
if ( ! s - > seen_sof ) {
av_log ( s - > avctx , AV_LOG_WARNING ,
" Can not process SOS before SOF, skipping \n " ) ;
return - 1 ;
}
if ( ! s - > got_picture | | ! s - > interlaced | | ! ( s - > bottom_field = = ! s - > interlace_polarity ) ) {
av_frame_unref ( s - > picture_ptr ) ;
if ( ff_get_buffer ( s - > avctx , s - > picture_ptr , AV_GET_BUFFER_FLAG_REF ) < 0 )
return - 1 ;
s - > picture_ptr - > pict_type = AV_PICTURE_TYPE_I ;
s - > picture_ptr - > key_frame = 1 ;
for ( i = 0 ; i < 4 ; i + + )
s - > linesize [ i ] = s - > picture_ptr - > linesize [ i ] < < s - > interlaced ;
if ( s - > picture_ptr - > format = = AV_PIX_FMT_PAL8 )
memcpy ( s - > picture_ptr - > data [ 1 ] , s - > palette , sizeof ( s - > palette ) ) ;
s - > got_picture = 1 ;
ff_dlog ( s - > avctx , " %d %d %d %d %d %d \n " ,
s - > width , s - > height , s - > linesize [ 0 ] , s - > linesize [ 1 ] ,
s - > interlaced , s - > avctx - > height ) ;
if ( s - > avctx - > hwaccel & & ! s - > hwaccel_picture_private ) {
s - > hwaccel_picture_private =
av_mallocz ( s - > avctx - > hwaccel - > frame_priv_data_size ) ;
if ( ! s - > hwaccel_picture_private )
return AVERROR ( ENOMEM ) ;
ret = s - > avctx - > hwaccel - > start_frame ( s - > avctx , s - > raw_image_buffer ,
s - > raw_image_buffer_size ) ;
if ( ret < 0 )
return ret ;
}
}
if ( reference ) {
if ( reference - > width ! = s - > picture_ptr - > width | |
reference - > height ! = s - > picture_ptr - > height | |
@ -2561,6 +2572,7 @@ eoi_parser:
break ;
}
if ( avctx - > skip_frame = = AVDISCARD_ALL ) {
s - > seen_sof = 0 ;
s - > got_picture = 0 ;
ret = AVERROR ( EAGAIN ) ;
goto the_end_no_picture ;
@ -2574,6 +2586,7 @@ eoi_parser:
}
if ( ( ret = av_frame_ref ( frame , s - > picture_ptr ) ) < 0 )
return ret ;
s - > seen_sof = 0 ;
s - > got_picture = 0 ;
frame - > pkt_dts = s - > pkt - > dts ;
@ -2634,6 +2647,7 @@ skip:
av_log ( avctx , AV_LOG_FATAL , " No JPEG data found in image \n " ) ;
return AVERROR_INVALIDDATA ;
fail :
s - > seen_sof = 0 ;
s - > got_picture = 0 ;
return ret ;
the_end :
@ -2924,6 +2938,7 @@ av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx)
static void decode_flush ( AVCodecContext * avctx )
{
MJpegDecodeContext * s = avctx - > priv_data ;
s - > seen_sof = 0 ;
s - > got_picture = 0 ;
s - > smv_next_frame = 0 ;