58 #include <SDL_thread.h>
67 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
71 #define SDL_AUDIO_MIN_BUFFER_SIZE 512
73 #define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30
76 #define AV_SYNC_THRESHOLD_MIN 0.04
78 #define AV_SYNC_THRESHOLD_MAX 0.1
80 #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
82 #define AV_NOSYNC_THRESHOLD 10.0
85 #define SAMPLE_CORRECTION_PERCENT_MAX 10
88 #define EXTERNAL_CLOCK_SPEED_MIN 0.900
89 #define EXTERNAL_CLOCK_SPEED_MAX 1.010
90 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
93 #define AUDIO_DIFF_AVG_NB 20
96 #define REFRESH_RATE 0.01
100 #define SAMPLE_ARRAY_SIZE (8 * 65536)
102 #define CURSOR_HIDE_DELAY 1000000
122 #define VIDEO_PICTURE_QUEUE_SIZE 3
123 #define SUBPICTURE_QUEUE_SIZE 16
328 static const char **vfilters_list = NULL;
329 static int nb_vfilters = 0;
330 static char *afilters = NULL;
340 #define FF_ALLOC_EVENT (SDL_USEREVENT)
341 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
346 static int opt_add_vfilter(
void *optctx,
const char *opt,
const char *
arg)
349 vfilters_list[nb_vfilters - 1] =
arg;
359 if (channel_count1 == 1 && channel_count2 == 1)
362 return channel_count1 != channel_count2 || fmt1 != fmt2;
369 return channel_layout;
386 if (pkt == &flush_pkt)
398 SDL_CondSignal(q->
cond);
410 SDL_LockMutex(q->
mutex);
412 SDL_UnlockMutex(q->
mutex);
414 if (pkt != &flush_pkt && ret < 0)
434 q->
mutex = SDL_CreateMutex();
435 q->
cond = SDL_CreateCond();
443 SDL_LockMutex(q->
mutex);
444 for (pkt = q->
first_pkt; pkt; pkt = pkt1) {
453 SDL_UnlockMutex(q->
mutex);
459 SDL_DestroyMutex(q->
mutex);
460 SDL_DestroyCond(q->
cond);
465 SDL_LockMutex(q->
mutex);
469 SDL_CondSignal(q->
cond);
471 SDL_UnlockMutex(q->
mutex);
476 SDL_LockMutex(q->
mutex);
479 SDL_UnlockMutex(q->
mutex);
488 SDL_LockMutex(q->
mutex);
516 SDL_UnlockMutex(q->
mutex);
528 SDL_FillRect(screen, &rect, color);
529 if (update && w > 0 && h > 0)
530 SDL_UpdateRect(screen, x, y, w, h);
542 w2 = width - (x + w);
548 h2 = height - (y + h);
556 xleft + width - w2, ytop,
564 xleft + w1, ytop + height - h2,
569 #define ALPHA_BLEND(a, oldp, newp, s)\
570 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
572 #define RGBA_IN(r, g, b, a, s)\
574 unsigned int v = ((const uint32_t *)(s))[0];\
575 a = (v >> 24) & 0xff;\
576 r = (v >> 16) & 0xff;\
577 g = (v >> 8) & 0xff;\
581 #define YUVA_IN(y, u, v, a, s, pal)\
583 unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
584 a = (val >> 24) & 0xff;\
585 y = (val >> 16) & 0xff;\
586 u = (val >> 8) & 0xff;\
590 #define YUVA_OUT(d, y, u, v, a)\
592 ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
600 int wrap, wrap3, width2, skip2;
601 int y,
u,
v,
a, u1, v1,
a1, w, h;
605 int dstx, dsty, dstw, dsth;
607 dstw = av_clip(rect->
w, 0, imgw);
608 dsth = av_clip(rect->
h, 0, imgh);
609 dstx = av_clip(rect->
x, 0, imgw - dstw);
610 dsty = av_clip(rect->
y, 0, imgh - dsth);
615 width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
620 pal = (
const uint32_t *)rect->
pict.
data[1];
637 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
664 p += wrap3 - dstw *
BPP;
665 lum += wrap - dstw - dstx;
666 cb += dst->
linesize[1] - width2 - skip2;
667 cr += dst->
linesize[2] - width2 - skip2;
669 for (h = dsth - (dsty & 1); h >= 2; h -= 2) {
694 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
726 p += -wrap3 + 2 *
BPP;
749 p += wrap3 + (wrap3 - dstw *
BPP);
750 lum += wrap + (wrap - dstw - dstx);
751 cb += dst->
linesize[1] - width2 - skip2;
752 cr += dst->
linesize[2] - width2 - skip2;
770 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
801 SDL_FreeYUVOverlay(vp->
bmp);
812 int scr_xleft,
int scr_ytop,
int scr_width,
int scr_height,
813 int pic_width,
int pic_height,
AVRational pic_sar)
818 if (pic_sar.
num == 0)
821 aspect_ratio =
av_q2d(pic_sar);
823 if (aspect_ratio <= 0.0)
825 aspect_ratio *= (float)pic_width / (
float)pic_height;
829 width = ((int)
rint(height * aspect_ratio)) & ~1;
830 if (width > scr_width) {
832 height = ((int)
rint(width / aspect_ratio)) & ~1;
834 x = (scr_width -
width) / 2;
835 y = (scr_height -
height) / 2;
836 rect->x = scr_xleft + x;
837 rect->y = scr_ytop +
y;
838 rect->w =
FFMAX(width, 1);
839 rect->h =
FFMAX(height, 1);
857 SDL_LockYUVOverlay (vp->
bmp);
859 pict.
data[0] = vp->
bmp->pixels[0];
860 pict.
data[1] = vp->
bmp->pixels[2];
861 pict.
data[2] = vp->
bmp->pixels[1];
871 SDL_UnlockYUVOverlay (vp->
bmp);
878 SDL_DisplayYUVOverlay(vp->
bmp, &rect);
881 int bgcolor = SDL_MapRGB(
screen->format, 0x00, 0x00, 0x00);
890 return a < 0 ? a%b + b : a%
b;
895 int i, i_start, x, y1,
y, ys, delay,
n, nb_display_channels;
896 int ch, channels, h, h2, bgcolor, fgcolor;
898 int rdft_bits, nb_freq;
900 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->
height; rdft_bits++)
902 nb_freq = 1 << (rdft_bits - 1);
906 nb_display_channels = channels;
908 int data_used= s->
show_mode == SHOW_MODE_WAVES ? s->
width : (2*nb_freq);
920 delay += 2 * data_used;
921 if (delay < data_used)
927 for (i = 0; i < 1000; i += channels) {
934 if (h < score && (b ^ c) < 0) {
946 bgcolor = SDL_MapRGB(
screen->format, 0x00, 0x00, 0x00);
952 fgcolor = SDL_MapRGB(
screen->format, 0xff, 0xff, 0xff);
955 h = s->
height / nb_display_channels;
958 for (ch = 0; ch < nb_display_channels; ch++) {
960 y1 = s->
ytop + ch * h + (h / 2);
961 for (x = 0; x < s->
width; x++) {
970 s->
xleft + x, ys, 1, y,
978 fgcolor = SDL_MapRGB(
screen->format, 0x00, 0x00, 0xff);
980 for (ch = 1; ch < nb_display_channels; ch++) {
981 y = s->
ytop + ch * h;
988 nb_display_channels=
FFMIN(nb_display_channels, 2);
998 for (ch = 0; ch < nb_display_channels; ch++) {
999 data[ch] = s->
rdft_data + 2 * nb_freq * ch;
1001 for (x = 0; x < 2 * nb_freq; x++) {
1002 double w = (x-nb_freq) * (1.0 / nb_freq);
1012 for (y = 0; y < s->
height; y++) {
1013 double w = 1 / sqrt(nb_freq);
1014 int a = sqrt(w * sqrt(data[0][2 * y + 0] * data[0][2 * y + 0] + data[0][2 * y + 1] * data[0][2 * y + 1]));
1015 int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0]
1016 + data[1][2 * y + 1] * data[1][2 * y + 1])) : a;
1019 fgcolor = SDL_MapRGB(
screen->format, a, b, (a + b) / 2);
1039 SDL_WaitThread(is->
read_tid, NULL);
1054 #if !CONFIG_AVFILTER
1093 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1097 else flags |= SDL_RESIZABLE;
1099 if (vp && vp->
width)
1112 w =
FFMIN(16383, w);
1116 screen = SDL_SetVideoMode(w, h, 0, flags);
1283 double sync_threshold, diff;
1296 if (diff <= -sync_threshold)
1297 delay =
FFMAX(0, delay + diff);
1299 delay = delay + diff;
1300 else if (diff >= sync_threshold)
1305 av_dlog(NULL,
"video: delay=%0.3f A-V=%f\n",
1385 double last_duration,
duration, delay;
1413 if (time < is->frame_timer + delay && !redisplay) {
1481 static int64_t last_time;
1483 int aqsize, vqsize, sqsize;
1487 if (!last_time || (cur_time - last_time) >= 30000) {
1505 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64
"/%"PRId64
" \r",
1537 bufferdiff = vp->
bmp ?
FFMAX(vp->
bmp->pixels[0], vp->
bmp->pixels[1]) -
FFMIN(vp->
bmp->pixels[0], vp->
bmp->pixels[1]) : 0;
1538 if (!vp->
bmp || vp->
bmp->pitches[0] < vp->
width || bufferdiff < (int64_t)vp->
height * vp->
bmp->pitches[0]) {
1542 "Error: the video system does not support an image\n"
1543 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1544 "to reduce the image size.\n", vp->
width, vp->
height );
1557 for (i = 0; i < 3; i++) {
1564 if (bmp->pitches[i] > width) {
1565 maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1566 for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1576 #if defined(DEBUG_SYNC) && 0
1577 printf(
"frame_type=%c pts=%0.3f\n",
1611 event.user.data1 = is;
1612 SDL_PushEvent(&event);
1636 SDL_LockYUVOverlay (vp->
bmp);
1638 pict.
data[0] = vp->
bmp->pixels[0];
1639 pict.
data[1] = vp->
bmp->pixels[2];
1640 pict.
data[2] = vp->
bmp->pixels[1];
1665 SDL_UnlockYUVOverlay(vp->
bmp);
1697 if (!got_picture && !pkt->
data)
1747 if (!outputs || !inputs) {
1755 outputs->
next = NULL;
1758 inputs->filter_ctx = sink_ctx;
1759 inputs->pad_idx = 0;
1760 inputs->next = NULL;
1770 for (i = 0; i < graph->
nb_filters - nb_filters; i++)
1783 char sws_flags_str[128];
1784 char buffersrc_args[256];
1794 snprintf(buffersrc_args,
sizeof(buffersrc_args),
1795 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1800 av_strlcatf(buffersrc_args,
sizeof(buffersrc_args),
":frame_rate=%d/%d", fr.
num, fr.
den);
1804 "ffplay_buffer", buffersrc_args, NULL,
1810 "ffplay_buffersink", NULL, NULL, graph);
1817 last_filter = filt_out;
1821 #define INSERT_FILT(name, arg) do { \
1822 AVFilterContext *filt_ctx; \
1824 ret = avfilter_graph_create_filter(&filt_ctx, \
1825 avfilter_get_by_name(name), \
1826 "ffplay_" name, arg, NULL, graph); \
1830 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1834 last_filter = filt_ctx; \
1839 INSERT_FILT(
"crop",
"floor(in_w/2)*2:floor(in_h/2)*2");
1843 if (rotate_tag && *rotate_tag->
value && strcmp(rotate_tag->
value,
"0")) {
1844 if (!strcmp(rotate_tag->
value,
"90")) {
1845 INSERT_FILT(
"transpose",
"clock");
1846 }
else if (!strcmp(rotate_tag->
value,
"180")) {
1847 INSERT_FILT(
"hflip", NULL);
1848 INSERT_FILT(
"vflip", NULL);
1849 }
else if (!strcmp(rotate_tag->
value,
"270")) {
1850 INSERT_FILT(
"transpose",
"cclock");
1852 char rotate_buf[64];
1853 snprintf(rotate_buf,
sizeof(rotate_buf),
"%s*PI/180", rotate_tag->
value);
1854 INSERT_FILT(
"rotate", rotate_buf);
1862 is->in_video_filter = filt_src;
1863 is->out_video_filter = filt_out;
1869 static int configure_audio_filters(
VideoState *is,
const char *afilters,
int force_output_format)
1873 int64_t channel_layouts[2] = { 0, -1 };
1874 int channels[2] = { 0, -1 };
1876 char aresample_swr_opts[512] =
"";
1878 char asrc_args[256];
1887 if (strlen(aresample_swr_opts))
1888 aresample_swr_opts[strlen(aresample_swr_opts)-1] =
'\0';
1889 av_opt_set(is->agraph,
"aresample_swr_opts", aresample_swr_opts, 0);
1891 ret =
snprintf(asrc_args,
sizeof(asrc_args),
1892 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1894 is->audio_filter_src.channels,
1895 1, is->audio_filter_src.freq);
1896 if (is->audio_filter_src.channel_layout)
1897 snprintf(asrc_args + ret,
sizeof(asrc_args) - ret,
1898 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1902 asrc_args, NULL, is->agraph);
1909 NULL, NULL, is->agraph);
1918 if (force_output_format) {
1936 is->in_audio_filter = filt_asrc;
1937 is->out_audio_filter = filt_asink;
1964 int last_serial = -1;
1965 int last_vfilter_idx = 0;
1981 if ( last_w != frame->
width
1982 || last_h != frame->
height
1983 || last_format != frame->
format
1984 || last_serial != serial
1985 || last_vfilter_idx != is->vfilter_idx) {
1987 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
1994 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
1997 event.user.data1 = is;
1998 SDL_PushEvent(&event);
2001 filt_in = is->in_video_filter;
2002 filt_out = is->out_video_filter;
2003 last_w = frame->
width;
2005 last_format = frame->
format;
2006 last_serial = serial;
2007 last_vfilter_idx = is->vfilter_idx;
2092 &got_subtitle, pkt);
2093 if (got_subtitle && sp->
sub.
format == 0) {
2117 }
else if (got_subtitle) {
2130 size = samples_size /
sizeof(short);
2148 int wanted_nb_samples = nb_samples;
2152 double diff, avg_diff;
2153 int min_nb_samples, max_nb_samples;
2167 wanted_nb_samples = nb_samples + (int)(diff * is->
audio_src.
freq);
2170 wanted_nb_samples =
FFMIN(
FFMAX(wanted_nb_samples, min_nb_samples), max_nb_samples);
2172 av_dlog(NULL,
"diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2173 diff, avg_diff, wanted_nb_samples - nb_samples,
2184 return wanted_nb_samples;
2199 int len1, data_size, resampled_data_size;
2200 int64_t dec_channel_layout;
2203 int wanted_nb_samples;
2234 pkt_temp->
data += len1;
2235 pkt_temp->
size -= len1;
2236 if (pkt_temp->
data && pkt_temp->
size <= 0 || !pkt_temp->
data && !got_frame)
2238 if (!pkt_temp->
data && !got_frame)
2263 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2265 is->audio_filter_src.channel_layout != dec_channel_layout ||
2270 char buf1[1024], buf2[1024];
2274 "Audio frame changed from rate:%d ch:%d fmt:%s layout:%s serial:%d to rate:%d ch:%d fmt:%s layout:%s serial:%d\n",
2280 is->audio_filter_src.channel_layout = dec_channel_layout;
2284 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2303 tb = is->out_audio_filter->inputs[0]->time_base;
2310 dec_channel_layout =
2326 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2362 if (len2 == out_count) {
2370 resampled_data_size = data_size;
2382 static double last_clock;
2383 printf(
"audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2389 return resampled_data_size;
2395 memset(pkt_temp, 0,
sizeof(*pkt_temp));
2396 pkt_temp->stream_index = -1;
2425 int audio_size, len1;
2432 if (audio_size < 0) {
2459 static int audio_open(
void *opaque, int64_t wanted_channel_layout,
int wanted_nb_channels,
int wanted_sample_rate,
struct AudioParams *audio_hw_params)
2461 SDL_AudioSpec wanted_spec, spec;
2463 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2464 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2465 int next_sample_rate_idx =
FF_ARRAY_ELEMS(next_sample_rates) - 1;
2467 env = SDL_getenv(
"SDL_AUDIO_CHANNELS");
2469 wanted_nb_channels = atoi(env);
2477 wanted_spec.channels = wanted_nb_channels;
2478 wanted_spec.freq = wanted_sample_rate;
2479 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2483 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2484 next_sample_rate_idx--;
2485 wanted_spec.format = AUDIO_S16SYS;
2486 wanted_spec.silence = 0;
2489 wanted_spec.userdata = opaque;
2490 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2492 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2493 wanted_spec.channels = next_nb_channels[
FFMIN(7, wanted_spec.channels)];
2494 if (!wanted_spec.channels) {
2495 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2496 wanted_spec.channels = wanted_nb_channels;
2497 if (!wanted_spec.freq) {
2499 "No more combinations to try, audio open failed\n");
2505 if (spec.format != AUDIO_S16SYS) {
2507 "SDL advised audio format %d is not supported!\n", spec.format);
2510 if (spec.channels != wanted_spec.channels) {
2512 if (!wanted_channel_layout) {
2514 "SDL advised channel count %d is not supported!\n", spec.channels);
2520 audio_hw_params->
freq = spec.freq;
2522 audio_hw_params->
channels = spec.channels;
2538 const char *forced_codec_name = NULL;
2542 int64_t channel_layout;
2544 int stream_lowres =
lowres;
2546 if (stream_index < 0 || stream_index >= ic->
nb_streams)
2557 if (forced_codec_name)
2561 "No codec could be found with name '%s'\n", forced_codec_name);
2563 "No codec could be found with id %d\n", avctx->
codec_id);
2603 is->audio_filter_src.channels = avctx->
channels;
2605 is->audio_filter_src.fmt = avctx->
sample_fmt;
2606 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2608 link = is->out_audio_filter->inputs[0];
2670 if (stream_index < 0 || stream_index >= ic->
nb_streams)
2762 if(s->
pb && ( !strncmp(s->
filename,
"rtp:", 4)
2763 || !strncmp(s->
filename,
"udp:", 4)
2779 int64_t stream_start_time;
2780 int pkt_in_play_range = 0;
2783 int orig_nb_streams;
2784 SDL_mutex *wait_mutex = SDL_CreateMutex();
2786 memset(st_index, -1,
sizeof(st_index));
2818 "%s: could not find codec parameters\n", is->
filename);
2822 for (i = 0; i < orig_nb_streams; i++)
2864 st_index[AVMEDIA_TYPE_VIDEO],
2870 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2871 st_index[AVMEDIA_TYPE_AUDIO] :
2872 st_index[AVMEDIA_TYPE_VIDEO]),
2879 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2888 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2893 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2897 is->
show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2899 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2910 if (infinite_buffer < 0 && is->realtime)
2923 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2934 int64_t seek_target = is->
seek_pos;
2935 int64_t seek_min = is->
seek_rel > 0 ? seek_target - is->
seek_rel + 2: INT64_MIN;
2936 int64_t seek_max = is->
seek_rel < 0 ? seek_target - is->
seek_rel - 2: INT64_MAX;
2943 "%s: error while seeking\n", is->
ic->
filename);
2988 SDL_LockMutex(wait_mutex);
2990 SDL_UnlockMutex(wait_mutex);
3020 SDL_LockMutex(wait_mutex);
3022 SDL_UnlockMutex(wait_mutex);
3065 event.user.data1 = is;
3066 SDL_PushEvent(&event);
3068 SDL_DestroyMutex(wait_mutex);
3114 int start_index, stream_index;
3130 stream_index = start_index;
3136 for (start_index = 0; start_index <
nb_streams; start_index++)
3139 if (start_index == nb_streams)
3141 stream_index = start_index;
3146 if (++stream_index >= nb_streams)
3154 if (start_index == -1)
3158 if (stream_index == start_index)
3163 switch (codec_type) {
3178 if (p && stream_index != -1)
3192 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3204 int bgcolor = SDL_MapRGB(
screen->format, 0x00, 0x00, 0x00);
3207 next = (next + 1) % SHOW_MODE_NB;
3208 }
while (next != is->
show_mode && (next == SHOW_MODE_VIDEO && !is->
video_st || next != SHOW_MODE_VIDEO && !is->
audio_st));
3219 double remaining_time = 0.0;
3221 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3226 if (remaining_time > 0.0)
3227 av_usleep((int64_t)(remaining_time * 1000000.0));
3266 double incr, pos, frac;
3271 switch (event.type) {
3277 switch (event.key.keysym.sym) {
3309 if (cur_stream->
show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3310 if (++cur_stream->vfilter_idx >= nb_vfilters)
3311 cur_stream->vfilter_idx = 0;
3313 cur_stream->vfilter_idx = 0;
3373 case SDL_VIDEOEXPOSE:
3376 case SDL_MOUSEBUTTONDOWN:
3381 case SDL_MOUSEMOTION:
3387 if (event.type == SDL_MOUSEBUTTONDOWN) {
3390 if (event.motion.state != SDL_PRESSED)
3400 int tns, thh, tmm, tss;
3403 tmm = (tns % 3600) / 60;
3405 frac = x / cur_stream->
width;
3408 mm = (ns % 3600) / 60;
3411 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3412 hh, mm, ss, thh, tmm, tss);
3419 case SDL_VIDEORESIZE:
3420 screen = SDL_SetVideoMode(
FFMIN(16383, event.resize.w), event.resize.h, 0,
3421 SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
3464 if (!file_iformat) {
3479 if (!strcmp(arg,
"audio"))
3481 else if (!strcmp(arg,
"video"))
3483 else if (!strcmp(arg,
"ext"))
3506 show_mode = !strcmp(arg,
"video") ? SHOW_MODE_VIDEO :
3507 !strcmp(arg,
"waves") ? SHOW_MODE_WAVES :
3508 !strcmp(arg,
"rdft" ) ? SHOW_MODE_RDFT :
3517 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3521 if (!strcmp(filename,
"-"))
3528 const char *spec = strchr(opt,
':');
3531 "No media specifier was specified in '%s' in option '%s'\n",
3542 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3552 {
"x",
HAS_ARG, { .func_arg =
opt_width },
"force displayed width",
"width" },
3553 {
"y",
HAS_ARG, { .func_arg =
opt_height },
"force displayed height",
"height" },
3562 {
"ss",
HAS_ARG, { .func_arg =
opt_seek },
"seek to a given position in seconds",
"pos" },
3563 {
"t",
HAS_ARG, { .func_arg =
opt_duration },
"play \"duration\" seconds of audio/video",
"duration" },
3574 {
"sync",
HAS_ARG |
OPT_EXPERT, { .func_arg =
opt_sync },
"set audio-video sync. type (type=audio/video/ext)",
"type" },
3583 {
"vf",
OPT_EXPERT |
HAS_ARG, { .func_arg = opt_add_vfilter },
"set video filters",
"filter_graph" },
3584 {
"af",
OPT_STRING |
HAS_ARG, { &afilters },
"set audio filters",
"filter_graph" },
3587 {
"showmode",
HAS_ARG, { .func_arg =
opt_show_mode},
"select show mode (0 = video, 1 = waves, 2 = RDFT)",
"mode" },
3589 {
"i",
OPT_BOOL, { &dummy},
"read specified file",
"input_file"},
3590 {
"codec",
HAS_ARG, { .func_arg =
opt_codec},
"force decoder",
"decoder_name" },
3614 #if !CONFIG_AVFILTER
3619 printf(
"\nWhile playing:\n"
3621 "f toggle full screen\n"
3623 "a cycle audio channel in the current program\n"
3624 "v cycle video channel\n"
3625 "t cycle subtitle channel in the current program\n"
3627 "w cycle video filters or show modes\n"
3628 "s activate frame-step mode\n"
3629 "left/right seek backward/forward 10 seconds\n"
3630 "down/up seek backward/forward 1 minute\n"
3631 "page down/page up seek backward/forward 10 minutes\n"
3632 "mouse click seek to percentage in file corresponding to fraction of width\n"
3640 *mtx = SDL_CreateMutex();
3645 return !!SDL_LockMutex(*mtx);
3647 return !!SDL_UnlockMutex(*mtx);
3649 SDL_DestroyMutex(*mtx);
3660 char dummy_videodriver[] =
"SDL_VIDEODRIVER=dummy";
3688 "Use -h to get full help or, even better, run 'man %s'\n",
program_name);
3695 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3697 flags &= ~SDL_INIT_AUDIO;
3699 SDL_putenv(dummy_videodriver);
3700 #if !defined(_WIN32) && !defined(__APPLE__)
3701 flags |= SDL_INIT_EVENTTHREAD;
3703 if (SDL_Init (flags)) {
3710 const SDL_VideoInfo *
vi = SDL_GetVideoInfo();
3715 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3716 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3717 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);