diff options
Diffstat (limited to 'video')
44 files changed, 1126 insertions, 960 deletions
diff --git a/video/csputils.c b/video/csputils.c index ffa1f82a6d..ea55d4ddbe 100644 --- a/video/csputils.c +++ b/video/csputils.c @@ -65,6 +65,7 @@ const struct m_opt_choice_alternatives mp_csp_prim_names[] = { {"prophoto", MP_CSP_PRIM_PRO_PHOTO}, {"cie1931", MP_CSP_PRIM_CIE_1931}, {"dci-p3", MP_CSP_PRIM_DCI_P3}, + {"v-gamut", MP_CSP_PRIM_V_GAMUT}, {0} }; @@ -78,6 +79,8 @@ const struct m_opt_choice_alternatives mp_csp_trc_names[] = { {"gamma2.8", MP_CSP_TRC_GAMMA28}, {"prophoto", MP_CSP_TRC_PRO_PHOTO}, {"st2084", MP_CSP_TRC_SMPTE_ST2084}, + {"std-b67", MP_CSP_TRC_ARIB_STD_B67}, + {"v-log", MP_CSP_TRC_V_LOG}, {0} }; @@ -171,8 +174,9 @@ enum mp_csp_trc avcol_trc_to_mp_csp_trc(int avtrc) case AVCOL_TRC_LINEAR: return MP_CSP_TRC_LINEAR; case AVCOL_TRC_GAMMA22: return MP_CSP_TRC_GAMMA22; case AVCOL_TRC_GAMMA28: return MP_CSP_TRC_GAMMA28; -#if HAVE_AVUTIL_ST2084 +#if HAVE_AVUTIL_HDR case AVCOL_TRC_SMPTEST2084: return MP_CSP_TRC_SMPTE_ST2084; + case AVCOL_TRC_ARIB_STD_B67: return MP_CSP_TRC_ARIB_STD_B67; #endif default: return MP_CSP_TRC_AUTO; } @@ -222,8 +226,9 @@ int mp_csp_trc_to_avcol_trc(enum mp_csp_trc trc) case MP_CSP_TRC_LINEAR: return AVCOL_TRC_LINEAR; case MP_CSP_TRC_GAMMA22: return AVCOL_TRC_GAMMA22; case MP_CSP_TRC_GAMMA28: return AVCOL_TRC_GAMMA28; -#if HAVE_AVUTIL_ST2084 +#if HAVE_AVUTIL_HDR case MP_CSP_TRC_SMPTE_ST2084: return AVCOL_TRC_SMPTEST2084; + case MP_CSP_TRC_ARIB_STD_B67: return AVCOL_TRC_ARIB_STD_B67; #endif default: return AVCOL_TRC_UNSPECIFIED; } @@ -419,11 +424,45 @@ struct mp_csp_primaries mp_get_csp_primaries(enum mp_csp_prim spc) .blue = {0.150, 0.060}, .white = d65 }; + // From Panasonic VARICAM reference manual + case MP_CSP_PRIM_V_GAMUT: + return (struct mp_csp_primaries) { + .red = {0.730, 0.280}, + .green = {0.165, 0.840}, + .blue = {0.100, -0.03}, + .white = d65 + }; default: return (struct mp_csp_primaries) {{0}}; } } +// Get the nominal peak for a given colorspace, based on a known reference peak +// (i.e. the display of a reference white illuminant. This may or may not +// be the actual signal peak) +float mp_csp_trc_nom_peak(enum mp_csp_trc trc, float ref_peak) +{ + switch (trc) { + case MP_CSP_TRC_SMPTE_ST2084: return 10000; // fixed peak + case MP_CSP_TRC_ARIB_STD_B67: return 12.0 * ref_peak; + case MP_CSP_TRC_V_LOG: return 46.0855 * ref_peak; + } + + return ref_peak; +} + +bool mp_trc_is_hdr(enum mp_csp_trc trc) +{ + switch (trc) { + case MP_CSP_TRC_SMPTE_ST2084: + case MP_CSP_TRC_ARIB_STD_B67: + case MP_CSP_TRC_V_LOG: + return true; + } + + return false; +} + // Compute the RGB/XYZ matrix as described here: // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html static void mp_get_rgb2xyz_matrix(struct mp_csp_primaries space, float m[3][3]) @@ -506,7 +545,7 @@ static void mp_apply_chromatic_adaptation(struct mp_csp_col_xy src, mp_mul_matrix3x3(m, tmp); } -// get the coefficients of the source -> bt2020 cms matrix +// get the coefficients of the source -> dest cms matrix void mp_get_cms_matrix(struct mp_csp_primaries src, struct mp_csp_primaries dest, enum mp_render_intent intent, float m[3][3]) { @@ -543,7 +582,7 @@ void mp_get_cms_matrix(struct mp_csp_primaries src, struct mp_csp_primaries dest static void mp_get_xyz2rgb_coeffs(struct mp_csp_params *params, enum mp_render_intent intent, struct mp_cmat *m) { - struct mp_csp_primaries prim = mp_get_csp_primaries(params->primaries); + struct mp_csp_primaries prim = mp_get_csp_primaries(params->color.primaries); float brightness = params->brightness; mp_get_rgb2xyz_matrix(prim, m->m); mp_invert_matrix3x3(m->m); @@ -620,10 +659,10 @@ static void luma_coeffs(struct mp_cmat *mat, float lr, float lg, float lb) // get the coefficients of the yuv -> rgb conversion matrix void mp_get_csp_matrix(struct mp_csp_params *params, struct mp_cmat *m) { - int colorspace = params->colorspace; + enum mp_csp colorspace = params->color.space; if (colorspace <= MP_CSP_AUTO || colorspace >= MP_CSP_COUNT) colorspace = MP_CSP_BT_601; - int levels_in = params->levels_in; + enum mp_csp_levels levels_in = params->color.levels; if (levels_in <= MP_CSP_LEVELS_AUTO || levels_in >= MP_CSP_LEVELS_COUNT) levels_in = MP_CSP_LEVELS_TV; @@ -682,6 +721,10 @@ void mp_get_csp_matrix(struct mp_csp_params *params, struct mp_cmat *m) // The values below are written in 0-255 scale - thus bring s into range. double s = mp_get_csp_mul(colorspace, params->input_bits, params->texture_bits) / 255; + // NOTE: The yuvfull ranges as presented here are arguably ambiguous, + // and conflict with at least the full-range YCbCr/ICtCp values as defined + // by ITU-R BT.2100. If somebody ever complains about full-range YUV looking + // different from their reference display, this comment is probably why. struct yuvlevels { double ymin, ymax, cmin, cmid; } yuvlim = { 16*s, 235*s, 16*s, 128*s }, yuvfull = { 0*s, 255*s, 1*s, 128*s }, // '1' for symmetry around 128 @@ -734,9 +777,17 @@ void mp_csp_set_image_params(struct mp_csp_params *params, { struct mp_image_params p = *imgparams; mp_image_params_guess_csp(&p); // ensure consistency - params->colorspace = p.colorspace; - params->levels_in = p.colorlevels; - params->primaries = p.primaries; + params->color = p.color; +} + +bool mp_colorspace_equal(struct mp_colorspace c1, struct mp_colorspace c2) +{ + return c1.space == c2.space && + c1.levels == c2.levels && + c1.primaries == c2.primaries && + c1.gamma == c2.gamma && + c1.sig_peak == c2.sig_peak && + c1.nom_peak == c2.nom_peak; } // Copy settings from eq into params. diff --git a/video/csputils.h b/video/csputils.h index 19dd88f145..0406ddf35f 100644 --- a/video/csputils.h +++ b/video/csputils.h @@ -64,6 +64,7 @@ enum mp_csp_prim { MP_CSP_PRIM_PRO_PHOTO, MP_CSP_PRIM_CIE_1931, MP_CSP_PRIM_DCI_P3, + MP_CSP_PRIM_V_GAMUT, MP_CSP_PRIM_COUNT }; @@ -79,6 +80,8 @@ enum mp_csp_trc { MP_CSP_TRC_GAMMA28, MP_CSP_TRC_PRO_PHOTO, MP_CSP_TRC_SMPTE_ST2084, + MP_CSP_TRC_ARIB_STD_B67, + MP_CSP_TRC_V_LOG, MP_CSP_TRC_COUNT }; @@ -113,11 +116,18 @@ extern const struct m_opt_choice_alternatives mp_stereo3d_names[]; #define MP_STEREO3D_NAME_DEF(x, def) \ (MP_STEREO3D_NAME(x) ? MP_STEREO3D_NAME(x) : (def)) -struct mp_csp_params { - enum mp_csp colorspace; - enum mp_csp_levels levels_in; // encoded video - enum mp_csp_levels levels_out; // output device +struct mp_colorspace { + enum mp_csp space; + enum mp_csp_levels levels; enum mp_csp_prim primaries; + enum mp_csp_trc gamma; + float nom_peak; // nominal (absolute) peak. 0 = auto/unknown + float sig_peak; // signal peak, highest value that occurs in the source +}; + +struct mp_csp_params { + struct mp_colorspace color; // input colorspace + enum mp_csp_levels levels_out; // output device float brightness; float contrast; float hue; @@ -131,9 +141,8 @@ struct mp_csp_params { }; #define MP_CSP_PARAMS_DEFAULTS { \ - .colorspace = MP_CSP_BT_601, \ - .levels_in = MP_CSP_LEVELS_TV, \ - .primaries = MP_CSP_PRIM_AUTO, \ + .color = { .space = MP_CSP_BT_601, \ + .levels = MP_CSP_LEVELS_TV }, \ .levels_out = MP_CSP_LEVELS_PC, \ .brightness = 0, .contrast = 1, .hue = 0, .saturation = 1, \ .gamma = 1, .texture_bits = 8, .input_bits = 8} @@ -142,6 +151,8 @@ struct mp_image_params; void mp_csp_set_image_params(struct mp_csp_params *params, const struct mp_image_params *imgparams); +bool mp_colorspace_equal(struct mp_colorspace c1, struct mp_colorspace c2); + enum mp_chroma_location { MP_CHROMA_AUTO, MP_CHROMA_LEFT, // mpeg2/4, h264 @@ -193,27 +204,19 @@ struct mp_csp_primaries { void mp_csp_copy_equalizer_values(struct mp_csp_params *params, const struct mp_csp_equalizer *eq); - int mp_csp_equalizer_set(struct mp_csp_equalizer *eq, const char *property, int value); - int mp_csp_equalizer_get(struct mp_csp_equalizer *eq, const char *property, int *out_value); enum mp_csp avcol_spc_to_mp_csp(int avcolorspace); - enum mp_csp_levels avcol_range_to_mp_csp_levels(int avrange); - enum mp_csp_prim avcol_pri_to_mp_csp_prim(int avpri); - enum mp_csp_trc avcol_trc_to_mp_csp_trc(int avtrc); int mp_csp_to_avcol_spc(enum mp_csp colorspace); - int mp_csp_levels_to_avcol_range(enum mp_csp_levels range); - int mp_csp_prim_to_avcol_pri(enum mp_csp_prim prim); - int mp_csp_trc_to_avcol_trc(enum mp_csp_trc trc); enum mp_csp mp_csp_guess_colorspace(int width, int height); @@ -221,10 +224,11 @@ enum mp_csp_prim mp_csp_guess_primaries(int width, int height); enum mp_chroma_location avchroma_location_to_mp(int avloc); int mp_chroma_location_to_av(enum mp_chroma_location mploc); - void mp_get_chroma_location(enum mp_chroma_location loc, int *x, int *y); struct mp_csp_primaries mp_get_csp_primaries(enum mp_csp_prim csp); +float mp_csp_trc_nom_peak(enum mp_csp_trc trc, float ref_peak); +bool mp_trc_is_hdr(enum mp_csp_trc trc); /* Color conversion matrix: RGB = m * YUV + c * m is in row-major matrix, with m[row][col], e.g.: diff --git a/video/decode/d3d.c b/video/decode/d3d.c index b978472723..b50f3a0288 100644 --- a/video/decode/d3d.c +++ b/video/decode/d3d.c @@ -24,6 +24,7 @@ #include "common/av_common.h" #include "video/fmt-conversion.h" #include "video/mp_image.h" +#include "video/mp_image_pool.h" #include "osdep/windows_utils.h" #include "d3d.h" @@ -68,7 +69,7 @@ struct d3dva_mode { #define MODE2(id) &MP_CONCAT(DXVA2_Mode, id), # id #define MODE(id) &MP_CONCAT(DXVA_, id), # id -// Prefered modes must come first +// Preferred modes must come first static const struct d3dva_mode d3dva_modes[] = { // MPEG-1/2 {MODE2(MPEG2_VLD), AV_CODEC_ID_MPEG2VIDEO, PROF_MPEG2_MAIN}, @@ -266,3 +267,95 @@ void copy_nv12(struct mp_image *dest, uint8_t *src_bits, buf.stride[1] = src_pitch; mp_image_copy_gpu(dest, &buf); } + +// Test if Direct3D11 can be used by us. Basically, this prevents trying to use +// D3D11 on Win7, and then failing somewhere in the process. +bool d3d11_check_decoding(ID3D11Device *dev) +{ + HRESULT hr; + // We assume that NV12 is always supported, if hw decoding is supported at + // all. + UINT supported = 0; + hr = ID3D11Device_CheckFormatSupport(dev, DXGI_FORMAT_NV12, &supported); + return !FAILED(hr) && (supported & D3D11_BIND_DECODER); +} + +static int get_dxgi_mpfmt(DWORD dxgi_fmt) +{ + switch (dxgi_fmt) { + case DXGI_FORMAT_NV12: return IMGFMT_NV12; + case DXGI_FORMAT_P010: return IMGFMT_P010; + case DXGI_FORMAT_P016: return IMGFMT_P010; + } + return 0; +} + +struct mp_image *d3d11_download_image(struct mp_hwdec_ctx *ctx, + struct mp_image *mpi, + struct mp_image_pool *swpool) +{ + HRESULT hr; + ID3D11Device *device = ctx->ctx; + + if (mpi->imgfmt != IMGFMT_D3D11VA && mpi->imgfmt != IMGFMT_D3D11NV12) + return NULL; + + ID3D11Texture2D *texture = (void *)mpi->planes[1]; + int subindex = (intptr_t)mpi->planes[2]; + if (!texture) + return NULL; + + D3D11_TEXTURE2D_DESC tex_desc; + ID3D11Texture2D_GetDesc(texture, &tex_desc); + int mpfmt = get_dxgi_mpfmt(tex_desc.Format); + if (!mpfmt) + return NULL; + + // create staging texture shared with the CPU with mostly the same + // parameters as the source texture + tex_desc.MipLevels = 1; + tex_desc.MiscFlags = 0; + tex_desc.ArraySize = 1; + tex_desc.Usage = D3D11_USAGE_STAGING; + tex_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + tex_desc.BindFlags = 0; + ID3D11Texture2D *staging = NULL; + hr = ID3D11Device_CreateTexture2D(device, &tex_desc, NULL, &staging); + if (FAILED(hr)) + return NULL; + + bool ok = false; + struct mp_image *sw_img = NULL; + ID3D11DeviceContext *device_ctx = NULL; + ID3D11Device_GetImmediateContext(device, &device_ctx); + + // copy to the staging texture + ID3D11DeviceContext_CopySubresourceRegion( + device_ctx, + (ID3D11Resource *)staging, 0, 0, 0, 0, + (ID3D11Resource *)texture, subindex, NULL); + + sw_img = mp_image_pool_get(swpool, mpfmt, tex_desc.Width, tex_desc.Height); + if (!sw_img) + goto done; + + // copy staging texture to the cpu mp_image + D3D11_MAPPED_SUBRESOURCE lock; + hr = ID3D11DeviceContext_Map(device_ctx, (ID3D11Resource *)staging, + 0, D3D11_MAP_READ, 0, &lock); + if (FAILED(hr)) + goto done; + copy_nv12(sw_img, lock.pData, lock.RowPitch, tex_desc.Height); + ID3D11DeviceContext_Unmap(device_ctx, (ID3D11Resource *)staging, 0); + + mp_image_set_size(sw_img, mpi->w, mpi->h); + mp_image_copy_attributes(sw_img, mpi); + ok = true; + +done: + ID3D11Texture2D_Release(staging); + ID3D11DeviceContext_Release(device_ctx); + if (!ok) + mp_image_unrefp(&sw_img); + return sw_img; +} diff --git a/video/decode/d3d.h b/video/decode/d3d.h index 15c423ab8c..6caeb2dc03 100644 --- a/video/decode/d3d.h +++ b/video/decode/d3d.h @@ -19,6 +19,9 @@ #define MPV_DECODE_D3D_H #include <windows.h> +#include <d3d11.h> + +#include <stdbool.h> #include <inttypes.h> struct mp_image; @@ -62,4 +65,10 @@ BOOL is_clearvideo(const GUID *mode_guid); void copy_nv12(struct mp_image *dest, uint8_t *src_bits, unsigned src_pitch, unsigned surf_height); +bool d3d11_check_decoding(ID3D11Device *dev); + +struct mp_image *d3d11_download_image(struct mp_hwdec_ctx *ctx, + struct mp_image *mpi, + struct mp_image_pool *swpool); + #endif diff --git a/video/decode/lavc.h b/video/decode/lavc.h index 689222d872..993c3ec437 100644 --- a/video/decode/lavc.h +++ b/video/decode/lavc.h @@ -25,6 +25,9 @@ typedef struct lavc_ctx { bool hwdec_failed; bool hwdec_notified; + // For HDR side-data caching + double cached_hdr_peak; + struct mp_image **delay_queue; int num_delay_queue; int max_delay_queue; diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index fbb04d1abd..5962f883cd 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -47,6 +47,10 @@ #include "video/csputils.h" #include "video/sws_utils.h" +#if HAVE_AVUTIL_MASTERING_METADATA +#include <libavutil/mastering_display_metadata.h> +#endif + #include "lavc.h" #if AVPALETTE_SIZE != MP_PALETTE_SIZE @@ -129,17 +133,21 @@ extern const struct vd_lavc_hwdec mp_vd_lavc_dxva2_copy; extern const struct vd_lavc_hwdec mp_vd_lavc_d3d11va; extern const struct vd_lavc_hwdec mp_vd_lavc_d3d11va_copy; +#if HAVE_RPI static const struct vd_lavc_hwdec mp_vd_lavc_rpi = { .type = HWDEC_RPI, .lavc_suffix = "_mmal", .image_format = IMGFMT_MMAL, }; +#endif +#if HAVE_ANDROID static const struct vd_lavc_hwdec mp_vd_lavc_mediacodec = { .type = HWDEC_MEDIACODEC, .lavc_suffix = "_mediacodec", .copying = true, }; +#endif static const struct vd_lavc_hwdec *const hwdec_list[] = { #if HAVE_RPI @@ -568,16 +576,39 @@ static void update_image_params(struct dec_video *vd, AVFrame *frame, vd_ffmpeg_ctx *ctx = vd->priv; struct MPOpts *opts = ctx->opts; +#if HAVE_AVUTIL_MASTERING_METADATA + // Get the reference peak (for HDR) if available. This is cached into ctx + // when it's found, since it's not available on every frame (and seems to + // be only available for keyframes) + AVFrameSideData *sd = av_frame_get_side_data(frame, + AV_FRAME_DATA_MASTERING_DISPLAY_METADATA); + if (sd) { + AVMasteringDisplayMetadata *mdm = (AVMasteringDisplayMetadata *)sd->data; + if (mdm->has_luminance) { + double peak = av_q2d(mdm->max_luminance); + if (!isnormal(peak) || peak < 10 || peak > 100000) { + // Invalid data, ignore it. Sadly necessary + MP_WARN(vd, "Invalid HDR reference peak in stream: %f\n", peak); + } else { + ctx->cached_hdr_peak = peak; + } + } + } +#endif + *out_params = (struct mp_image_params) { .imgfmt = pixfmt2imgfmt(frame->format), .w = frame->width, .h = frame->height, .p_w = frame->sample_aspect_ratio.num, .p_h = frame->sample_aspect_ratio.den, - .colorspace = avcol_spc_to_mp_csp(ctx->avctx->colorspace), - .colorlevels = avcol_range_to_mp_csp_levels(ctx->avctx->color_range), - .primaries = avcol_pri_to_mp_csp_prim(ctx->avctx->color_primaries), - .gamma = avcol_trc_to_mp_csp_trc(ctx->avctx->color_trc), + .color = { + .space = avcol_spc_to_mp_csp(ctx->avctx->colorspace), + .levels = avcol_range_to_mp_csp_levels(ctx->avctx->color_range), + .primaries = avcol_pri_to_mp_csp_prim(ctx->avctx->color_primaries), + .gamma = avcol_trc_to_mp_csp_trc(ctx->avctx->color_trc), + .sig_peak = ctx->cached_hdr_peak, + }, .chroma_location = avchroma_location_to_mp(ctx->avctx->chroma_sample_location), .rotate = vd->codec->rotate, diff --git a/video/filter/vf.c b/video/filter/vf.c index 176ac95b70..274ca945a2 100644 --- a/video/filter/vf.c +++ b/video/filter/vf.c @@ -227,6 +227,8 @@ void vf_print_filter_chain(struct vf_chain *c, int msglevel, for (vf_instance_t *f = c->first; f; f = f->next) { char b[128] = {0}; mp_snprintf_cat(b, sizeof(b), " [%s] ", f->info->name); + if (f->label) + mp_snprintf_cat(b, sizeof(b), "\"%s\" ", f->label); mp_snprintf_cat(b, sizeof(b), "%s", mp_image_params_to_str(&f->fmt_out)); if (f->autoinserted) mp_snprintf_cat(b, sizeof(b), " [a]"); @@ -298,6 +300,7 @@ void vf_remove_filter(struct vf_chain *c, struct vf_instance *vf) assert(prev); // not inserted prev->next = vf->next; vf_uninit_filter(vf); + c->initialized = 0; } struct vf_instance *vf_append_filter(struct vf_chain *c, const char *name, @@ -312,6 +315,7 @@ struct vf_instance *vf_append_filter(struct vf_chain *c, const char *name, pprev = &(*pprev)->next; vf->next = *pprev ? *pprev : NULL; *pprev = vf; + c->initialized = 0; } return vf; } @@ -652,7 +656,7 @@ int vf_reconfig(struct vf_chain *c, const struct mp_image_params *params) mp_msg(c->log, loglevel, "Video filter chain:\n"); vf_print_filter_chain(c, loglevel, failing); if (r < 0) - c->input_params = c->output_params = (struct mp_image_params){0}; + c->output_params = (struct mp_image_params){0}; return r; } diff --git a/video/filter/vf_d3d11vpp.c b/video/filter/vf_d3d11vpp.c index a0aa0edae2..6faf712a67 100644 --- a/video/filter/vf_d3d11vpp.c +++ b/video/filter/vf_d3d11vpp.c @@ -211,21 +211,21 @@ static int recreate_video_proc(struct vf_instance *vf) FALSE, 0); D3D11_VIDEO_PROCESSOR_COLOR_SPACE csp = { - .YCbCr_Matrix = p->params.colorspace != MP_CSP_BT_601, - .Nominal_Range = p->params.colorlevels == MP_CSP_LEVELS_TV ? 1 : 2, + .YCbCr_Matrix = p->params.color.space != MP_CSP_BT_601, + .Nominal_Range = p->params.color.levels == MP_CSP_LEVELS_TV ? 1 : 2, }; ID3D11VideoContext_VideoProcessorSetStreamColorSpace(p->video_ctx, p->video_proc, 0, &csp); if (p->out_rgb) { - if (p->params.colorspace != MP_CSP_BT_601 && - p->params.colorspace != MP_CSP_BT_709) + if (p->params.color.space != MP_CSP_BT_601 && + p->params.color.space != MP_CSP_BT_709) { MP_WARN(vf, "Unsupported video colorspace (%s/%s). Consider " "disabling hardware decoding, or using " "--hwdec=d3d11va-copy to get correct output.\n", - m_opt_choice_str(mp_csp_names, p->params.colorspace), - m_opt_choice_str(mp_csp_levels_names, p->params.colorlevels)); + m_opt_choice_str(mp_csp_names, p->params.color.space), + m_opt_choice_str(mp_csp_levels_names, p->params.color.levels)); } } else { ID3D11VideoContext_VideoProcessorSetOutputColorSpace(p->video_ctx, @@ -331,11 +331,6 @@ static int render(struct vf_instance *vf) goto cleanup; } - // Make sure the texture is updated correctly on the shared context. - // (I'm not sure if this is correct, though it won't harm.) - if (p->out_shared) - ID3D11DeviceContext_Flush(p->device_ctx); - res = 0; cleanup: if (in_view) @@ -360,8 +355,11 @@ static int filter_out(struct vf_instance *vf) // no filtering if (!mp_refqueue_should_deint(p->queue) && !p->require_filtering) { - struct mp_image *in = mp_refqueue_get(p->queue, 0); - vf_add_output_frame(vf, mp_image_new_ref(in)); + struct mp_image *in = mp_image_new_ref(mp_refqueue_get(p->queue, 0)); + if (!in) + return -1; + mp_image_set_params(in, &p->out_params); + vf_add_output_frame(vf, in); mp_refqueue_next(p->queue); return 0; } diff --git a/video/filter/vf_format.c b/video/filter/vf_format.c index 109fda4053..d406d98d9b 100644 --- a/video/filter/vf_format.c +++ b/video/filter/vf_format.c @@ -88,15 +88,15 @@ static int reconfig(struct vf_instance *vf, struct mp_image_params *in, if (p->outfmt) out->imgfmt = p->outfmt; if (p->colormatrix) - out->colorspace = p->colormatrix; + out->color.space = p->colormatrix; if (p->colorlevels) - out->colorlevels = p->colorlevels; + out->color.levels = p->c |