@ -191,12 +191,11 @@ typedef struct Decoder {
AVRational start_pts_tb ;
int64_t next_pts ;
AVRational next_pts_tb ;
SDL_Thread * decoder_tid ;
} Decoder ;
typedef struct VideoState {
SDL_Thread * read_tid ;
SDL_Thread * video_tid ;
SDL_Thread * audio_tid ;
AVInputFormat * iformat ;
int abort_request ;
int force_refresh ;
@ -264,7 +263,6 @@ typedef struct VideoState {
int xpos ;
double last_vis_time ;
SDL_Thread * subtitle_tid ;
int subtitle_stream ;
AVStream * subtitle_st ;
PacketQueue subtitleq ;
@ -280,6 +278,7 @@ typedef struct VideoState {
struct SwsContext * img_convert_ctx ;
# endif
SDL_Rect last_display_rect ;
int eof ;
char filename [ 1024 ] ;
int width , height , xleft , ytop ;
@ -768,6 +767,15 @@ static int64_t frame_queue_last_pos(FrameQueue *f)
return - 1 ;
}
static void decoder_abort ( Decoder * d , FrameQueue * fq )
{
packet_queue_abort ( d - > queue ) ;
frame_queue_signal ( fq ) ;
SDL_WaitThread ( d - > decoder_tid , NULL ) ;
d - > decoder_tid = NULL ;
packet_queue_flush ( d - > queue ) ;
}
static inline void fill_rectangle ( SDL_Surface * screen ,
int x , int y , int w , int h , int color , int update )
{
@ -1494,7 +1502,7 @@ static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_by
static void stream_toggle_pause ( VideoState * is )
{
if ( is - > paused ) {
is - > frame_timer + = av_gettime_relative ( ) / 1000000.0 + is - > vidclk . pts_drift - is - > vidclk . pts ;
is - > frame_timer + = av_gettime_relative ( ) / 1000000.0 - is - > vidclk . last_updated ;
if ( is - > read_pause_return ! = AVERROR ( ENOSYS ) ) {
is - > vidclk . paused = 0 ;
}
@ -2196,6 +2204,12 @@ static int audio_thread(void *arg)
return ret ;
}
static void decoder_start ( Decoder * d , int ( * fn ) ( void * ) , void * arg )
{
packet_queue_start ( d - > queue ) ;
d - > decoder_tid = SDL_CreateThread ( fn , arg ) ;
}
static int video_thread ( void * arg )
{
VideoState * is = arg ;
@ -2687,6 +2701,7 @@ static int stream_component_open(VideoState *is, int stream_index)
goto fail ;
}
is - > eof = 0 ;
ic - > streams [ stream_index ] - > discard = AVDISCARD_DEFAULT ;
switch ( avctx - > codec_type ) {
case AVMEDIA_TYPE_AUDIO :
@ -2729,31 +2744,28 @@ static int stream_component_open(VideoState *is, int stream_index)
is - > audio_stream = stream_index ;
is - > audio_st = ic - > streams [ stream_index ] ;
packet_queue_start ( & is - > audioq ) ;
decoder_init ( & is - > auddec , avctx , & is - > audioq , is - > continue_read_thread ) ;
if ( ( is - > ic - > iformat - > flags & ( AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK ) ) & & ! is - > ic - > iformat - > read_seek ) {
is - > auddec . start_pts = is - > audio_st - > start_time ;
is - > auddec . start_pts_tb = is - > audio_st - > time_base ;
}
is - > audio_tid = SDL_CreateThread ( audio_thread , is ) ;
decoder_start ( & is - > auddec , audio_thread , is ) ;
SDL_PauseAudio ( 0 ) ;
break ;
case AVMEDIA_TYPE_VIDEO :
is - > video_stream = stream_index ;
is - > video_st = ic - > streams [ stream_index ] ;
packet_queue_start ( & is - > videoq ) ;
decoder_init ( & is - > viddec , avctx , & is - > videoq , is - > continue_read_thread ) ;
is - > video_tid = SDL_CreateThread ( video_thread , is ) ;
decoder_start ( & is - > viddec , video_thread , is ) ;
is - > queue_attachments_req = 1 ;
break ;
case AVMEDIA_TYPE_SUBTITLE :
is - > subtitle_stream = stream_index ;
is - > subtitle_st = ic - > streams [ stream_index ] ;
packet_queue_start ( & is - > subtitleq ) ;
decoder_init ( & is - > subdec , avctx , & is - > subtitleq , is - > continue_read_thread ) ;
is - > subtitle_tid = SDL_CreateThread ( subtitle_thread , is ) ;
decoder_start ( & is - > subdec , subtitle_thread , is ) ;
break ;
default :
break ;
@ -2776,13 +2788,9 @@ static void stream_component_close(VideoState *is, int stream_index)
switch ( avctx - > codec_type ) {
case AVMEDIA_TYPE_AUDIO :
packet_queue_abort ( & is - > audioq ) ;
frame_queue_signal ( & is - > sampq ) ;
decoder_abort ( & is - > auddec , & is - > sampq ) ;
SDL_CloseAudio ( ) ;
SDL_WaitThread ( is - > audio_tid , NULL ) ;
decoder_destroy ( & is - > auddec ) ;
packet_queue_flush ( & is - > audioq ) ;
swr_free ( & is - > swr_ctx ) ;
av_freep ( & is - > audio_buf1 ) ;
is - > audio_buf1_size = 0 ;
@ -2796,28 +2804,12 @@ static void stream_component_close(VideoState *is, int stream_index)
}
break ;
case AVMEDIA_TYPE_VIDEO :
packet_queue_abort ( & is - > videoq ) ;
/* note: we also signal this mutex to make sure we deblock the
video thread in all cases */
frame_queue_signal ( & is - > pictq ) ;
SDL_WaitThread ( is - > video_tid , NULL ) ;
decoder_abort ( & is - > viddec , & is - > pictq ) ;
decoder_destroy ( & is - > viddec ) ;
packet_queue_flush ( & is - > videoq ) ;
break ;
case AVMEDIA_TYPE_SUBTITLE :
packet_queue_abort ( & is - > subtitleq ) ;
/* note: we also signal this mutex to make sure we deblock the
video thread in all cases */
frame_queue_signal ( & is - > subpq ) ;
SDL_WaitThread ( is - > subtitle_tid , NULL ) ;
decoder_abort ( & is - > subdec , & is - > subpq ) ;
decoder_destroy ( & is - > subdec ) ;
packet_queue_flush ( & is - > subtitleq ) ;
break ;
default :
break ;
@ -2873,7 +2865,6 @@ static int read_thread(void *arg)
int err , i , ret ;
int st_index [ AVMEDIA_TYPE_NB ] ;
AVPacket pkt1 , * pkt = & pkt1 ;
int eof = 0 ;
int64_t stream_start_time ;
int pkt_in_play_range = 0 ;
AVDictionaryEntry * t ;
@ -2887,6 +2878,7 @@ static int read_thread(void *arg)
is - > last_video_stream = is - > video_stream = - 1 ;
is - > last_audio_stream = is - > audio_stream = - 1 ;
is - > last_subtitle_stream = is - > subtitle_stream = - 1 ;
is - > eof = 0 ;
ic = avformat_alloc_context ( ) ;
ic - > interrupt_callback . callback = decode_interrupt_cb ;
@ -3084,7 +3076,7 @@ static int read_thread(void *arg)
}
is - > seek_req = 0 ;
is - > queue_attachments_req = 1 ;
eof = 0 ;
is - > eof = 0 ;
if ( is - > paused )
step_to_next_frame ( is ) ;
}
@ -3124,14 +3116,14 @@ static int read_thread(void *arg)
}
ret = av_read_frame ( ic , pkt ) ;
if ( ret < 0 ) {
if ( ( ret = = AVERROR_EOF | | avio_feof ( ic - > pb ) ) & & ! eof ) {
if ( ( ret = = AVERROR_EOF | | avio_feof ( ic - > pb ) ) & & ! is - > eof ) {
if ( is - > video_stream > = 0 )
packet_queue_put_nullpacket ( & is - > videoq , is - > video_stream ) ;
if ( is - > audio_stream > = 0 )
packet_queue_put_nullpacket ( & is - > audioq , is - > audio_stream ) ;
if ( is - > subtitle_stream > = 0 )
packet_queue_put_nullpacket ( & is - > subtitleq , is - > subtitle_stream ) ;
eof = 1 ;
is - > eof = 1 ;
}
if ( ic - > pb & & ic - > pb - > error )
break ;
@ -3140,7 +3132,7 @@ static int read_thread(void *arg)
SDL_UnlockMutex ( wait_mutex ) ;
continue ;
} else {
eof = 0 ;
is - > eof = 0 ;
}
/* check if packet is in play range specified by user, then queue, otherwise discard */
stream_start_time = ic - > streams [ pkt - > stream_index ] - > start_time ;