]> granicus.if.org Git - handbrake/commitdiff
QSV: port hb_qsv_info to hb_global_init().
authorRodeo <tdskywalker@gmail.com>
Wed, 5 Jun 2013 15:18:30 +0000 (15:18 +0000)
committerRodeo <tdskywalker@gmail.com>
Wed, 5 Jun 2013 15:18:30 +0000 (15:18 +0000)
git-svn-id: svn://svn.handbrake.fr/HandBrake/branches/qsv@5555 b64f7644-9d1e-0410-96f1-a4d463321fa5

libhb/common.c
libhb/decavcodec.c
libhb/enc_qsv.c
libhb/hb.c
libhb/hb.h
libhb/qsv_filter.c
test/test.c

index 8770d73e065b34c7f5bf8dc8ae3fbeb1ded03ffe..074d2a13508adeba6c90dfdc08c57c06f1f3cca8 100644 (file)
@@ -206,9 +206,9 @@ static int hb_video_encoder_is_enabled(int encoder)
 {
     switch (encoder)
     {
-#ifdef USE_QSV // TODO: runtime detection
+#ifdef USE_QSV
         case HB_VCODEC_QSV_H264:
-            return 1;
+            return hb_qsv_available();
 #endif
 
         // the following encoders are always enabled
index edb39ec3f4213ca04ea610cd53bd87cbb79be673..e453a7ed645a839fee6db67aff75adf98341bbad 100644 (file)
@@ -1105,7 +1105,7 @@ static int decavcodecvInit( hb_work_object_t * w, hb_job_t * job )
 
 #ifdef USE_QSV
     if(job){
-        qsv_param_set_defaults(&pv->qsv_config,hb_qsv_info_get(job->h));
+        qsv_param_set_defaults(&pv->qsv_config, hb_qsv_info);
 
         hb_dict_t * qsv_opts = NULL;
         if( job->advanced_opts != NULL && *job->advanced_opts != '\0' )
index 76f434e1baec85b56a4758d3e49cfd46f1c411cf..227d61a9d1431c3429ac9aa4dfde75f6ad7f7e2f 100644 (file)
@@ -27,6 +27,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 \* ********************************************************************* */
 
 #include <stdarg.h>
+#include "hb.h"
 #include "enc_qsv.h"
 #include "h264_common.h"
 
@@ -232,7 +233,7 @@ int qsv_enc_init( av_qsv_context* qsv, hb_work_private_t * pv ){
     AV_QSV_ZERO_MEMORY(qsv_encode->m_mfxVideoParam);
     AV_QSV_ZERO_MEMORY(qsv_encode->m_mfxVideoParam.mfx);
 
-    qsv_param_set_defaults(&pv->qsv_config,hb_qsv_info_get(job->h));
+    qsv_param_set_defaults(&pv->qsv_config, hb_qsv_info);
 
     hb_dict_t *qsv_opts_dict = NULL;
     if( job->advanced_opts != NULL && *job->advanced_opts != '\0' )
@@ -347,7 +348,7 @@ int qsv_enc_init( av_qsv_context* qsv, hb_work_private_t * pv ){
     }
 
     // version-specific encoder options
-    if( hb_qsv_info_get(job->h)->features & HB_QSV_FEATURE_CODEC_OPTIONS_2 )
+    if (hb_qsv_info->features & HB_QSV_FEATURE_CODEC_OPTIONS_2)
     {
         if ((entry = hb_dict_get(qsv_opts_dict, QSV_NAME_mbbrc)) != NULL && entry->value != NULL)
         {
@@ -898,14 +899,14 @@ int encqsvWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
 
                 av_qsv_dts *cur_dts = av_qsv_list_item(qsv->dts_seq,0);
 
-                //start -> PTS
-                //renderOffset -> DTS
+                // start        -> PTS
+                // renderOffset -> DTS
                 buf->s.start = task->bs->TimeStamp;
                 buf->s.stop  = task->bs->TimeStamp + duration;
-                if( hb_qsv_info_get(job->h)->features & HB_QSV_FEATURE_DECODE_TIMESTAMPS )
+                if (hb_qsv_info->features & HB_QSV_FEATURE_DECODE_TIMESTAMPS)
                     buf->s.renderOffset = task->bs->DecodeTimeStamp;
                 else
-                buf->s.renderOffset = cur_dts? cur_dts->dts : 0;
+                    buf->s.renderOffset = cur_dts != NULL ? cur_dts->dts : 0;
 
                 if(pv->qsv_config.gop_ref_dist > 1)
                     pv->qsv_config.gop_ref_dist--;
index ce603117d2ca0a256bfd57dcd18df567e9f428e7..7d999a51d99589f7ab3a02c8b3eb5d87e329bc26 100644 (file)
@@ -67,12 +67,7 @@ struct hb_handle_s
 
     // power management opaque pointer
     void *system_sleep_opaque;
-
-#ifdef USE_QSV
-    // detailed information about Intel QSV availability
-    hb_qsv_info_t qsv_info;
-#endif
-} ;
+};
 
 hb_work_object_t * hb_objects = NULL;
 int hb_instance_counter = 0;
@@ -352,6 +347,9 @@ void hb_ff_set_sample_fmt(AVCodecContext *context, AVCodec *codec,
 
 /* Intel Quick Sync Video utilities */
 #ifdef USE_QSV
+// make the Intel QSV information available to the UIs
+hb_qsv_info_t *hb_qsv_info = NULL;
+
 // minimum supported version (currently 1.4, for Sandy Bridge support)
 // let's keep this independent of what Libav can do for decode
 #define HB_QSV_MINVERSION_MAJOR 1
@@ -359,58 +357,64 @@ void hb_ff_set_sample_fmt(AVCodecContext *context, AVCodec *codec,
 
 // check available hardware & software versions against a minimum
 #define HB_QSV_MIN_HARDWARE(MAJOR, MINOR)           \
-    ((qsv_info->hardware_version.Major >  MAJOR) || \
-     (qsv_info->hardware_version.Major == MAJOR  && qsv_info->hardware_version.Minor >= MINOR))
+    ((hb_qsv_info->hardware_version.Major >  MAJOR) || \
+     (hb_qsv_info->hardware_version.Major == MAJOR  && hb_qsv_info->hardware_version.Minor >= MINOR))
 #define HB_QSV_MIN_SOFTWARE(MAJOR, MINOR)           \
-    ((qsv_info->software_version.Major >  MAJOR) || \
-     (qsv_info->software_version.Major == MAJOR  && qsv_info->software_version.Minor >= MINOR))
+    ((hb_qsv_info->software_version.Major >  MAJOR) || \
+     (hb_qsv_info->software_version.Major == MAJOR  && hb_qsv_info->software_version.Minor >= MINOR))
 
-hb_qsv_info_t* hb_qsv_info_get(hb_handle_t *h)
+static int hb_qsv_info_init()
 {
-    return &h->qsv_info;
-}
+    static int init_done = 0;
+    if (init_done)
+        return (hb_qsv_info == NULL);
+    init_done = 1;
+
+    hb_qsv_info = malloc(sizeof(*hb_qsv_info));
+    if (hb_qsv_info == NULL)
+    {
+        hb_error("hb_qsv_info_init: malloc failure");
+        return -1;
+    }
 
-// TODO: move usage of this outside of handle and into global init when possible
-static void hb_qsv_info_init(hb_qsv_info_t *qsv_info)
-{
     mfxSession session;
-    qsv_info->features              = 0;
-    qsv_info->minimum_version.Major = HB_QSV_MINVERSION_MAJOR;
-    qsv_info->minimum_version.Minor = HB_QSV_MINVERSION_MINOR;
-    qsv_info->software_available    = qsv_info->hardware_available = 0;
+    hb_qsv_info->features              = 0;
+    hb_qsv_info->minimum_version.Major = HB_QSV_MINVERSION_MAJOR;
+    hb_qsv_info->minimum_version.Minor = HB_QSV_MINVERSION_MINOR;
+    hb_qsv_info->software_available    = hb_qsv_info->hardware_available = 0;
 
     // check for software fallback
-    if (MFXInit(MFX_IMPL_SOFTWARE, &qsv_info->minimum_version, &session) ==
-        MFX_ERR_NONE)
+    if (MFXInit(MFX_IMPL_SOFTWARE,
+                &hb_qsv_info->minimum_version, &session) == MFX_ERR_NONE)
     {
-        qsv_info->software_available = 1;
+        hb_qsv_info->software_available = 1;
         // our minimum is supported, but query the actual version
-        MFXQueryVersion(session , &qsv_info->software_version);
+        MFXQueryVersion(session, &hb_qsv_info->software_version);
         MFXClose(session);
     }
 
     // check for actual hardware support, Hardware acceleration via any supported OS infrastructure
-    if (MFXInit(MFX_IMPL_HARDWARE_ANY | MFX_IMPL_VIA_ANY, &qsv_info->minimum_version, &session) ==
-        MFX_ERR_NONE)
+    if (MFXInit(MFX_IMPL_HARDWARE_ANY|MFX_IMPL_VIA_ANY,
+                &hb_qsv_info->minimum_version, &session) == MFX_ERR_NONE)
     {
-        qsv_info->hardware_available = 1;
+        hb_qsv_info->hardware_available = 1;
         // our minimum is supported, but query the actual version
-        MFXQueryVersion(session , &qsv_info->hardware_version);
+        MFXQueryVersion(session, &hb_qsv_info->hardware_version);
         MFXClose(session);
     }
 
     // support either implementation (at least for now)
-    qsv_info->qsv_available = (qsv_info->hardware_available ||
-                               qsv_info->software_available);
+    hb_qsv_info->qsv_available = (hb_qsv_info->hardware_available ||
+                                  hb_qsv_info->software_available);
 
     // check for version-dependent features
     if (HB_QSV_MIN_SOFTWARE(1, 6) || HB_QSV_MIN_HARDWARE(1, 6))
     {
-        qsv_info->features |= HB_QSV_FEATURE_DECODE_TIMESTAMPS;
-        qsv_info->features |= HB_QSV_FEATURE_CODEC_OPTIONS_2;
+        hb_qsv_info->features |= HB_QSV_FEATURE_DECODE_TIMESTAMPS;
+        hb_qsv_info->features |= HB_QSV_FEATURE_CODEC_OPTIONS_2;
     }
 
-    if( av_get_cpu_flags() & AV_CPU_FLAG_SSE )
+    if (av_get_cpu_flags() & AV_CPU_FLAG_SSE)
     {
         int eax, ebx, ecx, edx;
         int family = 0, model = 0;
@@ -420,43 +424,68 @@ static void hb_qsv_info_init(hb_qsv_info_t *qsv_info)
         model  = ((eax >> 4) & 0xf) + ((eax >> 12) & 0xf0);
 
         ff_cpu_cpuid(0x80000000, &eax, &ebx, &ecx, &edx);
-        if( (eax & 0x80000004) < 0x80000004 )
+        if ((eax & 0x80000004) < 0x80000004)
         {
             int offset = 0;
-            ff_cpu_cpuid(0x80000002, &qsv_info->cpu_name[offset], &qsv_info->cpu_name[offset+4], &qsv_info->cpu_name[offset+8], &qsv_info->cpu_name[offset+12]);
+            ff_cpu_cpuid(0x80000002,
+                         &hb_qsv_info->cpu_name[offset],
+                         &hb_qsv_info->cpu_name[offset+4],
+                         &hb_qsv_info->cpu_name[offset+8],
+                         &hb_qsv_info->cpu_name[offset+12]);
             offset += 16;
-            ff_cpu_cpuid(0x80000003, &qsv_info->cpu_name[offset], &qsv_info->cpu_name[offset+4], &qsv_info->cpu_name[offset+8], &qsv_info->cpu_name[offset+12]);
+            ff_cpu_cpuid(0x80000003,
+                         &hb_qsv_info->cpu_name[offset],
+                         &hb_qsv_info->cpu_name[offset+4],
+                         &hb_qsv_info->cpu_name[offset+8],
+                         &hb_qsv_info->cpu_name[offset+12]);
             offset += 16;
-            ff_cpu_cpuid(0x80000004, &qsv_info->cpu_name[offset], &qsv_info->cpu_name[offset+4], &qsv_info->cpu_name[offset+8], &qsv_info->cpu_name[offset+12]);
+            ff_cpu_cpuid(0x80000004,
+                         &hb_qsv_info->cpu_name[offset],
+                         &hb_qsv_info->cpu_name[offset+4],
+                         &hb_qsv_info->cpu_name[offset+8],
+                         &hb_qsv_info->cpu_name[offset+12]);
         }
 
-        // Intel 64 and IA-32 Architectures Software Developer\92s Manual
+        // Intel 64 and IA-32 Architectures Software Developer's Manual
         // Table 35-1. CPUID Signature Values of DisplayFamily_DisplayModel
-        if( family == 0x06 )
-            if( model == 0x3C ||
-                model == 0x45 )
-                qsv_info->cpu_details = HB_CPU_PLATFORM_INTEL_HSW;
-
-        if( family == 0x06 )
-            if( model == 0x3A ||
-                model == 0x3E )
-                qsv_info->cpu_details = HB_CPU_PLATFORM_INTEL_IVB;
-
-        if( family == 0x06 )
-            if( model == 0x2A ||
-                model == 0x2D )
-                qsv_info->cpu_details = HB_CPU_PLATFORM_INTEL_SNB;
+        if (family == 0x06)
+        {
+            switch (model)
+            {
+                case 0x2A:
+                case 0x2D:
+                    hb_qsv_info->cpu_platform = HB_CPU_PLATFORM_INTEL_SNB;
+                    break;
+
+                case 0x3A:
+                case 0x3E:
+                    hb_qsv_info->cpu_platform = HB_CPU_PLATFORM_INTEL_IVB;
+                    break;
+
+                case 0x3C:
+                case 0x45:
+                    hb_qsv_info->cpu_platform = HB_CPU_PLATFORM_INTEL_HSW;
+                    break;
+
+                default:
+                    hb_qsv_info->cpu_platform = HB_CPU_PLATFORM_UNSPECIFIED;
+                    break;
+            }
+        }
     }
 
     // note: we pass a pointer to MFXInit but it never gets modified
     //       let's make sure of it just to be safe though
-    if (qsv_info->minimum_version.Major != HB_QSV_MINVERSION_MAJOR ||
-        qsv_info->minimum_version.Minor != HB_QSV_MINVERSION_MINOR)
+    if (hb_qsv_info->minimum_version.Major != HB_QSV_MINVERSION_MAJOR ||
+        hb_qsv_info->minimum_version.Minor != HB_QSV_MINVERSION_MINOR)
     {
         hb_error("hb_qsv_info_init: minimum version (%d.%d) was modified",
-                 qsv_info->minimum_version.Major,
-                 qsv_info->minimum_version.Minor);
+                 hb_qsv_info->minimum_version.Major,
+                 hb_qsv_info->minimum_version.Minor);
     }
+
+    // success
+    return 0;
 }
 
 // we don't need those beyond this point
@@ -464,6 +493,68 @@ static void hb_qsv_info_init(hb_qsv_info_t *qsv_info)
 #undef HB_QSV_MINVERSION_MINOR
 #undef HB_QSV_MIN_HARDWARE
 #undef HB_QSV_MIN_SOFTWARE
+
+static void hb_qsv_info_print()
+{
+    if (hb_qsv_info == NULL)
+        return;
+
+    // is QSV available?
+    hb_log("Intel Quick Sync Video support: %s",
+           hb_qsv_info->qsv_available ? "yes": "no");
+    // print the hardware summary too
+    switch (hb_qsv_info->cpu_platform)
+    {
+        case HB_CPU_PLATFORM_INTEL_SNB:
+            hb_log(" - 2nd gen. Intel Core processor");
+            break;
+
+        case HB_CPU_PLATFORM_INTEL_IVB:
+            hb_log(" - 3rd gen. Intel Core processor");
+            break;
+
+        case HB_CPU_PLATFORM_INTEL_HSW:
+            hb_log(" - 4th gen. Intel Core processor");
+            break;
+
+        default:
+            break;
+    }
+
+    // skip leading whitespace to prettify
+    char *cpu_name = hb_qsv_info->cpu_name;
+    while (isspace(*cpu_name))
+    {
+        cpu_name++;
+    }
+    hb_log(" - hardware name:    %s", cpu_name);
+
+    // if we have Quick Sync Video support, also print the details
+    if (hb_qsv_info->qsv_available)
+    {
+        if (hb_qsv_info->hardware_available)
+        {
+            hb_log(" - hardware version: %d.%d (minimum: %d.%d)",
+                   hb_qsv_info->hardware_version.Major,
+                   hb_qsv_info->hardware_version.Minor,
+                   hb_qsv_info->minimum_version.Major,
+                   hb_qsv_info->minimum_version.Minor);
+        }
+        if (hb_qsv_info->software_available)
+        {
+            hb_log(" - software version: %d.%d (minimum: %d.%d)",
+                   hb_qsv_info->software_version.Major,
+                   hb_qsv_info->software_version.Minor,
+                   hb_qsv_info->minimum_version.Major,
+                   hb_qsv_info->minimum_version.Minor);
+        }
+    }
+}
+
+int hb_qsv_available()
+{
+    return hb_qsv_info != NULL && hb_qsv_info->qsv_available;
+}
 #endif // USE_QSV
 
 /**
@@ -561,6 +652,11 @@ hb_handle_t * hb_init( int verbose, int update_check )
     /* libavcodec */
     hb_avcodec_init();
 
+#ifdef USE_QSV
+    /* Intel Quick Sync Video */
+    hb_qsv_info_print();
+#endif
+
     /* Start library thread */
     hb_log( "hb_init: starting libhb thread" );
     h->die         = 0;
@@ -581,7 +677,6 @@ hb_handle_t * hb_init( int verbose, int update_check )
        hb_register( &hb_encx264 );
 #ifdef USE_QSV
     hb_register(&hb_encqsv);
-    hb_qsv_info_init(&h->qsv_info);
 #endif
     hb_register( &hb_enctheora );
        hb_register( &hb_deca52 );
@@ -666,6 +761,11 @@ hb_handle_t * hb_init_dl( int verbose, int update_check )
     /* libavcodec */
     hb_avcodec_init();
 
+#ifdef USE_QSV
+    /* Intel Quick Sync Video */
+    hb_qsv_info_print();
+#endif
+
     /* Start library thread */
     hb_log( "hb_init: starting libhb thread" );
     h->die         = 0;
@@ -686,7 +786,6 @@ hb_handle_t * hb_init_dl( int verbose, int update_check )
        hb_register( &hb_encx264 );
 #ifdef USE_QSV
     hb_register(&hb_encqsv);
-    hb_qsv_info_init(&h->qsv_info);
 #endif
     hb_register( &hb_enctheora );
        hb_register( &hb_deca52 );
@@ -1809,7 +1908,16 @@ int hb_global_init()
         hb_error("Platform specific initialization failed!");
         return -1;
     }
-    
+
+#ifdef USE_QSV
+    result = hb_qsv_info_init();
+    if (result < 0)
+    {
+        hb_error("hb_qsv_info_init failed!");
+        return -1;
+    }
+#endif
+
     hb_common_global_init();
 
     return result;
index 9c45853a6fa17862addd6bbf593c9fc995d28878..eca9f0e842e6e298e2b11f0281d9b69e03156430 100644 (file)
@@ -165,24 +165,26 @@ typedef struct hb_qsv_info_s
 #define HB_QSV_FEATURE_DECODE_TIMESTAMPS 0x0000001
 #define HB_QSV_FEATURE_CODEC_OPTIONS_2   0x0000002 // see mfxExtCodingOption2
 
-    // if a feature depend on cpu
-    char    cpu_name[48];
-
-enum
-{
-    // list of microarchitecture codenames
-    HB_CPU_PLATFORM_INTEL_SNB = 1,
-    HB_CPU_PLATFORM_INTEL_IVB,
-    HB_CPU_PLATFORM_INTEL_HSW,
-};
-    int     cpu_details;
+    // if a feature depends on the cpu generation
+    enum
+    {
+        // list of microarchitecture codenames
+        HB_CPU_PLATFORM_UNSPECIFIED = 0,
+        HB_CPU_PLATFORM_INTEL_SNB,
+        HB_CPU_PLATFORM_INTEL_IVB,
+        HB_CPU_PLATFORM_INTEL_HSW,
+    }    cpu_platform;
+    char cpu_name[48];
 
     // TODO: add available decoders, filters, encoders,
     //       maximum decode and encode resolution, etc.
 } hb_qsv_info_t;
 
-/* Get Intel QSV information from the handle, outside of hb.c */
-hb_qsv_info_t* hb_qsv_info_get(hb_handle_t*);
+/* Global Intel QSV information for use by the UIs */
+extern hb_qsv_info_t *hb_qsv_info;
+
+/* Whether QSV is available at all */
+int hb_qsv_available();
 #endif
 
 #ifdef __cplusplus
index f4d4d40ccff9e0b6b82fe1876d738036bfa3b0d6..9b5a5e0f8a34fd69265bdde01a951ac437987419 100644 (file)
@@ -111,7 +111,7 @@ static int filter_init( av_qsv_context* qsv, hb_filter_private_t * pv ){
     av_qsv_add_context_usage(qsv,HAVE_THREADS);
 
 
-    qsv_param_set_defaults(&pv->qsv_config,hb_qsv_info_get(pv->job->h));
+    qsv_param_set_defaults(&pv->qsv_config, hb_qsv_info);
     hb_dict_t * qsv_opts = NULL;
     if( pv->job->advanced_opts != NULL && *pv->job->advanced_opts != '\0' )
         qsv_opts = hb_encopts_to_dict( pv->job->advanced_opts, pv->job->vcodec );
index 7cfabaf8772c5e6896ebfb3b7d64a43febb980a8..5555ab4df7420a6ba00241d2fc61ec6141b3c102 100644 (file)
@@ -670,42 +670,6 @@ static int HandleEvents( hb_handle_t * h )
                 title = hb_list_item( title_set->list_title, 0 );
             }
 
-#ifdef USE_QSV
-            // this is where WinGUI parsing begins
-            hb_qsv_info_t *qsv_info = hb_qsv_info_get(h);
-            // show users (including the WinGUI) whether Quick Sync can be used
-            fprintf(stderr,"- intel quick sync video support: %s\n",
-                    qsv_info->qsv_available ? "yes": "no");
-            // if we have Quick Sync support, also print the details
-            if (qsv_info->qsv_available)
-            {
-                if (qsv_info->hardware_available)
-                {
-                    fprintf(stderr,
-                            "  - hardware version: %d.%d (minimum: %d.%d)\n",
-                            qsv_info->hardware_version.Major,
-                            qsv_info->hardware_version.Minor,
-                            qsv_info->minimum_version.Major,
-                            qsv_info->minimum_version.Minor);
-                }
-                if (qsv_info->software_available)
-                {
-                    fprintf(stderr,
-                            "  - software version: %d.%d (minimum: %d.%d)\n",
-                            qsv_info->software_version.Major,
-                            qsv_info->software_version.Minor,
-                            qsv_info->minimum_version.Major,
-                            qsv_info->minimum_version.Minor);
-                }
-
-                fprintf(stderr,
-                        "  - hardware details: %s%s\n", qsv_info->cpu_name,
-                                                qsv_info->cpu_details == HB_CPU_PLATFORM_INTEL_HSW ?
-                                                "/Fourth Generation Intel Core Processor":
-                                                "" );
-            }
-#endif
-
             if( !titleindex || titlescan )
             {
                 /* Scan-only mode, print infos and exit */
@@ -3076,13 +3040,25 @@ static void ShowHelp()
     }
     if( len )
         fprintf( out, "%s\n", tmp );
-    fprintf( out,
-    "    -x, --encopts <string>  Specify advanced encoder options in the\n"
-    "                            same style as mencoder (x264" );
+    fprintf(out,
+    "    -x, --encopts <string>  Specify advanced encoder options in the\n");
 #ifdef USE_QSV
-        fprintf( out,",QSV");
+if (hb_qsv_available())
+{
+    fprintf(out,
+    "                            same style as mencoder (x264/qsv/ffmpeg only):");
+}
+else
+{
+    fprintf(out,
+    "                            same style as mencoder (x264 and ffmpeg only):");
+}
+#else
+    fprintf(out,
+    "                            same style as mencoder (x264 and ffmpeg only):");
 #endif
-    fprintf( out," and ffmpeg only):\n"
+    
+    fprintf(out,
     "                            option1=value1:option2=value2\n"
     "        --h264-profile      When using x264, ensures compliance with the\n"
     "          <string>          specified H.264 profile:\n"
@@ -3341,7 +3317,10 @@ static void ShowHelp()
      "    -d, --deinterlace       Deinterlace video with Libav, yadif or mcdeint\n"
      "          <fast/slow/slower/bob");
 #ifdef USE_QSV
-     fprintf( out,"/qsv");
+if (hb_qsv_available())
+{
+    fprintf(out, "/qsv");
+}
 #endif
      fprintf( out, "> or omitted (default settings)\n"
      "           or\n"
@@ -3429,6 +3408,8 @@ static void ShowHelp()
     );
 
 #ifdef USE_QSV
+if (hb_qsv_available())
+{
     fprintf( out,
     "### QSV Options, via --encopts=\"option1=value1:option2=value2\" -----------\n\n"
     "        - target-usage  A range of numbers that indicate trade-offs between\n"
@@ -3446,6 +3427,7 @@ static void ShowHelp()
     "                            If zero, the value is not specified. Default is 4\n"
     "\n"
     );
+}
 #endif
 }