summaryrefslogtreecommitdiffstats
path: root/video/decode
diff options
context:
space:
mode:
authorMartin Herkt <lachs0r@srsfckn.biz>2016-12-25 13:28:05 +0100
committerMartin Herkt <lachs0r@srsfckn.biz>2016-12-25 13:28:05 +0100
commitb3d670a3e1ee9c60be33b6e5fafdf3b6449b5762 (patch)
tree341f80d55bf200c6bb195f77ce50a2fd1f030345 /video/decode
parent1d4273cfb52043c8165b85e9d7ac7bc14cb59cba (diff)
parent1c761bd6f59c369e45037e80f781429da65734c3 (diff)
downloadmpv-b3d670a3e1ee9c60be33b6e5fafdf3b6449b5762.tar.bz2
mpv-b3d670a3e1ee9c60be33b6e5fafdf3b6449b5762.tar.xz
Merge branch 'master' into release/current
Diffstat (limited to 'video/decode')
-rw-r--r--video/decode/cuda.c33
-rw-r--r--video/decode/d3d11va.c6
-rw-r--r--video/decode/dec_video.c19
-rw-r--r--video/decode/vd_lavc.c23
-rw-r--r--video/decode/vdpau.c12
5 files changed, 39 insertions, 54 deletions
diff --git a/video/decode/cuda.c b/video/decode/cuda.c
index f9dd418fd5..cad02b2353 100644
--- a/video/decode/cuda.c
+++ b/video/decode/cuda.c
@@ -17,22 +17,17 @@
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
+// This define and typedef prevent hwcontext_cuda.h trying to include cuda.h
+#define CUDA_VERSION 7050
+typedef void * CUcontext;
+
#include <libavutil/hwcontext.h>
#include <libavutil/hwcontext_cuda.h>
#include "common/av_common.h"
+#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)
{
@@ -43,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;
}
@@ -58,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) {
@@ -73,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) {
@@ -103,18 +91,13 @@ 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;
}
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;
}
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) {
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",
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index d25c99981e..cc3bbc86c7 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;
@@ -639,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 =
@@ -663,11 +662,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 +791,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 +803,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,9 +856,14 @@ 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);
+#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, &params);
mp_image_set_params(mpi, &params);
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)