@ -234,6 +234,7 @@ typedef struct VideoState {
# if !CONFIG_AVFILTER
# if !CONFIG_AVFILTER
struct SwsContext * img_convert_ctx ;
struct SwsContext * img_convert_ctx ;
# endif
# endif
SDL_Rect last_display_rect ;
char filename [ 1024 ] ;
char filename [ 1024 ] ;
int width , height , xleft , ytop ;
int width , height , xleft , ytop ;
@ -449,7 +450,7 @@ static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *seria
}
}
static inline void fill_rectangle ( SDL_Surface * screen ,
static inline void fill_rectangle ( SDL_Surface * screen ,
int x , int y , int w , int h , int color )
int x , int y , int w , int h , int color , int update )
{
{
SDL_Rect rect ;
SDL_Rect rect ;
rect . x = x ;
rect . x = x ;
@ -457,6 +458,44 @@ static inline void fill_rectangle(SDL_Surface *screen,
rect . w = w ;
rect . w = w ;
rect . h = h ;
rect . h = h ;
SDL_FillRect ( screen , & rect , color ) ;
SDL_FillRect ( screen , & rect , color ) ;
if ( update & & w > 0 & & h > 0 )
SDL_UpdateRect ( screen , x , y , w , h ) ;
}
/* draw only the border of a rectangle */
static void fill_border ( int xleft , int ytop , int width , int height , int x , int y , int w , int h , int color , int update )
{
int w1 , w2 , h1 , h2 ;
/* fill the background */
w1 = x ;
if ( w1 < 0 )
w1 = 0 ;
w2 = width - ( x + w ) ;
if ( w2 < 0 )
w2 = 0 ;
h1 = y ;
if ( h1 < 0 )
h1 = 0 ;
h2 = height - ( y + h ) ;
if ( h2 < 0 )
h2 = 0 ;
fill_rectangle ( screen ,
xleft , ytop ,
w1 , height ,
color , update ) ;
fill_rectangle ( screen ,
xleft + width - w2 , ytop ,
w2 , height ,
color , update ) ;
fill_rectangle ( screen ,
xleft + w1 , ytop ,
width - w1 - w2 , h1 ,
color , update ) ;
fill_rectangle ( screen ,
xleft + w1 , ytop + height - h2 ,
width - w1 - w2 , h2 ,
color , update ) ;
}
}
# define ALPHA_BLEND(a, oldp, newp, s)\
# define ALPHA_BLEND(a, oldp, newp, s)\
@ -759,6 +798,12 @@ static void video_image_display(VideoState *is)
calculate_display_rect ( & rect , is - > xleft , is - > ytop , is - > width , is - > height , vp ) ;
calculate_display_rect ( & rect , is - > xleft , is - > ytop , is - > width , is - > height , vp ) ;
SDL_DisplayYUVOverlay ( vp - > bmp , & rect ) ;
SDL_DisplayYUVOverlay ( vp - > bmp , & rect ) ;
if ( rect . x ! = is - > last_display_rect . x | | rect . y ! = is - > last_display_rect . y | | rect . w ! = is - > last_display_rect . w | | rect . h ! = is - > last_display_rect . h | | is - > force_refresh ) {
int bgcolor = SDL_MapRGB ( screen - > format , 0x00 , 0x00 , 0x00 ) ;
fill_border ( is - > xleft , is - > ytop , is - > width , is - > height , rect . x , rect . y , rect . w , rect . h , bgcolor , 1 ) ;
is - > last_display_rect = rect ;
}
}
}
}
}
@ -824,7 +869,7 @@ static void video_audio_display(VideoState *s)
if ( s - > show_mode = = SHOW_MODE_WAVES ) {
if ( s - > show_mode = = SHOW_MODE_WAVES ) {
fill_rectangle ( screen ,
fill_rectangle ( screen ,
s - > xleft , s - > ytop , s - > width , s - > height ,
s - > xleft , s - > ytop , s - > width , s - > height ,
bgcolor ) ;
bgcolor , 0 ) ;
fgcolor = SDL_MapRGB ( screen - > format , 0xff , 0xff , 0xff ) ;
fgcolor = SDL_MapRGB ( screen - > format , 0xff , 0xff , 0xff ) ;
@ -845,7 +890,7 @@ static void video_audio_display(VideoState *s)
}
}
fill_rectangle ( screen ,
fill_rectangle ( screen ,
s - > xleft + x , ys , 1 , y ,
s - > xleft + x , ys , 1 , y ,
fgcolor ) ;
fgcolor , 0 ) ;
i + = channels ;
i + = channels ;
if ( i > = SAMPLE_ARRAY_SIZE )
if ( i > = SAMPLE_ARRAY_SIZE )
i - = SAMPLE_ARRAY_SIZE ;
i - = SAMPLE_ARRAY_SIZE ;
@ -858,7 +903,7 @@ static void video_audio_display(VideoState *s)
y = s - > ytop + ch * h ;
y = s - > ytop + ch * h ;
fill_rectangle ( screen ,
fill_rectangle ( screen ,
s - > xleft , y , s - > width , 1 ,
s - > xleft , y , s - > width , 1 ,
fgcolor ) ;
fgcolor , 0 ) ;
}
}
SDL_UpdateRect ( screen , s - > xleft , s - > ytop , s - > width , s - > height ) ;
SDL_UpdateRect ( screen , s - > xleft , s - > ytop , s - > width , s - > height ) ;
} else {
} else {
@ -896,7 +941,7 @@ static void video_audio_display(VideoState *s)
fill_rectangle ( screen ,
fill_rectangle ( screen ,
s - > xpos , s - > height - y , 1 , 1 ,
s - > xpos , s - > height - y , 1 , 1 ,
fgcolor ) ;
fgcolor , 0 ) ;
}
}
}
}
SDL_UpdateRect ( screen , s - > xpos , s - > ytop , 1 , s - > height ) ;
SDL_UpdateRect ( screen , s - > xpos , s - > ytop , 1 , s - > height ) ;
@ -1636,7 +1681,7 @@ static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
goto fail ;
goto fail ;
}
}
return avfilter_graph_config ( graph , NULL ) ;
ret = avfilter_graph_config ( graph , NULL ) ;
fail :
fail :
avfilter_inout_free ( & outputs ) ;
avfilter_inout_free ( & outputs ) ;
avfilter_inout_free ( & inputs ) ;
avfilter_inout_free ( & inputs ) ;
@ -1650,9 +1695,12 @@ static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c
char buffersrc_args [ 256 ] ;
char buffersrc_args [ 256 ] ;
int ret ;
int ret ;
AVBufferSinkParams * buffersink_params = av_buffersink_params_alloc ( ) ;
AVBufferSinkParams * buffersink_params = av_buffersink_params_alloc ( ) ;
AVFilterContext * filt_src = NULL , * filt_out = NULL , * filt_format , * filt_ crop ;
AVFilterContext * filt_src = NULL , * filt_out = NULL , * filt_crop ;
AVCodecContext * codec = is - > video_st - > codec ;
AVCodecContext * codec = is - > video_st - > codec ;
if ( ! buffersink_params )
return AVERROR ( ENOMEM ) ;
snprintf ( sws_flags_str , sizeof ( sws_flags_str ) , " flags=%d " , sws_flags ) ;
snprintf ( sws_flags_str , sizeof ( sws_flags_str ) , " flags=%d " , sws_flags ) ;
graph - > scale_sws_opts = av_strdup ( sws_flags_str ) ;
graph - > scale_sws_opts = av_strdup ( sws_flags_str ) ;
@ -1666,37 +1714,32 @@ static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c
avfilter_get_by_name ( " buffer " ) ,
avfilter_get_by_name ( " buffer " ) ,
" ffplay_buffer " , buffersrc_args , NULL ,
" ffplay_buffer " , buffersrc_args , NULL ,
graph ) ) < 0 )
graph ) ) < 0 )
return ret ;
goto fail ;
buffersink_params - > pixel_fmts = pix_fmts ;
buffersink_params - > pixel_fmts = pix_fmts ;
ret = avfilter_graph_create_filter ( & filt_out ,
ret = avfilter_graph_create_filter ( & filt_out ,
avfilter_get_by_name ( " ffbuffersink " ) ,
avfilter_get_by_name ( " ffbuffersink " ) ,
" ffplay_buffersink " , NULL , buffersink_params , graph ) ;
" ffplay_buffersink " , NULL , buffersink_params , graph ) ;
av_freep ( & buffersink_params ) ;
if ( ret < 0 )
if ( ret < 0 )
return ret ;
goto fail ;
/* SDL YUV code is not handling odd width/height for some driver
/* SDL YUV code is not handling odd width/height for some driver
* combinations , therefore we crop the picture to an even width / height . */
* combinations , therefore we crop the picture to an even width / height . */
if ( ( ret = avfilter_graph_create_filter ( & filt_crop ,
if ( ( ret = avfilter_graph_create_filter ( & filt_crop ,
avfilter_get_by_name ( " crop " ) ,
avfilter_get_by_name ( " crop " ) ,
" ffplay_crop " , " floor(in_w/2)*2:floor(in_h/2)*2 " , NULL , graph ) ) < 0 )
" ffplay_crop " , " floor(in_w/2)*2:floor(in_h/2)*2 " , NULL , graph ) ) < 0 )
return ret ;
goto fail ;
if ( ( ret = avfilter_graph_create_filter ( & filt_format ,
if ( ( ret = avfilter_link ( filt_crop , 0 , filt_out , 0 ) ) < 0 )
avfilter_get_by_name ( " format " ) ,
goto fail ;
" format " , " yuv420p " , NULL , graph ) ) < 0 )
return ret ;
if ( ( ret = avfilter_link ( filt_crop , 0 , filt_format , 0 ) ) < 0 )
return ret ;
if ( ( ret = avfilter_link ( filt_format , 0 , filt_out , 0 ) ) < 0 )
return ret ;
if ( ( ret = configure_filtergraph ( graph , vfilters , filt_src , filt_crop ) ) < 0 )
if ( ( ret = configure_filtergraph ( graph , vfilters , filt_src , filt_crop ) ) < 0 )
return ret ;
goto fail ;
is - > in_video_filter = filt_src ;
is - > in_video_filter = filt_src ;
is - > out_video_filter = filt_out ;
is - > out_video_filter = filt_out ;
fail :
av_freep ( & buffersink_params ) ;
return ret ;
return ret ;
}
}
@ -2234,7 +2277,6 @@ static int stream_component_open(VideoState *is, int stream_index)
avctx = ic - > streams [ stream_index ] - > codec ;
avctx = ic - > streams [ stream_index ] - > codec ;
codec = avcodec_find_decoder ( avctx - > codec_id ) ;
codec = avcodec_find_decoder ( avctx - > codec_id ) ;
opts = filter_codec_opts ( codec_opts , avctx - > codec_id , ic , ic - > streams [ stream_index ] , codec ) ;
switch ( avctx - > codec_type ) {
switch ( avctx - > codec_type ) {
case AVMEDIA_TYPE_AUDIO : is - > last_audio_stream = stream_index ; if ( audio_codec_name ) codec = avcodec_find_decoder_by_name ( audio_codec_name ) ; break ;
case AVMEDIA_TYPE_AUDIO : is - > last_audio_stream = stream_index ; if ( audio_codec_name ) codec = avcodec_find_decoder_by_name ( audio_codec_name ) ; break ;
@ -2262,10 +2304,10 @@ static int stream_component_open(VideoState *is, int stream_index)
if ( codec - > capabilities & CODEC_CAP_DR1 )
if ( codec - > capabilities & CODEC_CAP_DR1 )
avctx - > flags | = CODEC_FLAG_EMU_EDGE ;
avctx - > flags | = CODEC_FLAG_EMU_EDGE ;
opts = filter_codec_opts ( codec_opts , avctx - > codec_id , ic , ic - > streams [ stream_index ] , codec ) ;
if ( ! av_dict_get ( opts , " threads " , NULL , 0 ) )
if ( ! av_dict_get ( opts , " threads " , NULL , 0 ) )
av_dict_set ( & opts , " threads " , " auto " , 0 ) ;
av_dict_set ( & opts , " threads " , " auto " , 0 ) ;
if ( ! codec | |
if ( avcodec_open2 ( avctx , codec , & opts ) < 0 )
avcodec_open2 ( avctx , codec , & opts ) < 0 )
return - 1 ;
return - 1 ;
if ( ( t = av_dict_get ( opts , " " , NULL , AV_DICT_IGNORE_SUFFIX ) ) ) {
if ( ( t = av_dict_get ( opts , " " , NULL , AV_DICT_IGNORE_SUFFIX ) ) ) {
av_log ( NULL , AV_LOG_ERROR , " Option %s not found. \n " , t - > key ) ;
av_log ( NULL , AV_LOG_ERROR , " Option %s not found. \n " , t - > key ) ;
@ -2828,8 +2870,7 @@ static void toggle_audio_display(VideoState *is)
is - > show_mode = ( is - > show_mode + 1 ) % SHOW_MODE_NB ;
is - > show_mode = ( is - > show_mode + 1 ) % SHOW_MODE_NB ;
fill_rectangle ( screen ,
fill_rectangle ( screen ,
is - > xleft , is - > ytop , is - > width , is - > height ,
is - > xleft , is - > ytop , is - > width , is - > height ,
bgcolor ) ;
bgcolor , 1 ) ;
SDL_UpdateRect ( screen , is - > xleft , is - > ytop , is - > width , is - > height ) ;
}
}
/* handle an event sent by the GUI */
/* handle an event sent by the GUI */