diff --git a/ffplay.c b/ffplay.c index 1bc8192db0..d62d99da6f 100644 --- a/ffplay.c +++ b/ffplay.c @@ -73,6 +73,7 @@ typedef struct VideoState { int no_background; int abort_request; int paused; + int last_paused; AVFormatContext *ic; int dtg_active_format; @@ -1041,6 +1042,14 @@ static void stream_component_close(VideoState *is, int stream_index) } } +/* since we have only one decoding thread, we can use a global + variable instead of a thread local variable */ +static VideoState *global_video_state; + +static int decode_interrupt_cb(void) +{ + return (global_video_state && global_video_state->abort_request); +} /* this thread gets the stream from the disk or the network */ static int decode_thread(void *arg) @@ -1055,6 +1064,9 @@ static int decode_thread(void *arg) is->video_stream = -1; is->audio_stream = -1; + global_video_state = is; + url_set_interrupt_cb(decode_interrupt_cb); + err = av_open_input_file(&ic, is->filename, NULL, 0, NULL); if (err < 0) return 0; @@ -1101,6 +1113,22 @@ static int decode_thread(void *arg) for(;;) { if (is->abort_request) break; + if (is->paused != is->last_paused) { + is->last_paused = is->paused; + if (ic->iformat == &rtsp_demux) { + if (is->paused) + rtsp_pause(ic); + else + rtsp_resume(ic); + } + } + if (is->paused && ic->iformat == &rtsp_demux) { + /* wait 10 ms to avoid trying to get another packet */ + /* XXX: horrible */ + SDL_Delay(10); + continue; + } + /* if the queue are full, no need to read more */ if (is->audioq.size > MAX_AUDIOQ_SIZE || is->videoq.size > MAX_VIDEOQ_SIZE) { @@ -1126,6 +1154,9 @@ static int decode_thread(void *arg) } fail: + /* disable interrupting */ + global_video_state = NULL; + /* close each stream */ if (is->audio_stream >= 0) stream_component_close(is, is->audio_stream); @@ -1134,6 +1165,8 @@ static int decode_thread(void *arg) av_close_input_file(is->ic); is->ic = NULL; /* safety */ + url_set_interrupt_cb(NULL); + return 0; } @@ -1315,6 +1348,12 @@ static void opt_format(const char *arg) } } +void opt_rtp_tcp(void) +{ + /* only tcp protocol */ + rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_TCP); +} + const OptionDef options[] = { { "h", 0, {(void*)show_help}, "show help" }, { "x", HAS_ARG, {(void*)opt_width}, "force displayed width", "width" }, @@ -1324,6 +1363,7 @@ const OptionDef options[] = { { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" }, { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" }, { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" }, + { "rtp_tcp", OPT_EXPERT, {(void*)&opt_rtp_tcp}, "force RTP/TCP protocol usage", "" }, { NULL, }, };