diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
index f1be8af2cd..1a895800a6 100644
--- a/libavcodec/hevcdec.c
+++ b/libavcodec/hevcdec.c
@@ -481,11 +481,19 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)
 #endif
     case AV_PIX_FMT_YUV420P12:
     case AV_PIX_FMT_YUV444P12:
+#if CONFIG_HEVC_VAAPI_HWACCEL
+       *fmt++ = AV_PIX_FMT_VAAPI;
+#endif
 #if CONFIG_HEVC_VDPAU_HWACCEL
         *fmt++ = AV_PIX_FMT_VDPAU;
 #endif
 #if CONFIG_HEVC_NVDEC_HWACCEL
         *fmt++ = AV_PIX_FMT_CUDA;
+#endif
+        break;
+    case AV_PIX_FMT_YUV422P12:
+#if CONFIG_HEVC_VAAPI_HWACCEL
+       *fmt++ = AV_PIX_FMT_VAAPI;
 #endif
         break;
     }
diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c
index bc2d3ed803..9ba7dfd886 100644
--- a/libavcodec/vaapi_decode.c
+++ b/libavcodec/vaapi_decode.c
@@ -262,16 +262,28 @@ static const struct {
     MAP(YUY2, YUYV422),
 #ifdef VA_FOURCC_Y210
     MAP(Y210,    Y210),
+#endif
+#ifdef VA_FOURCC_Y216
+    MAP(Y216,    Y216),
 #endif
     // 4:4:0
     MAP(422V, YUV440P),
     // 4:4:4
     MAP(444P, YUV444P),
     MAP(AYUV, VUYA),
+#ifdef VA_FOURCC_Y410
+    MAP(Y410,    Y410),
+#endif
+#ifdef VA_FOURCC_Y416
+    MAP(Y416,    Y416),
+#endif
     // 4:2:0 10-bit
 #ifdef VA_FOURCC_P010
     MAP(P010, P010),
 #endif
+#ifdef VA_FOURCC_P016
+    MAP(P016, P016),
+#endif
 #ifdef VA_FOURCC_I010
     MAP(I010, YUV420P10),
 #endif
@@ -415,6 +427,7 @@ static const struct {
 #if VA_CHECK_VERSION(0, 39, 0)
     MAP(VP9,         VP9_1,           VP9Profile1 ),
     MAP(VP9,         VP9_2,           VP9Profile2 ),
+    MAP(VP9,         VP9_3,           VP9Profile3 ),
 #endif
 #if VA_CHECK_VERSION(1, 8, 0)
     MAP(AV1,         AV1_MAIN,        AV1Profile0),
diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index f13daa5cff..3e6252ad4a 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -1305,7 +1305,11 @@ static const VAAPIEncodeRTFormat vaapi_encode_rt_formats[] = {
     { "YUV420",    VA_RT_FORMAT_YUV420,        8, 3, 1, 1 },
     { "YUV422",    VA_RT_FORMAT_YUV422,        8, 3, 1, 0 },
 #if VA_CHECK_VERSION(1, 2, 0)
+    { "YUV420_12", VA_RT_FORMAT_YUV420_12,    12, 3, 1, 1 },
     { "YUV422_10", VA_RT_FORMAT_YUV422_10,    10, 3, 1, 0 },
+    { "YUV422_12", VA_RT_FORMAT_YUV422_12,    12, 3, 1, 0 },
+    { "YUV444_10", VA_RT_FORMAT_YUV444_10,    10, 4, 0, 0 },
+    { "YUV444_12", VA_RT_FORMAT_YUV444_12,    12, 4, 0, 0 },
 #endif
     { "YUV444",    VA_RT_FORMAT_YUV444,        8, 3, 0, 0 },
     { "AYUV",      VA_RT_FORMAT_YUV444,        8, 4, 0, 0 },
@@ -1342,7 +1346,7 @@ static av_cold int vaapi_encode_profile_entrypoint(AVCodecContext *avctx)
     VAConfigAttrib rt_format_attr;
     const VAAPIEncodeRTFormat *rt_format;
     const char *profile_string, *entrypoint_string;
-    int i, j, n, depth, err;
+    int i, j, n, depth, logical_depth, err;
 
 
     if (ctx->low_power) {
@@ -1365,7 +1369,9 @@ static av_cold int vaapi_encode_profile_entrypoint(AVCodecContext *avctx)
     }
     depth = desc->comp[0].depth;
     for (i = 1; i < desc->nb_components; i++) {
-        if (desc->comp[i].depth != depth) {
+        // We do not apply this depth requirement to the fourth component as
+        // that will be the alpha channel when present, which can be smaller.
+        if (i < 3 && desc->comp[i].depth != depth) {
             av_log(avctx, AV_LOG_ERROR, "Invalid input pixfmt (%s).\n",
                    desc->name);
             return AVERROR(EINVAL);
@@ -1391,8 +1397,10 @@ static av_cold int vaapi_encode_profile_entrypoint(AVCodecContext *avctx)
     av_assert0(ctx->codec->profiles);
     for (i = 0; (ctx->codec->profiles[i].av_profile !=
                  FF_PROFILE_UNKNOWN); i++) {
+
         profile = &ctx->codec->profiles[i];
-        if (depth               != profile->depth ||
+        logical_depth = profile->depth > 10 ? 16 : profile->depth;
+        if (depth               != logical_depth ||
             desc->nb_components != profile->nb_components)
             continue;
         if (desc->nb_components > 1 &&
@@ -1476,7 +1484,8 @@ static av_cold int vaapi_encode_profile_entrypoint(AVCodecContext *avctx)
 
     for (i = 0; i < FF_ARRAY_ELEMS(vaapi_encode_rt_formats); i++) {
         rt_format = &vaapi_encode_rt_formats[i];
-        if (rt_format->depth         == depth &&
+        logical_depth = rt_format->depth > 10 ? 16 : rt_format->depth;
+        if (logical_depth            == depth &&
             rt_format->nb_components == profile->nb_components &&
             rt_format->log2_chroma_w == profile->log2_chroma_w &&
             rt_format->log2_chroma_h == profile->log2_chroma_h)
diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c
index 1de323af78..1a65fb9ebf 100644
--- a/libavcodec/vaapi_encode_h265.c
+++ b/libavcodec/vaapi_encode_h265.c
@@ -283,7 +283,9 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
             return AVERROR(EINVAL);
         }
     }
-    bit_depth = desc->comp[0].depth;
+    // Bit depth must be taken from the profile, as the pixel format will be
+    // 16bit for >= 12bit content.
+    bit_depth = ctx->profile->depth;
 
 
     // VPS
@@ -1276,10 +1278,14 @@ static const VAAPIEncodeProfile vaapi_encode_h265_profiles[] = {
     { FF_PROFILE_HEVC_REXT,    10, 3, 1, 1, VAProfileHEVCMain10     },
 #endif
 #if VA_CHECK_VERSION(1, 2, 0)
+    { FF_PROFILE_HEVC_REXT,    12, 3, 1, 1, VAProfileHEVCMain12 },
     { FF_PROFILE_HEVC_REXT,     8, 3, 1, 0, VAProfileHEVCMain422_10 },
     { FF_PROFILE_HEVC_REXT,    10, 3, 1, 0, VAProfileHEVCMain422_10 },
-    // Four channels because this uses the AYUV format which has Alpha
+    { FF_PROFILE_HEVC_REXT,    12, 3, 1, 0, VAProfileHEVCMain422_12 },
+    // Four channels because these use formats which have Alpha
     { FF_PROFILE_HEVC_REXT,     8, 4, 0, 0, VAProfileHEVCMain444 },
+    { FF_PROFILE_HEVC_REXT,    10, 4, 0, 0, VAProfileHEVCMain444_10 },
+    { FF_PROFILE_HEVC_REXT,    12, 4, 0, 0, VAProfileHEVCMain444_12 },
 #endif
     { FF_PROFILE_UNKNOWN }
 };
diff --git a/libavcodec/vaapi_encode_vp9.c b/libavcodec/vaapi_encode_vp9.c
index 9b455e10c9..e6c7f01f11 100644
--- a/libavcodec/vaapi_encode_vp9.c
+++ b/libavcodec/vaapi_encode_vp9.c
@@ -228,9 +228,11 @@ static av_cold int vaapi_encode_vp9_configure(AVCodecContext *avctx)
 
 static const VAAPIEncodeProfile vaapi_encode_vp9_profiles[] = {
     { FF_PROFILE_VP9_0,  8, 3, 1, 1, VAProfileVP9Profile0 },
-    // Four channels because this uses the AYUV format which has Alpha
+    // Four channels because this uses a format which has Alpha
     { FF_PROFILE_VP9_1,  8, 4, 0, 0, VAProfileVP9Profile1 },
     { FF_PROFILE_VP9_2, 10, 3, 1, 1, VAProfileVP9Profile2 },
+    // Four channels because this uses a format which has Alpha
+    { FF_PROFILE_VP9_3, 10, 4, 0, 0, VAProfileVP9Profile3 },
     { FF_PROFILE_UNKNOWN }
 };
 
diff --git a/libavcodec/vaapi_hevc.c b/libavcodec/vaapi_hevc.c
index d82975979a..20fb36adfa 100644
--- a/libavcodec/vaapi_hevc.c
+++ b/libavcodec/vaapi_hevc.c
@@ -567,15 +567,24 @@ VAProfile ff_vaapi_parse_hevc_rext_profile(AVCodecContext *avctx)
     }
 
 #if VA_CHECK_VERSION(1, 2, 0)
-    if (!strcmp(profile->name, "Main 4:2:2 10") ||
+    if (!strcmp(profile->name, "Main 12") ||
+        !strcmp(profile->name, "Main 12 Intra"))
+        return VAProfileHEVCMain12;
+    else if (!strcmp(profile->name, "Main 4:2:2 10") ||
         !strcmp(profile->name, "Main 4:2:2 10 Intra"))
         return VAProfileHEVCMain422_10;
+    else if (!strcmp(profile->name, "Main 4:2:2 12") ||
+        !strcmp(profile->name, "Main 4:2:2 12 Intra"))
+        return VAProfileHEVCMain422_12;
     else if (!strcmp(profile->name, "Main 4:4:4") ||
              !strcmp(profile->name, "Main 4:4:4 Intra"))
         return VAProfileHEVCMain444;
     else if (!strcmp(profile->name, "Main 4:4:4 10") ||
              !strcmp(profile->name, "Main 4:4:4 10 Intra"))
         return VAProfileHEVCMain444_10;
+    else if (!strcmp(profile->name, "Main 4:4:4 12") ||
+             !strcmp(profile->name, "Main 4:4:4 12 Intra"))
+        return VAProfileHEVCMain444_12;
 #else
     av_log(avctx, AV_LOG_WARNING, "HEVC profile %s is "
            "not supported with this VA version.\n", profile->name);
diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index 2ee5145727..c3e79907fd 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -121,6 +121,9 @@ static const VAAPIFormatDescriptor vaapi_format_map[] = {
     MAP(YUY2, YUV422,  YUYV422, 0),
 #ifdef VA_FOURCC_Y210
     MAP(Y210, YUV422_10,  Y210, 0),
+#endif
+#ifdef VA_FOURCC_Y216
+    MAP(Y216, YUV422_12,  Y216, 0),
 #endif
     MAP(411P, YUV411,  YUV411P, 0),
     MAP(422V, YUV422,  YUV440P, 0),
@@ -129,6 +132,9 @@ static const VAAPIFormatDescriptor vaapi_format_map[] = {
     MAP(Y800, YUV400,  GRAY8,   0),
 #ifdef VA_FOURCC_P010
     MAP(P010, YUV420_10BPP, P010, 0),
+#endif
+#ifdef VA_FOURCC_P016
+    MAP(P016, YUV420_12, P016, 0),
 #endif
     MAP(BGRA, RGB32,   BGRA, 0),
     MAP(BGRX, RGB32,   BGR0, 0),
@@ -143,6 +149,12 @@ static const VAAPIFormatDescriptor vaapi_format_map[] = {
 #ifdef VA_FOURCC_X2R10G10B10
     MAP(X2R10G10B10, RGB32_10, X2RGB10, 0),
 #endif
+#ifdef VA_FOURCC_Y410
+    MAP(Y410, YUV444_10,  Y410, 0),
+#endif
+#ifdef VA_FOURCC_Y416
+    MAP(Y416, YUV444_12,  Y416, 0),
+#endif
 };
 #undef MAP
 
