@ -175,6 +175,8 @@ typedef struct Vp3DecodeContext {
Vp3Fragment * all_fragments ;
int fragment_start [ 3 ] ;
int data_offset [ 3 ] ;
uint8_t offset_x ;
uint8_t offset_y ;
int8_t ( * motion_val [ 2 ] ) [ 2 ] ;
@ -1418,14 +1420,14 @@ static void vp3_draw_horiz_band(Vp3DecodeContext *s, int y)
int offset [ AV_NUM_DATA_POINTERS ] ;
if ( HAVE_THREADS & & s - > avctx - > active_thread_type & FF_THREAD_FRAME ) {
int y_flipped = s - > flipped_image ? s - > avctx - > height - y : y ;
int y_flipped = s - > flipped_image ? s - > height - y : y ;
/* At the end of the frame, report INT_MAX instead of the height of
* the frame . This makes the other threads ' ff_thread_await_progress ( )
* calls cheaper , because they don ' t have to clip their values . */
ff_thread_report_progress ( & s - > current_frame ,
y_flipped = = s - > avctx - > height ? INT_MAX
: y_flipped - 1 ,
y_flipped = = s - > height ? INT_MAX
: y_flipped - 1 ,
0 ) ;
}
@ -1437,7 +1439,7 @@ static void vp3_draw_horiz_band(Vp3DecodeContext *s, int y)
y - = h ;
if ( ! s - > flipped_image )
y = s - > avctx - > height - y - h ;
y = s - > height - y - h ;
cy = y > > s - > chroma_y_shift ;
offset [ 0 ] = s - > current_frame . f - > linesize [ 0 ] * y ;
@ -1730,8 +1732,8 @@ static av_cold int vp3_decode_init(AVCodecContext *avctx)
s - > version = 1 ;
s - > avctx = avctx ;
s - > width = FFALIGN ( avctx - > width , 16 ) ;
s - > height = FFALIGN ( avctx - > height , 16 ) ;
s - > width = FFALIGN ( avctx - > coded_ width, 16 ) ;
s - > height = FFALIGN ( avctx - > coded_ height, 16 ) ;
if ( avctx - > codec_id ! = AV_CODEC_ID_THEORA )
avctx - > pix_fmt = AV_PIX_FMT_YUV420P ;
avctx - > chroma_sample_location = AVCHROMA_LOC_CENTER ;
@ -2151,10 +2153,17 @@ static int vp3_decode_frame(AVCodecContext *avctx,
int row = ( s - > height > > ( 3 + ( i & & s - > chroma_y_shift ) ) ) - 1 ;
apply_loop_filter ( s , i , row , row + 1 ) ;
}
vp3_draw_horiz_band ( s , s - > avctx - > height ) ;
vp3_draw_horiz_band ( s , s - > height ) ;
/* output frame, offset as needed */
if ( ( ret = av_frame_ref ( data , s - > current_frame . f ) ) < 0 )
return ret ;
for ( i = 0 ; i < 3 ; i + + ) {
AVFrame * dst = data ;
int off = ( s - > offset_x > > ( i & & s - > chroma_y_shift ) ) +
( s - > offset_y > > ( i & & s - > chroma_y_shift ) ) * dst - > linesize [ i ] ;
dst - > data [ i ] + = off ;
}
* got_frame = 1 ;
if ( ! HAVE_THREADS | | ! ( s - > avctx - > active_thread_type & FF_THREAD_FRAME ) ) {
@ -2234,7 +2243,7 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb)
{
Vp3DecodeContext * s = avctx - > priv_data ;
int visible_width , visible_height , colorspace ;
int offset_x = 0 , offset_y = 0 ;
u int8_ t offset_x = 0 , offset_y = 0 ;
int ret ;
AVRational fps , aspect ;
@ -2262,6 +2271,17 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb)
offset_y = get_bits ( gb , 8 ) ; /* offset y, from bottom */
}
/* sanity check */
if ( av_image_check_size ( visible_width , visible_height , 0 , avctx ) < 0 | |
visible_width + offset_x > s - > width | |
visible_height + offset_y > s - > height ) {
av_log ( s , AV_LOG_ERROR ,
" Invalid frame dimensions - w:%d h:%d x:%d y:%d (%dx%d). \n " ,
visible_width , visible_height , offset_x , offset_y ,
s - > width , s - > height ) ;
return AVERROR_INVALIDDATA ;
}
fps . num = get_bits_long ( gb , 32 ) ;
fps . den = get_bits_long ( gb , 32 ) ;
if ( fps . num & & fps . den ) {
@ -2299,16 +2319,25 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb)
skip_bits ( gb , 3 ) ; /* reserved */
}
// align_get_bits(gb);
if ( visible_width < = s - > width & & visible_width > s - > width - 16 & &
visible_height < = s - > height & & visible_height > s - > height - 16 & &
! offset_x & & ( offset_y = = s - > height - visible_height ) )
ret = ff_set_dimensions ( avctx , visible_width , visible_height ) ;
else
ret = ff_set_dimensions ( avctx , s - > width , s - > height ) ;
ret = ff_set_dimensions ( avctx , s - > width , s - > height ) ;
if ( ret < 0 )
return ret ;
if ( ! ( avctx - > flags2 & CODEC_FLAG2_IGNORE_CROP ) & &
( visible_width ! = s - > width | | visible_height ! = s - > height ) ) {
avctx - > width = visible_width ;
avctx - > height = visible_height ;
// translate offsets from theora axis ([0,0] lower left)
// to normal axis ([0,0] upper left)
s - > offset_x = offset_x ;
s - > offset_y = s - > height - visible_height - offset_y ;
if ( ( s - > offset_x & 0x1F ) & & ! ( avctx - > flags & CODEC_FLAG_UNALIGNED ) ) {
s - > offset_x & = ~ 0x1F ;
av_log ( avctx , AV_LOG_WARNING , " Reducing offset_x from %d to %d "
" chroma samples to preserve alignment. \n " ,
offset_x , s - > offset_x ) ;
}
}
if ( colorspace = = 1 )
avctx - > color_primaries = AVCOL_PRI_BT470M ;