56 #include <SDL_thread.h>
65 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
70 #define SDL_AUDIO_BUFFER_SIZE 1024
73 #define AV_SYNC_THRESHOLD_MIN 0.01
75 #define AV_SYNC_THRESHOLD_MAX 0.1
77 #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
79 #define AV_NOSYNC_THRESHOLD 10.0
82 #define SAMPLE_CORRECTION_PERCENT_MAX 10
85 #define EXTERNAL_CLOCK_SPEED_MIN 0.900
86 #define EXTERNAL_CLOCK_SPEED_MAX 1.010
87 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
90 #define AUDIO_DIFF_AVG_NB 20
93 #define REFRESH_RATE 0.01
97 #define SAMPLE_ARRAY_SIZE (8 * 65536)
99 #define CURSOR_HIDE_DELAY 1000000
119 #define VIDEO_PICTURE_QUEUE_SIZE 3
120 #define SUBPICTURE_QUEUE_SIZE 4
325 static char *vfilters = NULL;
326 static char *afilters = NULL;
335 #define FF_ALLOC_EVENT (SDL_USEREVENT)
336 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
345 if (channel_count1 == 1 && channel_count2 == 1)
348 return channel_count1 != channel_count2 || fmt1 != fmt2;
355 return channel_layout;
374 if (pkt == &flush_pkt)
386 SDL_CondSignal(q->
cond);
398 SDL_LockMutex(q->
mutex);
400 SDL_UnlockMutex(q->
mutex);
402 if (pkt != &flush_pkt && ret < 0)
412 q->
mutex = SDL_CreateMutex();
413 q->
cond = SDL_CreateCond();
421 SDL_LockMutex(q->
mutex);
422 for (pkt = q->
first_pkt; pkt != NULL; pkt = pkt1) {
431 SDL_UnlockMutex(q->
mutex);
437 SDL_DestroyMutex(q->
mutex);
438 SDL_DestroyCond(q->
cond);
443 SDL_LockMutex(q->
mutex);
447 SDL_CondSignal(q->
cond);
449 SDL_UnlockMutex(q->
mutex);
454 SDL_LockMutex(q->
mutex);
457 SDL_UnlockMutex(q->
mutex);
466 SDL_LockMutex(q->
mutex);
494 SDL_UnlockMutex(q->
mutex);
499 int x,
int y,
int w,
int h,
int color,
int update)
506 SDL_FillRect(screen, &rect, color);
507 if (update && w > 0 && h > 0)
508 SDL_UpdateRect(screen, x, y, w, h);
520 w2 = width - (x + w);
526 h2 = height - (y + h);
534 xleft + width - w2, ytop,
542 xleft + w1, ytop + height - h2,
547 #define ALPHA_BLEND(a, oldp, newp, s)\
548 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
550 #define RGBA_IN(r, g, b, a, s)\
552 unsigned int v = ((const uint32_t *)(s))[0];\
553 a = (v >> 24) & 0xff;\
554 r = (v >> 16) & 0xff;\
555 g = (v >> 8) & 0xff;\
559 #define YUVA_IN(y, u, v, a, s, pal)\
561 unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
562 a = (val >> 24) & 0xff;\
563 y = (val >> 16) & 0xff;\
564 u = (val >> 8) & 0xff;\
568 #define YUVA_OUT(d, y, u, v, a)\
570 ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
578 int wrap, wrap3, width2, skip2;
579 int y,
u,
v,
a, u1, v1,
a1, w, h;
583 int dstx, dsty, dstw, dsth;
585 dstw = av_clip(rect->
w, 0, imgw);
586 dsth = av_clip(rect->
h, 0, imgh);
587 dstx = av_clip(rect->
x, 0, imgw - dstw);
588 dsty = av_clip(rect->
y, 0, imgh - dsth);
593 width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
598 pal = (
const uint32_t *)rect->
pict.
data[1];
615 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
642 p += wrap3 - dstw *
BPP;
643 lum += wrap - dstw - dstx;
644 cb += dst->
linesize[1] - width2 - skip2;
645 cr += dst->
linesize[2] - width2 - skip2;
647 for (h = dsth - (dsty & 1); h >= 2; h -= 2) {
672 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
704 p += -wrap3 + 2 *
BPP;
727 p += wrap3 + (wrap3 - dstw *
BPP);
728 lum += wrap + (wrap - dstw - dstx);
729 cb += dst->
linesize[1] - width2 - skip2;
730 cr += dst->
linesize[2] - width2 - skip2;
748 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
791 if (aspect_ratio <= 0.0)
793 aspect_ratio *= (float)vp->
width / (
float)vp->
height;
797 width = ((int)
rint(height * aspect_ratio)) & ~1;
798 if (width > scr_width) {
800 height = ((int)
rint(width / aspect_ratio)) & ~1;
802 x = (scr_width -
width) / 2;
803 y = (scr_height -
height) / 2;
804 rect->x = scr_xleft + x;
805 rect->y = scr_ytop +
y;
806 rect->w =
FFMAX(width, 1);
807 rect->h =
FFMAX(height, 1);
825 SDL_LockYUVOverlay (vp->
bmp);
827 pict.
data[0] = vp->
bmp->pixels[0];
828 pict.
data[1] = vp->
bmp->pixels[2];
829 pict.
data[2] = vp->
bmp->pixels[1];
839 SDL_UnlockYUVOverlay (vp->
bmp);
846 SDL_DisplayYUVOverlay(vp->
bmp, &rect);
849 int bgcolor = SDL_MapRGB(
screen->format, 0x00, 0x00, 0x00);
858 return a < 0 ? a%b + b : a%
b;
863 int i, i_start, x, y1,
y, ys, delay,
n, nb_display_channels;
864 int ch, channels, h, h2, bgcolor, fgcolor;
866 int rdft_bits, nb_freq;
868 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->
height; rdft_bits++)
870 nb_freq = 1 << (rdft_bits - 1);
874 nb_display_channels = channels;
876 int data_used= s->
show_mode == SHOW_MODE_WAVES ? s->
width : (2*nb_freq);
888 delay += 2 * data_used;
889 if (delay < data_used)
895 for (i = 0; i < 1000; i += channels) {
902 if (h < score && (b ^ c) < 0) {
914 bgcolor = SDL_MapRGB(
screen->format, 0x00, 0x00, 0x00);
920 fgcolor = SDL_MapRGB(
screen->format, 0xff, 0xff, 0xff);
923 h = s->
height / nb_display_channels;
926 for (ch = 0; ch < nb_display_channels; ch++) {
928 y1 = s->
ytop + ch * h + (h / 2);
929 for (x = 0; x < s->
width; x++) {
938 s->
xleft + x, ys, 1, y,
946 fgcolor = SDL_MapRGB(
screen->format, 0x00, 0x00, 0xff);
948 for (ch = 1; ch < nb_display_channels; ch++) {
949 y = s->
ytop + ch * h;
956 nb_display_channels=
FFMIN(nb_display_channels, 2);
966 for (ch = 0; ch < nb_display_channels; ch++) {
967 data[ch] = s->
rdft_data + 2 * nb_freq * ch;
969 for (x = 0; x < 2 * nb_freq; x++) {
970 double w = (x-nb_freq) * (1.0 / nb_freq);
979 for (y = 0; y < s->
height; y++) {
980 double w = 1 / sqrt(nb_freq);
981 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]));
982 int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0]
983 + data[1][2 * y + 1] * data[1][2 * y + 1])) : a;
986 fgcolor = SDL_MapRGB(
screen->format, a, b, (a + b) / 2);
1007 SDL_WaitThread(is->
read_tid, NULL);
1016 SDL_FreeYUVOverlay(vp->
bmp);
1025 #if !CONFIG_AVFILTER
1056 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1061 else flags |= SDL_RESIZABLE;
1063 if (vp && vp->
width) {
1079 w =
FFMIN(16383, w);
1083 screen = SDL_SetVideoMode(w, h, 0, flags);
1250 double sync_threshold,
diff;
1263 if (diff <= -sync_threshold)
1264 delay =
FFMAX(0, delay + diff);
1266 delay = delay +
diff;
1267 else if (diff >= sync_threshold)
1272 av_dlog(NULL,
"video: delay=%0.3f A-V=%f\n",
1351 double last_duration,
duration, delay;
1366 if (!
isnan(last_duration) && last_duration > 0 && last_duration < is->max_frame_duration) {
1376 if (time < is->frame_timer + delay && !redisplay) {
1392 duration = nextvp->
pts - vp->
pts;
1444 static int64_t last_time;
1446 int aqsize, vqsize, sqsize;
1450 if (!last_time || (cur_time - last_time) >= 30000) {
1468 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64
"/%"PRId64
" \r",
1494 SDL_FreeYUVOverlay(vp->
bmp);
1501 bufferdiff = vp->
bmp ?
FFMAX(vp->
bmp->pixels[0], vp->
bmp->pixels[1]) -
FFMIN(vp->
bmp->pixels[0], vp->
bmp->pixels[1]) : 0;
1502 if (!vp->
bmp || vp->
bmp->pitches[0] < vp->
width || bufferdiff < (int64_t)vp->
height * vp->
bmp->pitches[0]) {
1506 "Error: the video system does not support an image\n"
1507 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1508 "to reduce the image size.\n", vp->
width, vp->
height );
1521 for (i = 0; i < 3; i++) {
1528 if (bmp->pitches[i] > width) {
1529 maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1530 for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1540 #if defined(DEBUG_SYNC) && 0
1541 printf(
"frame_type=%c pts=%0.3f\n",
1576 event.user.data1 = is;
1577 SDL_PushEvent(&event);
1601 SDL_LockYUVOverlay (vp->
bmp);
1603 pict.
data[0] = vp->
bmp->pixels[0];
1604 pict.
data[1] = vp->
bmp->pixels[2];
1605 pict.
data[2] = vp->
bmp->pixels[1];
1630 SDL_UnlockYUVOverlay(vp->
bmp);
1725 if (!outputs || !inputs) {
1733 outputs->
next = NULL;
1736 inputs->filter_ctx = sink_ctx;
1737 inputs->pad_idx = 0;
1738 inputs->next = NULL;
1757 char sws_flags_str[128];
1758 char buffersrc_args[256];
1768 snprintf(buffersrc_args,
sizeof(buffersrc_args),
1769 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1774 av_strlcatf(buffersrc_args,
sizeof(buffersrc_args),
":frame_rate=%d/%d", fr.
num, fr.
den);
1778 "ffplay_buffer", buffersrc_args, NULL,
1784 "ffplay_buffersink", NULL, NULL, graph);
1795 "ffplay_crop",
"floor(in_w/2)*2:floor(in_h/2)*2", NULL, graph)) < 0)
1803 is->in_video_filter = filt_src;
1804 is->out_video_filter = filt_out;
1810 static int configure_audio_filters(
VideoState *is,
const char *afilters,
int force_output_format)
1814 int64_t channel_layouts[2] = { 0, -1 };
1815 int channels[2] = { 0, -1 };
1817 char asrc_args[256];
1824 ret =
snprintf(asrc_args,
sizeof(asrc_args),
1825 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1827 is->audio_filter_src.channels,
1828 1, is->audio_filter_src.freq);
1829 if (is->audio_filter_src.channel_layout)
1830 snprintf(asrc_args + ret,
sizeof(asrc_args) - ret,
1831 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1835 asrc_args, NULL, is->agraph);
1842 NULL, NULL, is->agraph);
1851 if (force_output_format) {
1869 is->in_audio_filter = filt_asrc;
1870 is->out_audio_filter = filt_asink;
1894 int last_serial = -1;
1911 if ( last_w != frame->
width
1912 || last_h != frame->
height
1913 || last_format != frame->
format
1914 || last_serial != serial) {
1916 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
1923 if ((ret = configure_video_filters(graph, is, vfilters, frame)) < 0) {
1926 event.user.data1 = is;
1927 SDL_PushEvent(&event);
1931 filt_in = is->in_video_filter;
1932 filt_out = is->out_video_filter;
1933 last_w = frame->
width;
1935 last_format = frame->
format;
1936 last_serial = serial;
2023 &got_subtitle, pkt);
2024 if (got_subtitle && sp->
sub.
format == 0) {
2059 size = samples_size /
sizeof(short);
2077 int wanted_nb_samples = nb_samples;
2081 double diff, avg_diff;
2082 int min_nb_samples, max_nb_samples;
2096 wanted_nb_samples = nb_samples + (int)(diff * is->
audio_src.
freq);
2099 wanted_nb_samples =
FFMIN(
FFMAX(wanted_nb_samples, min_nb_samples), max_nb_samples);
2101 av_dlog(NULL,
"diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2102 diff, avg_diff, wanted_nb_samples - nb_samples,
2113 return wanted_nb_samples;
2128 int len1, data_size, resampled_data_size;
2129 int64_t dec_channel_layout;
2133 int flush_complete = 0;
2134 int wanted_nb_samples;
2167 pkt_temp->
data += len1;
2168 pkt_temp->
size -= len1;
2189 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2191 is->audio_filter_src.channel_layout != dec_channel_layout ||
2196 char buf1[1024], buf2[1024];
2200 "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",
2206 is->audio_filter_src.channel_layout = dec_channel_layout;
2210 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2228 tb = is->out_audio_filter->inputs[0]->time_base;
2235 dec_channel_layout =
2251 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2287 if (len2 == out_count) {
2295 resampled_data_size = data_size;
2307 static double last_clock;
2308 printf(
"audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2314 return resampled_data_size;
2320 memset(pkt_temp, 0,
sizeof(*pkt_temp));
2356 if (audio_size < 0) {
2384 static int audio_open(
void *opaque, int64_t wanted_channel_layout,
int wanted_nb_channels,
int wanted_sample_rate,
struct AudioParams *audio_hw_params)
2386 SDL_AudioSpec wanted_spec, spec;
2388 const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2390 env = SDL_getenv(
"SDL_AUDIO_CHANNELS");
2392 wanted_nb_channels = atoi(env);
2400 wanted_spec.freq = wanted_sample_rate;
2401 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2405 wanted_spec.format = AUDIO_S16SYS;
2406 wanted_spec.silence = 0;
2409 wanted_spec.userdata = opaque;
2410 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2411 av_log(NULL,
AV_LOG_WARNING,
"SDL_OpenAudio (%d channels): %s\n", wanted_spec.channels, SDL_GetError());
2412 wanted_spec.channels = next_nb_channels[
FFMIN(7, wanted_spec.channels)];
2413 if (!wanted_spec.channels) {
2415 "No more channel combinations to try, audio open failed\n");
2420 if (spec.format != AUDIO_S16SYS) {
2422 "SDL advised audio format %d is not supported!\n", spec.format);
2425 if (spec.channels != wanted_spec.channels) {
2427 if (!wanted_channel_layout) {
2429 "SDL advised channel count %d is not supported!\n", spec.channels);
2435 audio_hw_params->
freq = spec.freq;
2437 audio_hw_params->
channels = spec.channels;
2447 const char *forced_codec_name = NULL;
2451 int64_t channel_layout;
2454 if (stream_index < 0 || stream_index >= ic->
nb_streams)
2465 if (forced_codec_name)
2469 "No codec could be found with name '%s'\n", forced_codec_name);
2471 "No codec could be found with id %d\n", avctx->
codec_id);
2513 is->audio_filter_src.channels = avctx->
channels;
2515 is->audio_filter_src.fmt = avctx->
sample_fmt;
2516 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2518 link = is->out_audio_filter->inputs[0];
2579 if (stream_index < 0 || stream_index >= ic->
nb_streams)
2671 if(s->
pb && ( !strncmp(s->
filename,
"rtp:", 4)
2672 || !strncmp(s->
filename,
"udp:", 4)
2688 int64_t stream_start_time;
2689 int pkt_in_play_range = 0;
2692 int orig_nb_streams;
2693 SDL_mutex *wait_mutex = SDL_CreateMutex();
2695 memset(st_index, -1,
sizeof(st_index));
2725 "%s: could not find codec parameters\n", is->
filename);
2729 for (i = 0; i < orig_nb_streams; i++)
2771 st_index[AVMEDIA_TYPE_VIDEO],
2777 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2778 st_index[AVMEDIA_TYPE_AUDIO] :
2779 st_index[AVMEDIA_TYPE_VIDEO]),
2788 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2793 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2797 is->
show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2799 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2809 if (infinite_buffer < 0 && is->realtime)
2822 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2833 int64_t seek_target = is->
seek_pos;
2834 int64_t seek_min = is->
seek_rel > 0 ? seek_target - is->
seek_rel + 2: INT64_MIN;
2835 int64_t seek_max = is->
seek_rel < 0 ? seek_target - is->
seek_rel - 2: INT64_MAX;
2842 "%s: error while seeking\n", is->
ic->
filename);
2886 SDL_LockMutex(wait_mutex);
2888 SDL_UnlockMutex(wait_mutex);
2924 SDL_LockMutex(wait_mutex);
2926 SDL_UnlockMutex(wait_mutex);
2969 event.user.data1 = is;
2970 SDL_PushEvent(&event);
2972 SDL_DestroyMutex(wait_mutex);
3018 int start_index, stream_index;
3032 stream_index = start_index;
3042 if (start_index == -1)
3046 if (stream_index == start_index)
3048 st = ic->
streams[stream_index];
3051 switch (codec_type) {
3073 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3085 int bgcolor = SDL_MapRGB(
screen->format, 0x00, 0x00, 0x00);
3088 next = (next + 1) % SHOW_MODE_NB;
3089 }
while (next != is->
show_mode && (next == SHOW_MODE_VIDEO && !is->
video_st || next != SHOW_MODE_VIDEO && !is->
audio_st));
3100 double remaining_time = 0.0;
3102 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3107 if (remaining_time > 0.0)
3108 av_usleep((int64_t)(remaining_time * 1000000.0));
3120 double incr, pos, frac;
3125 switch (event.type) {
3131 switch (event.key.keysym.sym) {
3204 case SDL_VIDEOEXPOSE:
3207 case SDL_MOUSEBUTTONDOWN:
3212 case SDL_MOUSEMOTION:
3218 if (event.type == SDL_MOUSEBUTTONDOWN) {
3221 if (event.motion.state != SDL_PRESSED)
3231 int tns, thh, tmm, tss;
3234 tmm = (tns % 3600) / 60;
3236 frac = x / cur_stream->
width;
3239 mm = (ns % 3600) / 60;
3242 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3243 hh, mm, ss, thh, tmm, tss);
3250 case SDL_VIDEORESIZE:
3251 screen = SDL_SetVideoMode(
FFMIN(16383, event.resize.w), event.resize.h, 0,
3252 SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
3295 if (!file_iformat) {
3310 if (!strcmp(arg,
"audio"))
3312 else if (!strcmp(arg,
"video"))
3314 else if (!strcmp(arg,
"ext"))
3337 show_mode = !strcmp(arg,
"video") ? SHOW_MODE_VIDEO :
3338 !strcmp(arg,
"waves") ? SHOW_MODE_WAVES :
3339 !strcmp(arg,
"rdft" ) ? SHOW_MODE_RDFT :
3348 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3352 if (!strcmp(filename,
"-"))
3359 const char *spec = strchr(opt,
':');
3362 "No media specifier was specified in '%s' in option '%s'\n",
3373 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3383 {
"x",
HAS_ARG, { .func_arg =
opt_width },
"force displayed width",
"width" },
3384 {
"y",
HAS_ARG, { .func_arg =
opt_height },
"force displayed height",
"height" },
3393 {
"ss",
HAS_ARG, { .func_arg =
opt_seek },
"seek to a given position in seconds",
"pos" },
3394 {
"t",
HAS_ARG, { .func_arg =
opt_duration },
"play \"duration\" seconds of audio/video",
"duration" },
3407 {
"sync",
HAS_ARG |
OPT_EXPERT, { .func_arg =
opt_sync },
"set audio-video sync. type (type=audio/video/ext)",
"type" },
3416 {
"vf",
OPT_STRING |
HAS_ARG, { &vfilters },
"set video filters",
"filter_graph" },
3417 {
"af",
OPT_STRING |
HAS_ARG, { &afilters },
"set audio filters",
"filter_graph" },
3420 {
"showmode",
HAS_ARG, { .func_arg =
opt_show_mode},
"select show mode (0 = video, 1 = waves, 2 = RDFT)",
"mode" },
3422 {
"i",
OPT_BOOL, { &dummy},
"read specified file",
"input_file"},
3423 {
"codec",
HAS_ARG, { .func_arg =
opt_codec},
"force decoder",
"decoder_name" },
3446 #if !CONFIG_AVFILTER
3451 printf(
"\nWhile playing:\n"
3453 "f toggle full screen\n"
3455 "a cycle audio channel\n"
3456 "v cycle video channel\n"
3457 "t cycle subtitle channel\n"
3458 "w show audio waves\n"
3459 "s activate frame-step mode\n"
3460 "left/right seek backward/forward 10 seconds\n"
3461 "down/up seek backward/forward 1 minute\n"
3462 "page down/page up seek backward/forward 10 minutes\n"
3463 "mouse click seek to percentage in file corresponding to fraction of width\n"
3471 *mtx = SDL_CreateMutex();
3476 return !!SDL_LockMutex(*mtx);
3478 return !!SDL_UnlockMutex(*mtx);
3480 SDL_DestroyMutex(*mtx);
3491 char dummy_videodriver[] =
"SDL_VIDEODRIVER=dummy";
3520 "Use -h to get full help or, even better, run 'man %s'\n",
program_name);
3527 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3529 flags &= ~SDL_INIT_AUDIO;
3531 SDL_putenv(dummy_videodriver);
3532 #if !defined(__MINGW32__) && !defined(__APPLE__)
3533 flags |= SDL_INIT_EVENTTHREAD;
3535 if (SDL_Init (flags)) {
3542 const SDL_VideoInfo *
vi = SDL_GetVideoInfo();
3547 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3548 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3549 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);