diff --git a/mythtv/configure b/mythtv/configure
index 07c67f7ebb5..2f1e147ddac 100755
--- a/mythtv/configure
+++ b/mythtv/configure
@@ -134,6 +134,7 @@ Advanced options (experts only):
   --disable-vdpau          disable NVidia VDPAU hardware acceleration.
   --disable-crystalhd      disable Broadcom CrystalHD hardware decoder support
   --disable-vaapi          disable VAAPI hardware accelerated video decoding
+  --disable-vaapi2         disable VAAPI@ hardware accelerated video decoding
   --disable-openmax        disable OpenMAX hardware accelerated video decoding
   --disable-dxva2          disable hardware accelerated decoding on windows
   --disable-mediacodec     disable hardware accelerated decoding on android
@@ -1401,6 +1402,7 @@ HWACCEL_AUTODETECT_LIBRARY_LIST="
     crystalhd
     dxva2
     vaapi
+    vaapi2
     vda
     vdpau
 "
@@ -2040,6 +2042,7 @@ USING_LIST='
     opengl
     opengles
     vaapi
+    vaapi2
     vdpau
     openmax
     mediacodec
@@ -7273,6 +7276,7 @@ if enabled x11 ; then
   echo "xv support                ${xv-no}"
   echo "VDPAU support             ${vdpau-no}"
   echo "VAAPI support             ${vaapi-no}"
+  echo "VAAPI2 support            ${vaapi2-no}"
   echo "CrystalHD support         ${crystalhd-no}"
   echo "OpenMAX support           ${openmax-no}"
   if enabled openmax ; then
diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp
index 6b9cca5663a..69a99ac4cc2 100644
--- a/mythtv/libs/libmythtv/avformatdecoder.cpp
+++ b/mythtv/libs/libmythtv/avformatdecoder.cpp
@@ -70,6 +70,10 @@ extern "C" {
 #include <QtAndroidExtras>
 #endif
 
+#ifdef USING_VAAPI2
+#include "vaapi2context.h"
+#endif
+
 extern "C" {
 #include "libavutil/avutil.h"
 #include "libavutil/error.h"
@@ -385,6 +389,10 @@ void AvFormatDecoder::GetDecoders(render_opts &opts)
     opts.decoders->append("vaapi");
     (*opts.equiv_decoders)["vaapi"].append("dummy");
 #endif
+#ifdef USING_VAAPI2
+    opts.decoders->append("vaapi2");
+    (*opts.equiv_decoders)["vaapi2"].append("dummy");
+#endif
 #ifdef USING_MEDIACODEC
     opts.decoders->append("mediacodec");
     (*opts.equiv_decoders)["mediacodec"].append("dummy");
@@ -1520,7 +1528,7 @@ enum AVPixelFormat get_format_dxva2(struct AVCodecContext *avctx,
 }
 #endif
 
-#ifdef USING_VAAPI
+
 static bool IS_VAAPI_PIX_FMT(enum AVPixelFormat fmt)
 {
     return fmt == AV_PIX_FMT_VAAPI_MOCO ||
@@ -1528,6 +1536,8 @@ static bool IS_VAAPI_PIX_FMT(enum AVPixelFormat fmt)
            fmt == AV_PIX_FMT_VAAPI_VLD;
 }
 
+#ifdef USING_VAAPI
+
 // Declared separately to allow attribute
 static enum AVPixelFormat get_format_vaapi(struct AVCodecContext *,
                                          const enum AVPixelFormat *) MUNUSED;
@@ -1554,6 +1564,28 @@ enum AVPixelFormat get_format_vaapi(struct AVCodecContext *avctx,
 }
 #endif
 
+#ifdef USING_VAAPI2
+static enum AVPixelFormat get_format_vaapi2(struct AVCodecContext *avctx,
+                                           const enum AVPixelFormat *valid_fmts)
+{
+    enum AVPixelFormat ret = AV_PIX_FMT_NONE;
+    while (*valid_fmts != AV_PIX_FMT_NONE) {
+        if (IS_VAAPI_PIX_FMT(*valid_fmts))
+        {
+            ret = *valid_fmts;
+            break;
+        }
+        valid_fmts++;
+    }
+
+    // AVBufferRef* dev_ctx = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_VAAPI);
+    // AVBufferRef* frame_ctx = av_hwframe_ctx_alloc(dev_ctx);
+    // avctx->hw_frames_ctx = frame_ctx;
+    // avctx->hwaccel_context =
+    return ret;
+}
+#endif
+
 #ifdef USING_MEDIACODEC
 static enum AVPixelFormat get_format_mediacodec(struct AVCodecContext *avctx,
                                            const enum AVPixelFormat *valid_fmts)
@@ -1634,7 +1666,7 @@ void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc,
     else
 #endif
 #ifdef USING_VAAPI
-    if (CODEC_IS_VAAPI(codec, enc))
+    if (CODEC_IS_VAAPI(codec, enc) && codec_is_vaapi(video_codec_id))
     {
         enc->get_buffer2     = get_avf_buffer_vaapi;
         enc->get_format      = get_format_vaapi;
@@ -1649,6 +1681,15 @@ void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc,
         enc->slice_flags     = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;
     }
     else
+#endif
+#ifdef USING_VAAPI2
+    if (codec_is_vaapi2(video_codec_id))
+    {
+        enc->get_format      = get_format_vaapi2;
+        // TODO - check return code from following call
+        Vaapi2Context::HwDecoderInit(enc);
+    }
+    else
 #endif
     if (codec && codec->capabilities & AV_CODEC_CAP_DR1)
     {
@@ -2542,6 +2583,24 @@ int AvFormatDecoder::ScanStreams(bool novideo)
                         foundgpudecoder = true;
                     }
                 }
+#endif // USING_MEDIACODEC
+#ifdef USING_VAAPI2
+                if (!foundgpudecoder)
+                {
+                    MythCodecID vaapi2_mcid;
+                    AVPixelFormat pix_fmt = AV_PIX_FMT_YUV420P;
+                    vaapi2_mcid = Vaapi2Context::GetBestSupportedCodec(
+                        &codec, dec, mpeg_version(enc->codec_id),
+                        pix_fmt);
+
+                    if (codec_is_vaapi2(vaapi2_mcid))
+                    {
+                        gCodecMap->freeCodecContext(ic->streams[selTrack]);
+                        enc = gCodecMap->getCodecContext(ic->streams[selTrack], codec);
+                        video_codec_id = vaapi2_mcid;
+                        foundgpudecoder = true;
+                    }
+                }
 #endif // USING_MEDIACODEC
             }
             // default to mpeg2
@@ -2563,7 +2622,9 @@ int AvFormatDecoder::ScanStreams(bool novideo)
 
             use_frame_timing = false;
             if (! private_dec
-                && (codec_is_std(video_codec_id) || codec_is_mediacodec(video_codec_id)))
+                && (codec_is_std(video_codec_id)
+                    || codec_is_mediacodec(video_codec_id))
+                    || codec_is_vaapi2(video_codec_id))
                 use_frame_timing = true;
 
             if (FlagIsSet(kDecodeSingleThreaded))
@@ -3847,6 +3908,24 @@ bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic)
     }
     else if (!directrendering)
     {
+        AVFrame *tmp_frame = NULL;
+
+        if (IS_VAAPI_PIX_FMT((AVPixelFormat)mpa_pic->format))
+        {
+            int ret = 0;
+            tmp_frame = av_frame_alloc();
+            /* retrieve data from GPU to CPU */
+            if ((ret = av_hwframe_transfer_data(tmp_frame, mpa_pic, 0)) < 0) {
+                LOG(VB_GENERAL, LOG_ERR, LOC
+                    + QString("Error %1 transferring the data to system memory")
+                        .arg(ret));
+                av_frame_free(&tmp_frame);
+                return false;
+            }
+        }
+        else
+            tmp_frame = mpa_pic;
+
         AVFrame tmppicture;
 
         VideoFrame *xf = picframe;
@@ -3854,8 +3933,8 @@ bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic)
 
         unsigned char *buf = picframe->buf;
         av_image_fill_arrays(tmppicture.data, tmppicture.linesize,
-            buf, AV_PIX_FMT_YUV420P, context->width,
-                       context->height, IMAGE_ALIGN);
+            buf, AV_PIX_FMT_YUV420P, tmp_frame->width,
+                       tmp_frame->height, IMAGE_ALIGN);
         tmppicture.data[0] = buf + picframe->offsets[0];
         tmppicture.data[1] = buf + picframe->offsets[1];
         tmppicture.data[2] = buf + picframe->offsets[2];
@@ -3864,9 +3943,9 @@ bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic)
         tmppicture.linesize[2] = picframe->pitches[2];
 
         QSize dim = get_video_dim(*context);
-        sws_ctx = sws_getCachedContext(sws_ctx, context->width,
-                                       context->height, context->pix_fmt,
-                                       context->width, context->height,
+        sws_ctx = sws_getCachedContext(sws_ctx, tmp_frame->width,
+                                       tmp_frame->height, (AVPixelFormat)tmp_frame->format,
+                                       tmp_frame->width, tmp_frame->height,
                                        AV_PIX_FMT_YUV420P, SWS_FAST_BILINEAR,
                                        NULL, NULL, NULL);
         if (!sws_ctx)
@@ -3874,7 +3953,7 @@ bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic)
             LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to allocate sws context");
             return false;
         }
-        sws_scale(sws_ctx, mpa_pic->data, mpa_pic->linesize, 0, dim.height(),
+        sws_scale(sws_ctx, tmp_frame->data, tmp_frame->linesize, 0, dim.height(),
                   tmppicture.data, tmppicture.linesize);
 
         if (xf)
@@ -3887,6 +3966,8 @@ bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic)
             xf->aspect = current_aspect;
             m_parent->DiscardVideoFrame(xf);
         }
+        if (tmp_frame)
+            av_frame_free(&tmp_frame);
     }
     else if (!picframe)
     {
diff --git a/mythtv/libs/libmythtv/libmythtv.pro b/mythtv/libs/libmythtv/libmythtv.pro
index 939ca20984b..75efa55ec13 100644
--- a/mythtv/libs/libmythtv/libmythtv.pro
+++ b/mythtv/libs/libmythtv/libmythtv.pro
@@ -505,6 +505,12 @@ using_frontend {
         using_opengl_video:DEFINES += USING_GLVAAPI
     }
 
+    using_vaapi2 {
+        DEFINES += USING_VAAPI2
+        HEADERS += vaapi2context.h
+        SOURCES += vaapi2context.cpp
+    }
+
     using_mediacodec {
         DEFINES += USING_MEDIACODEC
         HEADERS += mediacodeccontext.h
diff --git a/mythtv/libs/libmythtv/mythcodecid.cpp b/mythtv/libs/libmythtv/mythcodecid.cpp
index b2023512b5f..cff4ba03585 100644
--- a/mythtv/libs/libmythtv/mythcodecid.cpp
+++ b/mythtv/libs/libmythtv/mythcodecid.cpp
@@ -123,6 +123,27 @@ QString toString(MythCodecID codecid)
         case kCodec_HEVC_MEDIACODEC:
             return "HEVC MEDIACODEC";
 
+        case kCodec_MPEG1_VAAPI2:
+            return "MPEG1 VAAPI2";
+        case kCodec_MPEG2_VAAPI2:
+            return "MPEG2 VAAPI2";
+        case kCodec_H263_VAAPI2:
+            return "H.263 VAAPI2";
+        case kCodec_MPEG4_VAAPI2:
+            return "MPEG4 VAAPI2";
+        case kCodec_H264_VAAPI2:
+            return "H.264 VAAPI2";
+        case kCodec_VC1_VAAPI2:
+            return "VC1 VAAPI2";
+        case kCodec_WMV3_VAAPI2:
+            return "WMV3 VAAPI2";
+        case kCodec_VP8_VAAPI2:
+            return "VP8 VAAPI2";
+        case kCodec_VP9_VAAPI2:
+            return "VP9 VAAPI2";
+        case kCodec_HEVC_VAAPI2:
+            return "HEVC VAAPI2";
+
         default:
             break;
     }
@@ -305,6 +326,37 @@ int myth2av_codecid(MythCodecID codec_id, bool &vdpau)
             ret = AV_CODEC_ID_HEVC;
             break;
 
+        case kCodec_MPEG1_VAAPI2:
+            ret = AV_CODEC_ID_MPEG1VIDEO;
+            break;
+        case kCodec_MPEG2_VAAPI2:
+            ret = AV_CODEC_ID_MPEG2VIDEO;
+            break;
+        case kCodec_H263_VAAPI2:
+            ret = AV_CODEC_ID_H263;
+            break;
+        case kCodec_MPEG4_VAAPI2:
+            ret = AV_CODEC_ID_MPEG4;
+            break;
+        case kCodec_H264_VAAPI2:
+            ret = AV_CODEC_ID_H264;
+            break;
+        case kCodec_VC1_VAAPI2:
+            ret = AV_CODEC_ID_VC1;
+            break;
+        case kCodec_WMV3_VAAPI2:
+            ret = AV_CODEC_ID_WMV3;
+            break;
+        case kCodec_VP8_VAAPI2:
+            ret = AV_CODEC_ID_VP8;
+            break;
+        case kCodec_VP9_VAAPI2:
+            ret = AV_CODEC_ID_VP9;
+            break;
+        case kCodec_HEVC_VAAPI2:
+            ret = AV_CODEC_ID_HEVC;
+            break;
+
         default:
             LOG(VB_GENERAL, LOG_ERR,
                 QString("Error: MythCodecID %1 has not been "
@@ -356,11 +408,13 @@ QString get_encoding_type(MythCodecID codecid)
         case kCodec_MPEG1_VAAPI:
         case kCodec_MPEG1_DXVA2:
         case kCodec_MPEG1_MEDIACODEC:
+        case kCodec_MPEG1_VAAPI2:
         case kCodec_MPEG2:
         case kCodec_MPEG2_VDPAU:
         case kCodec_MPEG2_VAAPI:
         case kCodec_MPEG2_DXVA2:
         case kCodec_MPEG2_MEDIACODEC:
+        case kCodec_MPEG2_VAAPI2:
             return "MPEG-2";
 
         case kCodec_H263:
@@ -368,6 +422,7 @@ QString get_encoding_type(MythCodecID codecid)
         case kCodec_H263_VAAPI:
         case kCodec_H263_DXVA2:
         case kCodec_H263_MEDIACODEC:
+        case kCodec_H263_VAAPI2:
             return "H.263";
 
         case kCodec_NUV_MPEG4:
@@ -376,6 +431,7 @@ QString get_encoding_type(MythCodecID codecid)
         case kCodec_MPEG4_VAAPI:
         case kCodec_MPEG4_DXVA2:
         case kCodec_MPEG4_MEDIACODEC:
+        case kCodec_MPEG4_VAAPI2:
             return "MPEG-4";
 
         case kCodec_H264:
@@ -383,6 +439,7 @@ QString get_encoding_type(MythCodecID codecid)
         case kCodec_H264_VAAPI:
         case kCodec_H264_DXVA2:
         case kCodec_H264_MEDIACODEC:
+        case kCodec_H264_VAAPI2:
             return "H.264";
 
         case kCodec_VC1:
@@ -390,6 +447,7 @@ QString get_encoding_type(MythCodecID codecid)
         case kCodec_VC1_VAAPI:
         case kCodec_VC1_DXVA2:
         case kCodec_VC1_MEDIACODEC:
+        case kCodec_VC1_VAAPI2:
             return "VC-1";
 
         case kCodec_WMV3:
@@ -397,6 +455,7 @@ QString get_encoding_type(MythCodecID codecid)
         case kCodec_WMV3_VAAPI:
         case kCodec_WMV3_DXVA2:
         case kCodec_WMV3_MEDIACODEC:
+        case kCodec_WMV3_VAAPI2:
             return "WMV3";
 
         case kCodec_VP8:
@@ -404,6 +463,7 @@ QString get_encoding_type(MythCodecID codecid)
         case kCodec_VP8_VAAPI:
         case kCodec_VP8_DXVA2:
         case kCodec_VP8_MEDIACODEC:
+        case kCodec_VP8_VAAPI2:
             return "VP8";
 
         case kCodec_VP9:
@@ -411,6 +471,7 @@ QString get_encoding_type(MythCodecID codecid)
         case kCodec_VP9_VAAPI:
         case kCodec_VP9_DXVA2:
         case kCodec_VP9_MEDIACODEC:
+        case kCodec_VP9_VAAPI2:
             return "VP8";
 
         case kCodec_HEVC:
@@ -418,6 +479,7 @@ QString get_encoding_type(MythCodecID codecid)
         case kCodec_HEVC_VAAPI:
         case kCodec_HEVC_DXVA2:
         case kCodec_HEVC_MEDIACODEC:
+        case kCodec_HEVC_VAAPI2:
             return "HEVC";
 
         case kCodec_NONE:
@@ -426,6 +488,7 @@ QString get_encoding_type(MythCodecID codecid)
         case kCodec_VAAPI_END:
         case kCodec_DXVA2_END:
         case kCodec_MEDIACODEC_END:
+        case kCodec_VAAPI2_END:
             return QString();
     }
 
@@ -446,5 +509,8 @@ QString get_decoder_name(MythCodecID codec_id)
     if (codec_is_mediacodec(codec_id))
         return "mediacodec";
 
+    if (codec_is_vaapi2(codec_id))
+        return "vaapi2";
+
     return "ffmpeg";
 }
diff --git a/mythtv/libs/libmythtv/mythcodecid.h b/mythtv/libs/libmythtv/mythcodecid.h
index ce3620467d9..f1d225d4beb 100644
--- a/mythtv/libs/libmythtv/mythcodecid.h
+++ b/mythtv/libs/libmythtv/mythcodecid.h
@@ -91,6 +91,21 @@ typedef enum
 
     kCodec_MEDIACODEC_END,
 
+    kCodec_VAAPI2_BEGIN = kCodec_MEDIACODEC_END,
+
+    kCodec_MPEG1_VAAPI2,
+    kCodec_MPEG2_VAAPI2,
+    kCodec_H263_VAAPI2,
+    kCodec_MPEG4_VAAPI2,
+    kCodec_H264_VAAPI2,
+    kCodec_VC1_VAAPI2,
+    kCodec_WMV3_VAAPI2,
+    kCodec_VP8_VAAPI2,
+    kCodec_VP9_VAAPI2,
+    kCodec_HEVC_VAAPI2,
+
+    kCodec_VAAPI2_END,
+
 } MythCodecID;
 
 // MythCodecID convenience functions
@@ -113,8 +128,10 @@ typedef enum
                                 (id == kCodec_VC1_DXVA2)))
 #define codec_is_mediacodec(id) ((id > kCodec_MEDIACODEC_BEGIN) &&     \
                                (id < kCodec_MEDIACODEC_END))
+#define codec_is_vaapi2(id)    ((id > kCodec_VAAPI2_BEGIN) &&     \
+                               (id < kCodec_VAAPI2_END))
 
-#define codec_sw_copy(id) (codec_is_std(id) || codec_is_mediacodec(id))
+#define codec_sw_copy(id) (codec_is_std(id) || codec_is_mediacodec(id) || codec_is_vaapi2(id))
 
 QString get_encoding_type(MythCodecID codecid);
 QString get_decoder_name(MythCodecID codec_id);
@@ -156,9 +173,4 @@ int mpeg_version(int codec_id);
 #define CODEC_IS_MEDIACODEC(codec) (0)
 #endif
 
-#define CODEC_IS_HWACCEL(codec, enc) (CODEC_IS_VDPAU(codec)      ||     \
-                                      CODEC_IS_VAAPI(codec, enc) ||     \
-                                      CODEC_IS_DXVA2(codec, enc) ||    \
-                                      CODEC_IS_MEDIACODEC(codec))
-
 #endif // _MYTH_CODEC_ID_H_
diff --git a/mythtv/libs/libmythtv/vaapi2context.cpp b/mythtv/libs/libmythtv/vaapi2context.cpp
new file mode 100644
index 00000000000..2cd275b36b9
--- /dev/null
+++ b/mythtv/libs/libmythtv/vaapi2context.cpp
@@ -0,0 +1,94 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 MythTV Developers <mythtv-dev@mythtv.org>
+//
+// This is part of MythTV (https://www.mythtv.org)
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+//
+// You should have received a copy of the GNU General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include "vaapi2context.h"
+
+#include "mythlogging.h"
+
+extern "C" {
+    #include "libavutil/pixfmt.h"
+    #include "libavutil/hwcontext.h"
+    #include "libavcodec/avcodec.h"
+}
+
+#define LOC QString("VAAPI2: ")
+
+MythCodecID Vaapi2Context::GetBestSupportedCodec(
+    AVCodec **ppCodec,
+    const QString &decoder,
+    uint stream_type,
+    AVPixelFormat &pix_fmt)
+{
+    enum AVHWDeviceType type = AV_HWDEVICE_TYPE_VAAPI;
+
+    AVPixelFormat fmt = AV_PIX_FMT_NONE;
+    if (decoder == "vaapi2")
+    {
+        for (int i = 0;; i++) {
+            const AVCodecHWConfig *config = avcodec_get_hw_config(*ppCodec, i);
+            if (!config) {
+                LOG(VB_PLAYBACK, LOG_INFO, LOC +
+                    QString("Decoder %1 does not support device type %2.")
+                        .arg((*ppCodec)->name).arg(av_hwdevice_get_type_name(type)));
+                break;
+            }
+            if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX &&
+                config->device_type == type) {
+                fmt = config->pix_fmt;
+                break;
+            }
+        }
+    }
+    if (fmt == AV_PIX_FMT_NONE)
+        return (MythCodecID)(kCodec_MPEG1 + (stream_type - 1));
+    else
+    {
+        LOG(VB_PLAYBACK, LOG_INFO, LOC +
+            QString("Decoder %1 supports device type %2.")
+                .arg((*ppCodec)->name).arg(av_hwdevice_get_type_name(type)));
+        pix_fmt = fmt;
+        return (MythCodecID)(kCodec_MPEG1_VAAPI2 + (stream_type - 1));
+    }
+}
+
+int Vaapi2Context::HwDecoderInit(AVCodecContext *ctx)
+{
+    int ret = 0;
+    AVBufferRef *hw_device_ctx = NULL;
+
+    ret = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI,
+                                      NULL, NULL, 0);
+    if (ret < 0)
+    {
+        char error[AV_ERROR_MAX_STRING_SIZE];
+        LOG(VB_GENERAL, LOG_ERR, LOC +
+            QString("av_hwdevice_ctx_create error: %1 (%2)")
+            .arg(av_make_error_string(error, sizeof(error), ret))
+            .arg(ret));
+    }
+    else
+        ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
+
+    return ret;
+}
diff --git a/mythtv/libs/libmythtv/vaapi2context.h b/mythtv/libs/libmythtv/vaapi2context.h
new file mode 100644
index 00000000000..d8d9408530a
--- /dev/null
+++ b/mythtv/libs/libmythtv/vaapi2context.h
@@ -0,0 +1,45 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 MythTV Developers <mythtv-dev@mythtv.org>
+//
+// This is part of MythTV (https://www.mythtv.org)
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+//
+// You should have received a copy of the GNU General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef VAAPI2CONTEXT_H
+#define VAAPI2CONTEXT_H
+
+#include "mythcodecid.h"
+
+extern "C" {
+    #include "libavcodec/avcodec.h"
+}
+
+class Vaapi2Context
+{
+  public:
+    static MythCodecID GetBestSupportedCodec(AVCodec **ppCodec,
+                                             const QString &decoder,
+                                             uint stream_type,
+                                             AVPixelFormat &pix_fmt);
+    static int HwDecoderInit(AVCodecContext *ctx);
+};
+
+#endif // VIDEOOUTOPENGLMEDIACODEC_H
\ No newline at end of file
diff --git a/mythtv/libs/libmythtv/videodisplayprofile.cpp b/mythtv/libs/libmythtv/videodisplayprofile.cpp
index 700ee3bb990..5afdc0f2282 100644
--- a/mythtv/libs/libmythtv/videodisplayprofile.cpp
+++ b/mythtv/libs/libmythtv/videodisplayprofile.cpp
@@ -852,6 +852,7 @@ QString VideoDisplayProfile::GetDecoderName(const QString &decoder)
         dec_name["dxva2"]    = QObject::tr("Windows hardware acceleration");
         dec_name["vda"]      = QObject::tr("Mac VDA hardware acceleration");
         dec_name["mediacodec"] = QObject::tr("Android MediaCodec decoder");
+        dec_name["vaapi2"]   = QObject::tr("VAAPI2 acceleration");
     }
 
     QString ret = decoder;
@@ -913,6 +914,11 @@ QString VideoDisplayProfile::GetDecoderHelp(QString decoder)
             "Mediacodec will use the graphics hardware to "
             "accelerate video decoding on Android. ");
 
+    if (decoder == "vaapi2")
+        msg += QObject::tr(
+            "VAAPI2 is a new implemtation of VAAPI to will use the graphics hardware to "
+            "accelerate video decoding on Android. ");
+
     return msg;
 }
 
@@ -1468,6 +1474,19 @@ void VideoDisplayProfile::CreateProfiles(const QString &hostname)
         CreateProfile(groupid, 1, "", "", "",
                       "mediacodec", 4, true, "opengl",
                       "opengl2", true,
+                      "opengldoubleratelinearblend", "opengllinearblend",
+                      "");
+    }
+#endif
+
+#ifdef USING_VAAPI2
+    if (!profiles.contains("VAAPI2 Normal")) {
+        (void) QObject::tr("VAAPI2 Normal",
+                           "Sample: VAAPI2 Normal");
+        groupid = CreateProfileGroup("VAAPI2 Normal", hostname);
+        CreateProfile(groupid, 1, "", "", "",
+                      "vaapi2", 4, true, "opengl",
+                      "opengl2", true,
                       "none", "none",
                       "");
     }
diff --git a/mythtv/libs/libmythtv/videoout_opengl.cpp b/mythtv/libs/libmythtv/videoout_opengl.cpp
index b689947d738..b287086009e 100644
--- a/mythtv/libs/libmythtv/videoout_opengl.cpp
+++ b/mythtv/libs/libmythtv/videoout_opengl.cpp
@@ -40,6 +40,8 @@ void VideoOutputOpenGL::GetRenderOptions(render_opts &opts,
         (*opts.safe_renderers)["openmax"].append("opengl");
     if (opts.decoders->contains("mediacodec"))
         (*opts.safe_renderers)["mediacodec"].append("opengl");
+    if (opts.decoders->contains("vaapi2"))
+        (*opts.safe_renderers)["vaapi2"].append("opengl");
     opts.priorities->insert("opengl", 65);
 
     // lite profile - no colourspace control, GPU deinterlacing
@@ -270,7 +272,9 @@ bool VideoOutputOpenGL::InputChanged(const QSize &video_dim_buf,
         StopEmbedding();
     }
 
-    if (!codec_is_std(av_codec_id) && !codec_is_mediacodec(av_codec_id))
+    if (!codec_is_std(av_codec_id)
+        && !codec_is_mediacodec(av_codec_id)
+        && !codec_is_vaapi2(av_codec_id))
     {
         LOG(VB_GENERAL, LOG_ERR, LOC + "New video codec is not supported.");
         errorState = kError_Unknown;
@@ -741,7 +745,8 @@ QStringList VideoOutputOpenGL::GetAllowedRenderers(
     {
         list << "opengl" << "opengl-lite";
     }
-    else if (codec_is_mediacodec(myth_codec_id) && !getenv("NO_OPENGL"))
+    else if ((codec_is_mediacodec(myth_codec_id) || codec_is_vaapi2(myth_codec_id))
+            && !getenv("NO_OPENGL"))
     {
         list << "opengl";
     }
