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))
346 static const char **vfilters_list = NULL;
347 static int nb_vfilters = 0;
348 static char *afilters = NULL;
358 #define FF_ALLOC_EVENT (SDL_USEREVENT)
359 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
364 static int opt_add_vfilter(
void *optctx,
const char *opt,
const char *
arg)
367 vfilters_list[nb_vfilters - 1] =
arg;
377 if (channel_count1 == 1 && channel_count2 == 1)
380 return channel_count1 != channel_count2 || fmt1 != fmt2;
387 return channel_layout;
406 if (pkt == &flush_pkt)
418 SDL_CondSignal(q->
cond);
430 SDL_LockMutex(q->
mutex);
432 SDL_UnlockMutex(q->
mutex);
434 if (pkt != &flush_pkt && ret < 0)
454 q->
mutex = SDL_CreateMutex();
455 q->
cond = SDL_CreateCond();
463 SDL_LockMutex(q->
mutex);
464 for (pkt = q->
first_pkt; pkt; pkt = pkt1) {
473 SDL_UnlockMutex(q->
mutex);
479 SDL_DestroyMutex(q->
mutex);
480 SDL_DestroyCond(q->
cond);
485 SDL_LockMutex(q->
mutex);
489 SDL_CondSignal(q->
cond);
491 SDL_UnlockMutex(q->
mutex);
496 SDL_LockMutex(q->
mutex);
499 SDL_UnlockMutex(q->
mutex);
508 SDL_LockMutex(q->
mutex);
536 SDL_UnlockMutex(q->
mutex);
632 }
while (!got_frame && !d->
finished);
651 if (!(f->
mutex = SDL_CreateMutex()))
653 if (!(f->
cond = SDL_CreateCond()))
673 SDL_DestroyMutex(f->
mutex);
674 SDL_DestroyCond(f->
cond);
679 SDL_LockMutex(f->
mutex);
680 SDL_CondSignal(f->
cond);
681 SDL_UnlockMutex(f->
mutex);
702 SDL_LockMutex(f->
mutex);
707 SDL_UnlockMutex(f->
mutex);
718 SDL_LockMutex(f->
mutex);
723 SDL_UnlockMutex(f->
mutex);
735 SDL_LockMutex(f->
mutex);
737 SDL_CondSignal(f->
cond);
738 SDL_UnlockMutex(f->
mutex);
750 SDL_LockMutex(f->
mutex);
752 SDL_CondSignal(f->
cond);
753 SDL_UnlockMutex(f->
mutex);
788 SDL_FillRect(screen, &rect, color);
789 if (update && w > 0 && h > 0)
790 SDL_UpdateRect(screen, x, y, w, h);
802 w2 = width - (x + w);
808 h2 = height - (y + h);
816 xleft + width - w2, ytop,
824 xleft + w1, ytop + height - h2,
829 #define ALPHA_BLEND(a, oldp, newp, s)\
830 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
832 #define RGBA_IN(r, g, b, a, s)\
834 unsigned int v = ((const uint32_t *)(s))[0];\
835 a = (v >> 24) & 0xff;\
836 r = (v >> 16) & 0xff;\
837 g = (v >> 8) & 0xff;\
841 #define YUVA_IN(y, u, v, a, s, pal)\
843 unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
844 a = (val >> 24) & 0xff;\
845 y = (val >> 16) & 0xff;\
846 u = (val >> 8) & 0xff;\
850 #define YUVA_OUT(d, y, u, v, a)\
852 ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
860 int wrap, wrap3, width2, skip2;
861 int y,
u,
v,
a, u1, v1,
a1, w, h;
865 int dstx, dsty, dstw, dsth;
867 dstw = av_clip(rect->
w, 0, imgw);
868 dsth = av_clip(rect->
h, 0, imgh);
869 dstx = av_clip(rect->
x, 0, imgw - dstw);
870 dsty = av_clip(rect->
y, 0, imgh - dsth);
875 width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
880 pal = (
const uint32_t *)rect->
pict.
data[1];
897 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
924 p += wrap3 - dstw *
BPP;
925 lum += wrap - dstw - dstx;
926 cb += dst->
linesize[1] - width2 - skip2;
927 cr += dst->
linesize[2] - width2 - skip2;
929 for (h = dsth - (dsty & 1); h >= 2; h -= 2) {
954 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
986 p += -wrap3 + 2 *
BPP;
1009 p += wrap3 + (wrap3 - dstw *
BPP);
1010 lum += wrap + (wrap - dstw - dstx);
1011 cb += dst->
linesize[1] - width2 - skip2;
1012 cr += dst->
linesize[2] - width2 - skip2;
1030 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
1061 SDL_FreeYUVOverlay(vp->
bmp);
1067 int scr_xleft,
int scr_ytop,
int scr_width,
int scr_height,
1068 int pic_width,
int pic_height,
AVRational pic_sar)
1073 if (pic_sar.
num == 0)
1076 aspect_ratio =
av_q2d(pic_sar);
1078 if (aspect_ratio <= 0.0)
1080 aspect_ratio *= (float)pic_width / (
float)pic_height;
1083 height = scr_height;
1084 width = ((int)
rint(height * aspect_ratio)) & ~1;
1085 if (width > scr_width) {
1087 height = ((int)
rint(width / aspect_ratio)) & ~1;
1089 x = (scr_width -
width) / 2;
1090 y = (scr_height -
height) / 2;
1091 rect->x = scr_xleft + x;
1092 rect->y = scr_ytop +
y;
1093 rect->w =
FFMAX(width, 1);
1094 rect->h =
FFMAX(height, 1);
1112 SDL_LockYUVOverlay (vp->
bmp);
1114 pict.
data[0] = vp->
bmp->pixels[0];
1115 pict.
data[1] = vp->
bmp->pixels[2];
1116 pict.
data[2] = vp->
bmp->pixels[1];
1126 SDL_UnlockYUVOverlay (vp->
bmp);
1133 SDL_DisplayYUVOverlay(vp->
bmp, &rect);
1136 int bgcolor = SDL_MapRGB(
screen->format, 0x00, 0x00, 0x00);
1145 return a < 0 ? a%b + b : a%
b;
1150 int i, i_start, x, y1,
y, ys, delay,
n, nb_display_channels;
1151 int ch, channels, h, h2, bgcolor, fgcolor;
1153 int rdft_bits, nb_freq;
1155 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->
height; rdft_bits++)
1157 nb_freq = 1 << (rdft_bits - 1);
1161 nb_display_channels = channels;
1163 int data_used= s->
show_mode == SHOW_MODE_WAVES ? s->
width : (2*nb_freq);
1175 delay += 2 * data_used;
1176 if (delay < data_used)
1182 for (i = 0; i < 1000; i += channels) {
1189 if (h < score && (b ^ c) < 0) {
1201 bgcolor = SDL_MapRGB(
screen->format, 0x00, 0x00, 0x00);
1207 fgcolor = SDL_MapRGB(
screen->format, 0xff, 0xff, 0xff);
1210 h = s->
height / nb_display_channels;
1213 for (ch = 0; ch < nb_display_channels; ch++) {
1215 y1 = s->
ytop + ch * h + (h / 2);
1216 for (x = 0; x < s->
width; x++) {
1225 s->
xleft + x, ys, 1, y,
1233 fgcolor = SDL_MapRGB(
screen->format, 0x00, 0x00, 0xff);
1235 for (ch = 1; ch < nb_display_channels; ch++) {
1236 y = s->
ytop + ch * h;
1243 nb_display_channels=
FFMIN(nb_display_channels, 2);
1253 for (ch = 0; ch < nb_display_channels; ch++) {
1254 data[ch] = s->
rdft_data + 2 * nb_freq * ch;
1256 for (x = 0; x < 2 * nb_freq; x++) {
1257 double w = (x-nb_freq) * (1.0 / nb_freq);
1267 for (y = 0; y < s->
height; y++) {
1268 double w = 1 / sqrt(nb_freq);
1269 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]));
1270 int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0]
1271 + data[1][2 * y + 1] * data[1][2 * y + 1])) : a;
1274 fgcolor = SDL_MapRGB(
screen->format, a, b, (a + b) / 2);
1293 SDL_WaitThread(is->
read_tid, NULL);
1303 #if !CONFIG_AVFILTER
1342 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1346 else flags |= SDL_RESIZABLE;
1348 if (vp && vp->
width)
1361 w =
FFMIN(16383, w);
1365 screen = SDL_SetVideoMode(w, h, 0, flags);
1532 double sync_threshold, diff;
1545 if (diff <= -sync_threshold)
1546 delay =
FFMAX(0, delay + diff);
1548 delay = delay + diff;
1549 else if (diff >= sync_threshold)
1554 av_dlog(NULL,
"video: delay=%0.3f A-V=%f\n",
1606 double last_duration,
duration, delay;
1633 if (time < is->frame_timer + delay && !redisplay) {
1692 static int64_t last_time;
1694 int aqsize, vqsize, sqsize;
1698 if (!last_time || (cur_time - last_time) >= 30000) {
1716 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64
"/%"PRId64
" \r",
1748 bufferdiff = vp->
bmp ?
FFMAX(vp->
bmp->pixels[0], vp->
bmp->pixels[1]) -
FFMIN(vp->
bmp->pixels[0], vp->
bmp->pixels[1]) : 0;
1749 if (!vp->
bmp || vp->
bmp->pitches[0] < vp->
width || bufferdiff < (int64_t)vp->
height * vp->
bmp->pitches[0]) {
1753 "Error: the video system does not support an image\n"
1754 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1755 "to reduce the image size.\n", vp->
width, vp->
height );
1768 for (i = 0; i < 3; i++) {
1775 if (bmp->pitches[i] > width) {
1776 maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1777 for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1787 #if defined(DEBUG_SYNC) && 0
1788 printf(
"frame_type=%c pts=%0.3f\n",
1811 event.user.data1 = is;
1812 SDL_PushEvent(&event);
1836 SDL_LockYUVOverlay (vp->
bmp);
1838 pict.
data[0] = vp->
bmp->pixels[0];
1839 pict.
data[1] = vp->
bmp->pixels[2];
1840 pict.
data[2] = vp->
bmp->pixels[1];
1865 SDL_UnlockYUVOverlay(vp->
bmp);
1922 if (!outputs || !inputs) {
1930 outputs->
next = NULL;
1933 inputs->filter_ctx = sink_ctx;
1934 inputs->pad_idx = 0;
1935 inputs->next = NULL;
1945 for (i = 0; i < graph->
nb_filters - nb_filters; i++)
1958 char sws_flags_str[128];
1959 char buffersrc_args[256];
1969 snprintf(buffersrc_args,
sizeof(buffersrc_args),
1970 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1975 av_strlcatf(buffersrc_args,
sizeof(buffersrc_args),
":frame_rate=%d/%d", fr.
num, fr.
den);
1979 "ffplay_buffer", buffersrc_args, NULL,
1985 "ffplay_buffersink", NULL, NULL, graph);
1992 last_filter = filt_out;
1996 #define INSERT_FILT(name, arg) do { \
1997 AVFilterContext *filt_ctx; \
1999 ret = avfilter_graph_create_filter(&filt_ctx, \
2000 avfilter_get_by_name(name), \
2001 "ffplay_" name, arg, NULL, graph); \
2005 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
2009 last_filter = filt_ctx; \
2014 INSERT_FILT(
"crop",
"floor(in_w/2)*2:floor(in_h/2)*2");
2018 if (rotate_tag && *rotate_tag->
value && strcmp(rotate_tag->
value,
"0")) {
2019 if (!strcmp(rotate_tag->
value,
"90")) {
2020 INSERT_FILT(
"transpose",
"clock");
2021 }
else if (!strcmp(rotate_tag->
value,
"180")) {
2022 INSERT_FILT(
"hflip", NULL);
2023 INSERT_FILT(
"vflip", NULL);
2024 }
else if (!strcmp(rotate_tag->
value,
"270")) {
2025 INSERT_FILT(
"transpose",
"cclock");
2027 char rotate_buf[64];
2028 snprintf(rotate_buf,
sizeof(rotate_buf),
"%s*PI/180", rotate_tag->
value);
2029 INSERT_FILT(
"rotate", rotate_buf);
2037 is->in_video_filter = filt_src;
2038 is->out_video_filter = filt_out;
2044 static int configure_audio_filters(
VideoState *is,
const char *afilters,
int force_output_format)
2048 int64_t channel_layouts[2] = { 0, -1 };
2049 int channels[2] = { 0, -1 };
2051 char aresample_swr_opts[512] =
"";
2053 char asrc_args[256];
2062 if (strlen(aresample_swr_opts))
2063 aresample_swr_opts[strlen(aresample_swr_opts)-1] =
'\0';
2064 av_opt_set(is->agraph,
"aresample_swr_opts", aresample_swr_opts, 0);
2066 ret =
snprintf(asrc_args,
sizeof(asrc_args),
2067 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
2069 is->audio_filter_src.channels,
2070 1, is->audio_filter_src.freq);
2071 if (is->audio_filter_src.channel_layout)
2072 snprintf(asrc_args + ret,
sizeof(asrc_args) - ret,
2073 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
2077 asrc_args, NULL, is->agraph);
2084 NULL, NULL, is->agraph);
2093 if (force_output_format) {
2111 is->in_audio_filter = filt_asrc;
2112 is->out_audio_filter = filt_asink;
2127 int last_serial = -1;
2128 int64_t dec_channel_layout;
2149 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2151 is->audio_filter_src.channel_layout != dec_channel_layout ||
2152 is->audio_filter_src.freq != frame->
sample_rate ||
2156 char buf1[1024], buf2[1024];
2160 "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",
2161 is->audio_filter_src.freq, is->audio_filter_src.channels,
av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2164 is->audio_filter_src.fmt = frame->
format;
2166 is->audio_filter_src.channel_layout = dec_channel_layout;
2170 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2178 tb = is->out_audio_filter->inputs[0]->time_base;
2224 int last_serial = -1;
2225 int last_vfilter_idx = 0;
2236 if ( last_w != frame->
width
2237 || last_h != frame->
height
2238 || last_format != frame->
format
2240 || last_vfilter_idx != is->vfilter_idx) {
2242 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2249 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2252 event.user.data1 = is;
2253 SDL_PushEvent(&event);
2256 filt_in = is->in_video_filter;
2257 filt_out = is->out_video_filter;
2258 last_w = frame->
width;
2260 last_format = frame->
format;
2262 last_vfilter_idx = is->vfilter_idx;
2323 if (got_subtitle && sp->
sub.
format == 0) {
2343 }
else if (got_subtitle) {
2355 size = samples_size /
sizeof(short);
2373 int wanted_nb_samples = nb_samples;
2377 double diff, avg_diff;
2378 int min_nb_samples, max_nb_samples;
2392 wanted_nb_samples = nb_samples + (int)(diff * is->
audio_src.
freq);
2395 wanted_nb_samples =
FFMIN(
FFMAX(wanted_nb_samples, min_nb_samples), max_nb_samples);
2397 av_dlog(NULL,
"diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2398 diff, avg_diff, wanted_nb_samples - nb_samples,
2409 return wanted_nb_samples;
2421 int data_size, resampled_data_size;
2422 int64_t dec_channel_layout;
2424 int wanted_nb_samples;
2440 dec_channel_layout =
2456 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2493 if (len2 == out_count) {
2502 resampled_data_size = data_size;
2514 static double last_clock;
2515 printf(
"audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2521 return resampled_data_size;
2528 int audio_size, len1;
2535 if (audio_size < 0) {
2562 static int audio_open(
void *opaque, int64_t wanted_channel_layout,
int wanted_nb_channels,
int wanted_sample_rate,
struct AudioParams *audio_hw_params)
2564 SDL_AudioSpec wanted_spec, spec;
2566 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2567 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2568 int next_sample_rate_idx =
FF_ARRAY_ELEMS(next_sample_rates) - 1;
2570 env = SDL_getenv(
"SDL_AUDIO_CHANNELS");
2572 wanted_nb_channels = atoi(env);
2580 wanted_spec.channels = wanted_nb_channels;
2581 wanted_spec.freq = wanted_sample_rate;
2582 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2586 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2587 next_sample_rate_idx--;
2588 wanted_spec.format = AUDIO_S16SYS;
2589 wanted_spec.silence = 0;
2592 wanted_spec.userdata = opaque;
2593 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2595 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2596 wanted_spec.channels = next_nb_channels[
FFMIN(7, wanted_spec.channels)];
2597 if (!wanted_spec.channels) {
2598 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2599 wanted_spec.channels = wanted_nb_channels;
2600 if (!wanted_spec.freq) {
2602 "No more combinations to try, audio open failed\n");
2608 if (spec.format != AUDIO_S16SYS) {
2610 "SDL advised audio format %d is not supported!\n", spec.format);
2613 if (spec.channels != wanted_spec.channels) {
2615 if (!wanted_channel_layout) {
2617 "SDL advised channel count %d is not supported!\n", spec.channels);
2623 audio_hw_params->
freq = spec.freq;
2625 audio_hw_params->
channels = spec.channels;
2641 const char *forced_codec_name = NULL;
2645 int64_t channel_layout;
2647 int stream_lowres =
lowres;
2649 if (stream_index < 0 || stream_index >= ic->
nb_streams)
2660 if (forced_codec_name)
2664 "No codec could be found with name '%s'\n", forced_codec_name);
2666 "No codec could be found with id %d\n", avctx->
codec_id);
2707 is->audio_filter_src.channels = avctx->
channels;
2709 is->audio_filter_src.fmt = avctx->
sample_fmt;
2710 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2712 link = is->out_audio_filter->inputs[0];
2782 if (stream_index < 0 || stream_index >= ic->
nb_streams)
2869 if(s->
pb && ( !strncmp(s->
filename,
"rtp:", 4)
2870 || !strncmp(s->
filename,
"udp:", 4)
2886 int64_t stream_start_time;
2887 int pkt_in_play_range = 0;
2890 int orig_nb_streams;
2891 SDL_mutex *wait_mutex = SDL_CreateMutex();
2892 int scan_all_pmts_set = 0;
2894 memset(st_index, -1,
sizeof(st_index));
2904 scan_all_pmts_set = 1;
2912 if (scan_all_pmts_set)
2932 for (i = 0; i < orig_nb_streams; i++)
2938 "%s: could not find codec parameters\n", is->
filename);
2981 st_index[AVMEDIA_TYPE_VIDEO],
2987 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2988 st_index[AVMEDIA_TYPE_AUDIO] :
2989 st_index[AVMEDIA_TYPE_VIDEO]),
2996 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
3005 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
3010 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
3014 is->
show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
3016 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
3027 if (infinite_buffer < 0 && is->realtime)
3040 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
3051 int64_t seek_target = is->
seek_pos;
3052 int64_t seek_min = is->
seek_rel > 0 ? seek_target - is->
seek_rel + 2: INT64_MIN;
3053 int64_t seek_max = is->
seek_rel < 0 ? seek_target - is->
seek_rel - 2: INT64_MAX;
3060 "%s: error while seeking\n", is->
ic->
filename);
3105 SDL_LockMutex(wait_mutex);
3107 SDL_UnlockMutex(wait_mutex);
3133 SDL_LockMutex(wait_mutex);
3135 SDL_UnlockMutex(wait_mutex);
3181 event.user.data1 = is;
3182 SDL_PushEvent(&event);
3184 SDL_DestroyMutex(wait_mutex);
3231 int start_index, stream_index;
3247 stream_index = start_index;
3253 for (start_index = 0; start_index <
nb_streams; start_index++)
3256 if (start_index == nb_streams)
3258 stream_index = start_index;
3263 if (++stream_index >= nb_streams)
3271 if (start_index == -1)
3275 if (stream_index == start_index)
3280 switch (codec_type) {
3295 if (p && stream_index != -1)
3309 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3321 int bgcolor = SDL_MapRGB(
screen->format, 0x00, 0x00, 0x00);
3324 next = (next + 1) % SHOW_MODE_NB;
3325 }
while (next != is->
show_mode && (next == SHOW_MODE_VIDEO && !is->
video_st || next != SHOW_MODE_VIDEO && !is->
audio_st));
3336 double remaining_time = 0.0;
3338 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3343 if (remaining_time > 0.0)
3344 av_usleep((int64_t)(remaining_time * 1000000.0));
3383 double incr, pos, frac;
3388 switch (event.type) {
3394 switch (event.key.keysym.sym) {
3426 if (cur_stream->
show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3427 if (++cur_stream->vfilter_idx >= nb_vfilters)
3428 cur_stream->vfilter_idx = 0;
3430 cur_stream->vfilter_idx = 0;
3491 case SDL_VIDEOEXPOSE:
3494 case SDL_MOUSEBUTTONDOWN:
3499 case SDL_MOUSEMOTION:
3505 if (event.type == SDL_MOUSEBUTTONDOWN) {
3508 if (event.motion.state != SDL_PRESSED)
3518 int tns, thh, tmm, tss;
3521 tmm = (tns % 3600) / 60;
3523 frac = x / cur_stream->
width;
3526 mm = (ns % 3600) / 60;
3529 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3530 hh, mm, ss, thh, tmm, tss);
3537 case SDL_VIDEORESIZE:
3538 screen = SDL_SetVideoMode(
FFMIN(16383, event.resize.w), event.resize.h, 0,
3539 SDL_HWSURFACE|(
is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
3582 if (!file_iformat) {
3597 if (!strcmp(arg,
"audio"))
3599 else if (!strcmp(arg,
"video"))
3601 else if (!strcmp(arg,
"ext"))
3624 show_mode = !strcmp(arg,
"video") ? SHOW_MODE_VIDEO :
3625 !strcmp(arg,
"waves") ? SHOW_MODE_WAVES :
3626 !strcmp(arg,
"rdft" ) ? SHOW_MODE_RDFT :
3635 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3639 if (!strcmp(filename,
"-"))
3646 const char *spec = strchr(opt,
':');
3649 "No media specifier was specified in '%s' in option '%s'\n",
3660 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3670 {
"x",
HAS_ARG, { .func_arg =
opt_width },
"force displayed width",
"width" },
3671 {
"y",
HAS_ARG, { .func_arg =
opt_height },
"force displayed height",
"height" },
3680 {
"ss",
HAS_ARG, { .func_arg =
opt_seek },
"seek to a given position in seconds",
"pos" },
3681 {
"t",
HAS_ARG, { .func_arg =
opt_duration },
"play \"duration\" seconds of audio/video",
"duration" },
3691 {
"sync",
HAS_ARG |
OPT_EXPERT, { .func_arg =
opt_sync },
"set audio-video sync. type (type=audio/video/ext)",
"type" },
3700 {
"vf",
OPT_EXPERT |
HAS_ARG, { .func_arg = opt_add_vfilter },
"set video filters",
"filter_graph" },
3701 {
"af",
OPT_STRING |
HAS_ARG, { &afilters },
"set audio filters",
"filter_graph" },
3704 {
"showmode",
HAS_ARG, { .func_arg =
opt_show_mode},
"select show mode (0 = video, 1 = waves, 2 = RDFT)",
"mode" },
3706 {
"i",
OPT_BOOL, { &dummy},
"read specified file",
"input_file"},
3707 {
"codec",
HAS_ARG, { .func_arg =
opt_codec},
"force decoder",
"decoder_name" },
3731 #if !CONFIG_AVFILTER
3736 printf(
"\nWhile playing:\n"
3738 "f toggle full screen\n"
3740 "a cycle audio channel in the current program\n"
3741 "v cycle video channel\n"
3742 "t cycle subtitle channel in the current program\n"
3744 "w cycle video filters or show modes\n"
3745 "s activate frame-step mode\n"
3746 "left/right seek backward/forward 10 seconds\n"
3747 "down/up seek backward/forward 1 minute\n"
3748 "page down/page up seek backward/forward 10 minutes\n"
3749 "mouse click seek to percentage in file corresponding to fraction of width\n"
3757 *mtx = SDL_CreateMutex();
3762 return !!SDL_LockMutex(*mtx);
3764 return !!SDL_UnlockMutex(*mtx);
3766 SDL_DestroyMutex(*mtx);
3777 char dummy_videodriver[] =
"SDL_VIDEODRIVER=dummy";
3805 "Use -h to get full help or, even better, run 'man %s'\n",
program_name);
3812 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3814 flags &= ~SDL_INIT_AUDIO;
3816 SDL_putenv(dummy_videodriver);
3817 #if !defined(_WIN32) && !defined(__APPLE__)
3818 flags |= SDL_INIT_EVENTTHREAD;
3820 if (SDL_Init (flags)) {
3827 const SDL_VideoInfo *
vi = SDL_GetVideoInfo();
3832 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3833 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3834 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);