summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
Diffstat (limited to 'video')
-rw-r--r--video/decode/dec_video.c51
-rw-r--r--video/decode/dec_video.h2
-rw-r--r--video/decode/vd.c10
-rw-r--r--video/filter/vf.c17
-rw-r--r--video/filter/vf_scale.c69
-rw-r--r--video/filter/vf_sub.c12
-rw-r--r--video/mp_image.c2
-rw-r--r--video/out/vo.c9
8 files changed, 70 insertions, 102 deletions
diff --git a/video/decode/dec_video.c b/video/decode/dec_video.c
index cd9e8be1e5..595ffb0e16 100644
--- a/video/decode/dec_video.c
+++ b/video/decode/dec_video.c
@@ -106,62 +106,27 @@ int get_video_colors(sh_video_t *sh_video, const char *item, int *value)
// This is affected by user-specified overrides (aspect, colorspace...).
bool get_video_params(struct sh_video *sh, struct mp_image_params *p)
{
- struct MPOpts *opts = sh->opts;
-
if (!sh->vf_input)
return false;
*p = *sh->vf_input;
-
- // Apply user overrides
- if (opts->requested_colorspace != MP_CSP_AUTO)
- p->colorspace = opts->requested_colorspace;
- if (opts->requested_input_range != MP_CSP_LEVELS_AUTO)
- p->colorlevels = opts->requested_input_range;
-
- // Make sure the user-overrides are consistent (no RGB csp for YUV, etc.)
- mp_image_params_guess_csp(p);
-
return true;
}
-void set_video_colorspace(struct sh_video *sh)
+void set_video_output_levels(struct sh_video *sh)
{
struct MPOpts *opts = sh->opts;
- struct vf_instance *vf = sh->vfilter;
- struct mp_image_params params;
- if (!get_video_params(sh, &params))
+ if (!sh->vfilter)
return;
- struct mp_csp_details requested = {
- .format = params.colorspace,
- .levels_in = params.colorlevels,
- .levels_out = opts->requested_output_range,
- };
- if (requested.levels_out == MP_CSP_LEVELS_AUTO)
- requested.levels_out = MP_CSP_LEVELS_PC;
-
- vf_control(vf, VFCTRL_SET_YUV_COLORSPACE, &requested);
-
- struct mp_csp_details actual = MP_CSP_DETAILS_DEFAULTS;
- vf_control(vf, VFCTRL_GET_YUV_COLORSPACE, &actual);
-
- int success = actual.format == requested.format
- && actual.levels_in == requested.levels_in
- && actual.levels_out == requested.levels_out;
-
- if (!success)
- mp_tmsg(MSGT_DECVIDEO, MSGL_WARN,
- "Colorspace details not fully supported by selected vo.\n");
-
- if (actual.format != requested.format
- && requested.format == MP_CSP_SMPTE_240M) {
- // BT.709 is pretty close, much better than BT.601
- requested.format = MP_CSP_BT_709;
- vf_control(vf, VFCTRL_SET_YUV_COLORSPACE, &requested);
+ struct mp_csp_details csp;
+ if (vf_control(sh->vfilter, VFCTRL_GET_YUV_COLORSPACE, &csp) > 0) {
+ csp.levels_out = opts->requested_output_range;
+ if (csp.levels_out == MP_CSP_LEVELS_AUTO)
+ csp.levels_out = MP_CSP_LEVELS_PC;
+ vf_control(sh->vfilter, VFCTRL_SET_YUV_COLORSPACE, &csp);
}
-
}
void resync_video_stream(sh_video_t *sh_video)
diff --git a/video/decode/dec_video.h b/video/decode/dec_video.h
index 88161ee54f..141442fa19 100644
--- a/video/decode/dec_video.h
+++ b/video/decode/dec_video.h
@@ -39,7 +39,7 @@ int get_video_colors(sh_video_t *sh_video, const char *item, int *value);
int set_video_colors(sh_video_t *sh_video, const char *item, int value);
struct mp_image_params;
bool get_video_params(struct sh_video *sh, struct mp_image_params *p);
-void set_video_colorspace(struct sh_video *sh);
+void set_video_output_levels(struct sh_video *sh);
void resync_video_stream(sh_video_t *sh_video);
void video_reinit_vo(struct sh_video *sh_video);
int get_current_video_decoder_lag(sh_video_t *sh_video);
diff --git a/video/decode/vd.c b/video/decode/vd.c
index b344491c6b..98b9b155df 100644
--- a/video/decode/vd.c
+++ b/video/decode/vd.c
@@ -152,6 +152,14 @@ int mpcodecs_reconfig_vo(sh_video_t *sh, const struct mp_image_params *params)
p.d_w = d_w;
p.d_h = d_h;
+ // Apply user overrides
+ if (opts->requested_colorspace != MP_CSP_AUTO)
+ p.colorspace = opts->requested_colorspace;
+ if (opts->requested_input_range != MP_CSP_LEVELS_AUTO)
+ p.colorlevels = opts->requested_input_range;
+
+ // Detect colorspace from resolution.
+ // Make sure the user-overrides are consistent (no RGB csp for YUV, etc.).
mp_image_params_guess_csp(&p);
vocfg_flags = (opts->fullscreen ? VOFLAG_FULLSCREEN : 0) |
@@ -177,7 +185,7 @@ int mpcodecs_reconfig_vo(sh_video_t *sh, const struct mp_image_params *params)
sh->vf_input = talloc(sh, struct mp_image_params);
*sh->vf_input = p;
- set_video_colorspace(sh);
+ set_video_output_levels(sh);
if (opts->gamma_gamma != 1000)
set_video_colors(sh, "gamma", opts->gamma_gamma);
diff --git a/video/filter/vf.c b/video/filter/vf.c
index 1570e8402c..8946aeb801 100644
--- a/video/filter/vf.c
+++ b/video/filter/vf.c
@@ -170,6 +170,8 @@ static void print_fmt(int msglevel, struct vf_format *fmt)
mp_msg(MSGT_VFILTER, msglevel, "->%dx%d", p->d_w, p->d_h);
mp_msg(MSGT_VFILTER, msglevel, " %s %#x", mp_imgfmt_to_name(p->imgfmt),
fmt->flags);
+ mp_msg(MSGT_VFILTER, msglevel, " %s/%s", mp_csp_names[p->colorspace],
+ mp_csp_levels_names[p->colorlevels]);
} else {
mp_msg(MSGT_VFILTER, msglevel, "???");
}
@@ -357,8 +359,19 @@ unsigned int vf_match_csp(vf_instance_t **vfp, const unsigned int *list,
// Ownership of img is transferred from caller to the filter chain.
void vf_add_output_frame(struct vf_instance *vf, struct mp_image *img)
{
- if (img)
+ if (img) {
+ struct mp_image_params *p = &vf->fmt_out.params;
+ // vf_vo doesn't have output config
+ if (vf->fmt_out.configured) {
+ assert(p->imgfmt == img->imgfmt);
+ assert(p->w == img->w && p->h == img->h);
+ // Too many filters which don't set these correctly
+ img->colorspace = p->colorspace;
+ img->levels = p->colorlevels;
+ img->chroma_location = p->chroma_location;
+ }
MP_TARRAY_APPEND(vf, vf->out_queued, vf->num_out_queued, img);
+ }
}
static struct mp_image *vf_dequeue_output_frame(struct vf_instance *vf)
@@ -486,6 +499,8 @@ int vf_next_config(struct vf_instance *vf,
.colorlevels = vf->fmt_in.params.colorlevels,
.chroma_location = vf->fmt_in.params.chroma_location,
};
+ // Fix csp in case of pixel format change
+ mp_image_params_guess_csp(&p);
int r = vf_reconfig_wrapper(vf->next, &p, voflags);
return r < 0 ? 0 : 1;
}
diff --git a/video/filter/vf_scale.c b/video/filter/vf_scale.c
index f357581bb3..2a1c397807 100644
--- a/video/filter/vf_scale.c
+++ b/video/filter/vf_scale.c
@@ -50,7 +50,6 @@ static struct vf_priv_s {
int interlaced;
int noup;
int accurate_rnd;
- struct mp_csp_details colorspace;
} const vf_priv_dflt = {
0, 0,
-1,-1,
@@ -59,7 +58,7 @@ static struct vf_priv_s {
};
static int mp_sws_set_colorspace(struct SwsContext *sws,
- struct mp_csp_details *csp);
+ struct mp_image_params *p);
//===========================================================================//
@@ -197,20 +196,19 @@ static unsigned int find_best_out(vf_instance_t *vf, int in_format){
return best;
}
-static int config(struct vf_instance *vf,
- int width, int height, int d_width, int d_height,
- unsigned int flags, unsigned int outfmt){
+static int reconfig(struct vf_instance *vf, struct mp_image_params *p, int flags)
+{
+ int width = p->w, height = p->h, d_width = p->d_w, d_height = p->d_h;
+ unsigned int outfmt = p->imgfmt;
unsigned int best=find_best_out(vf, outfmt);
int int_sws_flags=0;
int round_w=0, round_h=0;
SwsFilter *srcFilter, *dstFilter;
enum PixelFormat dfmt, sfmt;
- vf->priv->colorspace = (struct mp_csp_details) {0};
-
if(!best){
mp_msg(MSGT_VFILTER,MSGL_WARN,"SwScale: no supported outfmt found :(\n");
- return 0;
+ return -1;
}
sfmt = imgfmt2pixfmt(outfmt);
dfmt = imgfmt2pixfmt(best);
@@ -235,7 +233,7 @@ static int config(struct vf_instance *vf,
// and find out what the heck he thinks MPlayer should do
// with this nonsense.
mp_msg(MSGT_VFILTER, MSGL_ERR, "SwScale: EUSERBROKEN Check your parameters, they make no sense!\n");
- return 0;
+ return -1;
}
if (vf->priv->w == -1)
@@ -301,7 +299,7 @@ static int config(struct vf_instance *vf,
if(!vf->priv->ctx){
// error...
mp_msg(MSGT_VFILTER,MSGL_WARN,"Couldn't init SwScaler for this setup\n");
- return 0;
+ return -1;
}
vf->priv->fmt=best;
// Compute new d_width and d_height, preserving aspect
@@ -315,7 +313,17 @@ static int config(struct vf_instance *vf,
}
//d_width=d_width*vf->priv->w/width;
//d_height=d_height*vf->priv->h/height;
- return vf_next_config(vf,vf->priv->w,vf->priv->h,d_width,d_height,flags,best);
+ p->w = vf->priv->w;
+ p->h = vf->priv->h;
+ p->d_w = d_width;
+ p->d_h = d_height;
+ p->imgfmt = best;
+ mp_sws_set_colorspace(vf->priv->ctx, p);
+ // In particular, fix up colorspace/levels if YUV<->RGB conversion is
+ // performed.
+ p->colorlevels = MP_CSP_LEVELS_TV; // in case output is YUV
+ mp_image_params_guess_csp(p);
+ return vf_next_reconfig(vf, p, flags);
}
static void scale(struct SwsContext *sws1, struct SwsContext *sws2, uint8_t *src[MP_MAX_PLANES], int src_stride[MP_MAX_PLANES],
@@ -407,30 +415,6 @@ static int control(struct vf_instance *vf, int request, void* data){
if(r<0) break;
return CONTROL_TRUE;
- case VFCTRL_SET_YUV_COLORSPACE: {
- struct mp_csp_details colorspace = *(struct mp_csp_details *)data;
- if (mp_sws_set_colorspace(vf->priv->ctx, &colorspace) >= 0) {
- vf->priv->colorspace = colorspace;
- return 1;
- }
- break;
- }
- case VFCTRL_GET_YUV_COLORSPACE: {
- /* This scale filter should never react to colorspace commands if it
- * doesn't do YUV->RGB conversion. But because finding out whether this
- * is really YUV->RGB (and not YUV->YUV or anything else) is hard,
- * react only if the colorspace has been set explicitly before. The
- * trick is that mp_sws_set_colorspace does not succeed for YUV->YUV
- * and RGB->YUV conversions, which makes this code correct in "most"
- * cases. (This would be trivial to do correctly if libswscale exposed
- * functionality like isYUV()).
- */
- if (vf->priv->colorspace.format) {
- *(struct mp_csp_details *)data = vf->priv->colorspace;
- return CONTROL_TRUE;
- }
- break;
- }
default:
break;
}
@@ -446,26 +430,22 @@ static const int mp_csp_to_swscale[MP_CSP_COUNT] = {
// Adjust the colorspace used for YUV->RGB conversion. On other conversions,
// do nothing or return an error.
-// The csp argument is set to the supported values.
// Return 0 on success and -1 on error.
static int mp_sws_set_colorspace(struct SwsContext *sws,
- struct mp_csp_details *csp)
+ struct mp_image_params *p)
{
int *table, *inv_table;
int brightness, contrast, saturation, srcRange, dstRange;
- csp->levels_out = MP_CSP_LEVELS_PC;
-
// NOTE: returns an error if the destination format is YUV
if (sws_getColorspaceDetails(sws, &inv_table, &srcRange, &table, &dstRange,
&brightness, &contrast, &saturation) == -1)
goto error_out;
- int sws_csp = mp_csp_to_swscale[csp->format];
+ int sws_csp = mp_csp_to_swscale[p->colorspace];
if (sws_csp == 0) {
// colorspace not supported, go with a reasonable default
- csp->format = SWS_CS_ITU601;
- sws_csp = MP_CSP_BT_601;
+ sws_csp = SWS_CS_ITU601;
}
/* The swscale API for these is hardly documented.
@@ -473,7 +453,7 @@ static int mp_sws_set_colorspace(struct SwsContext *sws,
* for YUV->RGB conversions, and conversions to limited-range RGB are
* not supported.
*/
- srcRange = csp->levels_in == MP_CSP_LEVELS_PC;
+ srcRange = p->colorlevels == MP_CSP_LEVELS_PC;
const int *new_inv_table = sws_getCoefficients(sws_csp);
if (sws_setColorspaceDetails(sws, new_inv_table, srcRange, table, dstRange,
@@ -483,7 +463,6 @@ static int mp_sws_set_colorspace(struct SwsContext *sws,
return 0;
error_out:
- *csp = (struct mp_csp_details){0};
return -1;
}
@@ -509,7 +488,7 @@ static void uninit(struct vf_instance *vf){
}
static int vf_open(vf_instance_t *vf, char *args){
- vf->config=config;
+ vf->reconfig=reconfig;
vf->filter=filter;
vf->query_format=query_format;
vf->control= control;
diff --git a/video/filter/vf_sub.c b/video/filter/vf_sub.c
index e918574c30..e85a58afb7 100644
--- a/video/filter/vf_sub.c
+++ b/video/filter/vf_sub.c
@@ -39,7 +39,6 @@
#include "video/sws_utils.h"
#include "video/memcpy_pic.h"
-#include "video/csputils.h"
#include "core/m_option.h"
#include "core/m_struct.h"
@@ -49,12 +48,10 @@ static const struct vf_priv_s {
int outh, outw;
- struct mp_csp_details csp;
-
struct osd_state *osd;
struct mp_osd_res dim;
} vf_priv_dflt = {
- .csp = MP_CSP_DETAILS_DEFAULTS,
+ 0
};
static int config(struct vf_instance *vf,
@@ -109,8 +106,6 @@ static struct mp_image *filter(struct vf_instance *vf, struct mp_image *mpi)
mpi = dmpi;
}
- mp_image_set_colorspace_details(mpi, &priv->csp);
-
osd_draw_on_image_p(osd, priv->dim, mpi->pts, OSD_DRAW_SUB_FILTER,
vf->out_pool, mpi);
@@ -132,11 +127,6 @@ static int control(vf_instance_t *vf, int request, void *data)
break;
case VFCTRL_INIT_OSD:
return CONTROL_TRUE;
- case VFCTRL_SET_YUV_COLORSPACE: {
- struct mp_csp_details colorspace = *(struct mp_csp_details *)data;
- vf->priv->csp = colorspace;
- break;
- }
}
return vf_next_control(vf, request, data);
}
diff --git a/video/mp_image.c b/video/mp_image.c
index c1e4ba18e7..029c5fa91b 100644
--- a/video/mp_image.c
+++ b/video/mp_image.c
@@ -439,6 +439,8 @@ void mp_image_set_colorspace_details(struct mp_image *image,
{
struct mp_image_params params;
mp_image_params_from_image(&params, image);
+ params.colorspace = csp->format;
+ params.colorlevels = csp->levels_in;
mp_image_params_guess_csp(&params);
image->colorspace = params.colorspace;
image->levels = params.colorlevels;
diff --git a/video/out/vo.c b/video/out/vo.c
index e05b1ae8a6..425c49aab8 100644
--- a/video/out/vo.c
+++ b/video/out/vo.c
@@ -441,6 +441,15 @@ int vo_reconfig(struct vo *vo, struct mp_image_params *params, int flags)
vo->waiting_mpi = NULL;
vo->redrawing = false;
vo->hasframe = false;
+ if (vo->config_ok) {
+ // Legacy
+ struct mp_csp_details csp;
+ if (vo_control(vo, VOCTRL_GET_YUV_COLORSPACE, &csp) > 0) {
+ csp.levels_in = params->colorlevels;
+ csp.format = params->colorspace;
+ vo_control(vo, VOCTRL_SET_YUV_COLORSPACE, &csp);
+ }
+ }
return ret;
}