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
124 #define SAMPLE_QUEUE_SIZE 9
125 #define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
339 static const char **vfilters_list =
NULL;
340 static int nb_vfilters = 0;
341 static char *afilters =
NULL;
351 #define FF_ALLOC_EVENT (SDL_USEREVENT)
352 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
357 static int opt_add_vfilter(
void *optctx,
const char *opt,
const char *
arg)
360 vfilters_list[nb_vfilters - 1] =
arg;
370 if (channel_count1 == 1 && channel_count2 == 1)
373 return channel_count1 != channel_count2 || fmt1 != fmt2;
380 return channel_layout;
399 if (pkt == &flush_pkt)
411 SDL_CondSignal(q->
cond);
423 SDL_LockMutex(q->
mutex);
425 SDL_UnlockMutex(q->
mutex);
427 if (pkt != &flush_pkt && ret < 0)
447 q->
mutex = SDL_CreateMutex();
448 q->
cond = SDL_CreateCond();
456 SDL_LockMutex(q->
mutex);
457 for (pkt = q->
first_pkt; pkt; pkt = pkt1) {
466 SDL_UnlockMutex(q->
mutex);
472 SDL_DestroyMutex(q->
mutex);
473 SDL_DestroyCond(q->
cond);
478 SDL_LockMutex(q->
mutex);
482 SDL_CondSignal(q->
cond);
484 SDL_UnlockMutex(q->
mutex);
489 SDL_LockMutex(q->
mutex);
492 SDL_UnlockMutex(q->
mutex);
501 SDL_LockMutex(q->
mutex);
529 SDL_UnlockMutex(q->
mutex);
622 }
while (!got_frame && !d->
finished);
641 if (!(f->
mutex = SDL_CreateMutex()))
643 if (!(f->
cond = SDL_CreateCond()))
663 SDL_DestroyMutex(f->
mutex);
664 SDL_DestroyCond(f->
cond);
669 SDL_LockMutex(f->
mutex);
670 SDL_CondSignal(f->
cond);
671 SDL_UnlockMutex(f->
mutex);
692 SDL_LockMutex(f->
mutex);
697 SDL_UnlockMutex(f->
mutex);
708 SDL_LockMutex(f->
mutex);
713 SDL_UnlockMutex(f->
mutex);
725 SDL_LockMutex(f->
mutex);
727 SDL_CondSignal(f->
cond);
728 SDL_UnlockMutex(f->
mutex);
740 SDL_LockMutex(f->
mutex);
742 SDL_CondSignal(f->
cond);
743 SDL_UnlockMutex(f->
mutex);
787 SDL_FillRect(screen, &rect, color);
788 if (update && w > 0 && h > 0)
789 SDL_UpdateRect(screen, x, y, w, h);
801 w2 = width - (x + w);
807 h2 = height - (y + h);
815 xleft + width - w2, ytop,
823 xleft + w1, ytop + height - h2,
828 #define ALPHA_BLEND(a, oldp, newp, s)\
829 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
831 #define RGBA_IN(r, g, b, a, s)\
833 unsigned int v = ((const uint32_t *)(s))[0];\
834 a = (v >> 24) & 0xff;\
835 r = (v >> 16) & 0xff;\
836 g = (v >> 8) & 0xff;\
840 #define YUVA_IN(y, u, v, a, s, pal)\
842 unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
843 a = (val >> 24) & 0xff;\
844 y = (val >> 16) & 0xff;\
845 u = (val >> 8) & 0xff;\
849 #define YUVA_OUT(d, y, u, v, a)\
851 ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
859 int wrap, wrap3, width2, skip2;
860 int y,
u,
v,
a, u1, v1,
a1, w, h;
864 int dstx, dsty, dstw, dsth;
866 dstw = av_clip(rect->
w, 0, imgw);
867 dsth = av_clip(rect->
h, 0, imgh);
868 dstx = av_clip(rect->
x, 0, imgw - dstw);
869 dsty = av_clip(rect->
y, 0, imgh - dsth);
874 width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
879 pal = (
const uint32_t *)rect->
pict.
data[1];
896 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
923 p += wrap3 - dstw *
BPP;
924 lum += wrap - dstw - dstx;
925 cb += dst->
linesize[1] - width2 - skip2;
926 cr += dst->
linesize[2] - width2 - skip2;
928 for (h = dsth - (dsty & 1); h >= 2; h -= 2) {
953 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
985 p += -wrap3 + 2 *
BPP;
1008 p += wrap3 + (wrap3 - dstw *
BPP);
1009 lum += wrap + (wrap - dstw - dstx);
1010 cb += dst->
linesize[1] - width2 - skip2;
1011 cr += dst->
linesize[2] - width2 - skip2;
1029 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
1060 SDL_FreeYUVOverlay(vp->
bmp);
1066 int scr_xleft,
int scr_ytop,
int scr_width,
int scr_height,
1067 int pic_width,
int pic_height,
AVRational pic_sar)
1072 if (pic_sar.
num == 0)
1075 aspect_ratio =
av_q2d(pic_sar);
1077 if (aspect_ratio <= 0.0)
1079 aspect_ratio *= (float)pic_width / (
float)pic_height;
1082 height = scr_height;
1083 width = ((int)
rint(height * aspect_ratio)) & ~1;
1084 if (width > scr_width) {
1086 height = ((int)
rint(width / aspect_ratio)) & ~1;
1088 x = (scr_width -
width) / 2;
1089 y = (scr_height -
height) / 2;
1090 rect->x = scr_xleft + x;
1091 rect->y = scr_ytop +
y;
1092 rect->w =
FFMAX(width, 1);
1093 rect->h =
FFMAX(height, 1);
1111 SDL_LockYUVOverlay (vp->
bmp);
1113 pict.
data[0] = vp->
bmp->pixels[0];
1114 pict.
data[1] = vp->
bmp->pixels[2];
1115 pict.
data[2] = vp->
bmp->pixels[1];
1125 SDL_UnlockYUVOverlay (vp->
bmp);
1132 SDL_DisplayYUVOverlay(vp->
bmp, &rect);
1135 int bgcolor = SDL_MapRGB(
screen->format, 0x00, 0x00, 0x00);
1144 return a < 0 ? a%b + b : a%
b;
1149 int i, i_start, x, y1,
y, ys, delay,
n, nb_display_channels;
1150 int ch, channels, h, h2, bgcolor, fgcolor;
1152 int rdft_bits, nb_freq;
1154 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->
height; rdft_bits++)
1156 nb_freq = 1 << (rdft_bits - 1);
1160 nb_display_channels = channels;
1162 int data_used= s->
show_mode == SHOW_MODE_WAVES ? s->
width : (2*nb_freq);
1174 delay += 2 * data_used;
1175 if (delay < data_used)
1181 for (i = 0; i < 1000; i += channels) {
1188 if (h < score && (b ^ c) < 0) {
1200 bgcolor = SDL_MapRGB(
screen->format, 0x00, 0x00, 0x00);
1206 fgcolor = SDL_MapRGB(
screen->format, 0xff, 0xff, 0xff);
1209 h = s->
height / nb_display_channels;
1212 for (ch = 0; ch < nb_display_channels; ch++) {
1214 y1 = s->
ytop + ch * h + (h / 2);
1215 for (x = 0; x < s->
width; x++) {
1224 s->
xleft + x, ys, 1, y,
1232 fgcolor = SDL_MapRGB(
screen->format, 0x00, 0x00, 0xff);
1234 for (ch = 1; ch < nb_display_channels; ch++) {
1235 y = s->
ytop + ch * h;
1242 nb_display_channels=
FFMIN(nb_display_channels, 2);
1255 for (ch = 0; ch < nb_display_channels; ch++) {
1256 data[ch] = s->
rdft_data + 2 * nb_freq * ch;
1258 for (x = 0; x < 2 * nb_freq; x++) {
1259 double w = (x-nb_freq) * (1.0 / nb_freq);
1269 for (y = 0; y < s->
height; y++) {
1270 double w = 1 / sqrt(nb_freq);
1271 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]));
1272 int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0]
1273 + data[1][2 * y + 1] * data[1][2 * y + 1])) : a;
1276 fgcolor = SDL_MapRGB(
screen->format, a, b, (a + b) / 2);
1305 #if !CONFIG_AVFILTER
1344 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1348 else flags |= SDL_RESIZABLE;
1350 if (vp && vp->
width)
1363 w =
FFMIN(16383, w);
1367 screen = SDL_SetVideoMode(w, h, 0, flags);
1534 double sync_threshold,
diff;
1547 if (diff <= -sync_threshold)
1548 delay =
FFMAX(0, delay + diff);
1550 delay = delay +
diff;
1551 else if (diff >= sync_threshold)
1608 double last_duration,
duration, delay;
1635 if (time < is->frame_timer + delay && !redisplay) {
1694 static int64_t last_time;
1696 int aqsize, vqsize, sqsize;
1700 if (!last_time || (cur_time - last_time) >= 30000) {
1718 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64
"/%"PRId64
" \r",
1750 bufferdiff = vp->
bmp ?
FFMAX(vp->
bmp->pixels[0], vp->
bmp->pixels[1]) -
FFMIN(vp->
bmp->pixels[0], vp->
bmp->pixels[1]) : 0;
1751 if (!vp->
bmp || vp->
bmp->pitches[0] < vp->
width || bufferdiff < (int64_t)vp->
height * vp->
bmp->pitches[0]) {
1755 "Error: the video system does not support an image\n"
1756 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1757 "to reduce the image size.\n", vp->
width, vp->
height );
1770 for (i = 0; i < 3; i++) {
1777 if (bmp->pitches[i] > width) {
1778 maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1779 for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1789 #if defined(DEBUG_SYNC) && 0
1790 printf(
"frame_type=%c pts=%0.3f\n",
1813 event.user.data1 = is;
1814 SDL_PushEvent(&event);
1838 SDL_LockYUVOverlay (vp->
bmp);
1840 pict.
data[0] = vp->
bmp->pixels[0];
1841 pict.
data[1] = vp->
bmp->pixels[2];
1842 pict.
data[2] = vp->
bmp->pixels[1];
1867 SDL_UnlockYUVOverlay(vp->
bmp);
1924 if (!outputs || !inputs) {
1935 inputs->filter_ctx = sink_ctx;
1936 inputs->pad_idx = 0;
1937 inputs->next =
NULL;
1947 for (i = 0; i < graph->
nb_filters - nb_filters; i++)
1960 char sws_flags_str[128];
1961 char buffersrc_args[256];
1971 snprintf(buffersrc_args,
sizeof(buffersrc_args),
1972 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1977 av_strlcatf(buffersrc_args,
sizeof(buffersrc_args),
":frame_rate=%d/%d", fr.
num, fr.
den);
1981 "ffplay_buffer", buffersrc_args,
NULL,
1987 "ffplay_buffersink",
NULL,
NULL, graph);
1994 last_filter = filt_out;
1998 #define INSERT_FILT(name, arg) do { \
1999 AVFilterContext *filt_ctx; \
2001 ret = avfilter_graph_create_filter(&filt_ctx, \
2002 avfilter_get_by_name(name), \
2003 "ffplay_" name, arg, NULL, graph); \
2007 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
2011 last_filter = filt_ctx; \
2016 INSERT_FILT(
"crop",
"floor(in_w/2)*2:floor(in_h/2)*2");
2020 if (rotate_tag && *rotate_tag->
value && strcmp(rotate_tag->
value,
"0")) {
2021 if (!strcmp(rotate_tag->
value,
"90")) {
2022 INSERT_FILT(
"transpose",
"clock");
2023 }
else if (!strcmp(rotate_tag->
value,
"180")) {
2024 INSERT_FILT(
"hflip",
NULL);
2025 INSERT_FILT(
"vflip",
NULL);
2026 }
else if (!strcmp(rotate_tag->
value,
"270")) {
2027 INSERT_FILT(
"transpose",
"cclock");
2029 char rotate_buf[64];
2030 snprintf(rotate_buf,
sizeof(rotate_buf),
"%s*PI/180", rotate_tag->
value);
2031 INSERT_FILT(
"rotate", rotate_buf);
2039 is->in_video_filter = filt_src;
2040 is->out_video_filter = filt_out;
2046 static int configure_audio_filters(
VideoState *is,
const char *afilters,
int force_output_format)
2050 int64_t channel_layouts[2] = { 0, -1 };
2051 int channels[2] = { 0, -1 };
2053 char aresample_swr_opts[512] =
"";
2055 char asrc_args[256];
2064 if (strlen(aresample_swr_opts))
2065 aresample_swr_opts[strlen(aresample_swr_opts)-1] =
'\0';
2066 av_opt_set(is->agraph,
"aresample_swr_opts", aresample_swr_opts, 0);
2068 ret =
snprintf(asrc_args,
sizeof(asrc_args),
2069 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
2071 is->audio_filter_src.channels,
2072 1, is->audio_filter_src.freq);
2073 if (is->audio_filter_src.channel_layout)
2074 snprintf(asrc_args + ret,
sizeof(asrc_args) - ret,
2075 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
2079 asrc_args,
NULL, is->agraph);
2095 if (force_output_format) {
2113 is->in_audio_filter = filt_asrc;
2114 is->out_audio_filter = filt_asink;
2129 int last_serial = -1;
2130 int64_t dec_channel_layout;
2151 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2153 is->audio_filter_src.channel_layout != dec_channel_layout ||
2154 is->audio_filter_src.freq != frame->
sample_rate ||
2158 char buf1[1024], buf2[1024];
2162 "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",
2163 is->audio_filter_src.freq, is->audio_filter_src.channels,
av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2166 is->audio_filter_src.fmt = frame->
format;
2168 is->audio_filter_src.channel_layout = dec_channel_layout;
2172 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2180 tb = is->out_audio_filter->inputs[0]->time_base;
2232 int last_serial = -1;
2233 int last_vfilter_idx = 0;
2247 if ( last_w != frame->
width
2248 || last_h != frame->
height
2249 || last_format != frame->
format
2251 || last_vfilter_idx != is->vfilter_idx) {
2253 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2260 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] :
NULL, frame)) < 0) {
2263 event.user.data1 = is;
2264 SDL_PushEvent(&event);
2267 filt_in = is->in_video_filter;
2268 filt_out = is->out_video_filter;
2269 last_w = frame->
width;
2271 last_format = frame->
format;
2273 last_vfilter_idx = is->vfilter_idx;
2334 if (got_subtitle && sp->
sub.
format == 0) {
2354 }
else if (got_subtitle) {
2366 size = samples_size /
sizeof(short);
2384 int wanted_nb_samples = nb_samples;
2388 double diff, avg_diff;
2389 int min_nb_samples, max_nb_samples;
2403 wanted_nb_samples = nb_samples + (int)(diff * is->
audio_src.
freq);
2406 wanted_nb_samples =
FFMIN(
FFMAX(wanted_nb_samples, min_nb_samples), max_nb_samples);
2408 av_dlog(
NULL,
"diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2409 diff, avg_diff, wanted_nb_samples - nb_samples,
2420 return wanted_nb_samples;
2432 int data_size, resampled_data_size;
2433 int64_t dec_channel_layout;
2435 int wanted_nb_samples;
2451 dec_channel_layout =
2467 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2504 if (len2 == out_count) {
2513 resampled_data_size = data_size;
2525 static double last_clock;
2526 printf(
"audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2532 return resampled_data_size;
2539 int audio_size, len1;
2546 if (audio_size < 0) {
2573 static int audio_open(
void *opaque, int64_t wanted_channel_layout,
int wanted_nb_channels,
int wanted_sample_rate,
struct AudioParams *audio_hw_params)
2575 SDL_AudioSpec wanted_spec, spec;
2577 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2578 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2579 int next_sample_rate_idx =
FF_ARRAY_ELEMS(next_sample_rates) - 1;
2581 env = SDL_getenv(
"SDL_AUDIO_CHANNELS");
2583 wanted_nb_channels = atoi(env);
2591 wanted_spec.channels = wanted_nb_channels;
2592 wanted_spec.freq = wanted_sample_rate;
2593 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2597 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2598 next_sample_rate_idx--;
2599 wanted_spec.format = AUDIO_S16SYS;
2600 wanted_spec.silence = 0;
2603 wanted_spec.userdata = opaque;
2604 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2606 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2607 wanted_spec.channels = next_nb_channels[
FFMIN(7, wanted_spec.channels)];
2608 if (!wanted_spec.channels) {
2609 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2610 wanted_spec.channels = wanted_nb_channels;
2611 if (!wanted_spec.freq) {
2613 "No more combinations to try, audio open failed\n");
2619 if (spec.format != AUDIO_S16SYS) {
2621 "SDL advised audio format %d is not supported!\n", spec.format);
2624 if (spec.channels != wanted_spec.channels) {
2626 if (!wanted_channel_layout) {
2628 "SDL advised channel count %d is not supported!\n", spec.channels);
2634 audio_hw_params->
freq = spec.freq;
2636 audio_hw_params->
channels = spec.channels;
2652 const char *forced_codec_name =
NULL;
2656 int64_t channel_layout;
2658 int stream_lowres =
lowres;
2660 if (stream_index < 0 || stream_index >= ic->
nb_streams)
2671 if (forced_codec_name)
2675 "No codec could be found with name '%s'\n", forced_codec_name);
2677 "No codec could be found with id %d\n", avctx->
codec_id);
2719 is->audio_filter_src.channels = avctx->
channels;
2721 is->audio_filter_src.fmt = avctx->
sample_fmt;
2722 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2724 link = is->out_audio_filter->inputs[0];
2791 if (stream_index < 0 || stream_index >= ic->
nb_streams)
2858 if(s->
pb && ( !strncmp(s->
filename,
"rtp:", 4)
2859 || !strncmp(s->
filename,
"udp:", 4)
2874 int64_t stream_start_time;
2875 int pkt_in_play_range = 0;
2878 int orig_nb_streams;
2879 SDL_mutex *wait_mutex = SDL_CreateMutex();
2880 int scan_all_pmts_set = 0;
2883 memset(st_index, -1,
sizeof(st_index));
2899 scan_all_pmts_set = 1;
2907 if (scan_all_pmts_set)
2927 for (i = 0; i < orig_nb_streams; i++)
2933 "%s: could not find codec parameters\n", is->
filename);
2980 st_index[i] = INT_MAX;
2992 st_index[AVMEDIA_TYPE_VIDEO],
2998 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2999 st_index[AVMEDIA_TYPE_AUDIO] :
3000 st_index[AVMEDIA_TYPE_VIDEO]),
3004 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
3013 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
3018 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
3022 is->
show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
3024 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
3035 if (infinite_buffer < 0 && is->realtime)
3048 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
3059 int64_t seek_target = is->
seek_pos;
3060 int64_t seek_min = is->
seek_rel > 0 ? seek_target - is->
seek_rel + 2: INT64_MIN;
3061 int64_t seek_max = is->
seek_rel < 0 ? seek_target - is->
seek_rel - 2: INT64_MAX;
3068 "%s: error while seeking\n", is->
ic->
filename);
3113 SDL_LockMutex(wait_mutex);
3115 SDL_UnlockMutex(wait_mutex);
3141 SDL_LockMutex(wait_mutex);
3143 SDL_UnlockMutex(wait_mutex);
3152 (pkt_ts - (stream_start_time !=
AV_NOPTS_VALUE ? stream_start_time : 0)) *
3190 event.user.data1 = is;
3191 SDL_PushEvent(&event);
3193 SDL_DestroyMutex(wait_mutex);
3240 int start_index, stream_index;
3256 stream_index = start_index;
3262 for (start_index = 0; start_index <
nb_streams; start_index++)
3265 if (start_index == nb_streams)
3267 stream_index = start_index;
3272 if (++stream_index >= nb_streams)
3280 if (start_index == -1)
3284 if (stream_index == start_index)
3289 switch (codec_type) {
3304 if (p && stream_index != -1)
3318 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3330 int bgcolor = SDL_MapRGB(
screen->format, 0x00, 0x00, 0x00);
3333 next = (next + 1) % SHOW_MODE_NB;
3334 }
while (next != is->
show_mode && (next == SHOW_MODE_VIDEO && !is->
video_st || next != SHOW_MODE_VIDEO && !is->
audio_st));
3345 double remaining_time = 0.0;
3347 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3352 if (remaining_time > 0.0)
3353 av_usleep((int64_t)(remaining_time * 1000000.0));
3392 double incr, pos, frac;
3397 switch (event.type) {
3403 switch (event.key.keysym.sym) {
3435 if (cur_stream->
show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3436 if (++cur_stream->vfilter_idx >= nb_vfilters)
3437 cur_stream->vfilter_idx = 0;
3439 cur_stream->vfilter_idx = 0;
3500 case SDL_VIDEOEXPOSE:
3503 case SDL_MOUSEBUTTONDOWN:
3508 case SDL_MOUSEMOTION:
3514 if (event.type == SDL_MOUSEBUTTONDOWN) {
3517 if (event.motion.state != SDL_PRESSED)
3527 int tns, thh, tmm, tss;
3530 tmm = (tns % 3600) / 60;
3532 frac = x / cur_stream->
width;
3535 mm = (ns % 3600) / 60;
3538 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3539 hh, mm, ss, thh, tmm, tss);
3546 case SDL_VIDEORESIZE:
3547 screen = SDL_SetVideoMode(
FFMIN(16383, event.resize.w), event.resize.h, 0,
3548 SDL_HWSURFACE|(
is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
3591 if (!file_iformat) {
3606 if (!strcmp(arg,
"audio"))
3608 else if (!strcmp(arg,
"video"))
3610 else if (!strcmp(arg,
"ext"))
3633 show_mode = !strcmp(arg,
"video") ? SHOW_MODE_VIDEO :
3634 !strcmp(arg,
"waves") ? SHOW_MODE_WAVES :
3635 !strcmp(arg,
"rdft" ) ? SHOW_MODE_RDFT :
3644 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3648 if (!strcmp(filename,
"-"))
3655 const char *spec = strchr(opt,
':');
3658 "No media specifier was specified in '%s' in option '%s'\n",
3669 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3679 {
"x",
HAS_ARG, { .func_arg =
opt_width },
"force displayed width",
"width" },
3680 {
"y",
HAS_ARG, { .func_arg =
opt_height },
"force displayed height",
"height" },
3689 {
"ss",
HAS_ARG, { .func_arg =
opt_seek },
"seek to a given position in seconds",
"pos" },
3690 {
"t",
HAS_ARG, { .func_arg =
opt_duration },
"play \"duration\" seconds of audio/video",
"duration" },
3700 {
"sync",
HAS_ARG |
OPT_EXPERT, { .func_arg =
opt_sync },
"set audio-video sync. type (type=audio/video/ext)",
"type" },
3709 {
"vf",
OPT_EXPERT |
HAS_ARG, { .func_arg = opt_add_vfilter },
"set video filters",
"filter_graph" },
3710 {
"af",
OPT_STRING |
HAS_ARG, { &afilters },
"set audio filters",
"filter_graph" },
3713 {
"showmode",
HAS_ARG, { .func_arg =
opt_show_mode},
"select show mode (0 = video, 1 = waves, 2 = RDFT)",
"mode" },
3715 {
"i",
OPT_BOOL, { &dummy},
"read specified file",
"input_file"},
3716 {
"codec",
HAS_ARG, { .func_arg =
opt_codec},
"force decoder",
"decoder_name" },
3740 #if !CONFIG_AVFILTER
3745 printf(
"\nWhile playing:\n"
3747 "f toggle full screen\n"
3749 "a cycle audio channel in the current program\n"
3750 "v cycle video channel\n"
3751 "t cycle subtitle channel in the current program\n"
3753 "w cycle video filters or show modes\n"
3754 "s activate frame-step mode\n"
3755 "left/right seek backward/forward 10 seconds\n"
3756 "down/up seek backward/forward 1 minute\n"
3757 "page down/page up seek backward/forward 10 minutes\n"
3758 "mouse click seek to percentage in file corresponding to fraction of width\n"
3766 *mtx = SDL_CreateMutex();
3771 return !!SDL_LockMutex(*mtx);
3773 return !!SDL_UnlockMutex(*mtx);
3775 SDL_DestroyMutex(*mtx);
3786 char dummy_videodriver[] =
"SDL_VIDEODRIVER=dummy";
3814 "Use -h to get full help or, even better, run 'man %s'\n",
program_name);
3821 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3823 flags &= ~SDL_INIT_AUDIO;
3825 SDL_putenv(dummy_videodriver);
3826 #if !defined(_WIN32) && !defined(__APPLE__)
3827 flags |= SDL_INIT_EVENTTHREAD;
3829 if (SDL_Init (flags)) {
3836 const SDL_VideoInfo *
vi = SDL_GetVideoInfo();
3841 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3842 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3843 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);