[FFmpeg-devel] [PATCH] Re: new command-line option for ffplay
Alexei Svitkine
alexei.svitkine
Thu Jun 24 01:07:12 CEST 2010
Patch is attached. Makes the input function a little cleaner, too.
-Alexei
On Wed, Jun 23, 2010 at 9:13 AM, Alexei Svitkine
<alexei.svitkine at gmail.com> wrote:
> Hello,
>
> I wish to add an extra command-line option to ffplay that will disable
> the regular input events - but treat any key press or mouse click as
> the "quit" event.
>
> This would be useful for my application that would launch ffplay
> processes programmatically (cutscenes for a game).
>
> I am wondering, would a patch with this change be accepted upstream?
>
> -Alexei
>
-------------- next part --------------
Index: ffplay.c
===================================================================
--- ffplay.c (revision 23733)
+++ ffplay.c (working copy)
@@ -259,6 +259,8 @@
static int error_concealment = 3;
static int decoder_reorder_pts= -1;
static int autoexit;
+static int exit_on_keydown;
+static int exit_on_mousedown;
static int loop=1;
static int framedrop=1;
@@ -2804,119 +2806,142 @@
}
}
+static void handle_keydown_event(SDL_Event *event)
+{
+ double incr, pos;
+
+ switch(event->key.keysym.sym) {
+ case SDLK_ESCAPE:
+ case SDLK_q:
+ do_exit();
+ break;
+ case SDLK_f:
+ toggle_full_screen();
+ break;
+ case SDLK_p:
+ case SDLK_SPACE:
+ toggle_pause();
+ break;
+ case SDLK_s: //S: Step to next frame
+ step_to_next_frame();
+ break;
+ case SDLK_a:
+ if (cur_stream)
+ stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
+ break;
+ case SDLK_v:
+ if (cur_stream)
+ stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
+ break;
+ case SDLK_t:
+ if (cur_stream)
+ stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
+ break;
+ case SDLK_w:
+ toggle_audio_display();
+ break;
+ case SDLK_LEFT:
+ incr = -10.0;
+ goto do_seek;
+ case SDLK_RIGHT:
+ incr = 10.0;
+ goto do_seek;
+ case SDLK_UP:
+ incr = 60.0;
+ goto do_seek;
+ case SDLK_DOWN:
+ incr = -60.0;
+ do_seek:
+ if (cur_stream) {
+ if (seek_by_bytes) {
+ if (cur_stream->video_stream >= 0 && cur_stream->video_current_pos >= 0) {
+ pos= cur_stream->video_current_pos;
+ } else if (cur_stream->audio_stream >= 0 && cur_stream->audio_pkt.pos >= 0) {
+ pos= cur_stream->audio_pkt.pos;
+ } else
+ pos = url_ftell(cur_stream->ic->pb);
+ if (cur_stream->ic->bit_rate)
+ incr *= cur_stream->ic->bit_rate / 8.0;
+ else
+ incr *= 180000.0;
+ pos += incr;
+ stream_seek(cur_stream, pos, incr, 1);
+ } else {
+ pos = get_master_clock(cur_stream);
+ pos += incr;
+ stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void handle_mouse_event(SDL_Event *event)
+{
+ double x, frac;
+
+ if (event->type == SDL_MOUSEBUTTONDOWN) {
+ x = event->button.x;
+ } else if (event->type == SDL_MOUSEMOTION && event->motion.state == SDL_PRESSED) {
+ x = event->motion.x;
+ } else {
+ return;
+ }
+
+ if (cur_stream) {
+ if (seek_by_bytes || cur_stream->ic->duration <= 0) {
+ uint64_t size= url_fsize(cur_stream->ic->pb);
+ stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
+ } else {
+ int64_t ts;
+ int ns, hh, mm, ss;
+ int tns, thh, tmm, tss;
+ tns = cur_stream->ic->duration/1000000LL;
+ thh = tns/3600;
+ tmm = (tns%3600)/60;
+ tss = (tns%60);
+ frac = x/cur_stream->width;
+ ns = frac*tns;
+ hh = ns/3600;
+ mm = (ns%3600)/60;
+ ss = (ns%60);
+ fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
+ hh, mm, ss, thh, tmm, tss);
+ ts = frac*cur_stream->ic->duration;
+ if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
+ ts += cur_stream->ic->start_time;
+ stream_seek(cur_stream, ts, 0, 0);
+ }
+ }
+}
+
/* handle an event sent by the GUI */
static void event_loop(void)
{
SDL_Event event;
- double incr, pos, frac;
for(;;) {
- double x;
SDL_WaitEvent(&event);
switch(event.type) {
case SDL_KEYDOWN:
- switch(event.key.keysym.sym) {
- case SDLK_ESCAPE:
- case SDLK_q:
+ if (exit_on_keydown) {
do_exit();
- break;
- case SDLK_f:
- toggle_full_screen();
- break;
- case SDLK_p:
- case SDLK_SPACE:
- toggle_pause();
- break;
- case SDLK_s: //S: Step to next frame
- step_to_next_frame();
- break;
- case SDLK_a:
- if (cur_stream)
- stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
- break;
- case SDLK_v:
- if (cur_stream)
- stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
- break;
- case SDLK_t:
- if (cur_stream)
- stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
- break;
- case SDLK_w:
- toggle_audio_display();
- break;
- case SDLK_LEFT:
- incr = -10.0;
- goto do_seek;
- case SDLK_RIGHT:
- incr = 10.0;
- goto do_seek;
- case SDLK_UP:
- incr = 60.0;
- goto do_seek;
- case SDLK_DOWN:
- incr = -60.0;
- do_seek:
- if (cur_stream) {
- if (seek_by_bytes) {
- if (cur_stream->video_stream >= 0 && cur_stream->video_current_pos>=0){
- pos= cur_stream->video_current_pos;
- }else if(cur_stream->audio_stream >= 0 && cur_stream->audio_pkt.pos>=0){
- pos= cur_stream->audio_pkt.pos;
- }else
- pos = url_ftell(cur_stream->ic->pb);
- if (cur_stream->ic->bit_rate)
- incr *= cur_stream->ic->bit_rate / 8.0;
- else
- incr *= 180000.0;
- pos += incr;
- stream_seek(cur_stream, pos, incr, 1);
- } else {
- pos = get_master_clock(cur_stream);
- pos += incr;
- stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
- }
- }
- break;
- default:
- break;
+ } else {
+ handle_keydown_event(&event);
}
break;
case SDL_MOUSEBUTTONDOWN:
- case SDL_MOUSEMOTION:
- if(event.type ==SDL_MOUSEBUTTONDOWN){
- x= event.button.x;
- }else{
- if(event.motion.state != SDL_PRESSED)
- break;
- x= event.motion.x;
+ if (exit_on_mousedown) {
+ do_exit();
+ } else {
+ handle_mouse_event(&event);
}
- if (cur_stream) {
- if(seek_by_bytes || cur_stream->ic->duration<=0){
- uint64_t size= url_fsize(cur_stream->ic->pb);
- stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
- }else{
- int64_t ts;
- int ns, hh, mm, ss;
- int tns, thh, tmm, tss;
- tns = cur_stream->ic->duration/1000000LL;
- thh = tns/3600;
- tmm = (tns%3600)/60;
- tss = (tns%60);
- frac = x/cur_stream->width;
- ns = frac*tns;
- hh = ns/3600;
- mm = (ns%3600)/60;
- ss = (ns%60);
- fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
- hh, mm, ss, thh, tmm, tss);
- ts = frac*cur_stream->ic->duration;
- if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
- ts += cur_stream->ic->start_time;
- stream_seek(cur_stream, ts, 0, 0);
- }
- }
break;
+ case SDL_MOUSEMOTION:
+ handle_mouse_event(&event);
+ break;
case SDL_VIDEORESIZE:
if (cur_stream) {
screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
@@ -3064,6 +3089,8 @@
{ "sync", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
{ "threads", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
{ "autoexit", OPT_BOOL | OPT_EXPERT, {(void*)&autoexit}, "exit at the end", "" },
+ { "exitonkeydown", OPT_BOOL | OPT_EXPERT, {(void*)&exit_on_keydown}, "exit on key down", "" },
+ { "exitonmousedown", OPT_BOOL | OPT_EXPERT, {(void*)&exit_on_mousedown}, "exit on mouse down", "" },
{ "loop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&loop}, "set number of times the playback shall be looped", "loop count" },
{ "framedrop", OPT_BOOL | OPT_EXPERT, {(void*)&framedrop}, "drop frames when cpu is too slow", "" },
{ "window_title", OPT_STRING | HAS_ARG, {(void*)&window_title}, "set window title", "window title" },
More information about the ffmpeg-devel
mailing list