[MPlayer-dev-eng] [PATCH] vo_vdpau: Add support for VDPAU accelerated HEVC decoding

Philip Langdale philipl at overt.org
Fri Jun 26 05:59:20 CEST 2015


This change adds support for decoding HEVC content through VDPAU. Note
that as things currently stand, the nvidia drivers are buggy and the
output is not watcheable (its interlacing the top and bottom halves
of each frame), but that should be fixed within the driver, hopefully
without any further changes here.
---
 codec-cfg.c              |  1 +
 configure                |  4 ++++
 etc/codecs.conf          | 10 ++++++++++
 libmpcodecs/img_format.c |  1 +
 libmpcodecs/img_format.h |  1 +
 libmpcodecs/vd_ffmpeg.c  |  1 +
 libvo/vo_vdpau.c         | 19 ++++++++++++++++++-
 7 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/codec-cfg.c b/codec-cfg.c
index b6825cc..aaa2080 100644
--- a/codec-cfg.c
+++ b/codec-cfg.c
@@ -256,6 +256,7 @@ static const struct {
     {"VDPAU_WMV3",  IMGFMT_VDPAU_WMV3},
     {"VDPAU_VC1",   IMGFMT_VDPAU_VC1},
     {"VDPAU_MPEG4", IMGFMT_VDPAU_MPEG4},
+    {"VDPAU_HEVC",  IMGFMT_VDPAU_HEVC},
 
     {NULL,    0}
 };
diff --git a/configure b/configure
index b90d34f..f796ed5 100755
--- a/configure
+++ b/configure
@@ -4721,6 +4721,7 @@ if test "$_vdpau" = auto && test "$_x11" = yes ; then
   _vdpau=no
   if test "$_dl" = yes ; then
     return_statement_check vdpau/vdpau_x11.h 'vdp_device_create_x11(0, 0, 0, 0)' VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1 -lvdpau && _vdpau=yes
+    return_statement_check vdpau/vdpau_x11.h 'vdp_device_create_x11(0, 0, 0, 0)' VDP_DECODER_PROFILE_HEVC_MAIN -lvdpau && _vdpau_hevc=yes
   fi
 fi
 if test "$_vdpau" = yes ; then
@@ -4728,6 +4729,9 @@ if test "$_vdpau" = yes ; then
   libs_mplayer="$libs_mplayer -lvdpau"
   vomodules="vdpau $vomodules"
   libavhwaccels="$libavhwaccels H263_VDPAU_HWACCEL H264_VDPAU_HWACCEL MPEG1_VDPAU_HWACCEL MPEG2_VDPAU_HWACCEL MPEG4_VDPAU_HWACCEL VC1_VDPAU_HWACCEL WMV3_VDPAU_HWACCEL"
+  if test "$_vdpau_hevc" = yes ; then
+    libavhwaccels="$libavhwaccels HEVC_VDPAU_HWACCEL"
+  fi
 else
   def_vdpau='#define CONFIG_VDPAU 0'
   novomodules="vdpau $novomodules"
diff --git a/etc/codecs.conf b/etc/codecs.conf
index c2c34d3..f4b6e76 100644
--- a/etc/codecs.conf
+++ b/etc/codecs.conf
@@ -1398,6 +1398,16 @@ videocodec ffhevc
   out 422P,422P9,422P10,444P12
   out 444P,444P9,444P10,444P12
 
+videocodec ffhevcvdpau
+  info "FFmpeg HEVC / H.265 (VDPAU)"
+  status buggy
+  fourcc HEVC
+  fourcc hvc1
+  fourcc hev1
+  driver ffmpeg
+  dll hevc
+  out VDPAU_HEVC
+
 videocodec ffh264
   info "FFmpeg H.264"
   status working
diff --git a/libmpcodecs/img_format.c b/libmpcodecs/img_format.c
index 085b38b..32a869f 100644
--- a/libmpcodecs/img_format.c
+++ b/libmpcodecs/img_format.c
@@ -142,6 +142,7 @@ const char *vo_format_name(int format)
     case IMGFMT_VDPAU_MPEG4:     return "MPEG-4 Part 2 VDPAU acceleration";
     case IMGFMT_VDPAU_WMV3:      return "WMV3 VDPAU acceleration";
     case IMGFMT_VDPAU_VC1:       return "VC1 VDPAU acceleration";
+    case IMGFMT_VDPAU_HEVC:      return "HEVC VDPAU acceleration";
     }
     snprintf(unknown_format,20,"Unknown 0x%04x",format);
     return unknown_format;
diff --git a/libmpcodecs/img_format.h b/libmpcodecs/img_format.h
index 5f42378..68581f5 100644
--- a/libmpcodecs/img_format.h
+++ b/libmpcodecs/img_format.h
@@ -290,6 +290,7 @@ static inline int normalize_yuvp16(int fmt) {
 #define IMGFMT_VDPAU_WMV3          (IMGFMT_VDPAU|0x04)
 #define IMGFMT_VDPAU_VC1           (IMGFMT_VDPAU|0x05)
 #define IMGFMT_VDPAU_MPEG4         (IMGFMT_VDPAU|0x06)
+#define IMGFMT_VDPAU_HEVC          (IMGFMT_VDPAU|0x07)
 
 #define IMGFMT_IS_HWACCEL(fmt) (IMGFMT_IS_VDPAU(fmt) || IMGFMT_IS_XVMC(fmt))
 
diff --git a/libmpcodecs/vd_ffmpeg.c b/libmpcodecs/vd_ffmpeg.c
index efcd278..a373458 100644
--- a/libmpcodecs/vd_ffmpeg.c
+++ b/libmpcodecs/vd_ffmpeg.c
@@ -235,6 +235,7 @@ static int pixfmt2imgfmt2(enum AVPixelFormat fmt, enum AVCodecID cid)
         case AV_CODEC_ID_MPEG4:      return IMGFMT_VDPAU_MPEG4;
         case AV_CODEC_ID_WMV3:       return IMGFMT_VDPAU_WMV3;
         case AV_CODEC_ID_VC1:        return IMGFMT_VDPAU_VC1;
+        case AV_CODEC_ID_HEVC:       return IMGFMT_VDPAU_HEVC;
         }
     return pixfmt2imgfmt(fmt);
 }
diff --git a/libvo/vo_vdpau.c b/libvo/vo_vdpau.c
index 8203a31..f9a8057 100644
--- a/libvo/vo_vdpau.c
+++ b/libvo/vo_vdpau.c
@@ -620,6 +620,12 @@ static int create_vdp_decoder(uint32_t format, uint32_t width, uint32_t height,
     case IMGFMT_VDPAU_MPEG4:
         vdp_decoder_profile = VDP_DECODER_PROFILE_MPEG4_PART2_ASP;
         break;
+#ifdef VDP_DECODER_PROFILE_HEVC_MAIN;
+    case IMGFMT_VDPAU_HEVC:
+        vdp_decoder_profile = VDP_DECODER_PROFILE_HEVC_MAIN;
+        mp_msg(MSGT_VO, MSGL_V, "[vdpau] Creating HEVC hardware decoder for %d reference frames.\n", max_refs);
+        break;
+#endif
     default:
         goto err_out;
     }
@@ -1028,7 +1034,17 @@ static int draw_slice(uint8_t *image[], int stride[], int w, int h,
 {
     VdpStatus vdp_st;
     struct vdpau_frame_data *rndr = (struct vdpau_frame_data *)image[0];
-    int max_refs = image_format == IMGFMT_VDPAU_H264 ? ((VdpPictureInfoH264 *)rndr->info)->num_ref_frames : 2;
+    int max_refs;
+    switch (image_format) {
+    case IMGFMT_VDPAU_H264:
+        max_refs = ((VdpPictureInfoH264 *)rndr->info)->num_ref_frames;
+        break;
+    case IMGFMT_VDPAU_HEVC:
+        max_refs = 16;
+        break;
+    default:
+        max_refs = 2;
+    }
 
     if (handle_preemption() < 0)
         return VO_TRUE;
@@ -1151,6 +1167,7 @@ static int query_format(uint32_t format)
     case IMGFMT_VDPAU_WMV3:
     case IMGFMT_VDPAU_VC1:
     case IMGFMT_VDPAU_MPEG4:
+    case IMGFMT_VDPAU_HEVC:
         // Note: this will break the current decoder
         // Not all implementations support safely instantiating
         // a second decoder, so this is the "lesser evil"
-- 
2.1.4



More information about the MPlayer-dev-eng mailing list