summaryrefslogtreecommitdiffstats
path: root/video/decode
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-06-08 01:35:44 +0200
committerwm4 <wm4@nowhere>2013-06-28 20:34:46 +0200
commit3382a6f6e48c7e093c2b7e0e4a0e28b60a084358 (patch)
treecc50df6d6ae5ffa6b1f7d3eb4e816a3afcfd1641 /video/decode
parent823e0c511bea235be06d5e2037ef9d0b345d9405 (diff)
downloadmpv-3382a6f6e48c7e093c2b7e0e4a0e28b60a084358.tar.bz2
mpv-3382a6f6e48c7e093c2b7e0e4a0e28b60a084358.tar.xz
video: add a new method to configure filters and VOs
The filter chain and the video ouputs have config() functions. They are strictly limited to transfering the video size and format. Other parameters (like color levels) have to be transferred separately. Improve upon this by introducing a separate set of reconfig() functions, which use mp_image_params to carry format parameters. This struct contains all image format related parameters from config(), plus additional parameters such as colorspace. Change vf_rotate to use it, as well as vo_opengl. vf_rotate is just an example/test case, but vo_opengl will need it later. The intention is also to get rid of VOCTRL_SET_YUV_COLORSPACE. This information is now handed to the VOs via reconfig(). The getter, VOCTRL_GET_YUV_COLORSPACE, will still be needed though.
Diffstat (limited to 'video/decode')
-rw-r--r--video/decode/lavc.h1
-rw-r--r--video/decode/vd.c50
-rw-r--r--video/decode/vd.h2
-rw-r--r--video/decode/vd_lavc.c22
4 files changed, 47 insertions, 28 deletions
diff --git a/video/decode/lavc.h b/video/decode/lavc.h
index 41701be1d6..25ed2b8ac5 100644
--- a/video/decode/lavc.h
+++ b/video/decode/lavc.h
@@ -18,6 +18,7 @@ typedef struct ffmpeg_ctx {
int do_hw_dr1;
int vo_initialized;
int best_csp;
+ struct mp_image_params image_params;
AVRational last_sample_aspect_ratio;
enum AVDiscard skip_frame;
const char *software_fallback_decoder;
diff --git a/video/decode/vd.c b/video/decode/vd.c
index b38d9d43d5..6f05ab334c 100644
--- a/video/decode/vd.c
+++ b/video/decode/vd.c
@@ -50,16 +50,22 @@ const vd_functions_t * const mpcodecs_vd_drivers[] = {
NULL
};
-int mpcodecs_config_vo(sh_video_t *sh, int w, int h, unsigned int out_fmt)
+int mpcodecs_reconfig_vo(sh_video_t *sh, const struct mp_image_params *params)
{
struct MPOpts *opts = sh->opts;
vf_instance_t *vf = sh->vfilter;
int vocfg_flags = 0;
-
- if (w)
- sh->disp_w = w;
- if (h)
- sh->disp_h = h;
+ struct mp_image_params p = *params;
+
+ if (!p.w || !p.h) {
+ // ideally, this should be dead code
+ mp_msg(MSGT_DECVIDEO, MSGL_WARN, "Unknown size, using container size.\n");
+ p.w = sh->disp_w;
+ p.h = sh->disp_h;
+ } else {
+ sh->disp_w = p.w;
+ sh->disp_h = p.h;
+ }
mp_msg(MSGT_DECVIDEO, MSGL_V,
"VIDEO: %dx%d %5.3f fps %5.1f kbps (%4.1f kB/s)\n",
@@ -67,10 +73,10 @@ int mpcodecs_config_vo(sh_video_t *sh, int w, int h, unsigned int out_fmt)
sh->i_bps / 1000.0);
if (!sh->disp_w || !sh->disp_h)
- return 0;
+ return -1;
mp_msg(MSGT_DECVIDEO, MSGL_V, "VDec: vo config request - %d x %d (%s)\n",
- w, h, vo_format_name(out_fmt));
+ p.w, p.h, vo_format_name(p.imgfmt));
if (get_video_quality_max(sh) <= 0 && opts->divx_quality) {
// user wants postprocess but no pp filter yet:
@@ -78,17 +84,17 @@ int mpcodecs_config_vo(sh_video_t *sh, int w, int h, unsigned int out_fmt)
}
// check if libvo and codec has common outfmt (no conversion):
+ int flags = 0;
for (;;) {
mp_msg(MSGT_VFILTER, MSGL_V, "Trying filter chain:\n");
vf_print_filter_chain(MSGL_V, vf);
- int flags = vf->query_format(vf, out_fmt);
+ flags = vf->query_format(vf, p.imgfmt);
mp_msg(MSGT_CPLAYER, MSGL_DBG2, "vo_debug: query(%s) returned 0x%X \n",
- vo_format_name(out_fmt), flags);
+ vo_format_name(p.imgfmt), flags);
if ((flags & VFCAP_CSP_SUPPORTED_BY_HW)
|| (flags & VFCAP_CSP_SUPPORTED))
{
- sh->output_flags = flags;
break;
}
// TODO: no match - we should use conversion...
@@ -104,16 +110,13 @@ int mpcodecs_config_vo(sh_video_t *sh, int w, int h, unsigned int out_fmt)
mp_tmsg(MSGT_VFILTER, MSGL_WARN, "Attempted filter chain:\n");
vf_print_filter_chain(MSGL_WARN, vf);
sh->vf_initialized = -1;
- return 0; // failed
+ return -1; // failed
}
- sh->outfmt = out_fmt;
- mp_msg(MSGT_CPLAYER, MSGL_V, "VDec: using %s as output csp\n",
- vo_format_name(out_fmt));
sh->vfilter = vf;
// autodetect flipping
bool flip = opts->flip;
- if (flip && !(sh->output_flags & VFCAP_FLIP)) {
+ if (flip && !(flags & VFCAP_FLIP)) {
// we need to flip, but no flipping filter avail.
vf_add_before_vo(&vf, "flip", NULL);
sh->vfilter = vf;
@@ -147,19 +150,21 @@ int mpcodecs_config_vo(sh_video_t *sh, int w, int h, unsigned int out_fmt)
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_ASPECT=%1.4f\n", sh->aspect);
}
+ p.d_w = d_w;
+ p.d_h = d_h;
+
vocfg_flags = (opts->fullscreen ? VOFLAG_FULLSCREEN : 0) |
(flip ? VOFLAG_FLIPPING : 0);
// Time to config libvo!
mp_msg(MSGT_CPLAYER, MSGL_V,
"VO Config (%dx%d->%dx%d,flags=%d,0x%X)\n", sh->disp_w,
- sh->disp_h, d_w, d_h, vocfg_flags, out_fmt);
+ sh->disp_h, d_w, d_h, vocfg_flags, p.imgfmt);
- if (vf_config_wrapper(vf, sh->disp_w, sh->disp_h, d_w, d_h, vocfg_flags,
- out_fmt) == 0) {
+ if (vf_reconfig_wrapper(vf, &p, vocfg_flags) < 0) {
mp_tmsg(MSGT_CPLAYER, MSGL_WARN, "FATAL: Cannot initialize video driver.\n");
sh->vf_initialized = -1;
- return 0;
+ return -1;
}
mp_tmsg(MSGT_VFILTER, MSGL_V, "Video filter chain:\n");
@@ -167,6 +172,9 @@ int mpcodecs_config_vo(sh_video_t *sh, int w, int h, unsigned int out_fmt)
sh->vf_initialized = 1;
+ sh->colorspace = p.colorspace;
+ sh->color_range = p.colorlevels;
+
set_video_colorspace(sh);
if (opts->gamma_gamma != 1000)
@@ -180,5 +188,5 @@ int mpcodecs_config_vo(sh_video_t *sh, int w, int h, unsigned int out_fmt)
if (opts->gamma_hue != 1000)
set_video_colors(sh, "hue", opts->gamma_hue);
- return 1;
+ return 0;
}
diff --git a/video/decode/vd.h b/video/decode/vd.h
index 0e06f7bb40..ca4107dca9 100644
--- a/video/decode/vd.h
+++ b/video/decode/vd.h
@@ -44,6 +44,6 @@ extern const vd_functions_t *const mpcodecs_vd_drivers[];
#define VDCTRL_QUERY_UNSEEN_FRAMES 9 // current decoder lag
#define VDCTRL_REINIT_VO 10 // reinit filter/VO chain
-int mpcodecs_config_vo(sh_video_t *sh, int w, int h, unsigned int outfmt);
+int mpcodecs_reconfig_vo(sh_video_t *sh, const struct mp_image_params *params);
#endif /* MPLAYER_VD_H */
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index 1f5ae68bbf..f67e6dfbe6 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -436,10 +436,19 @@ static int init_vo(sh_video_t *sh, AVFrame *frame)
ctx->pix_fmt = pix_fmt;
ctx->best_csp = pixfmt2imgfmt(pix_fmt);
- sh->colorspace = avcol_spc_to_mp_csp(ctx->avctx->colorspace);
- sh->color_range = avcol_range_to_mp_csp_levels(ctx->avctx->color_range);
+ ctx->image_params = (struct mp_image_params) {
+ .imgfmt = ctx->best_csp,
+ .w = width,
+ .h = height,
+ // Ideally, we should also set aspect ratio, but we aren't there yet
+ // - so vd.c calculates display size from sh->aspect.
+ .d_w = width,
+ .d_h = height,
+ .colorspace = avcol_spc_to_mp_csp(ctx->avctx->colorspace),
+ .colorlevels = avcol_range_to_mp_csp_levels(ctx->avctx->color_range),
+ };
- if (!mpcodecs_config_vo(sh, sh->disp_w, sh->disp_h, ctx->best_csp))
+ if (mpcodecs_reconfig_vo(sh, &ctx->image_params) < 0)
return -1;
ctx->vo_initialized = 1;
@@ -690,8 +699,8 @@ static int decode(struct sh_video *sh, struct demux_packet *packet,
struct mp_image *mpi = image_from_decoder(sh);
assert(mpi->planes[0]);
- mpi->colorspace = sh->colorspace;
- mpi->levels = sh->color_range;
+ mpi->colorspace = ctx->image_params.colorspace;
+ mpi->levels = ctx->image_params.colorlevels;
*out_image = mpi;
return 1;
@@ -745,7 +754,8 @@ static int control(sh_video_t *sh, int cmd, void *arg)
*(int *)arg = delay;
return CONTROL_TRUE;
case VDCTRL_REINIT_VO:
- mpcodecs_config_vo(sh, sh->disp_w, sh->disp_h, ctx->best_csp);
+ if (ctx->vo_initialized)
+ mpcodecs_reconfig_vo(sh, &ctx->image_params);
return true;
}
return CONTROL_UNKNOWN;