From 745862131f2e03bfb7b8fae4499d84522f0cc1a2 Mon Sep 17 00:00:00 2001 From: James Ross-Gowan Date: Wed, 23 Nov 2016 00:55:20 +1100 Subject: d3d11va: unconditionally load D3D DLLs At least with Nvidia drivers, some thread tries to access D3D11 objects after ANGLE unloads d3d11.dll. Fix this by holding a reference to d3d11.dll ourselves. Might fix the crash in #3348. (I wish I knew why though.) --- video/decode/d3d11va.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'video/decode') diff --git a/video/decode/d3d11va.c b/video/decode/d3d11va.c index 8ce07880e7..e31582d37c 100644 --- a/video/decode/d3d11va.c +++ b/video/decode/d3d11va.c @@ -429,7 +429,6 @@ static bool create_device(struct lavc_ctx *s, BOOL thread_safe) HRESULT hr; struct priv *p = s->hwdec_priv; - d3d_load_dlls(); if (!d3d11_dll) { MP_ERR(p, "Failed to load D3D11 library\n"); return false; @@ -492,6 +491,11 @@ static int d3d11va_init(struct lavc_ctx *s) if (!p) return -1; + // Unconditionally load Direct3D DLLs, even when using a VO-supplied D3D11 + // device. This prevents a crash that occurs at least with NVIDIA drivers, + // where D3D objects are accessed after ANGLE unloads d3d11.dll. + d3d_load_dlls(); + s->hwdec_priv = p; p->log = mp_log_new(s, s->log, "d3d11va"); if (s->hwdec->type == HWDEC_D3D11VA_COPY) { -- cgit v1.2.3 From 585c5c34f1195007beb012668aa9a22cb47b1f37 Mon Sep 17 00:00:00 2001 From: Philip Langdale Date: Sat, 19 Nov 2016 13:57:23 -0800 Subject: vo_opengl: hwdec_cuda: Support P016 output surfaces The latest 375.xx nvidia drivers add support for P016 output surfaces. In combination with an ffmpeg change to return those surfaces, we can display them. The bulk of the work is related to knowing which format you're dealing with at the right time. Once you know, it's straight forward. --- video/decode/cuda.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'video/decode') diff --git a/video/decode/cuda.c b/video/decode/cuda.c index f9dd418fd5..b606315906 100644 --- a/video/decode/cuda.c +++ b/video/decode/cuda.c @@ -21,6 +21,7 @@ #include #include "common/av_common.h" +#include "video/fmt-conversion.h" #include "video/decode/lavc.h" typedef struct CUVIDContext { @@ -114,7 +115,7 @@ static void uninit(struct lavc_ctx *ctx) static struct mp_image *process_image(struct lavc_ctx *ctx, struct mp_image *img) { if (img->imgfmt == IMGFMT_CUDA) - img->params.hw_subfmt = IMGFMT_NV12; + img->params.hw_subfmt = pixfmt2imgfmt(ctx->avctx->sw_pix_fmt); return img; } -- cgit v1.2.3 From f5e82d5ed345dbb894ff75591abc4b262b65d0dd Mon Sep 17 00:00:00 2001 From: Philip Langdale Date: Sat, 8 Oct 2016 16:51:15 -0700 Subject: vo_opengl: hwdec_cuda: Use dynamic loading for cuda functions This change applies the pattern used in ffmpeg to dynamically load cuda, to avoid requiring the CUDA SDK at build time. --- video/decode/cuda.c | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) (limited to 'video/decode') diff --git a/video/decode/cuda.c b/video/decode/cuda.c index b606315906..cad02b2353 100644 --- a/video/decode/cuda.c +++ b/video/decode/cuda.c @@ -17,6 +17,10 @@ * License along with mpv. If not, see . */ +// This define and typedef prevent hwcontext_cuda.h trying to include cuda.h +#define CUDA_VERSION 7050 +typedef void * CUcontext; + #include #include @@ -24,16 +28,6 @@ #include "video/fmt-conversion.h" #include "video/decode/lavc.h" -typedef struct CUVIDContext { - CUcontext cuda_ctx; -} CUVIDContext; - -static void cuvid_ctx_free(AVHWDeviceContext *ctx) -{ - AVCUDADeviceContext *hwctx = ctx->hwctx; - cuCtxDestroy(hwctx->cuda_ctx); -} - static int probe(struct lavc_ctx *ctx, struct vd_lavc_hwdec *hwdec, const char *codec) { @@ -44,12 +38,7 @@ static int probe(struct lavc_ctx *ctx, struct vd_lavc_hwdec *hwdec, static int init(struct lavc_ctx *ctx) { - struct CUVIDContext *p = talloc_ptrtype(NULL, p); - - *p = (struct CUVIDContext) { - .cuda_ctx = hwdec_devices_get(ctx->hwdec_devs, HWDEC_CUDA)->ctx, - }; - ctx->hwdec_priv = p; + ctx->hwdec_priv = hwdec_devices_get(ctx->hwdec_devs, HWDEC_CUDA)->ctx; return 0; } @@ -59,7 +48,6 @@ static int init_decoder(struct lavc_ctx *ctx, int w, int h) AVCUDADeviceContext *device_hwctx; AVHWDeviceContext *device_ctx; AVHWFramesContext *hwframe_ctx; - CUVIDContext *priv = ctx->hwdec_priv; int ret = 0; if (avctx->hw_frames_ctx) { @@ -74,10 +62,9 @@ static int init_decoder(struct lavc_ctx *ctx, int w, int h) } device_ctx = (AVHWDeviceContext*)hw_device_ctx->data; - device_ctx->free = cuvid_ctx_free; device_hwctx = device_ctx->hwctx; - device_hwctx->cuda_ctx = priv->cuda_ctx; + device_hwctx->cuda_ctx = ctx->hwdec_priv; ret = av_hwdevice_ctx_init(hw_device_ctx); if (ret < 0) { @@ -104,11 +91,6 @@ static int init_decoder(struct lavc_ctx *ctx, int w, int h) static void uninit(struct lavc_ctx *ctx) { - struct CUVIDContext *p = ctx->hwdec_priv; - if (!p) - return; - - talloc_free(p); ctx->hwdec_priv = NULL; } -- cgit v1.2.3 From a89785f2971273b3c0592a5819f9618aaabf19f9 Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 2 Dec 2016 16:06:16 +0100 Subject: vdpau: fix vaapi probing if libvdpau-va-gl1 is present Needs explicit logic. Fixes a pretty bad regression which prefers vdpau-copy over native vaapi with direct rendering (with --hwdec=auto) if libvdpau-va-gl1 is present. The reason is that vdpau-copy is above vaapi, simply because all vdpau hwdecs are grouped and happened to be listed before vaapi. Although this is not that bad for copy-mode (unlike the case described above), it's still a good idea to use our native vaapi code instead. --- video/decode/vdpau.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'video/decode') diff --git a/video/decode/vdpau.c b/video/decode/vdpau.c index 93a1e6d9a3..a6b6210804 100644 --- a/video/decode/vdpau.c +++ b/video/decode/vdpau.c @@ -146,12 +146,14 @@ static int probe_copy(struct lavc_ctx *ctx, struct vd_lavc_hwdec *hwdec, const char *codec) { assert(!ctx->hwdec_priv); - int r = init_copy(ctx); - if (ctx->hwdec_priv) - uninit(ctx); - ctx->hwdec_priv = NULL; - return r < 0 ? HWDEC_ERR_NO_CTX : 0; + int r = HWDEC_ERR_NO_CTX; + if (init_copy(ctx) >=0 ) { + struct priv *p = ctx->hwdec_priv; + r = mp_vdpau_guess_if_emulated(p->mpvdp) ? HWDEC_ERR_EMULATED : 0; + uninit(ctx); + } + return r; } static struct mp_image *copy_image(struct lavc_ctx *ctx, struct mp_image *img) -- cgit v1.2.3 From 3eceac2eab0b42ee082a0b615ebf40a21f0fb915 Mon Sep 17 00:00:00 2001 From: wm4 Date: Wed, 7 Dec 2016 19:44:29 +0100 Subject: Remove compatibility things Possible with bumped FFmpeg/Libav. These are just the simple cases. --- video/decode/vd_lavc.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'video/decode') diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index d25c99981e..4a25060081 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -663,11 +663,9 @@ static enum AVPixelFormat get_format_hwdec(struct AVCodecContext *avctx, MP_VERBOSE(vd, " %s", av_get_pix_fmt_name(fmt[i])); MP_VERBOSE(vd, "\n"); -#if HAVE_AVCODEC_PROFILE_NAME const char *profile = avcodec_profile_name(avctx->codec_id, avctx->profile); MP_VERBOSE(vd, "Codec profile: %s (0x%x)\n", profile ? profile : "unknown", avctx->profile); -#endif assert(ctx->hwdec); @@ -794,7 +792,6 @@ static void decode(struct dec_video *vd, struct demux_packet *packet, reset_avctx(vd); hwdec_lock(ctx); -#if HAVE_AVCODEC_NEW_CODEC_API ret = avcodec_send_packet(avctx, packet ? &pkt : NULL); if (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { if (ret >= 0) @@ -807,10 +804,6 @@ static void decode(struct dec_video *vd, struct demux_packet *packet, } else { consumed = true; } -#else - ret = avcodec_decode_video2(avctx, ctx->pic, &got_picture, &pkt); - consumed = true; -#endif hwdec_unlock(ctx); // Reset decoder if it was fully flushed. Caller might send more flush @@ -864,7 +857,7 @@ static void decode(struct dec_video *vd, struct demux_packet *packet, return; } assert(mpi->planes[0] || mpi->planes[3]); - mpi->pts = mp_pts_from_av(MP_AVFRAME_DEC_PTS(ctx->pic), &ctx->codec_timebase); + mpi->pts = mp_pts_from_av(ctx->pic->pts, &ctx->codec_timebase); mpi->dts = mp_pts_from_av(ctx->pic->pkt_dts, &ctx->codec_timebase); struct mp_image_params params; -- cgit v1.2.3 From e57037dc952def5c2b2d2be7535052f94dfb9294 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 18 Dec 2016 12:27:47 +0100 Subject: ad_lavc, vd_lavc: don't set AVCodecContext.refcounted_frames This field is (or should be) deprecated, and there's no need to set it with the new API. --- video/decode/vd_lavc.c | 1 - 1 file changed, 1 deletion(-) (limited to 'video/decode') diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index 4a25060081..cd3c611ebd 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -501,7 +501,6 @@ static void init_avctx(struct dec_video *vd, const char *decoder, avctx->pkt_timebase = ctx->codec_timebase; #endif - avctx->refcounted_frames = 1; ctx->pic = av_frame_alloc(); if (!ctx->pic) goto error; -- cgit v1.2.3 From b1c0bbe8b8b9d25c2682f29af66ad243e0072897 Mon Sep 17 00:00:00 2001 From: wm4 Date: Wed, 21 Dec 2016 18:18:24 +0100 Subject: video: use demuxer-signaled duration for last video frame Helps with gif, probably does unwanted things with other formats. This doesn't handle --end quite correctly, but this could be added later. Fixes #3924. --- video/decode/vd_lavc.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'video/decode') diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index cd3c611ebd..78d34bbb47 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -859,6 +859,11 @@ static void decode(struct dec_video *vd, struct demux_packet *packet, mpi->pts = mp_pts_from_av(ctx->pic->pts, &ctx->codec_timebase); mpi->dts = mp_pts_from_av(ctx->pic->pkt_dts, &ctx->codec_timebase); +#if LIBAVCODEC_VERSION_MICRO >= 100 + mpi->pkt_duration = + mp_pts_from_av(av_frame_get_pkt_duration(ctx->pic), &ctx->codec_timebase); +#endif + struct mp_image_params params; update_image_params(vd, ctx->pic, ¶ms); mp_image_set_params(mpi, ¶ms); -- cgit v1.2.3 From 17d6ba7f776d6fd0ebc7a9881a999299c3fa9471 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 22 Dec 2016 18:40:17 +0100 Subject: vd_lavc: use AVFrame fields directly instead of AVCodecContext Conceptually cleaner, although the API claims this is equivalent. Originally, AVCodecContext fields were used, because not all supported libavcodec/libavutil versions had the AVFrame fields. This is not done for chroma_sample_location - it has no AVFrame field. --- video/decode/vd_lavc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'video/decode') diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index 78d34bbb47..cc3bbc86c7 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -638,10 +638,10 @@ static void update_image_params(struct dec_video *vd, AVFrame *frame, .p_w = frame->sample_aspect_ratio.num, .p_h = frame->sample_aspect_ratio.den, .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), + .space = avcol_spc_to_mp_csp(frame->colorspace), + .levels = avcol_range_to_mp_csp_levels(frame->color_range), + .primaries = avcol_pri_to_mp_csp_prim(frame->color_primaries), + .gamma = avcol_trc_to_mp_csp_trc(frame->color_trc), .sig_peak = ctx->cached_hdr_peak, }, .chroma_location = -- cgit v1.2.3 From 9d21f2503f28a7be0e493ab18a4acbaae02c3d0a Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 23 Dec 2016 18:12:29 +0100 Subject: options: deprecate codec family selection in --vd/--ad Useless now, so get rid of it. Also affects some user-visible display things (like reported codec in use). --- video/decode/dec_video.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'video/decode') diff --git a/video/decode/dec_video.c b/video/decode/dec_video.c index dea5b594c7..d9dbf0f326 100644 --- a/video/decode/dec_video.c +++ b/video/decode/dec_video.c @@ -116,11 +116,12 @@ struct mp_decoder_list *video_decoder_list(void) return list; } -static struct mp_decoder_list *mp_select_video_decoders(const char *codec, +static struct mp_decoder_list *mp_select_video_decoders(struct mp_log *log, + const char *codec, char *selection) { struct mp_decoder_list *list = video_decoder_list(); - struct mp_decoder_list *new = mp_select_decoders(list, codec, selection); + struct mp_decoder_list *new = mp_select_decoders(log, list, codec, selection); talloc_free(list); return new; } @@ -143,8 +144,9 @@ bool video_init_best_codec(struct dec_video *d_video) d_video->has_broken_packet_pts = -10; // needs 10 packets to reach decision struct mp_decoder_entry *decoder = NULL; - struct mp_decoder_list *list = - mp_select_video_decoders(d_video->codec->codec, opts->video_decoders); + struct mp_decoder_list *list = mp_select_video_decoders(d_video->log, + d_video->codec->codec, + opts->video_decoders); mp_print_decoders(d_video->log, MSGL_V, "Codec list:", list); @@ -153,22 +155,19 @@ bool video_init_best_codec(struct dec_video *d_video) const struct vd_functions *driver = find_driver(sel->family); if (!driver) continue; - MP_VERBOSE(d_video, "Opening video decoder %s:%s\n", - sel->family, sel->decoder); + MP_VERBOSE(d_video, "Opening video decoder %s\n", sel->decoder); d_video->vd_driver = driver; if (init_video_codec(d_video, sel->decoder)) { decoder = sel; break; } d_video->vd_driver = NULL; - MP_WARN(d_video, "Video decoder init failed for " - "%s:%s\n", sel->family, sel->decoder); + MP_WARN(d_video, "Video decoder init failed for %s\n", sel->decoder); } if (d_video->vd_driver) { d_video->decoder_desc = - talloc_asprintf(d_video, "%s [%s:%s]", decoder->desc, decoder->family, - decoder->decoder); + talloc_asprintf(d_video, "%s (%s)", decoder->decoder, decoder->desc); MP_VERBOSE(d_video, "Selected video codec: %s\n", d_video->decoder_desc); } else { MP_ERR(d_video, "Failed to initialize a video decoder for codec '%s'.\n", -- cgit v1.2.3