1 /*############################################################################
2   # Copyright (C) 2005 Intel Corporation
3   #
4   # SPDX-License-Identifier: MIT
5   ############################################################################*/
6 
7 #include <regex>
8 #include "mfx_samples_config.h"
9 #include "plugin_utils.h"
10 #include "sample_defs.h"
11 
12 #if defined(_WIN32) || defined(_WIN64)
13     #include <d3d9.h>
14     #include <psapi.h>
15     #include <windows.h>
16     #include "d3d11_allocator.h"
17     #include "d3d_allocator.h"
18 
19 #else
20     #include <stdarg.h>
21     #include "vaapi_allocator.h"
22 #endif
23 
24 #include "sysmem_allocator.h"
25 #include "transcode_utils.h"
26 
27 #include "version.h"
28 
29 #include <algorithm>
30 #include <cctype>
31 #include <cmath>
32 #include <cstdlib>
33 #include <cstring>
34 #include <fstream>
35 #include <iterator>
36 #include <limits>
37 #include <memory>
38 #include <sstream>
39 #include <string>
40 #include <vector>
41 
42 using namespace TranscodingSample;
43 
44 // parsing defines
45 #define IS_SEPARATOR(ch) ((ch) <= ' ' || (ch) == '=')
46 #define VAL_CHECK(val, argIdx, argName)                                                        \
47     {                                                                                          \
48         if (val) {                                                                             \
49             PrintError(MSDK_STRING("Input argument number %d \"%s\" require more parameters"), \
50                        argIdx,                                                                 \
51                        argName);                                                               \
52             return MFX_ERR_UNSUPPORTED;                                                        \
53         }                                                                                      \
54     }
55 
56 #define SIZE_CHECK(cond)                                    \
57     {                                                       \
58         if (cond) {                                         \
59             PrintError(MSDK_STRING("Buffer is too small")); \
60             return MFX_ERR_UNSUPPORTED;                     \
61         }                                                   \
62     }
63 
64 #ifndef MFX_VERSION
65     #error MFX_VERSION not defined
66 #endif
67 
GetTick()68 msdk_tick TranscodingSample::GetTick() {
69     return msdk_time_get_tick();
70 }
71 
GetTime(msdk_tick start)72 mfxF64 TranscodingSample::GetTime(msdk_tick start) {
73     static msdk_tick frequency = msdk_time_get_frequency();
74 
75     return MSDK_GET_TIME(msdk_time_get_tick(), start, frequency);
76 }
77 
PrintError(const msdk_char * strErrorMessage,...)78 void TranscodingSample::PrintError(const msdk_char* strErrorMessage, ...) {
79     if (strErrorMessage) {
80         msdk_printf(MSDK_STRING("ERROR: "));
81         va_list args;
82         va_start(args, strErrorMessage);
83         msdk_vprintf(strErrorMessage, args);
84         va_end(args);
85         msdk_printf(
86             MSDK_STRING("\nUsage: sample_multi_transcode [options] [--] pipeline-description\n"));
87         msdk_printf(MSDK_STRING("   or: sample_multi_transcode [options] -par ParFile\n"));
88         msdk_printf(MSDK_STRING("\n"));
89         msdk_printf(MSDK_STRING("Run application with -? option to get full help text.\n\n"));
90     }
91 }
92 
PrintHelp()93 void TranscodingSample::PrintHelp() {
94     msdk_printf(MSDK_STRING("Multi Transcoding Sample Version %s\n\n"),
95                 GetMSDKSampleVersion().c_str());
96     msdk_printf(MSDK_STRING("Command line parameters\n"));
97 
98     msdk_printf(MSDK_STRING("Usage: sample_multi_transcode [options] [--] pipeline-description\n"));
99     msdk_printf(MSDK_STRING("   or: sample_multi_transcode [options] -par ParFile\n"));
100     msdk_printf(MSDK_STRING("\n"));
101     msdk_printf(MSDK_STRING("  -stat <N>\n"));
102     msdk_printf(MSDK_STRING("                Output statistic every N transcoding cycles\n"));
103     msdk_printf(MSDK_STRING("  -stat-log <name>\n"));
104     msdk_printf(MSDK_STRING(
105         "                Output statistic to the specified file (opened in append mode)\n"));
106     msdk_printf(MSDK_STRING("  -stat-per-frame <name>\n"));
107     msdk_printf(MSDK_STRING(
108         "                Output per-frame latency values to a file (opened in append mode). The file name will be for an input sesssion: <name>_input_ID_<N>.log\n"));
109     msdk_printf(MSDK_STRING(
110         "                or, for output session: <name>_output_ID_<N>.log; <N> - a number of a session.\n"));
111 
112     msdk_printf(MSDK_STRING("Options:\n"));
113     //                     ("  ............xx
114     msdk_printf(MSDK_STRING("  -?            Print this help and exit\n"));
115     msdk_printf(MSDK_STRING("  -p <file-name>\n"));
116     msdk_printf(MSDK_STRING("                Collect performance statistics in specified file\n"));
117     msdk_printf(MSDK_STRING("  -timeout <seconds>\n"));
118     msdk_printf(MSDK_STRING("                Set time to run transcoding in seconds\n"));
119     msdk_printf(MSDK_STRING("  -greedy \n"));
120     msdk_printf(
121         MSDK_STRING("                Use greedy formula to calculate number of surfaces\n"));
122     msdk_printf(MSDK_STRING("\n"));
123     msdk_printf(MSDK_STRING("Pipeline description (general options):\n"));
124     msdk_printf(MSDK_STRING("  -i::h265|h264|mpeg2|vc1|mvc|jpeg|vp9|av1 <file-name>\n"));
125     msdk_printf(MSDK_STRING("                 Set input file and decoder type\n"));
126     msdk_printf(MSDK_STRING("  -i::i420|nv12 <file-name>\n"));
127     msdk_printf(MSDK_STRING("                 Set raw input file and color format\n"));
128     msdk_printf(MSDK_STRING(
129         "  -i::rgb4_frame Set input rgb4 file for compositon. File should contain just one single frame (-vpp_comp_src_h and -vpp_comp_src_w should be specified as well).\n"));
130     msdk_printf(MSDK_STRING("  -o::h265|h264|mpeg2|mvc|jpeg|vp9|av1|raw <file-name>|null\n"));
131     msdk_printf(MSDK_STRING("                Set output file and encoder type\n"));
132     msdk_printf(MSDK_STRING(
133         "                \'null\' keyword as file-name disables output file writing \n"));
134     msdk_printf(MSDK_STRING("  -sw|-hw|-hw_d3d11|-hw_d3d9\n"));
135     msdk_printf(MSDK_STRING("                SDK implementation to use: \n"));
136     msdk_printf(MSDK_STRING(
137         "                      -hw - platform-specific on default display adapter (default)\n"));
138     msdk_printf(MSDK_STRING(
139         "                      -hw_d3d11 - platform-specific via d3d11 (d3d11 is default for win)\n"));
140     msdk_printf(MSDK_STRING("                      -hw_d3d9 - platform-specific via d3d9\n"));
141     msdk_printf(MSDK_STRING("                      -sw - software\n"));
142 #if defined(LINUX32) || defined(LINUX64)
143     msdk_printf(MSDK_STRING("   -device /path/to/device - set graphics device for processing\n"));
144     msdk_printf(
145         MSDK_STRING("                              For example: '-device /dev/dri/card0'\n"));
146     msdk_printf(
147         MSDK_STRING("                                           '-device /dev/dri/renderD128'\n"));
148     msdk_printf(MSDK_STRING(
149         "                              If not specified, defaults to the first Intel device found on the system\n"));
150 #endif
151 #if (defined(_WIN64) || defined(_WIN32))
152     msdk_printf(MSDK_STRING(
153         "   [-dual_gfx::<on,off,adaptive>] - prefer encode processing on both iGfx and dGfx simultaneously\n"));
154 #endif
155 #ifdef ONEVPL_EXPERIMENTAL
156     #if (defined(_WIN64) || defined(_WIN32))
157     msdk_printf(MSDK_STRING("   -luid <HighPart:LowPart> - setup adapter by LUID  \n"));
158     msdk_printf(MSDK_STRING("                                 For example: \"0x0:0x8a46\"  \n"));
159     #endif
160     msdk_printf(MSDK_STRING("   -pci <domain:bus:device.function> - setup device with PCI \n"));
161     msdk_printf(MSDK_STRING("                                 For example: \"0:3:0.0\"  \n"));
162 #endif
163     msdk_printf(MSDK_STRING(
164         "   [-dGfx] - preffer processing on dGfx (by default system decides), also can be set with index, for example: '-dGfx 1'\n"));
165     msdk_printf(
166         MSDK_STRING("   [-iGfx] - preffer processing on iGfx (by default system decides)\n"));
167     msdk_printf(
168         MSDK_STRING("   [-AdapterNum] - specifies adpter number for processing, starts from 0\n"));
169     msdk_printf(MSDK_STRING(
170         "   [-dispatcher:fullSearch]  - enable search for all available implementations in oneVPL dispatcher\n"));
171     msdk_printf(MSDK_STRING(
172         "  -mfe_frames <N> maximum number of frames to be combined in multi-frame encode pipeline"));
173     msdk_printf(MSDK_STRING("               0 - default for platform will be used\n"));
174     msdk_printf(MSDK_STRING(
175         "  -mfe_mode 0|1|2|3 multi-frame encode operation mode - should be the same for all sessions\n"));
176     msdk_printf(MSDK_STRING(
177         "            0, MFE operates as DEFAULT mode, decided by SDK if MFE enabled\n"));
178     msdk_printf(MSDK_STRING("            1, MFE is disabled\n"));
179     msdk_printf(MSDK_STRING("            2, MFE operates as AUTO mode\n"));
180     msdk_printf(MSDK_STRING("            3, MFE operates as MANUAL mode\n"));
181     msdk_printf(MSDK_STRING(
182         "  -mfe_timeout <N> multi-frame encode timeout in milliseconds - set per sessions control\n"));
183 
184 #ifdef ENABLE_MCTF
185     #if !defined ENABLE_MCTF_EXT
186     msdk_printf(MSDK_STRING("  -mctf [Strength]\n"));
187     msdk_printf(MSDK_STRING("        Strength is an optional value;  it is in range [0...20]\n"));
188     msdk_printf(MSDK_STRING("        value 0 makes MCTF operates in auto mode;\n"));
189     msdk_printf(MSDK_STRING(
190         "        Strength: integer, [0...20]. Default value is 0.Might be a CSV filename (upto 15 symbols); if a string is convertable to an integer, integer has a priority over filename\n"));
191     msdk_printf(MSDK_STRING(
192         "        In fixed-strength mode, MCTF strength can be adjusted at framelevel;\n"));
193     msdk_printf(MSDK_STRING("        If no Strength is given, MCTF operates in auto mode.\n"));
194     #else
195     msdk_printf(MSDK_STRING("  -mctf MctfMode:BitsPerPixel:Strength:ME:Overlap:DB\n"));
196     msdk_printf(MSDK_STRING(
197         "        every parameter may be missed; in this case default value is used.\n"));
198     msdk_printf(MSDK_STRING("        MctfMode: 0 - spatial filter\n"));
199     msdk_printf(MSDK_STRING("        MctfMode: 1- temporal filtering, 1 backward reference\n"));
200     msdk_printf(
201         MSDK_STRING("        MctfMode: 2- temporal filtering, 1 backward & 1 forward reference\n"));
202     msdk_printf(MSDK_STRING(
203         "        MctfMode: 3- temporal filtering, 2 backward & 2 forward references\n"));
204     msdk_printf(MSDK_STRING("        MctfMode:  other values: force default mode to be used\n"));
205     msdk_printf(MSDK_STRING(
206         "        BitsPerPixel: float, valid range [0...12.0]; if exists, is used for automatic filter strength adaptation. Default is 0.0\n"));
207     msdk_printf(MSDK_STRING(
208         "        Strength: integer, [0...20]. Default value is 0.Might be a CSV filename (upto 15 symbols); if a string is convertable to an integer, integer has a priority over filename\n"));
209     msdk_printf(MSDK_STRING(
210         "        ME: Motion Estimation precision; 0 - integer ME (default); 1 - quater-pel ME\n"));
211     msdk_printf(MSDK_STRING(
212         "        Overlap: 0 - do not apply overlap ME (default); 1 - to apply overlap ME\n"));
213     msdk_printf(MSDK_STRING(
214         "        DB: 0 - do not apply deblock Filter (default); 1 - to apply Deblock Filter\n"));
215     #endif //ENABLE_MCTF_EXT
216 #endif //ENABLE_MCTF
217 
218     msdk_printf(MSDK_STRING(
219         "  -robust       Recover from gpu hang errors as they come (by resetting components)\n"));
220     msdk_printf(MSDK_STRING("  -robust:soft  Recover from gpu hang errors by inserting an IDR\n"));
221 
222     msdk_printf(MSDK_STRING("  -async        Depth of asynchronous pipeline. default value 1\n"));
223     msdk_printf(MSDK_STRING(
224         "  -join         Join session with other session(s), by default sessions are not joined\n"));
225     msdk_printf(MSDK_STRING(
226         "  -priority     Use priority for join sessions. 0 - Low, 1 - Normal, 2 - High. Normal by default\n"));
227     msdk_printf(MSDK_STRING("  -threads num  Number of session internal threads to create\n"));
228     msdk_printf(
229         MSDK_STRING("  -n            Number of frames to transcode\n") MSDK_STRING(
230             "                  (session ends after this number of frames is reached). \n")
231             MSDK_STRING(
232                 "                In decoding sessions (-o::sink) this parameter limits number\n")
233                 MSDK_STRING("                   of frames acquired from decoder.\n") MSDK_STRING(
234                     "                In encoding sessions (-o::source) and transcoding sessions \n")
235                     MSDK_STRING(
236                         "                  this parameter limits number of frames sent to encoder.\n"));
237 
238     msdk_printf(
239         MSDK_STRING("  -MemType::video    Force usage of external video allocator (default)\n"));
240     msdk_printf(
241         MSDK_STRING("  -ext_allocator     Force usage of external video allocator (default)\n"));
242     msdk_printf(MSDK_STRING("  -MemType::system   Force usage of external system allocator\n"));
243     msdk_printf(MSDK_STRING("  -sys   Force usage of external system allocator\n"));
244     msdk_printf(MSDK_STRING("  -MemType::opaque   Force usage of internal allocator\n"));
245     msdk_printf(MSDK_STRING("  -MemModel::GeneralAlloc (default)\n"));
246     msdk_printf(MSDK_STRING("        Force usage of:\n"));
247     msdk_printf(
248         MSDK_STRING("              External allocator in the case of video/system memory type\n"));
249     msdk_printf(
250         MSDK_STRING("              Internal allocator in the case of opaque memory type\n"));
251     msdk_printf(MSDK_STRING(
252         "  -MemModel::VisibleIntAlloc   Force usage of internal allocation with manual surfaces control\n"));
253     msdk_printf(MSDK_STRING(
254         "  -MemModel::HiddenIntAlloc    Force usage of internal allocation without manual surfaces control\n"));
255     msdk_printf(MSDK_STRING("  -memory [1/2/3]\n"));
256     msdk_printf(
257         MSDK_STRING("  1 - GeneralAlloc(default), 2 - VisibleIntAlloc, 3 - HiddenIntAlloc \n"));
258     msdk_printf(MSDK_STRING(
259         "  -AllocPolicy::optimal       Force optimal allocation policy for surface pool\n"));
260     msdk_printf(MSDK_STRING(
261         "  -AllocPolicy::limited       Force limited allocation policy for surface pool\n"));
262     msdk_printf(MSDK_STRING(
263         "  -AllocPolicy::unlimited     Force unlimited allocation policy for surface pool\n"));
264     msdk_printf(MSDK_STRING(
265         "  -preallocate <number of surfaces> Set numebr of surfaces to preallocate for -AllocPolicy::limited\n"));
266 
267     msdk_printf(MSDK_STRING("  -dec::sys     Set dec output to system memory\n"));
268     msdk_printf(MSDK_STRING("  -vpp::sys     Set vpp output to system memory\n"));
269     msdk_printf(MSDK_STRING("  -vpp::vid     Set vpp output to video memory\n"));
270     msdk_printf(MSDK_STRING("  -fps <frames per second>\n"));
271     msdk_printf(MSDK_STRING("                Transcoding frame rate limit\n"));
272     msdk_printf(MSDK_STRING("  -pe           Set encoding plugin for this particular session.\n"));
273     msdk_printf(MSDK_STRING(
274         "                This setting overrides plugin settings defined by SET clause.\n"));
275     msdk_printf(MSDK_STRING("  -pd           Set decoding plugin for this particular session.\n"));
276     msdk_printf(MSDK_STRING(
277         "                This setting overrides plugin settings defined by SET clause.\n"));
278     msdk_printf(MSDK_STRING(
279         "                Supported values: hevcd_sw, hevcd_hw, hevce_sw, hevce_gacc, hevce_hw, vp8d_hw, vp8e_hw, vp9d_hw, vp9e_hw, camera_hw, capture_hw, h264_la_hw, ptir_hw, hevce_fei_hw\n"));
280     msdk_printf(MSDK_STRING("                Direct GUID number can be used as well\n"));
281     msdk_printf(MSDK_STRING("\n"));
282     msdk_printf(MSDK_STRING("Pipeline description (encoding options):\n"));
283     MOD_SMT_PRINT_HELP;
284     msdk_printf(MSDK_STRING("  -b <Kbits per second>\n"));
285     msdk_printf(
286         MSDK_STRING("                Encoded bit rate, valid for H.264, MPEG2 and MVC encoders\n"));
287     msdk_printf(MSDK_STRING(
288         "  -bm           Bitrate multiplier. Use it when required bitrate isn't fit into 16-bit\n"));
289     msdk_printf(MSDK_STRING(
290         "                Affects following parameters: InitialDelayInKB, BufferSizeInKB, TargetKbps, MaxKbps\n"));
291     msdk_printf(MSDK_STRING("  -f <frames per second>\n"));
292     msdk_printf(
293         MSDK_STRING("                Video frame rate for the FRC and deinterlace options\n"));
294     msdk_printf(MSDK_STRING("  -fe <frames per second>\n"));
295     msdk_printf(MSDK_STRING(
296         "                Video frame rate for the FRC and deinterlace options (deprecated, will be removed in next versions).\n"));
297     msdk_printf(MSDK_STRING("  -override_decoder_framerate <framerate> \n"));
298     msdk_printf(MSDK_STRING(
299         "                Forces decoder output framerate to be set to provided value (overwriting actual framerate from decoder)\n"));
300     msdk_printf(MSDK_STRING("  -override_encoder_framerate <framerate> \n"));
301     msdk_printf(MSDK_STRING(
302         "                Overwrites framerate of stream going into encoder input with provided value (this option does not enable FRC, it just ovewrites framerate value)\n"));
303     msdk_printf(MSDK_STRING("  -override_encoder_picstruct <picstruct> \n"));
304     msdk_printf(MSDK_STRING("                Overwrites encoder picstruct with specific value\n"));
305     msdk_printf(MSDK_STRING(
306         "  -u <usage>    Target usage. Valid for H.265, H.264, MPEG2 and MVC encoders. Expected values:\n"));
307     msdk_printf(MSDK_STRING(
308         "                veryslow(quality), slower, slow, medium(balanced), fast, faster, veryfast(speed)\n"));
309     msdk_printf(MSDK_STRING(
310         "  -q <quality>  Quality parameter for JPEG encoder; in range [1,100], 100 is the best quality\n"));
311     msdk_printf(MSDK_STRING("  -l numSlices  Number of slices for encoder; default value 0 \n"));
312     msdk_printf(MSDK_STRING("  -mss maxSliceSize \n"));
313     msdk_printf(MSDK_STRING(
314         "                Maximum slice size in bytes. Supported only with -hw and h264 codec. This option is not compatible with -l option.\n"));
315     msdk_printf(MSDK_STRING("  -BitrateLimit:<on,off>\n"));
316     msdk_printf(MSDK_STRING(
317         "                Turn this flag ON to set bitrate limitations imposed by the SDK encoder. Off by default.\n"));
318     msdk_printf(MSDK_STRING(
319         "  -la           Use the look ahead bitrate control algorithm (LA BRC) for H.264 encoder. Supported only with -hw option on 4th Generation Intel Core processors. \n"));
320     msdk_printf(MSDK_STRING(
321         "  -lad depth    Depth parameter for the LA BRC, the number of frames to be analyzed before encoding. In range [0,100] (0 - default: auto-select by mediasdk library).\n"));
322     msdk_printf(
323         MSDK_STRING("                May be 1 in the case when -mss option is specified \n"));
324     msdk_printf(MSDK_STRING(
325         "  -la_ext       Use external LA plugin (compatible with h264 & hevc encoders)\n"));
326     msdk_printf(MSDK_STRING("  -vbr          Variable bitrate control\n"));
327     msdk_printf(MSDK_STRING("  -cbr          Constant bitrate control\n"));
328     msdk_printf(MSDK_STRING("  -vcm          Video Conferencing Mode (VCM) bitrate control\n"));
329     msdk_printf(MSDK_STRING("  -hrd <KBytes> Maximum possible size of any compressed frames \n"));
330     msdk_printf(MSDK_STRING("  -wb <Kbits per second>\n"));
331     msdk_printf(MSDK_STRING("                Maximum bitrate for sliding window\n"));
332     msdk_printf(MSDK_STRING("  -ws           Sliding window size in frames\n"));
333     msdk_printf(MSDK_STRING("  -gop_size     Size of GOP structure in frames \n"));
334     msdk_printf(MSDK_STRING("  -dist         Distance between I- or P- key frames \n"));
335     msdk_printf(MSDK_STRING("  -num_ref      Number of reference frames\n"));
336     msdk_printf(MSDK_STRING("  -bref         Arrange B frames in B pyramid reference structure\n"));
337     msdk_printf(MSDK_STRING(
338         "  -nobref       Do not use B-pyramid (by default the decision is made by library)\n"));
339     msdk_printf(MSDK_STRING("  -bpyr         Enable B pyramid\n"));
340     msdk_printf(
341         MSDK_STRING("  -NumActiveRefP         - Number of active reference frames for P Frames\n"));
342     msdk_printf(
343         MSDK_STRING("  -gpb:<on,off>          - Enable or disable Generalized P/B frames\n"));
344     msdk_printf(MSDK_STRING("  -TransformSkip:<on,off>- Enable or disable TransformSkip\n"));
345     msdk_printf(MSDK_STRING("  -trows <rows>          - Number of rows for tiled encoding\n"));
346     msdk_printf(MSDK_STRING("  -tcols <cols>          - Number of columns for tiled encoding\n"));
347     msdk_printf(MSDK_STRING("  -CodecProfile          - Specifies codec profile\n"));
348     msdk_printf(MSDK_STRING("  -CodecLevel            - Specifies codec level\n"));
349     msdk_printf(MSDK_STRING("  -GopOptFlag:closed     - Closed gop\n"));
350     msdk_printf(MSDK_STRING("  -GopOptFlag:strict     - Strict gop\n"));
351     msdk_printf(MSDK_STRING("  -AdaptiveI:<on,off>    - Turn Adaptive I frames on/off\n"));
352     msdk_printf(MSDK_STRING("  -AdaptiveB:<on,off>    - Turn Adaptive B frames on/off\n"));
353     msdk_printf(MSDK_STRING(
354         "  -InitialDelayInKB      - The decoder starts decoding after the buffer reaches the initial size InitialDelayInKB, \n\
355                             which is equivalent to reaching an initial delay of InitialDelayInKB*8000/TargetKbps ms\n"));
356     msdk_printf(MSDK_STRING(
357         "  -MaxKbps               - For variable bitrate control, specifies the maximum bitrate at which \n\
358                             the encoded data enters the Video Buffering Verifier buffer\n"));
359     msdk_printf(MSDK_STRING("  -gpucopy::<on,off> Enable or disable GPU copy mode\n"));
360     msdk_printf(MSDK_STRING(
361         "  -repartitioncheck::<on,off> Enable or disable RepartitionCheckEnable mode\n"));
362     msdk_printf(MSDK_STRING(
363         "  -cqp          Constant quantization parameter (CQP BRC) bitrate control method\n"));
364     msdk_printf(MSDK_STRING(
365         "                              (by default constant bitrate control method is used), should be used along with -qpi, -qpp, -qpb.\n"));
366     msdk_printf(MSDK_STRING(
367         "  -qpi          Constant quantizer for I frames (if bitrace control method is CQP). In range [1,51]. 0 by default, i.e.no limitations on QP.\n"));
368     msdk_printf(MSDK_STRING(
369         "  -qpp          Constant quantizer for P frames (if bitrace control method is CQP). In range [1,51]. 0 by default, i.e.no limitations on QP.\n"));
370     msdk_printf(MSDK_STRING(
371         "  -qpb          Constant quantizer for B frames (if bitrace control method is CQP). In range [1,51]. 0 by default, i.e.no limitations on QP.\n"));
372     msdk_printf(MSDK_STRING(
373         "  -DisableQPOffset         Disable QP adjustment for GOP pyramid-level frames\n"));
374     msdk_printf(MSDK_STRING(
375         "  -MinQPI <QP>  min QP for I frames. In range [1,51]. 0 by default i.e. no limits\n"));
376     msdk_printf(MSDK_STRING(
377         "  -MaxQPI <QP>  max QP for I frames. In range [1,51]. 0 by default i.e. no limits\n"));
378     msdk_printf(MSDK_STRING(
379         "  -MinQPP <QP>  min QP for P frames. In range [1,51]. 0 by default i.e. no limits\n"));
380     msdk_printf(MSDK_STRING(
381         "  -MaxQPP <QP>  max QP for P frames. In range [1,51]. 0 by default i.e. no limits\n"));
382     msdk_printf(MSDK_STRING(
383         "  -MinQPB <QP>  min QP for B frames. In range [1,51]. 0 by default i.e. no limits\n"));
384     msdk_printf(MSDK_STRING(
385         "  -MaxQPB <QP>  max QP for B frames. In range [1,51]. 0 by default i.e. no limits\n"));
386     msdk_printf(MSDK_STRING(
387         "  -lowpower:<on,off>       Turn this option ON to enable QuickSync Fixed Function (low-power HW) encoding mode\n"));
388     msdk_printf(MSDK_STRING(
389         "  -qsv-ff                  Turn option lowpower ON to enable QuickSync Fixed Function (low-power HW) encoding mode\n"));
390     msdk_printf(MSDK_STRING(
391         "   [-TargetBitDepthLuma] - Encoding target bit depth for luma samples, by default same as source one.\n"));
392     msdk_printf(MSDK_STRING(
393         "   [-TargetBitDepthChroma] - Encoding target bit depth for chroma samples, by default same as source one.\n"));
394     msdk_printf(MSDK_STRING("  -roi_file <roi-file-name>\n"));
395     msdk_printf(MSDK_STRING(
396         "                Set Regions of Interest for each frame from <roi-file-name>\n"));
397     msdk_printf(MSDK_STRING("  -roi_qpmap    Use QP map to emulate ROI for CQP mode\n"));
398     msdk_printf(MSDK_STRING("  -extmbqp      Use external MBQP map\n"));
399     msdk_printf(MSDK_STRING(
400         "  -AvcTemporalLayers [array:Layer.Scale]    Configures the temporal layers hierarchy\n"));
401     msdk_printf(MSDK_STRING(
402         "  -BaseLayerPID <pid>                       Sets priority ID for the base layer\n"));
403     msdk_printf(MSDK_STRING(
404         "  -SPSId <pid>                              Sets sequence parameter set ID\n"));
405     msdk_printf(
406         MSDK_STRING("  -PPSId <pid>                              Sets picture parameter set ID\n"));
407     msdk_printf(MSDK_STRING(
408         "  -PicTimingSEI:<on,off>                    Enables or disables picture timing SEI\n"));
409     msdk_printf(MSDK_STRING(
410         "  -NalHrdConformance:<on,off>               Enables or disables picture HRD conformance\n"));
411     msdk_printf(MSDK_STRING(
412         "  -VuiNalHrdParameters:<on,off>             Enables or disables NAL HRD parameters in VUI header\n"));
413     msdk_printf(
414         MSDK_STRING("  -EmbeddedDenoise <mode> <level>           Enables Denoiser in encoder\n"));
415     msdk_printf(MSDK_STRING("           mode - mode of deniose\n"));
416     msdk_printf(MSDK_STRING("               0    - default\n"));
417     msdk_printf(MSDK_STRING("               1001 - auto BD rate\n"));
418     msdk_printf(MSDK_STRING("               1002 - auto subjective\n"));
419     msdk_printf(MSDK_STRING("               1003 - auto adjust\n"));
420     msdk_printf(MSDK_STRING("               1004 - manual mode for pre-processing, need level\n"));
421     msdk_printf(MSDK_STRING("               1005 - manual mode for post-processing, need level\n"));
422     msdk_printf(MSDK_STRING("           level - range of noise level is [0, 100]\n"));
423     msdk_printf(MSDK_STRING(
424         "  -idr_interval size      idr interval, default 0 means every I is an IDR, 1 means every other I frame is an IDR etc\n"));
425     msdk_printf(MSDK_STRING("  -ivf:<on,off> Turn IVF header on/off\n"));
426     msdk_printf(MSDK_STRING("\n"));
427     msdk_printf(MSDK_STRING("Pipeline description (vpp options):\n"));
428     msdk_printf(MSDK_STRING("  -deinterlace             Forces VPP to deinterlace input stream\n"));
429     msdk_printf(MSDK_STRING(
430         "  -deinterlace::ADI        Forces VPP to deinterlace input stream using ADI algorithm\n"));
431     msdk_printf(MSDK_STRING(
432         "  -deinterlace::ADI_SCD    Forces VPP to deinterlace input stream using ADI_SCD algorithm\n"));
433     msdk_printf(MSDK_STRING(
434         "  -deinterlace::ADI_NO_REF Forces VPP to deinterlace input stream using ADI no ref algorithm\n"));
435     msdk_printf(MSDK_STRING(
436         "  -deinterlace::BOB        Forces VPP to deinterlace input stream using BOB algorithm\n"));
437     msdk_printf(MSDK_STRING(
438         "  -detail <level>          Enables detail (edge enhancement) filter with provided level(0..100)\n"));
439     msdk_printf(MSDK_STRING(
440         "  -denoise <level>         Enables denoise filter with provided level (0..100)\n"));
441     msdk_printf(
442         MSDK_STRING("  -FRC::PT      Enables FRC filter with Preserve Timestamp algorithm\n"));
443     msdk_printf(
444         MSDK_STRING("  -FRC::DT      Enables FRC filter with Distributed Timestamp algorithm\n"));
445     msdk_printf(
446         MSDK_STRING("  -FRC::INTERP  Enables FRC filter with Frame Interpolation algorithm\n"));
447     msdk_printf(MSDK_STRING("  -scaling_mode <mode> Specifies scaling mode (lowpower/quality)\n"));
448     msdk_printf(MSDK_STRING(
449         "  -ec::nv12|rgb4|yuy2|nv16|p010|p210|y210|y410|p016|y216   Forces encoder input to use provided chroma mode\n"));
450     msdk_printf(MSDK_STRING(
451         "  -dc::nv12|rgb4|yuy2|p010|y210|y410|p016|y216|y416   Forces decoder output to use provided chroma mode\n"));
452     msdk_printf(MSDK_STRING(
453         "     NOTE: chroma transform VPP may be automatically enabled if -ec/-dc parameters are provided\n"));
454     msdk_printf(MSDK_STRING(
455         "  -angle 180    Enables 180 degrees picture rotation user module before encoding\n"));
456     msdk_printf(MSDK_STRING(
457         "  -opencl       Uses implementation of rotation plugin (enabled with -angle option) through Intel(R) OpenCL\n"));
458     msdk_printf(MSDK_STRING(
459         "  -w            Destination picture width, invokes VPP resize or decoder fixed function resize engine (if -dec_postproc specified)\n"));
460     msdk_printf(MSDK_STRING(
461         "  -h            Destination picture height, invokes VPP resize or decoder fixed function resize engine (if -dec_postproc specified)\n"));
462     msdk_printf(MSDK_STRING("  -field_processing t2t|t2b|b2t|b2b|fr2fr - Field Copy feature\n"));
463     msdk_printf(MSDK_STRING(
464         "  -WeightedPred::default|implicit       Enambles weighted prediction usage\n"));
465     msdk_printf(MSDK_STRING(
466         "  -WeightedBiPred::default|implicit     Enambles weighted bi-prediction usage\n"));
467     msdk_printf(MSDK_STRING(
468         "  -ir_type               - Intra refresh type. 0 - no refresh, 1 - vertical refresh, 2 - horisontal refresh, 3 - slice refresh\n"));
469     msdk_printf(MSDK_STRING(
470         "  -ir_cycle_size         - Number of pictures within refresh cycle starting from 2\n"));
471     msdk_printf(MSDK_STRING(
472         "  -ir_qp_delta           - QP difference for inserted intra MBs. This is signed value in [-51, 51] range\n"));
473     msdk_printf(MSDK_STRING(
474         "  -ir_cycle_dist         - Distance between the beginnings of the intra-refresh cycles in frames\n"));
475     msdk_printf(MSDK_STRING(
476         "  -LowDelayBRC           - strictly obey average frame size set by MaxKbps\n"));
477     msdk_printf(MSDK_STRING(
478         "  -amfs:<on,off>         - adaptive max frame size. If set on, P or B frame size can exceed MaxFrameSize when the scene change is detected.\
479                             It can benefit the video quality \n"));
480     msdk_printf(MSDK_STRING(
481         "  -mfs                   - maximum frame size in bytes. Supported only with h264 and hevc codec for VBR mode.\n"));
482     msdk_printf(MSDK_STRING(
483         "  -extbrc::<on,off,implicit>           Enables external BRC for AVC and HEVC encoders\n"));
484     msdk_printf(
485         MSDK_STRING("  -ExtBrcAdaptiveLTR:<on,off>         Set AdaptiveLTR for implicit extbrc"));
486     msdk_printf(MSDK_STRING(
487         "  -vpp_comp <sourcesNum>      Enables composition from several decoding sessions. Result is written to the file\n"));
488     msdk_printf(MSDK_STRING(
489         "  -vpp_comp_only <sourcesNum> Enables composition from several decoding sessions. Result is shown on screen\n"));
490     msdk_printf(MSDK_STRING(
491         "  -vpp_comp_num_tiles <Num>   Quantity of tiles for composition. if equal to 0 tiles processing ignored\n"));
492     msdk_printf(MSDK_STRING(
493         "  -vpp_comp_render            Set pipeline mode when pipeline makes vpp composition + encode and get data from shared buffer\n"));
494     msdk_printf(MSDK_STRING(
495         "  -vpp_comp_dst_x             X position of this stream in composed stream (should be used in decoder session)\n"));
496     msdk_printf(MSDK_STRING(
497         "  -vpp_comp_dst_y             Y position of this stream in composed stream (should be used in decoder session)\n"));
498     msdk_printf(MSDK_STRING(
499         "  -vpp_comp_dst_h             Height of this stream in composed stream (should be used in decoder session)\n"));
500     msdk_printf(MSDK_STRING(
501         "  -vpp_comp_dst_w             Width of this stream in composed stream (should be used in decoder session)\n"));
502     msdk_printf(MSDK_STRING(
503         "  -vpp_comp_src_h             Width of this stream in composed stream (should be used in decoder session)\n"));
504     msdk_printf(MSDK_STRING(
505         "  -vpp_comp_src_w             Width of this stream in composed stream (should be used in decoder session)\n"));
506     msdk_printf(MSDK_STRING(
507         "  -vpp_comp_tile_id           Tile_id for current channel of composition (should be used in decoder session)\n"));
508     msdk_printf(MSDK_STRING(
509         "  -vpp_comp_dump <file-name>  Dump of VPP Composition's output into file. Valid if with -vpp_comp* options\n"));
510     msdk_printf(MSDK_STRING(
511         "  -vpp_comp_dump null_render  Disabling rendering after VPP Composition. This is for performance measurements\n"));
512     msdk_printf(MSDK_STRING(
513         "  -dec_postproc               Resize after decoder using direct pipe (should be used in decoder session)\n"));
514     msdk_printf(
515         MSDK_STRING("  -single_texture_d3d11       single texture mode for d3d11 allocator \n"));
516     msdk_printf(MSDK_STRING(
517         "  -preset <default,dss,conference,gaming> Use particular preset for encoding parameters\n"));
518     msdk_printf(MSDK_STRING("  -pp                         Print preset parameters\n"));
519     msdk_printf(MSDK_STRING(
520         "  -forceSyncAllSession:<on,off>         Enable across-session synchronization \n"));
521     msdk_printf(MSDK_STRING(
522         "                              How it works: the decoder takes a required number of surfaces for work, \n"));
523     msdk_printf(MSDK_STRING(
524         "                              and when it ready to take more, does not take a new one, \n"));
525     msdk_printf(MSDK_STRING(
526         "                              but waits until one of them is available for work \n"));
527     msdk_printf(MSDK_STRING(
528         "                              Opion is ON by default for -MemModel::VisibleIntAlloc/HiddenIntAlloc(-memory 2/3) and 1->N scenarios"));
529     msdk_printf(MSDK_STRING(
530         "                              Option is not intended for -memory 1 and for transcoding scenarios  \n"));
531     msdk_printf(MSDK_STRING(
532         "   -dump [fileName]         - dump MSDK components configuration to the file in text form\n"));
533     msdk_printf(MSDK_STRING("   -cs                      - turn on cascade scaling\n"));
534     msdk_printf(MSDK_STRING("   -trace                   - turn on tracing \n"));
535 #if defined(LIBVA_X11_SUPPORT)
536     msdk_printf(MSDK_STRING("   -rx11                    - use libva X11 backend \n"));
537 #endif
538 #if defined(LIBVA_WAYLAND_SUPPORT)
539     msdk_printf(MSDK_STRING("   -rwld                    - use libva WAYLAND backend \n"));
540 #endif
541 #if defined(LIBVA_DRM_SUPPORT)
542     msdk_printf(MSDK_STRING("   -rdrm                    - use libva DRM backend \n"));
543 #endif
544     msdk_printf(MSDK_STRING("\n"));
545     msdk_printf(MSDK_STRING("ParFile format:\n"));
546     msdk_printf(MSDK_STRING(
547         "  ParFile is extension of what can be achieved by setting pipeline in the command\n"));
548     msdk_printf(MSDK_STRING(
549         "line. For more information on ParFile format see readme-multi-transcode.pdf\n"));
550     msdk_printf(MSDK_STRING("\n"));
551     msdk_printf(MSDK_STRING("Examples:\n"));
552     msdk_printf(MSDK_STRING("  sample_multi_transcode -i::mpeg2 in.mpeg2 -o::h264 out.h264\n"));
553     msdk_printf(
554         MSDK_STRING("  sample_multi_transcode -i::mvc in.mvc -o::mvc out.mvc -w 320 -h 240\n"));
555 }
556 
PrintInfo(mfxU32 session_number,sInputParams * pParams,mfxVersion * pVer)557 void TranscodingSample::PrintInfo(mfxU32 session_number, sInputParams* pParams, mfxVersion* pVer) {
558     msdk_char buf[2048];
559     MSDK_CHECK_POINTER_NO_RET(pVer);
560 
561     if ((MFX_IMPL_AUTO <= pParams->libType) && (MFX_IMPL_HARDWARE4 >= pParams->libType)) {
562         msdk_printf(MSDK_STRING("MFX %s Session %d API ver %d.%d parameters: \n"),
563                     (MFX_IMPL_SOFTWARE == pParams->libType) ? MSDK_STRING("SOFTWARE")
564                                                             : MSDK_STRING("HARDWARE"),
565                     session_number,
566                     pVer->Major,
567                     pVer->Minor);
568     }
569 
570     if (0 == pParams->DecodeId)
571         msdk_printf(MSDK_STRING("Input  video: From parent session\n"));
572     else
573         msdk_printf(MSDK_STRING("Input  video: %s\n"), CodecIdToStr(pParams->DecodeId).c_str());
574 
575     // means that source is parent session
576     if (0 == pParams->EncodeId)
577         msdk_printf(MSDK_STRING("Output video: To child session\n"));
578     else
579         msdk_printf(MSDK_STRING("Output video: %s\n"), CodecIdToStr(pParams->EncodeId).c_str());
580     if (PrintDllInfo(buf, MSDK_ARRAY_LEN(buf), pParams))
581         msdk_printf(MSDK_STRING("MFX dll: %s\n"), buf);
582     msdk_printf(MSDK_STRING("\n"));
583 }
584 
PrintDllInfo(msdk_char * buf,mfxU32 buf_size,sInputParams * pParams)585 bool TranscodingSample::PrintDllInfo(msdk_char* buf, mfxU32 buf_size, sInputParams* pParams) {
586 #if defined(_WIN32) || defined(_WIN64)
587     HANDLE hCurrent = GetCurrentProcess();
588     HMODULE* pModules;
589     DWORD cbNeeded;
590     int nModules;
591     if (NULL == EnumProcessModules(hCurrent, NULL, 0, &cbNeeded))
592         return false;
593 
594     nModules = cbNeeded / sizeof(HMODULE);
595 
596     pModules = new HMODULE[nModules];
597     if (NULL == pModules) {
598         return false;
599     }
600     if (NULL == EnumProcessModules(hCurrent, pModules, cbNeeded, &cbNeeded)) {
601         delete[] pModules;
602         return false;
603     }
604 
605     for (int i = 0; i < nModules; i++) {
606         GetModuleFileName(pModules[i], buf, buf_size);
607         if (_tcsstr(buf, MSDK_STRING("libmfxhw")) && (MFX_IMPL_SOFTWARE != pParams->libType)) {
608             delete[] pModules;
609             return true;
610         }
611         else if (_tcsstr(buf, MSDK_STRING("libmfxsw")) && (MFX_IMPL_SOFTWARE == pParams->libType)) {
612             delete[] pModules;
613             return true;
614         }
615     }
616     delete[] pModules;
617     return false;
618 #else
619     return false;
620 #endif
621 }
622 
CmdProcessor()623 CmdProcessor::CmdProcessor() {
624     m_SessionParamId = 0;
625     m_SessionArray.clear();
626     m_decoderPlugins.clear();
627     m_encoderPlugins.clear();
628     m_PerfFILE           = NULL;
629     m_parName            = NULL;
630     m_nTimeout           = 0;
631     statisticsWindowSize = 0;
632     statisticsLogFile    = NULL;
633     DumpLogFileName.clear();
634     shouldUseGreedyFormula = false;
635     bRobustFlag            = false;
636     bSoftRobustFlag        = false;
637 
638 } //CmdProcessor::CmdProcessor()
639 
~CmdProcessor()640 CmdProcessor::~CmdProcessor() {
641     m_SessionArray.clear();
642     m_decoderPlugins.clear();
643     m_encoderPlugins.clear();
644     if (m_PerfFILE)
645         fclose(m_PerfFILE);
646     if (statisticsLogFile)
647         fclose(statisticsLogFile);
648 
649 } //CmdProcessor::~CmdProcessor()
650 
PrintParFileName()651 void CmdProcessor::PrintParFileName() {
652     if (m_parName && m_PerfFILE) {
653         msdk_fprintf(m_PerfFILE, MSDK_STRING("Input par file: %s\n\n"), m_parName);
654     }
655 }
656 
GetLine(mfxU32 n)657 msdk_string CmdProcessor::GetLine(mfxU32 n) {
658     if (m_lines.size() > n)
659         return m_lines[n];
660     return msdk_string();
661 }
662 
ParseCmdLine(int argc,msdk_char * argv[])663 mfxStatus CmdProcessor::ParseCmdLine(int argc, msdk_char* argv[]) {
664     FILE* parFile = NULL;
665     mfxStatus sts = MFX_ERR_UNSUPPORTED;
666 
667     if (1 == argc) {
668         PrintError(MSDK_STRING("Too few parameters"), NULL);
669         return MFX_ERR_UNSUPPORTED;
670     }
671 
672     --argc;
673     ++argv;
674 
675     while (argv[0]) {
676         if (0 == msdk_strcmp(argv[0], MSDK_STRING("-par"))) {
677             --argc;
678             ++argv;
679             if (!argv[0]) {
680                 msdk_printf(MSDK_STRING("error: no argument given for '-par' option\n"));
681             }
682             m_parName = argv[0];
683         }
684         else if (0 == msdk_strcmp(argv[0], MSDK_STRING("-timeout"))) {
685             --argc;
686             ++argv;
687             if (!argv[0]) {
688                 msdk_printf(MSDK_STRING("error: no argument given for '-timeout' option\n"));
689             }
690             if (MFX_ERR_NONE != msdk_opt_read(argv[0], m_nTimeout)) {
691                 msdk_printf(MSDK_STRING("error: -timeout \"%s\" is invalid"), argv[0]);
692                 return MFX_ERR_UNSUPPORTED;
693             }
694         }
695         else if (0 == msdk_strcmp(argv[0], MSDK_STRING("-robust"))) {
696             bRobustFlag = true;
697         }
698         else if (0 == msdk_strcmp(argv[0], MSDK_STRING("-robust:soft"))) {
699             bSoftRobustFlag = true;
700         }
701         else if (0 == msdk_strcmp(argv[0], MSDK_STRING("-?"))) {
702             PrintHelp();
703             return MFX_WRN_OUT_OF_RANGE;
704         }
705         else if (0 == msdk_strcmp(argv[0], MSDK_STRING("-greedy"))) {
706             shouldUseGreedyFormula = true;
707         }
708         else if (0 == msdk_strcmp(argv[0], MSDK_STRING("-p"))) {
709             if (m_PerfFILE) {
710                 msdk_printf(MSDK_STRING("error: only one performance file is supported"));
711                 return MFX_ERR_UNSUPPORTED;
712             }
713             --argc;
714             ++argv;
715             if (!argv[0]) {
716                 msdk_printf(MSDK_STRING("error: no argument given for '-p' option\n"));
717             }
718             MSDK_FOPEN(m_PerfFILE, argv[0], MSDK_STRING("w"));
719             if (NULL == m_PerfFILE) {
720                 msdk_printf(MSDK_STRING("error: performance file \"%s\" not found"), argv[0]);
721                 return MFX_ERR_UNSUPPORTED;
722             }
723         }
724         else if (0 == msdk_strcmp(argv[0], MSDK_STRING("--"))) {
725             // just skip separator "--" which delimits cmd options and pipeline settings
726             break;
727         }
728         else if (0 == msdk_strcmp(argv[0], MSDK_STRING("-stat"))) {
729             --argc;
730             ++argv;
731             if (!argv[0]) {
732                 msdk_printf(MSDK_STRING("error: no argument given for 'stat' option\n"));
733             }
734             if (MFX_ERR_NONE != msdk_opt_read(argv[0], statisticsWindowSize)) {
735                 msdk_printf(MSDK_STRING("error: stat \"%s\" is invalid"), argv[0]);
736                 return MFX_ERR_UNSUPPORTED;
737             }
738         }
739         else if (0 == msdk_strcmp(argv[0], MSDK_STRING("-stat-log"))) {
740             if (statisticsLogFile) {
741                 msdk_printf(MSDK_STRING("error: only one statistics file is supported"));
742                 return MFX_ERR_UNSUPPORTED;
743             }
744             --argc;
745             ++argv;
746             if (!argv[0]) {
747                 msdk_printf(MSDK_STRING("error: no argument given for 'stat-log' option\n"));
748             }
749             MSDK_FOPEN(statisticsLogFile, argv[0], MSDK_STRING("w"));
750             if (NULL == statisticsLogFile) {
751                 msdk_printf(MSDK_STRING("error: statistics file \"%s\" not found"), argv[0]);
752                 return MFX_ERR_UNSUPPORTED;
753             }
754         }
755         else if (0 == msdk_strcmp(argv[0], MSDK_STRING("-stat-per-frame"))) {
756             if (!DumpLogFileName.empty()) {
757                 msdk_printf(MSDK_STRING("error: only one dump file is supported"));
758                 return MFX_ERR_UNSUPPORTED;
759             }
760             --argc;
761             ++argv;
762             if (!argv[0]) {
763                 msdk_printf(MSDK_STRING("error: no argument given for 'stat-dump' option\n"));
764             }
765             DumpLogFileName = argv[0];
766         }
767         else {
768             break;
769         }
770         --argc;
771         ++argv;
772     }
773 
774     msdk_printf(MSDK_STRING("Multi Transcoding Sample Version %s\n\n"),
775                 GetMSDKSampleVersion().c_str());
776 
777     //Read pipeline from par file
778     if (m_parName && !argv[0]) {
779         MSDK_FOPEN(parFile, m_parName, MSDK_STRING("r"));
780         if (NULL == parFile) {
781             msdk_printf(MSDK_STRING("error: ParFile \"%s\" not found\n"), m_parName);
782             return MFX_ERR_UNSUPPORTED;
783         }
784 
785         if (NULL != m_parName)
786             msdk_printf(MSDK_STRING("Par file is: %s\n\n"), m_parName);
787 
788         sts = ParseParFile(parFile);
789 
790         if (MFX_ERR_NONE != sts) {
791             fclose(parFile);
792             return sts;
793         }
794 
795         fclose(parFile);
796     }
797     //Read pipeline from cmd line
798     else if (!argv[0]) {
799         msdk_printf(MSDK_STRING("error: pipeline description not found\n"));
800         return MFX_ERR_UNSUPPORTED;
801     }
802     else if (argv[0] && m_parName) {
803         msdk_printf(MSDK_STRING(
804             "error: simultaneously enabling parfile and description pipeline from command line forbidden\n"));
805         return MFX_ERR_UNSUPPORTED;
806     }
807     else {
808         sts = ParseParamsForOneSession(argc, argv);
809         if (MFX_ERR_NONE != sts) {
810             msdk_printf(MSDK_STRING("error: pipeline description is invalid\n"));
811             return sts;
812         }
813     }
814 
815     return sts;
816 
817 } //mfxStatus CmdProcessor::ParseCmdLine(int argc, msdk_char *argv[])
818 
ParseParFile(FILE * parFile)819 mfxStatus CmdProcessor::ParseParFile(FILE* parFile) {
820     mfxStatus sts = MFX_ERR_UNSUPPORTED;
821     if (!parFile)
822         return MFX_ERR_UNSUPPORTED;
823 
824     mfxU32 currPos   = 0;
825     mfxU32 lineIndex = 0;
826 
827     // calculate file size
828     fseek(parFile, 0, SEEK_END);
829     mfxU32 fileSize = ftell(parFile) + 1;
830     fseek(parFile, 0, SEEK_SET);
831 
832     // allocate buffer for parsing
833     auto parBuf = std::make_unique<msdk_char[]>(fileSize);
834     msdk_char* pCur;
835 
836     while (currPos < fileSize) {
837         pCur = /*_fgetts*/ msdk_fgets(parBuf.get(), fileSize, parFile);
838         if (!pCur)
839             return MFX_ERR_NONE;
840         while (pCur[currPos] != '\n' && pCur[currPos] != 0) {
841             currPos++;
842             if (pCur + currPos >= parBuf.get() + fileSize)
843                 return sts;
844         }
845         // zero string
846         if (!currPos)
847             continue;
848 
849         sts = TokenizeLine(pCur, currPos);
850         MSDK_CHECK_STATUS(sts, "TokenizeLine failed");
851 
852         currPos = 0;
853         lineIndex++;
854     }
855 
856     return MFX_ERR_NONE;
857 
858 } //mfxStatus CmdProcessor::ParseParFile(FILE *parFile)
859 
860 // calculate length of string literal, including leading and trailing "
861 // pTempLine = start of string (must begin with ")
862 // length = remaining characters in pTempLine
863 // returns length of string, or 0 if error
GetStringLength(msdk_char * pTempLine,mfxU32 length)864 mfxU32 CmdProcessor::GetStringLength(msdk_char* pTempLine, mfxU32 length) {
865     mfxU32 i;
866 
867     // error - no leading " found
868     if (pTempLine[0] != '\"')
869         return 0;
870 
871     for (i = 1; i < length; i++) {
872         if (pTempLine[i] == '\"')
873             break;
874     }
875 
876     // error - no closing " found
877     if (i == length)
878         return 0;
879 
880     return i + 1;
881 }
882 
TokenizeLine(msdk_char * pLine,mfxU32 length)883 mfxStatus CmdProcessor::TokenizeLine(msdk_char* pLine, mfxU32 length) {
884     mfxU32 i, strArgLen;
885     const mfxU8 maxArgNum = 255;
886     msdk_char* argv[maxArgNum + 1];
887     mfxU32 argc   = 0;
888     auto pMemLine = std::make_unique<msdk_char[]>(length + 2);
889 
890     msdk_char* pTempLine = pMemLine.get();
891     pTempLine[0]         = ' ';
892     pTempLine++;
893 
894     MSDK_MEMCPY_BUF(pTempLine, 0, length * sizeof(msdk_char), pLine, length * sizeof(msdk_char));
895 
896     // parse into command streams
897     for (i = 0; i < length; i++) {
898         // check if separator
899         if (IS_SEPARATOR(pTempLine[-1]) && !IS_SEPARATOR(pTempLine[0])) {
900             argv[argc++] = pTempLine;
901             if (argc > maxArgNum) {
902                 PrintError(MSDK_STRING("Too many parameters (reached maximum of %d)"), maxArgNum);
903                 return MFX_ERR_UNSUPPORTED;
904             }
905         }
906 
907         if (*pTempLine == '\"') {
908             strArgLen = GetStringLength(pTempLine, length - i);
909             if (!strArgLen) {
910                 PrintError(MSDK_STRING("Error parsing string literal"));
911                 return MFX_ERR_UNSUPPORTED;
912             }
913 
914             // remove leading and trailing ", bump pointer ahead to next argument
915             pTempLine[0]             = ' ';
916             pTempLine[strArgLen - 1] = ' ';
917             pTempLine += strArgLen;
918             i += strArgLen;
919         }
920 
921         if (*pTempLine == ' ' || *pTempLine == '\r' || *pTempLine == '\n') {
922             *pTempLine = 0;
923         }
924         pTempLine++;
925     }
926 
927     // EOL for last parameter
928     pTempLine[0] = 0;
929 
930     return ParseParamsForOneSession(argc, argv);
931 }
932 
isspace(char a)933 bool CmdProcessor::isspace(char a) {
934     return (std::isspace(a) != 0);
935 }
936 
is_not_allowed_char(char a)937 bool CmdProcessor::is_not_allowed_char(char a) {
938     return (std::isdigit(a) == 0) && (std::isspace(a) == 0) && (a != ';') && (a != '-');
939 }
940 
ParseROIFile(const msdk_char * roi_file_name,std::vector<mfxExtEncoderROI> & m_ROIData)941 bool CmdProcessor::ParseROIFile(const msdk_char* roi_file_name,
942                                 std::vector<mfxExtEncoderROI>& m_ROIData) {
943     FILE* roi_file = NULL;
944     MSDK_FOPEN(roi_file, roi_file_name, MSDK_STRING("rb"));
945 
946     m_ROIData.clear();
947 
948     if (roi_file) {
949         // read file to buffer
950         fseek(roi_file, 0, SEEK_END);
951         long file_size = ftell(roi_file);
952         rewind(roi_file);
953         std::vector<char> buffer(file_size);
954         char* roi_data = &buffer[0];
955         if (file_size < 0 || (size_t)file_size != fread(roi_data, 1, file_size, roi_file)) {
956             fclose(roi_file);
957             return false;
958         }
959         fclose(roi_file);
960 
961         // search for not allowed characters
962         char* not_allowed_char = std::find_if(roi_data, roi_data + file_size, is_not_allowed_char);
963         if (not_allowed_char != (roi_data + file_size)) {
964             return false;
965         }
966 
967         // get unformatted roi data
968         std::string unformatted_roi_data;
969         unformatted_roi_data.clear();
970         std::remove_copy_if(roi_data,
971                             roi_data + file_size,
972                             std::inserter(unformatted_roi_data, unformatted_roi_data.end()),
973                             isspace);
974 
975         // split data to items
976         std::stringstream unformatted_roi_data_ss(unformatted_roi_data);
977         std::vector<std::string> items;
978         items.clear();
979         std::string item;
980         while (std::getline(unformatted_roi_data_ss, item, ';')) {
981             items.push_back(item);
982         }
983 
984         // parse data and store roi data for each frame
985         unsigned int item_ind = 0;
986         while (1) {
987             if (item_ind >= items.size())
988                 break;
989 
990             mfxExtEncoderROI frame_roi;
991             std::memset(&frame_roi, 0, sizeof(frame_roi));
992             frame_roi.Header.BufferId = MFX_EXTBUFF_ENCODER_ROI;
993             frame_roi.ROIMode         = MFX_ROI_MODE_QP_DELTA;
994 
995             int roi_num = std::atoi(items[item_ind].c_str());
996             if (roi_num < 0 || roi_num > (int)(sizeof(frame_roi.ROI) / sizeof(frame_roi.ROI[0]))) {
997                 m_ROIData.clear();
998                 return false;
999             }
1000             if ((item_ind + 5 * roi_num) >= items.size()) {
1001                 m_ROIData.clear();
1002                 return false;
1003             }
1004 
1005             for (int i = 0; i < roi_num; i++) {
1006                 // do not handle out of range integer errors
1007                 frame_roi.ROI[i].Left    = std::atoi(items[item_ind + i * 5 + 1].c_str());
1008                 frame_roi.ROI[i].Top     = std::atoi(items[item_ind + i * 5 + 2].c_str());
1009                 frame_roi.ROI[i].Right   = std::atoi(items[item_ind + i * 5 + 3].c_str());
1010                 frame_roi.ROI[i].Bottom  = std::atoi(items[item_ind + i * 5 + 4].c_str());
1011                 frame_roi.ROI[i].DeltaQP = (mfxI16)std::atoi(items[item_ind + i * 5 + 5].c_str());
1012             }
1013             frame_roi.NumROI = (mfxU16)roi_num;
1014             m_ROIData.push_back(frame_roi);
1015             item_ind = item_ind + roi_num * 5 + 1;
1016         }
1017     }
1018     else {
1019         return false;
1020     }
1021     return true;
1022 }
1023 #ifdef ENABLE_MCTF
1024 
1025 // returns a pointer to start of argument with a number argn;
1026 // if failes to find argn, returns NULL
ParseArgn(msdk_char * pIn,mfxU32 argn,msdk_char separator)1027 msdk_char* ParseArgn(msdk_char* pIn, mfxU32 argn, msdk_char separator) {
1028     msdk_char* pstr = pIn;
1029     if (!argn)
1030         return pIn;
1031     else {
1032         for (mfxU32 n = 0; n != argn; ++n) {
1033             while (separator != *pstr && msdk_char('\0') != *pstr)
1034                 ++pstr;
1035             if (msdk_char('\0') == *pstr)
1036                 return NULL;
1037             else
1038                 ++pstr;
1039         }
1040         return pstr;
1041     }
1042 };
1043 
1044 template <typename T>
ArgConvert(msdk_char * pIn,mfxU32 argn,const msdk_char * pattern,T * pArg,const T & ArgDefault,mfxU32 & NumOfGoodConverts)1045 bool ArgConvert(msdk_char* pIn,
1046                 mfxU32 argn,
1047                 const msdk_char* pattern,
1048                 T* pArg,
1049                 const T& ArgDefault,
1050                 mfxU32& NumOfGoodConverts) {
1051     bool bConvertIsOk = false;
1052     msdk_char* pargs  = ParseArgn(pIn, argn, msdk_char(':'));
1053     if (pargs) {
1054         if (!msdk_sscanf(pargs, pattern, pArg))
1055             *pArg = ArgDefault;
1056         else {
1057             ++NumOfGoodConverts;
1058             bConvertIsOk = true;
1059         }
1060     };
1061     return bConvertIsOk;
1062 }
1063 
1064 //template <typename T=msdk_string>
ArgConvert(msdk_char * pIn,mfxU32 argn,const msdk_char * pattern,msdk_char * pArg,mfxU32 MaxChars2Read,mfxU32 & NumOfGoodConverts)1065 bool ArgConvert(msdk_char* pIn,
1066                 mfxU32 argn,
1067                 const msdk_char* pattern,
1068                 msdk_char* pArg,
1069                 mfxU32 MaxChars2Read,
1070                 mfxU32& NumOfGoodConverts) {
1071     bool bConvertIsOk = false;
1072     msdk_char* pargs  = ParseArgn(pIn, argn, msdk_char(':'));
1073     if (pargs) {
1074         // lets calculate length of potential name:
1075         msdk_char* temp(pargs);
1076         while (*temp != msdk_char(':') && *temp != msdk_char('\0'))
1077             ++temp;
1078         std::iterator_traits<msdk_char*>::difference_type distance = std::distance(pargs, temp);
1079         if (distance < std::iterator_traits<msdk_char*>::difference_type(MaxChars2Read)) {
1080             if (msdk_sscanf(pargs, pattern, pArg, MaxChars2Read)) {
1081                 ++NumOfGoodConverts;
1082                 bConvertIsOk = true;
1083             }
1084         };
1085     };
1086     return bConvertIsOk;
1087 }
1088 
ParseMCTFParams(msdk_char * strInput[],mfxU32 nArgNum,mfxU32 & curArg,sInputParams * pParams)1089 void ParseMCTFParams(msdk_char* strInput[], mfxU32 nArgNum, mfxU32& curArg, sInputParams* pParams) {
1090     mfxU32& i = curArg;
1091     if (0 == msdk_strcmp(strInput[i], MSDK_STRING("-mctf"))) {
1092         pParams->mctfParam.mode                  = VPP_FILTER_ENABLED_DEFAULT;
1093         pParams->mctfParam.params.FilterStrength = 0;
1094         pParams->mctfParam.rtParams.Reset();
1095         bool bFSByValue = true;
1096     #if defined ENABLE_MCTF_EXT
1097         pParams->mctfParam.params.TemporalMode      = MFX_MCTF_TEMPORAL_MODE_2REF; // default
1098         pParams->mctfParam.params.BitsPerPixelx100k = 0;
1099         pParams->mctfParam.params.Deblocking        = MFX_CODINGOPTION_OFF;
1100         pParams->mctfParam.params.Overlap           = MFX_CODINGOPTION_OFF;
1101         pParams->mctfParam.params.MVPrecision       = MFX_MVPRECISION_INTEGER;
1102     #endif
1103 
1104         if (i + 1 < nArgNum) {
1105             mfxU16 _strength(0);
1106             mfxU32 strength_idx            = 0;
1107             mfxU32 ParsedArgsNumber        = 0;
1108             const mfxU32 max_name_len      = 15;
1109             const mfxU32 max_elems_in_file = 10000;
1110             msdk_stringstream file_pattern;
1111             file_pattern << MSDK_STRING("%") << max_name_len << MSDK_STRING("ls:%*c") << std::ends;
1112             msdk_char _tmp_str[max_name_len + 1];
1113             memset(_tmp_str, 0, sizeof(_tmp_str));
1114     #if defined ENABLE_MCTF_EXT
1115             strength_idx = 2;
1116     #endif
1117             //the order of arguments is:
1118             // MctfMode:BitsPerPixel:Strength:ME:Overlap:DB
1119             // try to read fs defined as a value:
1120             bool res = ArgConvert(strInput[i + 1],
1121                                   strength_idx,
1122                                   MSDK_STRING("%hd:%*c"),
1123                                   &_strength,
1124                                   _strength,
1125                                   ParsedArgsNumber);
1126             if (!res) {
1127                 bFSByValue = false;
1128                 // if it was not possible, try to get a file-name (upto 15 chars):
1129                 res = ArgConvert(strInput[i + 1],
1130                                  strength_idx,
1131                                  file_pattern.str().c_str(),
1132                                  &(_tmp_str[0]),
1133                                  max_name_len,
1134                                  ParsedArgsNumber);
1135                 if (res) {
1136                     msdk_fstream fs_file(_tmp_str, std::ios_base::in);
1137                     if (!fs_file.is_open()) {
1138                         msdk_printf(MSDK_STRING(
1139                             "MCTF Filter-strength file is not exist; decay to default FS value;.\n"));
1140                         bFSByValue = true;
1141                     }
1142                     else {
1143                         mfxU32 nOfRTParams(0);
1144                         for (msdk_string line; std::getline(fs_file, line, msdk_char(',')) &&
1145                                                nOfRTParams < max_elems_in_file;
1146                              ++nOfRTParams) {
1147                             // currently, there is just 1 param in the file;
1148                             sMctfRunTimeParam tmp;
1149                             if (msdk_sscanf(line.c_str(),
1150                                             MSDK_STRING("%hu:%*c"),
1151                                             &(tmp.FilterStrength)))
1152                                 pParams->mctfParam.rtParams.RunTimeParams.push_back(tmp);
1153                             else {
1154                                 msdk_printf(MSDK_STRING(
1155                                     "there was an error met during parsing FS file;.only a few values were parsed.\n"));
1156                                 break;
1157                             }
1158                         }
1159                     }
1160                 }
1161                 else
1162                     bFSByValue = true;
1163             }
1164     #if defined ENABLE_MCTF_EXT
1165             mfxU16 _refnum(2);
1166             mfxF64 _bitsperpixel(0.0);
1167             mfxU16 _me_precision(0);
1168             mfxU16 _overlap(0);
1169             mfxU16 _deblock(0);
1170 
1171             ArgConvert(strInput[i + 1],
1172                        0,
1173                        MSDK_STRING("%hd:%*c"),
1174                        &_refnum,
1175                        _refnum,
1176                        ParsedArgsNumber);
1177             ArgConvert(strInput[i + 1],
1178                        1,
1179                        MSDK_STRING("%lf:%*c"),
1180                        &_bitsperpixel,
1181                        _bitsperpixel,
1182                        ParsedArgsNumber);
1183             ArgConvert(strInput[i + 1],
1184                        3,
1185                        MSDK_STRING("%hd:%*c"),
1186                        &_me_precision,
1187                        _me_precision,
1188                        ParsedArgsNumber);
1189             ArgConvert(strInput[i + 1],
1190                        4,
1191                        MSDK_STRING("%hd:%*c"),
1192                        &_overlap,
1193                        _overlap,
1194                        ParsedArgsNumber);
1195             ArgConvert(strInput[i + 1],
1196                        5,
1197                        MSDK_STRING("%hd:%*c"),
1198                        &_deblock,
1199                        _deblock,
1200                        ParsedArgsNumber);
1201     #endif
1202             if (0 == ParsedArgsNumber) {
1203                 pParams->mctfParam.mode = VPP_FILTER_ENABLED_DEFAULT;
1204                 msdk_printf(MSDK_STRING("MCTF works in default mode; no parameters are passed.\n"));
1205             }
1206             else {
1207                 pParams->mctfParam.mode = VPP_FILTER_ENABLED_CONFIGURED;
1208                 pParams->mctfParam.rtParams.Restart();
1209                 if (bFSByValue) {
1210                     pParams->mctfParam.params.FilterStrength = _strength;
1211                 }
1212                 else {
1213                     // take very first FS value from the file and use it as a value for FilterStrength
1214                     if (pParams->mctfParam.rtParams.GetCurParam()) {
1215                         pParams->mctfParam.params.FilterStrength =
1216                             pParams->mctfParam.rtParams.GetCurParam()->FilterStrength;
1217                     }
1218                 }
1219     #if defined ENABLE_MCTF_EXT
1220                 pParams->mctfParam.params.BitsPerPixelx100k =
1221                     mfxU32(_bitsperpixel * MCTF_BITRATE_MULTIPLIER);
1222                 switch (_refnum) {
1223                     case 0:
1224                         pParams->mctfParam.params.TemporalMode = MFX_MCTF_TEMPORAL_MODE_SPATIAL;
1225                         break;
1226                     case 1:
1227                         pParams->mctfParam.params.TemporalMode = MFX_MCTF_TEMPORAL_MODE_1REF;
1228                         break;
1229                     case 2:
1230                         pParams->mctfParam.params.TemporalMode = MFX_MCTF_TEMPORAL_MODE_2REF;
1231                         break;
1232                     case 3:
1233                         pParams->mctfParam.params.TemporalMode = MFX_MCTF_TEMPORAL_MODE_4REF;
1234                         break;
1235                     default:
1236                         pParams->mctfParam.params.TemporalMode = MFX_MCTF_TEMPORAL_MODE_UNKNOWN;
1237                 };
1238                 switch (_deblock) {
1239                     case 0:
1240                         pParams->mctfParam.params.Deblocking = MFX_CODINGOPTION_OFF;
1241                         break;
1242                     case 1:
1243                         pParams->mctfParam.params.Deblocking = MFX_CODINGOPTION_ON;
1244                         break;
1245                     default:
1246                         pParams->mctfParam.params.Deblocking = MFX_CODINGOPTION_UNKNOWN;
1247                 };
1248                 switch (_overlap) {
1249                     case 0:
1250                         pParams->mctfParam.params.Overlap = MFX_CODINGOPTION_OFF;
1251                         break;
1252                     case 1:
1253                         pParams->mctfParam.params.Overlap = MFX_CODINGOPTION_ON;
1254                         break;
1255                     default:
1256                         pParams->mctfParam.params.Overlap = MFX_CODINGOPTION_UNKNOWN;
1257                 };
1258                 switch (_me_precision) {
1259                     case 0:
1260                         pParams->mctfParam.params.MVPrecision = MFX_MVPRECISION_INTEGER;
1261                         break;
1262                     case 1:
1263                         pParams->mctfParam.params.MVPrecision = MFX_MVPRECISION_QUARTERPEL;
1264                         break;
1265                     default:
1266                         pParams->mctfParam.params.MVPrecision = MFX_MVPRECISION_UNKNOWN;
1267                 };
1268     #endif
1269             }
1270             if (ParsedArgsNumber)
1271                 i++;
1272         }
1273         else {
1274             msdk_printf(MSDK_STRING("MCTF works in default mode; no parameters are passed.\n"));
1275         }
1276     }
1277 }
1278 #endif
1279 
1280 // return values:
1281 //   0 if argv[i] is processed successfully (MFX_ERR_NONE)
1282 // < 1 if argv[i] is processed and generates an error OR argv[i] is not processed (no match)
ParseAdditionalParams(msdk_char * argv[],mfxU32 argc,mfxU32 & i,TranscodingSample::sInputParams & InputParams)1283 mfxStatus ParseAdditionalParams(msdk_char* argv[],
1284                                 mfxU32 argc,
1285                                 mfxU32& i,
1286                                 TranscodingSample::sInputParams& InputParams) {
1287     if (0 == msdk_strcmp(argv[i], MSDK_STRING("-AvcTemporalLayers"))) {
1288         InputParams.nAvcTemp = 1;
1289         VAL_CHECK(i + 1 >= argc, i, argv[i]);
1290         mfxU16 arr[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
1291         int j, k;
1292         k = msdk_sscanf(argv[i + 1],
1293                         MSDK_STRING("%hu %hu %hu %hu %hu %hu %hu %hu"),
1294                         &arr[0],
1295                         &arr[1],
1296                         &arr[2],
1297                         &arr[3],
1298                         &arr[4],
1299                         &arr[5],
1300                         &arr[6],
1301                         &arr[7]);
1302         if (k != 8) {
1303             PrintError(argv[0], MSDK_STRING("Invalid number of layers for AvcTemporalLayers"));
1304             return MFX_ERR_UNSUPPORTED;
1305         }
1306 
1307         for (j = 0; j < 8; j++) {
1308             InputParams.nAvcTemporalLayers[j] = arr[j];
1309         }
1310         i += 1;
1311     }
1312     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-BaseLayerPID"))) {
1313         VAL_CHECK(i + 1 >= argc, i, argv[i]);
1314         if (MFX_ERR_NONE != msdk_opt_read(argv[++i], InputParams.nBaseLayerPID)) {
1315             PrintError(argv[0], MSDK_STRING("BaseLayerPID is invalid"));
1316             return MFX_ERR_UNSUPPORTED;
1317         }
1318     }
1319     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-SPSId"))) {
1320         VAL_CHECK(i + 1 >= argc, i, argv[i]);
1321         if (MFX_ERR_NONE != msdk_opt_read(argv[++i], InputParams.nSPSId)) {
1322             PrintError(argv[0], MSDK_STRING("SPSId is invalid"));
1323             return MFX_ERR_UNSUPPORTED;
1324         }
1325     }
1326     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-PPSId"))) {
1327         VAL_CHECK(i + 1 >= argc, i, argv[i]);
1328         if (MFX_ERR_NONE != msdk_opt_read(argv[++i], InputParams.nPPSId)) {
1329             PrintError(argv[0], MSDK_STRING("PPSId is invalid"));
1330             return MFX_ERR_UNSUPPORTED;
1331         }
1332     }
1333     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-lowpower:on"))) {
1334         InputParams.enableQSVFF = true;
1335     }
1336     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-lowpower:off"))) {
1337         InputParams.enableQSVFF = false;
1338     }
1339     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-PicTimingSEI:on"))) {
1340         InputParams.nPicTimingSEI = MFX_CODINGOPTION_ON;
1341     }
1342     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-PicTimingSEI:off"))) {
1343         InputParams.nPicTimingSEI = MFX_CODINGOPTION_OFF;
1344     }
1345     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-NalHrdConformance:on"))) {
1346         InputParams.nNalHrdConformance = MFX_CODINGOPTION_ON;
1347     }
1348     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-NalHrdConformance:off"))) {
1349         InputParams.nNalHrdConformance = MFX_CODINGOPTION_OFF;
1350     }
1351     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-VuiNalHrdParameters:on"))) {
1352         InputParams.nVuiNalHrdParameters = MFX_CODINGOPTION_ON;
1353     }
1354     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-VuiNalHrdParameters:off"))) {
1355         InputParams.nVuiNalHrdParameters = MFX_CODINGOPTION_OFF;
1356     }
1357     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-BitrateLimit:on"))) {
1358         InputParams.BitrateLimit = MFX_CODINGOPTION_ON;
1359     }
1360     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-BitrateLimit:off"))) {
1361         InputParams.BitrateLimit = MFX_CODINGOPTION_OFF;
1362     }
1363     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-AdaptiveI:on"))) {
1364         InputParams.AdaptiveI = MFX_CODINGOPTION_ON;
1365     }
1366     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-AdaptiveI:off"))) {
1367         InputParams.AdaptiveI = MFX_CODINGOPTION_OFF;
1368     }
1369     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-AdaptiveB:on"))) {
1370         InputParams.AdaptiveB = MFX_CODINGOPTION_ON;
1371     }
1372     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-AdaptiveB:off"))) {
1373         InputParams.AdaptiveB = MFX_CODINGOPTION_OFF;
1374     }
1375     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-iGfx"))) {
1376         InputParams.adapterType = mfxMediaAdapterType::MFX_MEDIA_INTEGRATED;
1377     }
1378     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-dGfx"))) {
1379         InputParams.adapterType = mfxMediaAdapterType::MFX_MEDIA_DISCRETE;
1380         if (i + 1 < argc && isdigit(*argv[1 + i])) {
1381             if (MFX_ERR_NONE != msdk_opt_read(argv[++i], InputParams.dGfxIdx)) {
1382                 PrintError(argv[0], MSDK_STRING("value of -dGfx is invalid"));
1383                 return MFX_ERR_UNSUPPORTED;
1384             }
1385         }
1386     }
1387     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-AdapterNum"))) {
1388         VAL_CHECK(i + 1 >= argc, i, argv[i]);
1389         if (MFX_ERR_NONE != msdk_opt_read(argv[++i], InputParams.adapterNum)) {
1390             PrintError(argv[0], MSDK_STRING("Value of -AdapterNum is invalid"));
1391             return MFX_ERR_UNSUPPORTED;
1392         }
1393     }
1394     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-dispatcher:fullSearch"))) {
1395         InputParams.dispFullSearch = true;
1396     }
1397     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-dec::sys"))) {
1398         InputParams.DecOutPattern = MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
1399     }
1400 #ifdef ENABLE_MCTF
1401     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-mctf"))) {
1402         ParseMCTFParams(argv, argc, i, &InputParams);
1403     }
1404 #endif
1405     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-ext_allocator")) ||
1406              0 == msdk_strcmp(argv[i], MSDK_STRING("-MemType::video"))) {
1407         InputParams.bForceSysMem = false;
1408     }
1409     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-sys")) ||
1410              0 == msdk_strcmp(argv[i], MSDK_STRING("-MemType::system"))) {
1411         InputParams.bForceSysMem = true;
1412     }
1413     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-opaq")) ||
1414              0 == msdk_strcmp(argv[i], MSDK_STRING("-MemType::opaque"))) {
1415         msdk_printf(MSDK_STRING(
1416             "WARNING: -opaq option is ignored, opaque memory support is disabled in opeVPL.\n"));
1417     }
1418     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-memory"))) {
1419         VAL_CHECK(i + 1 >= argc, i, argv[i]);
1420         if (MFX_ERR_NONE != msdk_opt_read(argv[++i], InputParams.nMemoryModel)) {
1421             PrintError(MSDK_STRING("-memory %s is invalid"), argv[i]);
1422             return MFX_ERR_UNSUPPORTED;
1423         }
1424         if (InputParams.nMemoryModel < 1 || InputParams.nMemoryModel > 3) {
1425             PrintError(MSDK_STRING(" \"%s\" memory type is invalid. Default (1) will be used."),
1426                        argv[i]);
1427             InputParams.nMemoryModel = GENERAL_ALLOC;
1428         }
1429     }
1430     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-MemModel::GeneralAlloc"))) {
1431         InputParams.nMemoryModel = GENERAL_ALLOC;
1432     }
1433     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-MemModel::VisibleIntAlloc"))) {
1434         InputParams.nMemoryModel = VISIBLE_INT_ALLOC;
1435     }
1436     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-MemModel::HiddenIntAlloc"))) {
1437         InputParams.nMemoryModel = HIDDEN_INT_ALLOC;
1438     }
1439     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-AllocPolicy::optimal"))) {
1440         InputParams.AllocPolicy   = MFX_ALLOCATION_OPTIMAL;
1441         InputParams.useAllocHints = true;
1442     }
1443     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-AllocPolicy::limited"))) {
1444         InputParams.AllocPolicy   = MFX_ALLOCATION_LIMITED;
1445         InputParams.useAllocHints = true;
1446     }
1447     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-AllocPolicy::unlimited"))) {
1448         InputParams.AllocPolicy   = MFX_ALLOCATION_UNLIMITED;
1449         InputParams.useAllocHints = true;
1450     }
1451     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-preallocate"))) {
1452         VAL_CHECK(i + 1 >= argc, i, argv[i]);
1453 
1454         if (MFX_ERR_NONE != msdk_opt_read(argv[++i], InputParams.preallocate)) {
1455             PrintError(MSDK_STRING("preallocate param is invalid"));
1456             return MFX_ERR_UNSUPPORTED;
1457         }
1458     }
1459     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-TargetBitDepthLuma"))) {
1460         VAL_CHECK(i + 1 >= argc, i, argv[i]);
1461 
1462         if (MFX_ERR_NONE != msdk_opt_read(argv[++i], InputParams.TargetBitDepthLuma)) {
1463             PrintError(MSDK_STRING("TargetBitDepthLuma param is invalid"));
1464             return MFX_ERR_UNSUPPORTED;
1465         }
1466     }
1467     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-TargetBitDepthChroma"))) {
1468         VAL_CHECK(i + 1 >= argc, i, argv[i]);
1469 
1470         if (MFX_ERR_NONE != msdk_opt_read(argv[++i], InputParams.TargetBitDepthChroma)) {
1471             PrintError(MSDK_STRING("TargetBitDepthChroma param is invalid"));
1472             return MFX_ERR_UNSUPPORTED;
1473         }
1474     }
1475     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-cs"))) {
1476         InputParams.CascadeScaler = true;
1477     }
1478     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-trace"))) {
1479         InputParams.EnableTracing = true;
1480     }
1481 #if (defined(_WIN64) || defined(_WIN32))
1482     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-dual_gfx::on"))) {
1483         InputParams.isDualMode = true;
1484         InputParams.hyperMode  = MFX_HYPERMODE_ON;
1485     }
1486     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-dual_gfx::off"))) {
1487         InputParams.isDualMode = true;
1488         InputParams.hyperMode  = MFX_HYPERMODE_OFF;
1489     }
1490     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-dual_gfx::adaptive"))) {
1491         InputParams.isDualMode = true;
1492         InputParams.hyperMode  = MFX_HYPERMODE_ADAPTIVE;
1493     }
1494 #endif
1495     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-idr_interval"))) {
1496         VAL_CHECK(i + 1 >= argc, i, argv[i]);
1497         if (MFX_ERR_NONE != msdk_opt_read(argv[++i], InputParams.nIdrInterval)) {
1498             PrintError(argv[0], MSDK_STRING("IdrInterval is invalid"));
1499             return MFX_ERR_UNSUPPORTED;
1500         }
1501     }
1502     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-EmbeddedDenoise"))) {
1503         VAL_CHECK(i + 1 >= argc, i, argv[i]);
1504         if (MFX_ERR_NONE != msdk_opt_read(argv[++i], InputParams.DenoiseMode)) {
1505             PrintError(argv[0], MSDK_STRING("DenoiseMode is invalid"));
1506             return MFX_ERR_UNSUPPORTED;
1507         }
1508         VAL_CHECK(i + 1 >= argc, i, argv[i]);
1509         if (MFX_ERR_NONE != msdk_opt_read(argv[++i], InputParams.DenoiseLevel)) {
1510             PrintError(argv[0], MSDK_STRING("DenoiseLevel is invalid"));
1511             return MFX_ERR_UNSUPPORTED;
1512         }
1513         InputParams.bEmbeddedDenoiser = true;
1514     }
1515     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-MinQPI"))) {
1516         VAL_CHECK(i + 1 >= argc, i, argv[i]);
1517         if (MFX_ERR_NONE != msdk_opt_read(argv[++i], InputParams.nMinQPI)) {
1518             PrintError(MSDK_STRING("Min Quantizer for I frames is invalid"));
1519             return MFX_ERR_UNSUPPORTED;
1520         }
1521     }
1522     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-MinQPP"))) {
1523         VAL_CHECK(i + 1 >= argc, i, argv[i]);
1524         if (MFX_ERR_NONE != msdk_opt_read(argv[++i], InputParams.nMinQPP)) {
1525             PrintError(MSDK_STRING("Min Quantizer for P frames is invalid"));
1526             return MFX_ERR_UNSUPPORTED;
1527         }
1528     }
1529     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-MinQPB"))) {
1530         VAL_CHECK(i + 1 >= argc, i, argv[i]);
1531         if (MFX_ERR_NONE != msdk_opt_read(argv[++i], InputParams.nMinQPB)) {
1532             PrintError(MSDK_STRING("Min Quantizer for B frames is invalid"));
1533             return MFX_ERR_UNSUPPORTED;
1534         }
1535     }
1536     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-MaxQPI"))) {
1537         VAL_CHECK(i + 1 >= argc, i, argv[i]);
1538         if (MFX_ERR_NONE != msdk_opt_read(argv[++i], InputParams.nMaxQPI)) {
1539             PrintError(MSDK_STRING("Max Quantizer for I frames is invalid"));
1540             return MFX_ERR_UNSUPPORTED;
1541         }
1542     }
1543     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-MaxQPP"))) {
1544         VAL_CHECK(i + 1 >= argc, i, argv[i]);
1545         if (MFX_ERR_NONE != msdk_opt_read(argv[++i], InputParams.nMaxQPP)) {
1546             PrintError(MSDK_STRING("Max Quantizer for P frames is invalid"));
1547             return MFX_ERR_UNSUPPORTED;
1548         }
1549     }
1550     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-MaxQPB"))) {
1551         VAL_CHECK(i + 1 >= argc, i, argv[i]);
1552         if (MFX_ERR_NONE != msdk_opt_read(argv[++i], InputParams.nMaxQPB)) {
1553             PrintError(MSDK_STRING("Max Quantizer for B frames is invalid"));
1554             return MFX_ERR_UNSUPPORTED;
1555         }
1556     }
1557     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-NumActiveRefP"))) {
1558         VAL_CHECK(i + 1 == argc, i, argv[i]);
1559         i++;
1560         if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.nNumRefActiveP)) {
1561             PrintError(
1562                 MSDK_STRING("Number of active reference frames for P frames \"%s\" is invalid"),
1563                 argv[i]);
1564             return MFX_ERR_UNSUPPORTED;
1565         }
1566     }
1567 #ifdef ONEVPL_EXPERIMENTAL
1568     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-pci"))) {
1569         msdk_char deviceInfo[MSDK_MAX_FILENAME_LEN];
1570         VAL_CHECK(i + 1 == argc, i, argv[i]);
1571         i++;
1572         SIZE_CHECK((msdk_strlen(argv[i]) + 1) > MSDK_ARRAY_LEN(deviceInfo));
1573         if (MFX_ERR_NONE != msdk_opt_read(argv[i], deviceInfo)) {
1574             PrintError(MSDK_STRING("-pci is invalid"));
1575             return MFX_ERR_UNSUPPORTED;
1576         }
1577 
1578         // template: <domain:bus:device.function>
1579         std::string temp = std::string(deviceInfo);
1580         const std::regex pieces_regex("([0-9]+):([0-9]+):([0-9]+).([0-9]+)");
1581         std::smatch pieces_match;
1582 
1583         // pieces_match = [full match, PCIDomain, PCIBus, PCIDevice, PCIFunction]
1584         if (std::regex_match(temp, pieces_match, pieces_regex) && pieces_match.size() == 5) {
1585             InputParams.PCIDomain      = std::atoi(pieces_match[1].str().c_str());
1586             InputParams.PCIBus         = std::atoi(pieces_match[2].str().c_str());
1587             InputParams.PCIDevice      = std::atoi(pieces_match[3].str().c_str());
1588             InputParams.PCIFunction    = std::atoi(pieces_match[4].str().c_str());
1589             InputParams.PCIDeviceSetup = true;
1590         }
1591         else {
1592             PrintError(
1593                 MSDK_STRING(
1594                     "format of -pci \"%s\" is invalid, please, use: domain:bus:device.function"),
1595                 argv[i]);
1596             return MFX_ERR_UNSUPPORTED;
1597         }
1598     }
1599     #if defined(_WIN32)
1600     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-LUID"))) {
1601         // <HighPart:LowPart>
1602         msdk_char luid[MSDK_MAX_FILENAME_LEN];
1603         VAL_CHECK(i + 1 == argc, i, argv[i]);
1604         i++;
1605         if (MFX_ERR_NONE != msdk_opt_read(argv[i], luid)) {
1606             PrintError(MSDK_STRING("-LUID is invalid"));
1607             return MFX_ERR_UNSUPPORTED;
1608         }
1609 
1610         std::string temp = std::string(luid);
1611         const std::regex pieces_regex("(0[xX][0-9a-fA-F]+):(0[xX][0-9a-fA-F]+)");
1612         std::smatch pieces_match;
1613 
1614         // pieces_match = [full match, HighPart, LowPart]
1615         if (std::regex_match(temp, pieces_match, pieces_regex) && pieces_match.size() == 3) {
1616             InputParams.luid.HighPart = std::strtol(pieces_match[1].str().c_str(), 0, 16);
1617             InputParams.luid.LowPart  = std::strtol(pieces_match[2].str().c_str(), 0, 16);
1618         }
1619         else {
1620             PrintError(
1621                 MSDK_STRING("format of -LUID \"%s\" is invalid, please, use: HighPart:LowPart"),
1622                 argv[i]);
1623             return MFX_ERR_UNSUPPORTED;
1624         }
1625     }
1626     #endif
1627 #endif
1628     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-ivf:on"))) {
1629         InputParams.nIVFHeader = MFX_CODINGOPTION_ON;
1630     }
1631     else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-ivf:off"))) {
1632         InputParams.nIVFHeader = MFX_CODINGOPTION_OFF;
1633     }
1634     else {
1635         // no matching argument was found
1636         return MFX_ERR_NOT_FOUND;
1637     }
1638 
1639     return MFX_ERR_NONE;
1640 }
1641 
ParseVPPCmdLine(msdk_char * argv[],mfxU32 argc,mfxU32 & index,TranscodingSample::sInputParams * params,mfxU32 & skipped)1642 mfxStatus ParseVPPCmdLine(msdk_char* argv[],
1643                           mfxU32 argc,
1644                           mfxU32& index,
1645                           TranscodingSample::sInputParams* params,
1646                           mfxU32& skipped) {
1647     if (0 == msdk_strcmp(argv[index], MSDK_STRING("-denoise"))) {
1648         VAL_CHECK(index + 1 == argc, index, argv[index]);
1649         index++;
1650         if (MFX_ERR_NONE != msdk_opt_read(argv[index], params->DenoiseLevel) ||
1651             !(params->DenoiseLevel >= 0 && params->DenoiseLevel <= 100)) {
1652             PrintError(NULL, MSDK_STRING("-denoise \"%s\" is invalid"), argv[index]);
1653             return MFX_ERR_UNSUPPORTED;
1654         }
1655         skipped += 2;
1656         return MFX_ERR_NONE;
1657     }
1658     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-detail"))) {
1659         VAL_CHECK(index + 1 == argc, index, argv[index]);
1660         index++;
1661         if (MFX_ERR_NONE != msdk_opt_read(argv[index], params->DetailLevel) ||
1662             !(params->DetailLevel >= 0 && params->DetailLevel <= 100)) {
1663             PrintError(NULL, MSDK_STRING("-detail \"%s\" is invalid"), argv[index]);
1664             return MFX_ERR_UNSUPPORTED;
1665         }
1666         skipped += 2;
1667         return MFX_ERR_NONE;
1668     }
1669     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-FRC::PT"))) {
1670         params->FRCAlgorithm = MFX_FRCALGM_PRESERVE_TIMESTAMP;
1671         return MFX_ERR_NONE;
1672     }
1673     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-FRC::DT"))) {
1674         params->FRCAlgorithm = MFX_FRCALGM_DISTRIBUTED_TIMESTAMP;
1675         return MFX_ERR_NONE;
1676     }
1677     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-FRC::INTERP"))) {
1678         params->FRCAlgorithm = MFX_FRCALGM_FRAME_INTERPOLATION;
1679         return MFX_ERR_NONE;
1680     }
1681     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-deinterlace"))) {
1682         params->bEnableDeinterlacing = true;
1683         params->DeinterlacingMode    = 0;
1684         return MFX_ERR_NONE;
1685     }
1686     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-deinterlace::ADI"))) {
1687         params->bEnableDeinterlacing = true;
1688         params->DeinterlacingMode    = MFX_DEINTERLACING_ADVANCED;
1689         return MFX_ERR_NONE;
1690     }
1691     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-deinterlace::ADI_SCD"))) {
1692         params->bEnableDeinterlacing = true;
1693         params->DeinterlacingMode    = MFX_DEINTERLACING_ADVANCED_SCD;
1694         return MFX_ERR_NONE;
1695     }
1696     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-deinterlace::BOB"))) {
1697         params->bEnableDeinterlacing = true;
1698         params->DeinterlacingMode    = MFX_DEINTERLACING_BOB;
1699         return MFX_ERR_NONE;
1700     }
1701     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-deinterlace::ADI_NO_REF"))) {
1702         params->bEnableDeinterlacing = true;
1703         params->DeinterlacingMode    = MFX_DEINTERLACING_ADVANCED_NOREF;
1704         return MFX_ERR_NONE;
1705     }
1706     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-scaling_mode"))) {
1707         VAL_CHECK(index + 1 == argc, index, argv[index]);
1708         index++;
1709         if (0 == msdk_strcmp(argv[index], MSDK_STRING("lowpower")))
1710             params->ScalingMode = MFX_SCALING_MODE_LOWPOWER;
1711         else if (0 == msdk_strcmp(argv[index], MSDK_STRING("quality")))
1712             params->ScalingMode = MFX_SCALING_MODE_QUALITY;
1713         else {
1714             PrintError(NULL, MSDK_STRING("-scaling_mode \"%s\" is invalid"), argv[index]);
1715             return MFX_ERR_UNSUPPORTED;
1716         }
1717         return MFX_ERR_NONE;
1718     }
1719     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-ec::rgb4"))) {
1720         params->EncoderFourCC = MFX_FOURCC_RGB4;
1721         return MFX_ERR_NONE;
1722     }
1723     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-ec::yuy2"))) {
1724         params->EncoderFourCC = MFX_FOURCC_YUY2;
1725         return MFX_ERR_NONE;
1726     }
1727     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-ec::nv12"))) {
1728         params->EncoderFourCC = MFX_FOURCC_NV12;
1729         return MFX_ERR_NONE;
1730     }
1731     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-ec::nv16"))) {
1732         params->EncoderFourCC = MFX_FOURCC_NV16;
1733         return MFX_ERR_NONE;
1734     }
1735     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-ec::p010"))) {
1736         params->EncoderFourCC = MFX_FOURCC_P010;
1737         return MFX_ERR_NONE;
1738     }
1739     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-ec::p210"))) {
1740         params->EncoderFourCC = MFX_FOURCC_P210;
1741         return MFX_ERR_NONE;
1742     }
1743     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-dc::p010"))) {
1744         params->DecoderFourCC = MFX_FOURCC_P010;
1745         return MFX_ERR_NONE;
1746     }
1747     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-dc::p016"))) {
1748         params->DecoderFourCC = MFX_FOURCC_P016;
1749         return MFX_ERR_NONE;
1750     }
1751     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-dc::y216"))) {
1752         params->DecoderFourCC = MFX_FOURCC_Y216;
1753         return MFX_ERR_NONE;
1754     }
1755     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-dc::y416"))) {
1756         params->DecoderFourCC = MFX_FOURCC_Y216;
1757         return MFX_ERR_NONE;
1758     }
1759     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-ec::p016"))) {
1760         params->EncoderFourCC = MFX_FOURCC_P016;
1761         return MFX_ERR_NONE;
1762     }
1763     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-ec::y216"))) {
1764         params->EncoderFourCC = MFX_FOURCC_Y216;
1765         return MFX_ERR_NONE;
1766     }
1767     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-dc::rgb4"))) {
1768         params->DecoderFourCC = MFX_FOURCC_RGB4;
1769         return MFX_ERR_NONE;
1770     }
1771     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-dc::yuy2"))) {
1772         params->DecoderFourCC = MFX_FOURCC_YUY2;
1773         return MFX_ERR_NONE;
1774     }
1775     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-dc::nv12"))) {
1776         params->DecoderFourCC = MFX_FOURCC_NV12;
1777         return MFX_ERR_NONE;
1778     }
1779     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-dc::y210"))) {
1780         params->DecoderFourCC = MFX_FOURCC_Y210;
1781         return MFX_ERR_NONE;
1782     }
1783     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-dc::y410"))) {
1784         params->DecoderFourCC = MFX_FOURCC_Y410;
1785         return MFX_ERR_NONE;
1786     }
1787     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-ec::y210"))) {
1788         params->EncoderFourCC = MFX_FOURCC_Y210;
1789         return MFX_ERR_NONE;
1790     }
1791     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-ec::y410"))) {
1792         params->EncoderFourCC = MFX_FOURCC_Y410;
1793         return MFX_ERR_NONE;
1794     }
1795     else if (0 == msdk_strcmp(argv[index], MSDK_STRING("-field_processing"))) {
1796         VAL_CHECK(index + 1 == argc, index, argv[index]);
1797         index++;
1798         if (0 == msdk_strcmp(argv[index], MSDK_STRING("t2t")))
1799             params->fieldProcessingMode = FC_T2T;
1800         else if (0 == msdk_strcmp(argv[index], MSDK_STRING("t2b")))
1801             params->fieldProcessingMode = FC_T2B;
1802         else if (0 == msdk_strcmp(argv[index], MSDK_STRING("b2t")))
1803             params->fieldProcessingMode = FC_B2T;
1804         else if (0 == msdk_strcmp(argv[index], MSDK_STRING("b2b")))
1805             params->fieldProcessingMode = FC_B2B;
1806         else if (0 == msdk_strcmp(argv[index], MSDK_STRING("fr2fr")))
1807             params->fieldProcessingMode = FC_FR2FR;
1808         else {
1809             PrintError(NULL, MSDK_STRING("-field_processing \"%s\" is invalid"), argv[index]);
1810             return MFX_ERR_UNSUPPORTED;
1811         }
1812         return MFX_ERR_NONE;
1813     }
1814 
1815     return MFX_ERR_MORE_DATA;
1816 }
1817 
ParseParamsForOneSession(mfxU32 argc,msdk_char * argv[])1818 mfxStatus CmdProcessor::ParseParamsForOneSession(mfxU32 argc, msdk_char* argv[]) {
1819     mfxStatus sts           = MFX_ERR_NONE;
1820     mfxStatus stsExtBuf     = MFX_ERR_NONE;
1821     mfxStatus stsAddlParams = MFX_ERR_NONE;
1822     mfxU32 skipped          = 0;
1823 
1824     // save original cmd line for debug purpose
1825     msdk_stringstream cmd;
1826     for (mfxU32 i = 0; i < argc; i++)
1827         cmd << argv[i] << MSDK_STRING(" ");
1828     m_lines.push_back(cmd.str());
1829 
1830     TranscodingSample::sInputParams InputParams;
1831     if (m_nTimeout)
1832         InputParams.nTimeout = m_nTimeout;
1833     if (bRobustFlag)
1834         InputParams.bRobustFlag = true;
1835     if (bSoftRobustFlag)
1836         InputParams.bSoftRobustFlag = true;
1837 
1838     InputParams.shouldUseGreedyFormula = shouldUseGreedyFormula;
1839 
1840     InputParams.statisticsWindowSize = statisticsWindowSize;
1841     InputParams.statisticsLogFile    = statisticsLogFile;
1842 
1843     //bind to a dump-log-file name
1844     InputParams.DumpLogFileName = DumpLogFileName;
1845 
1846     if (0 == msdk_strcmp(argv[0], MSDK_STRING("set"))) {
1847         if (argc != 3) {
1848             msdk_printf(MSDK_STRING("error: number of arguments for 'set' options is wrong"));
1849             return MFX_ERR_UNSUPPORTED;
1850         }
1851         sts = ParseOption__set(argv[1], argv[2]);
1852         return sts;
1853     }
1854     // default implementation
1855     InputParams.libType = MFX_IMPL_HARDWARE_ANY;
1856 #if defined(_WIN32) || defined(_WIN64)
1857     InputParams.libType = MFX_IMPL_HARDWARE_ANY | MFX_IMPL_VIA_D3D11;
1858 #endif
1859     InputParams.eModeExt = Native;
1860 
1861     for (mfxU32 i = 0; i < argc; i++) {
1862         // process multi-character options
1863         if ((0 == msdk_strncmp(MSDK_STRING("-i::"), argv[i], msdk_strlen(MSDK_STRING("-i::")))) &&
1864             (0 != msdk_strncmp(argv[i] + 4,
1865                                MSDK_STRING("source"),
1866                                msdk_strlen(MSDK_STRING("source"))))) {
1867             sts = StrFormatToCodecFormatFourCC(argv[i] + 4, InputParams.DecodeId);
1868             if (sts != MFX_ERR_NONE) {
1869                 return MFX_ERR_UNSUPPORTED;
1870             }
1871             VAL_CHECK(i + 1 == argc, i, argv[i]);
1872             i++;
1873             SIZE_CHECK((msdk_strlen(argv[i]) + 1) > MSDK_ARRAY_LEN(InputParams.strSrcFile));
1874             msdk_opt_read(argv[i], InputParams.strSrcFile);
1875             if (InputParams.eMode == Source) {
1876                 switch (InputParams.DecodeId) {
1877                     case MFX_CODEC_MPEG2:
1878                     case MFX_CODEC_HEVC:
1879                     case MFX_CODEC_AVC:
1880                     case MFX_CODEC_VC1:
1881                     case MFX_CODEC_VP9:
1882                     case MFX_CODEC_AV1:
1883                     case CODEC_MVC:
1884                     case MFX_CODEC_JPEG:
1885                         return MFX_ERR_UNSUPPORTED;
1886                 }
1887             }
1888             if (InputParams.DecodeId == CODEC_MVC) {
1889                 InputParams.DecodeId = MFX_CODEC_AVC;
1890                 InputParams.bIsMVC   = true;
1891             }
1892         }
1893         else if ((0 ==
1894                   msdk_strncmp(MSDK_STRING("-o::"), argv[i], msdk_strlen(MSDK_STRING("-o::")))) &&
1895                  (0 != msdk_strncmp(argv[i] + 4,
1896                                     MSDK_STRING("sink"),
1897                                     msdk_strlen(MSDK_STRING("sink"))))) {
1898             sts = StrFormatToCodecFormatFourCC(argv[i] + 4, InputParams.EncodeId);
1899 
1900             if (sts != MFX_ERR_NONE) {
1901                 return MFX_ERR_UNSUPPORTED;
1902             }
1903             VAL_CHECK(i + 1 == argc, i, argv[i]);
1904             i++;
1905             SIZE_CHECK((msdk_strlen(argv[i]) + 1) > MSDK_ARRAY_LEN(InputParams.strDstFile));
1906             msdk_opt_read(argv[i], InputParams.strDstFile);
1907             if (InputParams.eMode == Sink || InputParams.bIsMVC) {
1908                 switch (InputParams.EncodeId) {
1909                     case MFX_CODEC_MPEG2:
1910                     case MFX_CODEC_HEVC:
1911                     case MFX_CODEC_AVC:
1912                     case MFX_CODEC_JPEG:
1913                     case MFX_CODEC_DUMP:
1914                         return MFX_ERR_UNSUPPORTED;
1915                 }
1916             }
1917             if (InputParams.EncodeId == CODEC_MVC) {
1918                 if (InputParams.eMode == Sink)
1919                     return MFX_ERR_UNSUPPORTED;
1920 
1921                 InputParams.EncodeId = MFX_CODEC_AVC;
1922                 InputParams.bIsMVC   = true;
1923             }
1924         }
1925         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-roi_file"))) {
1926             VAL_CHECK(i + 1 == argc, i, argv[i]);
1927             i++;
1928 
1929             msdk_char strRoiFile[MSDK_MAX_FILENAME_LEN];
1930             SIZE_CHECK((msdk_strlen(argv[i]) + 1) > MSDK_ARRAY_LEN(strRoiFile));
1931             msdk_opt_read(argv[i], strRoiFile);
1932 
1933             if (!ParseROIFile(strRoiFile, InputParams.m_ROIData)) {
1934                 PrintError(MSDK_STRING("Incorrect ROI file: \"%s\" "), argv[i]);
1935                 return MFX_ERR_UNSUPPORTED;
1936             }
1937         }
1938         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-p"))) {
1939             if (m_PerfFILE) {
1940                 msdk_printf(MSDK_STRING("error: only one performance file is supported"));
1941                 return MFX_ERR_UNSUPPORTED;
1942             }
1943             --argc;
1944             ++argv;
1945             if (!argv[i]) {
1946                 msdk_printf(MSDK_STRING("error: no argument given for '-p' option\n"));
1947             }
1948             MSDK_FOPEN(m_PerfFILE, argv[i], MSDK_STRING("w"));
1949             if (NULL == m_PerfFILE) {
1950                 msdk_printf(MSDK_STRING("error: performance file \"%s\" not found"), argv[i]);
1951                 return MFX_ERR_UNSUPPORTED;
1952             }
1953         }
1954         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-roi_qpmap"))) {
1955             InputParams.bROIasQPMAP = true;
1956         }
1957         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-extmbqp"))) {
1958             InputParams.bExtMBQP = true;
1959         }
1960         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-sw"))) {
1961             InputParams.libType = MFX_IMPL_SOFTWARE;
1962         }
1963         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-hw"))) {
1964 #if defined(_WIN32) || defined(_WIN64)
1965             InputParams.libType = MFX_IMPL_HARDWARE_ANY | MFX_IMPL_VIA_D3D11;
1966 #elif defined(LIBVA_SUPPORT)
1967             InputParams.libType = MFX_IMPL_HARDWARE_ANY;
1968 #endif
1969         }
1970         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-hw_d3d11"))) {
1971             InputParams.libType = MFX_IMPL_HARDWARE_ANY | MFX_IMPL_VIA_D3D11;
1972         }
1973         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-hw_d3d9"))) {
1974             InputParams.libType = MFX_IMPL_HARDWARE_ANY | MFX_IMPL_VIA_D3D9;
1975         }
1976 #if (defined(LINUX32) || defined(LINUX64))
1977         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-device"))) {
1978             if (!InputParams.strDevicePath.empty()) {
1979                 msdk_printf(MSDK_STRING("error: you can specify only one device\n"));
1980                 return MFX_ERR_UNSUPPORTED;
1981             }
1982 
1983             VAL_CHECK(i + 1 == argc, i, argv[i]);
1984             InputParams.strDevicePath = argv[++i];
1985 
1986             size_t pos = InputParams.strDevicePath.find("renderD");
1987             if (pos != std::string::npos) {
1988                 InputParams.DRMRenderNodeNum =
1989                     std::stoi(InputParams.strDevicePath.substr(pos + 7, 3));
1990             }
1991         }
1992 #endif
1993         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-robust"))) {
1994             InputParams.bRobustFlag = true;
1995         }
1996         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-robust:soft"))) {
1997             InputParams.bSoftRobustFlag = true;
1998         }
1999         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-threads"))) {
2000             VAL_CHECK(i + 1 == argc, i, argv[i]);
2001             i++;
2002             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.nThreadsNum)) {
2003                 PrintError(MSDK_STRING("Threads number is invalid"));
2004                 return MFX_ERR_UNSUPPORTED;
2005             }
2006         }
2007         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-f"))) {
2008             VAL_CHECK(i + 1 == argc, i, argv[i]);
2009             i++;
2010             // Temporary check for giving priority to -fe option
2011             if (!InputParams.dVPPOutFramerate) {
2012                 if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.dVPPOutFramerate)) {
2013                     PrintError(MSDK_STRING("FrameRate \"%s\" is invalid"), argv[i]);
2014                     return MFX_ERR_UNSUPPORTED;
2015                 }
2016             }
2017         }
2018         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-fe"))) {
2019             VAL_CHECK(i + 1 == argc, i, argv[i]);
2020             i++;
2021             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.dVPPOutFramerate)) {
2022                 PrintError(MSDK_STRING("FrameRate \"%s\" is invalid"), argv[i]);
2023                 return MFX_ERR_UNSUPPORTED;
2024             }
2025         }
2026         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-fps"))) {
2027             VAL_CHECK(i + 1 == argc, i, argv[i]);
2028             i++;
2029             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.nFPS)) {
2030                 PrintError(MSDK_STRING("FPS limit \"%s\" is invalid"), argv[i]);
2031                 return MFX_ERR_UNSUPPORTED;
2032             }
2033         }
2034         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-b"))) {
2035             VAL_CHECK(i + 1 == argc, i, argv[i]);
2036             i++;
2037             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.nBitRate)) {
2038                 PrintError(MSDK_STRING("BitRate \"%s\" is invalid"), argv[i]);
2039                 return MFX_ERR_UNSUPPORTED;
2040             }
2041         }
2042         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-bm"))) {
2043             VAL_CHECK(i + 1 == argc, i, argv[i]);
2044             i++;
2045             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.nBitRateMultiplier)) {
2046                 PrintError(MSDK_STRING("Bitrate multiplier \"%s\" is invalid"), argv[i]);
2047                 return MFX_ERR_UNSUPPORTED;
2048             }
2049         }
2050         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-wb"))) {
2051             VAL_CHECK(i + 1 == argc, i, argv[i]);
2052             i++;
2053             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.WinBRCMaxAvgKbps)) {
2054                 PrintError(MSDK_STRING("Maximum bitrate for sliding window \"%s\" is invalid"),
2055                            argv[i]);
2056                 return MFX_ERR_UNSUPPORTED;
2057             }
2058         }
2059         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-ws"))) {
2060             VAL_CHECK(i + 1 == argc, i, argv[i]);
2061             i++;
2062             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.WinBRCSize)) {
2063                 PrintError(MSDK_STRING("Sliding window size \"%s\" is invalid"), argv[i]);
2064                 return MFX_ERR_UNSUPPORTED;
2065             }
2066         }
2067         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-hrd"))) {
2068             VAL_CHECK(i + 1 == argc, i, argv[i]);
2069             i++;
2070             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.BufferSizeInKB)) {
2071                 PrintError(MSDK_STRING("Frame buffer size \"%s\" is invalid"), argv[i]);
2072                 return MFX_ERR_UNSUPPORTED;
2073             }
2074         }
2075         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-dist"))) {
2076             VAL_CHECK(i + 1 == argc, i, argv[i]);
2077             i++;
2078             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.GopRefDist)) {
2079                 PrintError(MSDK_STRING("GOP reference distance \"%s\" is invalid"), argv[i]);
2080                 return MFX_ERR_UNSUPPORTED;
2081             }
2082         }
2083         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-gop_size"))) {
2084             VAL_CHECK(i + 1 == argc, i, argv[i]);
2085             i++;
2086             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.GopPicSize)) {
2087                 PrintError(MSDK_STRING("GOP size \"%s\" is invalid"), argv[i]);
2088                 return MFX_ERR_UNSUPPORTED;
2089             }
2090         }
2091         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-num_ref"))) {
2092             VAL_CHECK(i + 1 == argc, i, argv[i]);
2093             i++;
2094             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.NumRefFrame)) {
2095                 PrintError(MSDK_STRING("Number of reference frames \"%s\" is invalid"), argv[i]);
2096                 return MFX_ERR_UNSUPPORTED;
2097             }
2098         }
2099         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-trows"))) {
2100             VAL_CHECK(i + 1 == argc, i, argv[i]);
2101             i++;
2102             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.nEncTileRows)) {
2103                 PrintError(MSDK_STRING("Encoding tile row count \"%s\" is invalid"), argv[i]);
2104                 return MFX_ERR_UNSUPPORTED;
2105             }
2106         }
2107         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-tcols"))) {
2108             VAL_CHECK(i + 1 == argc, i, argv[i]);
2109             i++;
2110             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.nEncTileCols)) {
2111                 PrintError(MSDK_STRING("Encoding tile column count \"%s\" is invalid"), argv[i]);
2112                 return MFX_ERR_UNSUPPORTED;
2113             }
2114         }
2115         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-CodecLevel"))) {
2116             VAL_CHECK(i + 1 == argc, i, argv[i]);
2117             i++;
2118             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.CodecLevel)) {
2119                 PrintError(MSDK_STRING("CodecLevel \"%s\" is invalid"), argv[i]);
2120                 return MFX_ERR_UNSUPPORTED;
2121             }
2122         }
2123         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-CodecProfile"))) {
2124             VAL_CHECK(i + 1 == argc, i, argv[i]);
2125             i++;
2126             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.CodecProfile)) {
2127                 PrintError(MSDK_STRING("CodecProfile \"%s\" is invalid"), argv[i]);
2128                 return MFX_ERR_UNSUPPORTED;
2129             }
2130         }
2131         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-MaxKbps"))) {
2132             VAL_CHECK(i + 1 == argc, i, argv[i]);
2133             i++;
2134             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.MaxKbps)) {
2135                 PrintError(MSDK_STRING("MaxKbps \"%s\" is invalid"), argv[i]);
2136                 return MFX_ERR_UNSUPPORTED;
2137             }
2138         }
2139         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-InitialDelayInKB"))) {
2140             VAL_CHECK(i + 1 == argc, i, argv[i]);
2141             i++;
2142             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.InitialDelayInKB)) {
2143                 PrintError(MSDK_STRING("InitialDelayInKB \"%s\" is invalid"), argv[i]);
2144                 return MFX_ERR_UNSUPPORTED;
2145             }
2146         }
2147         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-GopOptFlag:closed"))) {
2148             InputParams.GopOptFlag = MFX_GOP_CLOSED;
2149         }
2150         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-GopOptFlag:strict"))) {
2151             InputParams.GopOptFlag = MFX_GOP_STRICT;
2152         }
2153         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-bref"))) {
2154             InputParams.nBRefType = MFX_B_REF_PYRAMID;
2155         }
2156         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-nobref"))) {
2157             InputParams.nBRefType = MFX_B_REF_OFF;
2158         }
2159         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-gpb:on"))) {
2160             InputParams.GPB = MFX_CODINGOPTION_ON;
2161         }
2162         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-gpb:off"))) {
2163             InputParams.GPB = MFX_CODINGOPTION_OFF;
2164         }
2165         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-TransformSkip:on"))) {
2166             InputParams.nTransformSkip = MFX_CODINGOPTION_ON;
2167         }
2168         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-TransformSkip:off"))) {
2169             InputParams.nTransformSkip = MFX_CODINGOPTION_OFF;
2170         }
2171         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-u"))) {
2172             VAL_CHECK(i + 1 == argc, i, argv[i]);
2173             i++;
2174             InputParams.nTargetUsage = StrToTargetUsage(argv[i]);
2175             if (!InputParams.nTargetUsage) {
2176                 PrintError(MSDK_STRING(" \"%s\" target usage is invalid. Balanced will be used."),
2177                            argv[i]);
2178                 InputParams.nTargetUsage = MFX_TARGETUSAGE_BALANCED;
2179             }
2180         }
2181         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-WeightedPred::default"))) {
2182             InputParams.WeightedPred = MFX_WEIGHTED_PRED_DEFAULT;
2183         }
2184         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-WeightedPred::implicit"))) {
2185             InputParams.WeightedPred = MFX_WEIGHTED_PRED_IMPLICIT;
2186         }
2187         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-WeightedBiPred::default"))) {
2188             InputParams.WeightedBiPred = MFX_WEIGHTED_PRED_DEFAULT;
2189         }
2190         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-WeightedBiPred::implicit"))) {
2191             InputParams.WeightedBiPred = MFX_WEIGHTED_PRED_IMPLICIT;
2192         }
2193         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-q"))) {
2194             VAL_CHECK(i + 1 == argc, i, argv[i]);
2195             i++;
2196             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.nQuality)) {
2197                 PrintError(MSDK_STRING(" \"%s\" quality is invalid"), argv[i]);
2198                 return MFX_ERR_UNSUPPORTED;
2199             }
2200         }
2201         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-w"))) {
2202             VAL_CHECK(i + 1 == argc, i, argv[i]);
2203             i++;
2204             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.nDstWidth)) {
2205                 PrintError(MSDK_STRING("width \"%s\" is invalid"), argv[i]);
2206                 return MFX_ERR_UNSUPPORTED;
2207             }
2208         }
2209         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-h"))) {
2210             VAL_CHECK(i + 1 == argc, i, argv[i]);
2211             i++;
2212             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.nDstHeight)) {
2213                 PrintError(MSDK_STRING("height \"%s\" is invalid"), argv[i]);
2214                 return MFX_ERR_UNSUPPORTED;
2215             }
2216         }
2217         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-l"))) {
2218             VAL_CHECK(i + 1 == argc, i, argv[i]);
2219             i++;
2220             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.nSlices)) {
2221                 PrintError(MSDK_STRING("numSlices \"%s\" is invalid"), argv[i]);
2222                 return MFX_ERR_UNSUPPORTED;
2223             }
2224         }
2225         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-mss"))) {
2226             VAL_CHECK(i + 1 == argc, i, argv[i]);
2227             i++;
2228             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.nMaxSliceSize)) {
2229                 PrintError(MSDK_STRING("maxSliceSize \"%s\" is invalid"), argv[i]);
2230                 return MFX_ERR_UNSUPPORTED;
2231             }
2232         }
2233         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-async"))) {
2234             VAL_CHECK(i + 1 == argc, i, argv[i]);
2235             i++;
2236             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.nAsyncDepth)) {
2237                 PrintError(MSDK_STRING("async \"%s\" is invalid"), argv[i]);
2238                 return MFX_ERR_UNSUPPORTED;
2239             }
2240         }
2241         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-join"))) {
2242             InputParams.bIsJoin = true;
2243         }
2244         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-priority"))) {
2245             VAL_CHECK(i + 1 == argc, i, argv[i]);
2246             i++;
2247             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.priority)) {
2248                 PrintError(MSDK_STRING("priority \"%s\" is invalid"), argv[i]);
2249                 return MFX_ERR_UNSUPPORTED;
2250             }
2251         }
2252         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-i::source"))) {
2253             if (InputParams.eMode != Native) {
2254                 PrintError(NULL, "-i::source cannot be used here");
2255                 return MFX_ERR_UNSUPPORTED;
2256             }
2257 
2258             InputParams.eMode = Source;
2259         }
2260         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-o::sink"))) {
2261             if (InputParams.eMode != Native) {
2262                 PrintError(NULL, "-o::sink cannot be used here");
2263                 return MFX_ERR_UNSUPPORTED;
2264             }
2265 
2266             InputParams.eMode = Sink;
2267         }
2268         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-vpp_comp"))) {
2269             VAL_CHECK(i + 1 == argc, i, argv[i]);
2270             i++;
2271             /* NB! numSurf4Comp should be equal to Number of decoding session */
2272             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.numSurf4Comp)) {
2273                 PrintError(MSDK_STRING("-n \"%s\" is invalid"), argv[i]);
2274                 return MFX_ERR_UNSUPPORTED;
2275             }
2276             /* This is can init early */
2277             if (InputParams.eModeExt == Native)
2278                 InputParams.eModeExt = VppComp;
2279         }
2280         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-vpp_comp_only"))) {
2281             /* for VPP comp with rendering we have to use ext allocator */
2282 #ifdef LIBVA_SUPPORT
2283             InputParams.libvaBackend = MFX_LIBVA_DRM;
2284 #endif
2285 
2286             VAL_CHECK(i + 1 == argc, i, argv[i]);
2287             i++;
2288             /* NB! numSurf4Comp should be equal to Number of decoding session */
2289             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.numSurf4Comp)) {
2290                 PrintError(MSDK_STRING("-n \"%s\" is invalid"), argv[i]);
2291                 return MFX_ERR_UNSUPPORTED;
2292             }
2293             /* This is can init early */
2294             if (InputParams.eModeExt == Native)
2295                 InputParams.eModeExt = VppCompOnly;
2296         }
2297         else if (0 == msdk_strncmp(MSDK_STRING("-vpp_comp_dump"),
2298                                    argv[i],
2299                                    msdk_strlen(MSDK_STRING("-vpp_comp_dump")))) {
2300             VAL_CHECK(i + 1 == argc, i, argv[i]);
2301             i++;
2302             SIZE_CHECK((msdk_strlen(argv[i]) + 1) > MSDK_ARRAY_LEN(InputParams.strDumpVppCompFile));
2303             msdk_opt_read(argv[i], InputParams.strDumpVppCompFile);
2304         }
2305 #if defined(LIBVA_X11_SUPPORT)
2306         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-rx11"))) {
2307             InputParams.libvaBackend = MFX_LIBVA_X11;
2308         }
2309 #endif
2310 
2311 #if defined(LIBVA_WAYLAND_SUPPORT)
2312         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-rwld"))) {
2313             InputParams.nRenderWinX  = 0;
2314             InputParams.nRenderWinY  = 0;
2315             InputParams.bPerfMode    = false;
2316             InputParams.libvaBackend = MFX_LIBVA_WAYLAND;
2317         }
2318 #endif
2319 
2320 #if defined(LIBVA_DRM_SUPPORT)
2321         else if (0 == msdk_strncmp(argv[i], MSDK_STRING("-rdrm"), 5)) {
2322             InputParams.libvaBackend = MFX_LIBVA_DRM_MODESET;
2323             InputParams.monitorType  = getMonitorType(&argv[i][5]);
2324             if (argv[i][5]) {
2325                 if (argv[i][5] != '-') {
2326                     PrintError(MSDK_STRING("unsupported monitor type"));
2327                     return MFX_ERR_UNSUPPORTED;
2328                 }
2329                 InputParams.monitorType = getMonitorType(&argv[i][6]);
2330                 if (InputParams.monitorType >= MFX_MONITOR_MAXNUMBER) {
2331                     PrintError(MSDK_STRING("unsupported monitor type"));
2332                     return MFX_ERR_UNSUPPORTED;
2333                 }
2334             }
2335             else {
2336                 InputParams.monitorType = MFX_MONITOR_AUTO; // that's case of "-rdrm" pure option
2337             }
2338         }
2339 #endif
2340         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-vpp::sys"))) {
2341             InputParams.VppOutPattern = MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
2342         }
2343         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-vpp::vid"))) {
2344             InputParams.VppOutPattern = MFX_IOPATTERN_OUT_VIDEO_MEMORY;
2345         }
2346         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-vpp_comp_dst_x"))) {
2347             VAL_CHECK(i + 1 == argc, i, argv[i]);
2348             i++;
2349             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.nVppCompDstX)) {
2350                 PrintError(MSDK_STRING("vpp_comp_dst_x %s is invalid"), argv[i]);
2351                 return MFX_ERR_UNSUPPORTED;
2352             }
2353             if (InputParams.eModeExt != VppComp)
2354                 InputParams.eModeExt = VppComp;
2355         }
2356         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-vpp_comp_dst_y"))) {
2357             VAL_CHECK(i + 1 == argc, i, argv[i]);
2358             i++;
2359             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.nVppCompDstY)) {
2360                 PrintError(MSDK_STRING("-vpp_comp_dst_y %s is invalid"), argv[i]);
2361                 return MFX_ERR_UNSUPPORTED;
2362             }
2363             if (InputParams.eModeExt != VppComp)
2364                 InputParams.eModeExt = VppComp;
2365         }
2366         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-vpp_comp_dst_w"))) {
2367             VAL_CHECK(i + 1 == argc, i, argv[i]);
2368             i++;
2369             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.nVppCompDstW)) {
2370                 PrintError(MSDK_STRING("-vpp_comp_dst_w %s is invalid"), argv[i]);
2371                 return MFX_ERR_UNSUPPORTED;
2372             }
2373             if (InputParams.eModeExt != VppComp)
2374                 InputParams.eModeExt = VppComp;
2375         }
2376         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-vpp_comp_dst_h"))) {
2377             VAL_CHECK(i + 1 == argc, i, argv[i]);
2378             i++;
2379             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.nVppCompDstH)) {
2380                 PrintError(MSDK_STRING("-vpp_comp_dst_h %s is invalid"), argv[i]);
2381                 return MFX_ERR_UNSUPPORTED;
2382             }
2383             if (InputParams.eModeExt != VppComp)
2384                 InputParams.eModeExt = VppComp;
2385         }
2386         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-vpp_comp_src_w"))) {
2387             VAL_CHECK(i + 1 == argc, i, argv[i]);
2388             i++;
2389             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.nVppCompSrcW)) {
2390                 PrintError(MSDK_STRING("-vpp_comp_src_w %s is invalid"), argv[i]);
2391                 return MFX_ERR_UNSUPPORTED;
2392             }
2393             if (InputParams.eModeExt != VppComp)
2394                 InputParams.eModeExt = VppComp;
2395         }
2396         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-vpp_comp_src_h"))) {
2397             VAL_CHECK(i + 1 == argc, i, argv[i]);
2398             i++;
2399             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.nVppCompSrcH)) {
2400                 PrintError(MSDK_STRING("-vpp_comp_src_h %s is invalid"), argv[i]);
2401                 return MFX_ERR_UNSUPPORTED;
2402             }
2403             if (InputParams.eModeExt != VppComp)
2404                 InputParams.eModeExt = VppComp;
2405         }
2406         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-vpp_comp_num_tiles"))) {
2407             VAL_CHECK(i + 1 == argc, i, argv[i]);
2408             i++;
2409             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.numTiles4Comp)) {
2410                 PrintError(MSDK_STRING("-vpp_comp_num_tiles %s is invalid"), argv[i]);
2411                 return MFX_ERR_UNSUPPORTED;
2412             }
2413             if (InputParams.eModeExt != VppCompOnly)
2414                 InputParams.eModeExt = VppCompOnly;
2415         }
2416         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-vpp_comp_tile_id"))) {
2417             VAL_CHECK(i + 1 == argc, i, argv[i]);
2418             i++;
2419             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.nVppCompTileId)) {
2420                 PrintError(MSDK_STRING("-vpp_comp_tile_id %s is invalid"), argv[i]);
2421                 return MFX_ERR_UNSUPPORTED;
2422             }
2423         }
2424         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-vpp_comp_render"))) {
2425             if (InputParams.eModeExt != VppComp)
2426                 InputParams.eModeExt = VppComp;
2427         }
2428         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-dec_postproc"))) {
2429             InputParams.bDecoderPostProcessing = true;
2430         }
2431         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-n"))) {
2432             VAL_CHECK(i + 1 == argc, i, argv[i]);
2433             i++;
2434             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.MaxFrameNumber)) {
2435                 PrintError(MSDK_STRING("-n %s is invalid"), argv[i]);
2436                 return MFX_ERR_UNSUPPORTED;
2437             }
2438         }
2439         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-angle"))) {
2440             VAL_CHECK(i + 1 == argc, i, argv[i]);
2441             i++;
2442             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.nRotationAngle)) {
2443                 PrintError(MSDK_STRING("-angle %s is invalid"), argv[i]);
2444                 return MFX_ERR_UNSUPPORTED;
2445             }
2446             if (InputParams.strVPPPluginDLLPath[0] == '\0') {
2447                 msdk_opt_read(MSDK_CPU_ROTATE_PLUGIN, InputParams.strVPPPluginDLLPath);
2448             }
2449         }
2450         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-mfe_frames"))) {
2451             VAL_CHECK(i + 1 == argc, i, argv[i]);
2452             i++;
2453             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.numMFEFrames)) {
2454                 PrintError(MSDK_STRING("-mfe_frames %s num frames is invalid"), argv[i]);
2455                 return MFX_ERR_UNSUPPORTED;
2456             }
2457         }
2458         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-mfe_mode"))) {
2459             VAL_CHECK(i + 1 == argc, i, argv[i]);
2460             i++;
2461             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.MFMode)) {
2462                 PrintError(MSDK_STRING("-mfe_mode %s is invalid"), argv[i]);
2463                 return MFX_ERR_UNSUPPORTED;
2464             }
2465         }
2466         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-mfe_timeout"))) {
2467             VAL_CHECK(i + 1 == argc, i, argv[i]);
2468             i++;
2469             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.mfeTimeout)) {
2470                 PrintError(MSDK_STRING("-mfe_timeout %s is invalid"), argv[i]);
2471                 return MFX_ERR_UNSUPPORTED;
2472             }
2473         }
2474         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-timeout"))) {
2475             VAL_CHECK(i + 1 == argc, i, argv[i]);
2476             i++;
2477             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.nTimeout)) {
2478                 PrintError(MSDK_STRING("-timeout %s is invalid"), argv[i]);
2479                 return MFX_ERR_UNSUPPORTED;
2480             }
2481             skipped += 2;
2482         }
2483         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-dump"))) {
2484             VAL_CHECK(i + 1 == argc, i, argv[i]);
2485             i++;
2486             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.strMfxParamsDumpFile)) {
2487                 PrintError(MSDK_STRING("Dump file name \"%s\" is invalid"), argv[i]);
2488                 return MFX_ERR_UNSUPPORTED;
2489             }
2490         }
2491         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-robust"))) {
2492             InputParams.bRobustFlag = true;
2493         }
2494         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-opencl"))) {
2495             msdk_opt_read(MSDK_OCL_ROTATE_PLUGIN, InputParams.strVPPPluginDLLPath);
2496             InputParams.bOpenCL = true;
2497         }
2498 
2499         // output PicStruct
2500         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-la_ext"))) {
2501             InputParams.bEnableExtLA = true;
2502         }
2503         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-la"))) {
2504             InputParams.bLABRC             = true;
2505             InputParams.nRateControlMethod = MFX_RATECONTROL_LA;
2506         }
2507         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-vbr"))) {
2508             InputParams.nRateControlMethod = MFX_RATECONTROL_VBR;
2509         }
2510         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-cbr"))) {
2511             InputParams.nRateControlMethod = MFX_RATECONTROL_CBR;
2512         }
2513         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-bpyr"))) {
2514             InputParams.bEnableBPyramid = true;
2515         }
2516         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-vcm"))) {
2517             InputParams.nRateControlMethod = MFX_RATECONTROL_VCM;
2518         }
2519         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-lad"))) {
2520             VAL_CHECK(i + 1 == argc, i, argv[i]);
2521             i++;
2522             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.nLADepth)) {
2523                 PrintError(MSDK_STRING("look ahead depth \"%s\" is invalid"), argv[i]);
2524                 return MFX_ERR_UNSUPPORTED;
2525             }
2526         }
2527         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-pe"))) {
2528             VAL_CHECK(i + 1 == argc, i, argv[i]);
2529             InputParams.encoderPluginParams = ParsePluginGuid(argv[i + 1]);
2530             if (AreGuidsEqual(InputParams.encoderPluginParams.pluginGuid, MSDK_PLUGINGUID_NULL)) {
2531                 PrintError(MSDK_STRING("Invalid encoder guid"), argv[i]);
2532                 return MFX_ERR_UNSUPPORTED;
2533             }
2534             i++;
2535         }
2536         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-pd"))) {
2537             VAL_CHECK(i + 1 == argc, i, argv[i]);
2538             InputParams.decoderPluginParams = ParsePluginGuid(argv[i + 1]);
2539             if (AreGuidsEqual(InputParams.decoderPluginParams.pluginGuid, MSDK_PLUGINGUID_NULL)) {
2540                 PrintError(MSDK_STRING("Invalid decoder guid"), argv[i]);
2541                 return MFX_ERR_UNSUPPORTED;
2542             }
2543             i++;
2544         }
2545         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-override_decoder_framerate"))) {
2546             VAL_CHECK(i + 1 == argc, i, argv[i]);
2547             i++;
2548             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.dDecoderFrameRateOverride)) {
2549                 PrintError(MSDK_STRING("Framerate \"%s\" is invalid"), argv[i]);
2550                 return MFX_ERR_UNSUPPORTED;
2551             }
2552         }
2553         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-override_encoder_framerate"))) {
2554             VAL_CHECK(i + 1 == argc, i, argv[i]);
2555             i++;
2556             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.dEncoderFrameRateOverride)) {
2557                 PrintError(MSDK_STRING("Framerate \"%s\" is invalid"), argv[i]);
2558                 return MFX_ERR_UNSUPPORTED;
2559             }
2560         }
2561         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-override_encoder_picstruct"))) {
2562             VAL_CHECK(i + 1 == argc, i, argv[i]);
2563             i++;
2564             if (MFX_ERR_NONE != msdk_opt_read(argv[i], InputParams.EncoderPicstructOverride)) {
2565                 PrintError(MSDK_STRING("Picstruct \"%s\" is invalid"), argv[i]);
2566                 return MFX_ERR_UNSUPPORTED;
2567             }
2568         }
2569         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-gpucopy::on"))) {
2570             InputParams.nGpuCopyMode = MFX_GPUCOPY_ON;
2571         }
2572         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-gpucopy::off"))) {
2573             InputParams.nGpuCopyMode = MFX_GPUCOPY_OFF;
2574         }
2575         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-repartitioncheck::on"))) {
2576             InputParams.RepartitionCheckMode = MFX_CODINGOPTION_ON;
2577         }
2578         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-repartitioncheck::off"))) {
2579             InputParams.RepartitionCheckMode = MFX_CODINGOPTION_OFF;
2580         }
2581         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-cqp"))) {
2582             InputParams.nRateControlMethod = MFX_RATECONTROL_CQP;
2583         }
2584         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-qpi"))) {
2585             VAL_CHECK(i + 1 == argc, i, argv[i]);
2586             if (MFX_ERR_NONE != msdk_opt_read(argv[++i], InputParams.nQPI)) {
2587                 PrintError(MSDK_STRING("Quantizer for I frames is invalid"));
2588                 return MFX_ERR_UNSUPPORTED;
2589             }
2590         }
2591         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-qpp"))) {
2592             VAL_CHECK(i + 1 == argc, i, argv[i]);
2593             if (MFX_ERR_NONE != msdk_opt_read(argv[++i], InputParams.nQPP)) {
2594                 PrintError(MSDK_STRING("Quantizer for P frames is invalid"));
2595                 return MFX_ERR_UNSUPPORTED;
2596             }
2597         }
2598         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-qpb"))) {
2599             VAL_CHECK(i + 1 == argc, i, argv[i]);
2600             if (MFX_ERR_NONE != msdk_opt_read(argv[++i], InputParams.nQPB)) {
2601                 PrintError(MSDK_STRING("Quantizer for B frames is invalid"));
2602                 return MFX_ERR_UNSUPPORTED;
2603             }
2604         }
2605         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-DisableQPOffset"))) {
2606             InputParams.bDisableQPOffset = true;
2607         }
2608         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-qsv-ff"))) {
2609             InputParams.enableQSVFF = true;
2610         }
2611         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-single_texture_d3d11"))) {
2612             InputParams.bSingleTexture = true;
2613         }
2614         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-extbrc::on"))) {
2615             InputParams.nExtBRC = EXTBRC_ON;
2616         }
2617         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-extbrc::off"))) {
2618             InputParams.nExtBRC = EXTBRC_OFF;
2619         }
2620         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-extbrc::implicit"))) {
2621             InputParams.nExtBRC = EXTBRC_IMPLICIT;
2622         }
2623         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-ExtBrcAdaptiveLTR:on"))) {
2624             InputParams.ExtBrcAdaptiveLTR = MFX_CODINGOPTION_ON;
2625         }
2626         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-ExtBrcAdaptiveLTR:off"))) {
2627             InputParams.ExtBrcAdaptiveLTR = MFX_CODINGOPTION_OFF;
2628         }
2629         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-pp"))) {
2630             InputParams.shouldPrintPresets = true;
2631         }
2632         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-preset"))) {
2633             msdk_char presetName[MSDK_MAX_FILENAME_LEN];
2634             VAL_CHECK(i + 1 >= argc, i, argv[i]);
2635             if (MFX_ERR_NONE != msdk_opt_read(argv[++i], presetName)) {
2636                 PrintError(MSDK_STRING("Preset Name is not defined"));
2637                 return MFX_ERR_UNSUPPORTED;
2638             }
2639 
2640             InputParams.PresetMode = CPresetManager::PresetNameToMode(presetName);
2641             if (InputParams.PresetMode == PRESET_MAX_MODES) {
2642                 PrintError(MSDK_STRING("Preset Name is invalid"));
2643                 return MFX_ERR_UNSUPPORTED;
2644             }
2645         }
2646         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-forceSyncAllSession:on"))) {
2647             InputParams.forceSyncAllSession = MFX_CODINGOPTION_ON;
2648         }
2649         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-forceSyncAllSession:off"))) {
2650             InputParams.forceSyncAllSession = MFX_CODINGOPTION_OFF;
2651         }
2652         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-ir_type"))) {
2653             VAL_CHECK(i + 1 >= argc, i, argv[i]);
2654 
2655             if (MFX_ERR_NONE != msdk_opt_read(argv[++i], InputParams.IntRefType)) {
2656                 PrintError(MSDK_STRING("Intra refresh type is invalid"));
2657                 return MFX_ERR_UNSUPPORTED;
2658             }
2659         }
2660         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-ir_cycle_size"))) {
2661             VAL_CHECK(i + 1 >= argc, i, argv[i]);
2662 
2663             if (MFX_ERR_NONE != msdk_opt_read(argv[++i], InputParams.IntRefCycleSize)) {
2664                 PrintError(MSDK_STRING("IR refresh cycle size param is invalid"));
2665                 return MFX_ERR_UNSUPPORTED;
2666             }
2667         }
2668         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-ir_qp_delta"))) {
2669             VAL_CHECK(i + 1 >= argc, i, argv[i]);
2670 
2671             if (MFX_ERR_NONE != msdk_opt_read(argv[++i], InputParams.IntRefQPDelta)) {
2672                 PrintError(MSDK_STRING("IR QP delta param is invalid"));
2673                 return MFX_ERR_UNSUPPORTED;
2674             }
2675         }
2676         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-ir_cycle_dist"))) {
2677             VAL_CHECK(i + 1 >= argc, i, argv[i]);
2678 
2679             if (MFX_ERR_NONE != msdk_opt_read(argv[++i], InputParams.IntRefCycleDist)) {
2680                 PrintError(MSDK_STRING("IR cycle distance param is invalid"));
2681                 return MFX_ERR_UNSUPPORTED;
2682             }
2683         }
2684         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-LowDelayBRC"))) {
2685             InputParams.LowDelayBRC = MFX_CODINGOPTION_ON;
2686         }
2687         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-amfs:on"))) {
2688             InputParams.nAdaptiveMaxFrameSize = MFX_CODINGOPTION_ON;
2689         }
2690         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-amfs:off"))) {
2691             InputParams.nAdaptiveMaxFrameSize = MFX_CODINGOPTION_OFF;
2692         }
2693         else if (0 == msdk_strcmp(argv[i], MSDK_STRING("-mfs"))) {
2694             VAL_CHECK(i + 1 >= argc, i, argv[i]);
2695             if (MFX_ERR_NONE != msdk_opt_read(argv[++i], InputParams.nMaxFrameSize)) {
2696                 PrintError(MSDK_STRING("MaxFrameSize is invalid"));
2697                 return MFX_ERR_UNSUPPORTED;
2698             }
2699         }
2700         MOD_SMT_PARSE_INPUT
2701         else if ((stsExtBuf = ParseVPPCmdLine(argv, argc, i, &InputParams, skipped)) !=
2702                  MFX_ERR_MORE_DATA) {
2703             if (stsExtBuf == MFX_ERR_UNSUPPORTED) {
2704                 return MFX_ERR_UNSUPPORTED;
2705             }
2706         }
2707         else {
2708             // WA for compiler error C1061 (too many chained else-if clauses)
2709             // ParseAdditionalParams returns:
2710             //    0  if argv[i] is processed successfully by this function
2711             //  < 1  if argv[i] is processed and generates an error
2712             //          OR
2713             //       if argv[i] was not processed (did not match any switches)
2714             stsAddlParams = ParseAdditionalParams(argv, argc, i, InputParams);
2715 
2716             // either unrecognized parameter, or parse error with recognized parameter
2717             if (stsAddlParams) {
2718                 if (stsAddlParams == MFX_ERR_NOT_FOUND)
2719                     PrintError(MSDK_STRING("Invalid input argument number %d %s"), i, argv[i]);
2720                 return MFX_ERR_UNSUPPORTED;
2721             }
2722         }
2723     }
2724 
2725     if (skipped < argc) {
2726         sts = VerifyAndCorrectInputParams(InputParams);
2727         MSDK_CHECK_STATUS(sts, "VerifyAndCorrectInputParams failed");
2728         m_SessionArray.push_back(InputParams);
2729     }
2730 
2731     return MFX_ERR_NONE;
2732 
2733 } //mfxStatus CmdProcessor::ParseParamsForOneSession(msdk_char *pLine, mfxU32 length)
2734 
ParseOption__set(msdk_char * strCodecType,msdk_char * strPluginGuid)2735 mfxStatus CmdProcessor::ParseOption__set(msdk_char* strCodecType, msdk_char* strPluginGuid) {
2736     mfxU32 codecid = 0;
2737     mfxU32 type    = 0;
2738     sPluginParams pluginParams;
2739 
2740     //Parse codec type - decoder or encoder
2741     if (0 == msdk_strncmp(MSDK_STRING("-i::"), strCodecType, 4)) {
2742         type = MSDK_VDECODE;
2743     }
2744     else if (0 == msdk_strncmp(MSDK_STRING("-o::"), strCodecType, 4)) {
2745         type = MSDK_VENCODE;
2746     }
2747     else {
2748         msdk_printf(MSDK_STRING("error: incorrect definition codec type (must be -i:: or -o::)\n"));
2749         return MFX_ERR_UNSUPPORTED;
2750     }
2751 
2752     if (StrFormatToCodecFormatFourCC(strCodecType + 4, codecid) != MFX_ERR_NONE) {
2753         msdk_printf(MSDK_STRING("error: codec is unknown\n"));
2754         return MFX_ERR_UNSUPPORTED;
2755     }
2756 
2757     if (!IsPluginCodecSupported(codecid)) {
2758         msdk_printf(MSDK_STRING("error: codec is unsupported\n"));
2759         return MFX_ERR_UNSUPPORTED;
2760     }
2761 
2762     pluginParams = ParsePluginGuid(strPluginGuid);
2763     if (AreGuidsEqual(pluginParams.pluginGuid, MSDK_PLUGINGUID_NULL)) {
2764         msdk_printf(MSDK_STRING("error: invalid codec guid\n"));
2765         return MFX_ERR_UNSUPPORTED;
2766     }
2767 
2768     if (type == MSDK_VDECODE)
2769         m_decoderPlugins.insert(std::pair<mfxU32, sPluginParams>(codecid, pluginParams));
2770     else
2771         m_encoderPlugins.insert(std::pair<mfxU32, sPluginParams>(codecid, pluginParams));
2772 
2773     return MFX_ERR_NONE;
2774 };
2775 
VerifyAndCorrectInputParams(TranscodingSample::sInputParams & InputParams)2776 mfxStatus CmdProcessor::VerifyAndCorrectInputParams(TranscodingSample::sInputParams& InputParams) {
2777     if (0 == msdk_strlen(InputParams.strSrcFile) &&
2778         (InputParams.eMode == Sink || InputParams.eMode == Native)) {
2779         PrintError(MSDK_STRING("Source file name not found"));
2780         return MFX_ERR_UNSUPPORTED;
2781     };
2782 
2783     if (0 == msdk_strlen(InputParams.strDstFile) &&
2784         (InputParams.eMode == Source || InputParams.eMode == Native ||
2785          InputParams.eMode == VppComp) &&
2786         InputParams.eModeExt != VppCompOnly) {
2787         PrintError(MSDK_STRING("Destination file name not found"));
2788         return MFX_ERR_UNSUPPORTED;
2789     };
2790 
2791     if (MFX_CODEC_JPEG != InputParams.EncodeId && MFX_CODEC_MPEG2 != InputParams.EncodeId &&
2792         MFX_CODEC_AVC != InputParams.EncodeId && MFX_CODEC_HEVC != InputParams.EncodeId &&
2793         MFX_CODEC_VP9 != InputParams.EncodeId && MFX_CODEC_DUMP != InputParams.EncodeId &&
2794         MFX_CODEC_AV1 != InputParams.EncodeId && InputParams.eMode != Sink &&
2795         InputParams.eModeExt != VppCompOnly) {
2796         PrintError(MSDK_STRING("Unknown encoder\n"));
2797         return MFX_ERR_UNSUPPORTED;
2798     }
2799 
2800     if (MFX_CODEC_MPEG2 != InputParams.DecodeId && MFX_CODEC_AVC != InputParams.DecodeId &&
2801         MFX_CODEC_HEVC != InputParams.DecodeId && MFX_CODEC_VC1 != InputParams.DecodeId &&
2802         MFX_CODEC_JPEG != InputParams.DecodeId && MFX_CODEC_VP9 != InputParams.DecodeId &&
2803         MFX_CODEC_VP8 != InputParams.DecodeId && MFX_CODEC_AV1 != InputParams.DecodeId &&
2804         MFX_CODEC_RGB4 != InputParams.DecodeId && MFX_CODEC_NV12 != InputParams.DecodeId &&
2805         MFX_CODEC_I420 != InputParams.DecodeId && InputParams.eMode != Source) {
2806         PrintError(MSDK_STRING("Unknown decoder\n"));
2807         return MFX_ERR_UNSUPPORTED;
2808     }
2809 
2810     if (MFX_CODEC_I420 == InputParams.DecodeId || MFX_CODEC_NV12 == InputParams.DecodeId) {
2811         InputParams.rawInput = true;
2812     }
2813     else {
2814         InputParams.rawInput = false;
2815     }
2816 
2817     if (MFX_CODEC_RGB4 == InputParams.DecodeId &&
2818         (!InputParams.nVppCompSrcH || !InputParams.nVppCompSrcW)) {
2819         PrintError(MSDK_STRING(
2820             "VppCompSrcH and VppCompSrcW must be specified in case of -i::rgb4_frame\n"));
2821         return MFX_ERR_UNSUPPORTED;
2822     }
2823 
2824     if ((!InputParams.FRCAlgorithm && !InputParams.bEnableDeinterlacing) &&
2825         InputParams.dVPPOutFramerate) {
2826         msdk_printf(MSDK_STRING(
2827             "-f option is ignored, it can be used with FRC or deinterlace options only. \n"));
2828         InputParams.dVPPOutFramerate = 0;
2829     }
2830 
2831     if (InputParams.FRCAlgorithm && InputParams.bEnableExtLA) {
2832         PrintError(MSDK_STRING("-la_ext and FRC options cannot be used together\n"));
2833         return MFX_ERR_UNSUPPORTED;
2834     }
2835 
2836     if (InputParams.nQuality && InputParams.EncodeId && (MFX_CODEC_JPEG != InputParams.EncodeId)) {
2837         PrintError(MSDK_STRING("-q option is supported only for JPEG encoder\n"));
2838         return MFX_ERR_UNSUPPORTED;
2839     }
2840 
2841     if ((InputParams.nTargetUsage || InputParams.nBitRate) &&
2842         (MFX_CODEC_JPEG == InputParams.EncodeId)) {
2843         PrintError(MSDK_STRING(
2844             "-b and -u options are supported only for H.264, MPEG2 and MVC encoders. For JPEG encoder use -q\n"));
2845         return MFX_ERR_UNSUPPORTED;
2846     }
2847 
2848     // valid target usage range is: [MFX_TARGETUSAGE_BEST_QUALITY .. MFX_TARGETUSAGE_BEST_SPEED] (at the moment [1..7])
2849     // If target usage is kept unknown - presets manager will fill in proper value
2850     if ((InputParams.nTargetUsage < MFX_TARGETUSAGE_UNKNOWN) ||
2851         (InputParams.nTargetUsage > MFX_TARGETUSAGE_BEST_SPEED)) {
2852         PrintError(NULL, "Unsupported target usage");
2853         return MFX_ERR_UNSUPPORTED;
2854     }
2855 
2856     // Ignoring user-defined Async Depth for LA
2857     if (InputParams.nMaxSliceSize) {
2858         InputParams.nAsyncDepth = 1;
2859     }
2860 
2861     // For decoder session of inter-session case, let's set AsyncDepth to 4 by default
2862     if (InputParams.eMode == Sink && !InputParams.nAsyncDepth) {
2863         InputParams.nAsyncDepth = 4;
2864     }
2865 
2866     if (InputParams.bLABRC && !(InputParams.libType & MFX_IMPL_HARDWARE_ANY)) {
2867         PrintError(MSDK_STRING("Look ahead BRC is supported only with -hw option!"));
2868         return MFX_ERR_UNSUPPORTED;
2869     }
2870 
2871     if (InputParams.bLABRC && (InputParams.EncodeId != MFX_CODEC_AVC) &&
2872         (InputParams.eMode == Source)) {
2873         PrintError(MSDK_STRING("Look ahead BRC is supported only with H.264 encoder!"));
2874         return MFX_ERR_UNSUPPORTED;
2875     }
2876 
2877     if ((InputParams.nRateControlMethod == MFX_RATECONTROL_LA ||
2878          InputParams.nRateControlMethod == MFX_RATECONTROL_LA_EXT ||
2879          InputParams.nRateControlMethod == MFX_RATECONTROL_LA_ICQ ||
2880          InputParams.nRateControlMethod == MFX_RATECONTROL_LA_HRD) &&
2881         (InputParams.nLADepth > 100)) {
2882         PrintError(MSDK_STRING(
2883             "Unsupported value of -lad parameter, must be in range [1,100] or 0 for automatic selection"));
2884         return MFX_ERR_UNSUPPORTED;
2885     }
2886 
2887     if (!InputParams.nRateControlMethod && InputParams.nLADepth) {
2888         InputParams.nRateControlMethod = MFX_RATECONTROL_LA;
2889     }
2890 
2891     if ((InputParams.nMaxSliceSize) && !(InputParams.libType & MFX_IMPL_HARDWARE_ANY)) {
2892         PrintError(MSDK_STRING("MaxSliceSize option is supported only with -hw option!"));
2893         return MFX_ERR_UNSUPPORTED;
2894     }
2895     if ((InputParams.nMaxSliceSize) && (InputParams.nSlices)) {
2896         PrintError(MSDK_STRING("-mss and -l options are not compatible!"));
2897     }
2898     if ((InputParams.nMaxSliceSize) && (InputParams.EncodeId != MFX_CODEC_AVC)) {
2899         PrintError(MSDK_STRING("MaxSliceSize option is supported only with H.264 encoder!"));
2900         return MFX_ERR_UNSUPPORTED;
2901     }
2902 
2903     if (InputParams.BitrateLimit == MFX_CODINGOPTION_UNKNOWN) {
2904         InputParams.BitrateLimit = MFX_CODINGOPTION_OFF;
2905     }
2906 
2907     if (InputParams.enableQSVFF && InputParams.eMode == Sink) {
2908         msdk_printf(MSDK_STRING(
2909             "WARNING: -lowpower(-qsv-ff) option is not valid for decoder-only sessions, this parameter will be ignored.\n"));
2910     }
2911 
2912     std::map<mfxU32, sPluginParams>::iterator it;
2913 
2914     // Set decoder plugins parameters only if they were not set before
2915     if (!memcmp(InputParams.decoderPluginParams.pluginGuid.Data,
2916                 MSDK_PLUGINGUID_NULL.Data,
2917                 sizeof(MSDK_PLUGINGUID_NULL)) &&
2918         !strcmp(InputParams.decoderPluginParams.strPluginPath, "")) {
2919         it = m_decoderPlugins.find(InputParams.DecodeId);
2920         if (it != m_decoderPlugins.end())
2921             InputParams.decoderPluginParams = it->second;
2922     }
2923     else {
2924         // Decoding plugin was set manually, so let's check if codec supports plugins
2925         if (!IsPluginCodecSupported(InputParams.DecodeId)) {
2926             msdk_printf(MSDK_STRING("error: decoder does not support plugins\n"));
2927             return MFX_ERR_UNSUPPORTED;
2928         }
2929     }
2930 
2931     // Set encoder plugins parameters only if they were not set before
2932     if (!memcmp(InputParams.encoderPluginParams.pluginGuid.Data,
2933                 MSDK_PLUGINGUID_NULL.Data,
2934                 sizeof(MSDK_PLUGINGUID_NULL)) &&
2935         !strcmp(InputParams.encoderPluginParams.strPluginPath, "")) {
2936         it = m_encoderPlugins.find(InputParams.EncodeId);
2937         if (it != m_encoderPlugins.end())
2938             InputParams.encoderPluginParams = it->second;
2939     }
2940     else {
2941         // Encoding plugin was set manually, so let's check if codec supports plugins
2942         if (!IsPluginCodecSupported(InputParams.EncodeId)) {
2943             msdk_printf(MSDK_STRING("error: encoder does not support plugins\n"));
2944             return MFX_ERR_UNSUPPORTED;
2945         }
2946     }
2947 
2948     if (InputParams.EncoderFourCC && InputParams.eMode == Sink) {
2949         msdk_printf(MSDK_STRING(
2950             "WARNING: -ec option is used in session without encoder, this parameter will be ignored \n"));
2951     }
2952 
2953     if (InputParams.DecoderFourCC && InputParams.eMode != Native && InputParams.eMode != Sink) {
2954         msdk_printf(MSDK_STRING(
2955             "WARNING: -dc option is used in session without decoder, this parameter will be ignored \n"));
2956     }
2957 
2958     if (InputParams.EncoderFourCC && InputParams.EncoderFourCC != MFX_FOURCC_NV12 &&
2959         InputParams.EncoderFourCC != MFX_FOURCC_RGB4 &&
2960         InputParams.EncoderFourCC != MFX_FOURCC_YUY2 && InputParams.EncodeId == MFX_CODEC_DUMP) {
2961         PrintError(MSDK_STRING(
2962             "-o::raw option can be used with NV12, RGB4 and YUY2 color formats only.\n"));
2963         return MFX_ERR_UNSUPPORTED;
2964     }
2965 
2966     if ((InputParams.nEncTileRows || InputParams.nEncTileCols) &&
2967         (InputParams.EncodeId != MFX_CODEC_HEVC) && (InputParams.EncodeId != MFX_CODEC_VP9)) {
2968         msdk_printf(MSDK_STRING("WARNING: -trows and -tcols are only supported for") MSDK_STRING(
2969             " VP9 and") MSDK_STRING(" HEVC encoder, these parameters will be ignored.\n"));
2970         InputParams.nEncTileRows = 0;
2971         InputParams.nEncTileCols = 0;
2972     }
2973 
2974     if (InputParams.forceSyncAllSession && InputParams.nMemoryModel == GENERAL_ALLOC) {
2975         msdk_printf(MSDK_STRING(
2976             "WARNING: forceSyncAllSession option is not valid for general memory type, this parameter will be ignored.\n"));
2977     }
2978 
2979     mfxU16 mfxU16Limit = std::numeric_limits<mfxU16>::max();
2980     if (InputParams.MaxKbps > mfxU16Limit || InputParams.nBitRate > mfxU16Limit ||
2981         InputParams.InitialDelayInKB > mfxU16Limit || InputParams.BufferSizeInKB > mfxU16Limit) {
2982         mfxU32 maxVal = std::max<mfxU32>({ InputParams.MaxKbps,
2983                                            InputParams.nBitRate,
2984                                            InputParams.InitialDelayInKB,
2985                                            InputParams.BufferSizeInKB });
2986         InputParams.nBitRateMultiplier =
2987             (mfxU16)std::ceil(static_cast<double>(maxVal) / mfxU16Limit);
2988         msdk_printf(MSDK_STRING("WARNING: BitRateMultiplier(-bm) was updated, new value: %d. \n"),
2989                     InputParams.nBitRateMultiplier);
2990 
2991         auto recalculate = [mfxU16Limit, InputParams](mfxU32& param, std::string paramName) {
2992             if (param) {
2993                 if (param > mfxU16Limit) {
2994                     msdk_printf(MSDK_STRING("WARNING: %s (%d) > allow limit (%d). \n"),
2995                                 paramName.c_str(),
2996                                 param,
2997                                 mfxU16Limit);
2998                 }
2999                 param = param / InputParams.nBitRateMultiplier;
3000                 msdk_printf(MSDK_STRING("WARNING: %s was updated, new value: %d. \n"),
3001                             paramName.c_str(),
3002                             param);
3003             }
3004         };
3005 
3006         recalculate(InputParams.MaxKbps, "MaxKbps");
3007         recalculate(InputParams.nBitRate, "nBitRate(-b)");
3008         recalculate(InputParams.InitialDelayInKB, "InitialDelayInKB");
3009         recalculate(InputParams.BufferSizeInKB, "BufferSizeInKB");
3010     }
3011 
3012     return MFX_ERR_NONE;
3013 } //mfxStatus CmdProcessor::VerifyAndCorrectInputParams(TranscodingSample::sInputParams &InputParams)
3014 
GetNextSessionParams(TranscodingSample::sInputParams & InputParams)3015 bool CmdProcessor::GetNextSessionParams(TranscodingSample::sInputParams& InputParams) {
3016     if (!m_SessionArray.size())
3017         return false;
3018     if (m_SessionParamId == m_SessionArray.size()) {
3019         return false;
3020     }
3021     InputParams = m_SessionArray[m_SessionParamId];
3022 
3023     m_SessionParamId++;
3024     return true;
3025 
3026 } //bool  CmdProcessor::GetNextSessionParams(TranscodingSample::sInputParams &InputParams)
3027