[vlc-devel] [PATCH 8/8] [RFC] avcodec: video: setup the hardware pipeline before ffmpeg_OpenCodec is called on Win32

Steve Lhomme robux4 at videolabs.io
Fri May 5 18:42:24 CEST 2017


This way we can disable multithreading when hardware decoding is used.

Fixes #18261
---
 modules/codec/avcodec/video.c | 64 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c
index ef2045c39b..245ead392b 100644
--- a/modules/codec/avcodec/video.c
+++ b/modules/codec/avcodec/video.c
@@ -529,6 +529,70 @@ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context,
         //FIXME: take in count the decoding time
         i_thread_count = __MIN( i_thread_count, p_codec->id == AV_CODEC_ID_HEVC ? 6 : 4 );
     }
+#ifdef _WIN32
+    char *psz_codec;
+    switch( p_codec->id )
+    {
+        /* all DXVA supported codecs, keep in sync with directx_va.c */
+        case AV_CODEC_ID_MPEG4:
+        case AV_CODEC_ID_H263:
+        case AV_CODEC_ID_MPEG1VIDEO:
+        case AV_CODEC_ID_MPEG2VIDEO:
+        case AV_CODEC_ID_H264:
+        case AV_CODEC_ID_VC1:
+        case AV_CODEC_ID_WMV3:
+        case AV_CODEC_ID_HEVC:
+        case AV_CODEC_ID_VP9:
+            /* we may use hardware decoding, minimize the number of threads */
+            psz_codec = var_InheritString(p_dec, "avcodec-hw");
+            if (psz_codec) {
+                if (strcasecmp(psz_codec,"none")) {
+                    int err;
+                    enum PixelFormat swfmt;
+                    if ( p_codec->id == AV_CODEC_ID_HEVC &&
+                         p_dec->fmt_in.i_profile == FF_PROFILE_HEVC_MAIN_10)
+                        swfmt = AV_PIX_FMT_YUV420P10LE;
+                    else
+                        swfmt = AV_PIX_FMT_YUV420P;
+
+                    /* create the vout and va early to see if we can use it */
+                    video_format_t fmt_out = p_dec->fmt_in.video;
+                    fmt_out.p_palette = NULL;
+
+                    /* we didn't call ffmpeg_OpenCodec() so we need to guess
+                     * some AVContext values based on the source input */
+                    p_context->width  = fmt_out.i_visible_width;
+                    p_context->height = fmt_out.i_visible_height;
+                    p_context->coded_width  = fmt_out.i_width;
+                    p_context->coded_height = fmt_out.i_height;
+
+                    hwfmt = AV_PIX_FMT_D3D11VA_VLD;
+                    fmt_out.i_chroma = vlc_va_GetChroma(hwfmt, swfmt);
+                    err = SetupHardwareFormat(p_dec, p_context, hwfmt, &fmt_out);
+                    if (err != 0)
+                    {
+                        hwfmt = AV_PIX_FMT_DXVA2_VLD;
+                        fmt_out.i_chroma = vlc_va_GetChroma(hwfmt, swfmt);
+                        err = SetupHardwareFormat(p_dec, p_context, hwfmt, &fmt_out);
+                    }
+                    if (err == 0)
+                    {
+                        /* keep values to init AVContext we what we already have */
+                        i_profile = p_dec->fmt_in.i_profile;
+                        i_level   = p_dec->fmt_in.i_level;
+                        msg_Dbg( p_dec, "disabling threads for hardware decoding" );
+                        i_thread_count = 1;
+                    }
+                    else
+                        hwfmt = AV_PIX_FMT_NONE;
+                }
+                free(psz_codec);
+            }
+            break;
+        default:
+            break;
+    }
+#endif
     i_thread_count = __MIN( i_thread_count, 16 );
     msg_Dbg( p_dec, "allowing %d thread(s) for decoding", i_thread_count );
     p_context->thread_count = i_thread_count;
-- 
2.12.1



More information about the vlc-devel mailing list