static int subtitle_disable;
static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
static int seek_by_bytes = -1;
+static float seek_interval = 10;
static int display_disable;
static int borderless;
static int startup_volume = 100;
return ret;
}
+static void set_sdl_yuv_conversion_mode(AVFrame *frame)
+{
+#if SDL_VERSION_ATLEAST(2,0,8)
+ SDL_YUV_CONVERSION_MODE mode = SDL_YUV_CONVERSION_AUTOMATIC;
+ if (frame && (frame->format == AV_PIX_FMT_YUV420P || frame->format == AV_PIX_FMT_YUYV422 || frame->format == AV_PIX_FMT_UYVY422)) {
+ if (frame->color_range == AVCOL_RANGE_JPEG)
+ mode = SDL_YUV_CONVERSION_JPEG;
+ else if (frame->colorspace == AVCOL_SPC_BT709)
+ mode = SDL_YUV_CONVERSION_BT709;
+ else if (frame->colorspace == AVCOL_SPC_BT470BG || frame->colorspace == AVCOL_SPC_SMPTE170M || frame->colorspace == AVCOL_SPC_SMPTE240M)
+ mode = SDL_YUV_CONVERSION_BT601;
+ }
+ SDL_SetYUVConversionMode(mode);
+#endif
+}
+
static void video_image_display(VideoState *is)
{
Frame *vp;
vp->flip_v = vp->frame->linesize[0] < 0;
}
+ set_sdl_yuv_conversion_mode(vp->frame);
SDL_RenderCopyEx(renderer, is->vid_texture, NULL, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
+ set_sdl_yuv_conversion_mode(NULL);
if (sp) {
#if USE_ONEPASS_SUBTITLE_RENDER
SDL_RenderCopy(renderer, is->sub_texture, NULL, &rect);
ret = queue_picture(is, frame, pts, duration, frame->pkt_pos, is->viddec.pkt_serial);
av_frame_unref(frame);
#if CONFIG_AVFILTER
+ if (is->videoq.serial != is->viddec.pkt_serial)
+ break;
}
#endif
if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
"No codec could be found with name '%s'\n", forced_codec_name);
else av_log(NULL, AV_LOG_WARNING,
- "No codec could be found with id %d\n", avctx->codec_id);
+ "No decoder could be found for codec %s\n", avcodec_get_name(avctx->codec_id));
ret = AVERROR(EINVAL);
goto fail;
}
refresh_loop_wait_event(cur_stream, &event);
switch (event.type) {
case SDL_KEYDOWN:
- if (exit_on_keydown) {
+ if (exit_on_keydown || event.key.keysym.sym == SDLK_ESCAPE || event.key.keysym.sym == SDLK_q) {
do_exit(cur_stream);
break;
}
+ // If we don't yet have a window, skip all key events, because read_thread might still be initializing...
+ if (!cur_stream->width)
+ continue;
switch (event.key.keysym.sym) {
- case SDLK_ESCAPE:
- case SDLK_q:
- do_exit(cur_stream);
- break;
case SDLK_f:
toggle_full_screen(cur_stream);
cur_stream->force_refresh = 1;
seek_chapter(cur_stream, -1);
break;
case SDLK_LEFT:
- incr = -10.0;
+ incr = seek_interval ? -seek_interval : -10.0;
goto do_seek;
case SDLK_RIGHT:
- incr = 10.0;
+ incr = seek_interval ? seek_interval : 10.0;
goto do_seek;
case SDLK_UP:
incr = 60.0;
{ "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
{ "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
{ "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
+ { "seek_interval", OPT_FLOAT | HAS_ARG, { &seek_interval }, "set seek interval for left/right keys, in seconds", "seconds" },
{ "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
{ "noborder", OPT_BOOL, { &borderless }, "borderless window" },
{ "volume", OPT_INT | HAS_ARG, { &startup_volume}, "set startup volume 0=min 100=max", "volume" },
"c cycle program\n"
"w cycle video filters or show modes\n"
"s activate frame-step mode\n"
- "left/right seek backward/forward 10 seconds\n"
+ "left/right seek backward/forward 10 seconds or to custom interval if -seek_interval is set\n"
"down/up seek backward/forward 1 minute\n"
"page down/page up seek backward/forward 10 minutes\n"
"right mouse click seek to percentage in file corresponding to fraction of width\n"