extras: tools: Update to meson 0.49.1
[vlc.git] / modules / codec / qsv.c
1 /*****************************************************************************
2  * qsv.c: mpeg4-part10/mpeg2 video encoder using Intel Media SDK
3  *****************************************************************************
4  * Copyright (C) 2013 VideoLabs
5  *
6  * Authors: Julien 'Lta' BALLET <contact@lta.io>
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation; either version 2.1 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21  *****************************************************************************/
22
23 /*****************************************************************************
24  * Preamble
25  *****************************************************************************/
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <vlc_common.h>
31 #include <vlc_plugin.h>
32 #include <vlc_picture.h>
33 #include <vlc_codec.h>
34 #include <vlc_picture_pool.h>
35
36 #include <vlc_fifo_helper.h>
37
38 #include <mfx/mfxvideo.h>
39 #include "../demux/mpeg/timestamps.h"
40
41 #define SOUT_CFG_PREFIX     "sout-qsv-"
42
43 #define QSV_HAVE_CO2 (MFX_VERSION_MAJOR > 1 || (MFX_VERSION_MAJOR == 1 && MFX_VERSION_MINOR >= 6))
44
45 /* Default wait on libavcodec */
46 #define QSV_SYNCPOINT_WAIT  (1000)
47 /* Encoder input synchronization busy wait loop time */
48 #define QSV_BUSYWAIT_TIME   VLC_HARD_MIN_SLEEP
49 /* The SDK doesn't have a default bitrate, so here's one. */
50 #define QSV_BITRATE_DEFAULT (842)
51
52 /* Makes x a multiple of 'align'. 'align' must be a power of 2 */
53 #define QSV_ALIGN(align, x)     (((x)+(align)-1)&~((align)-1))
54
55 /*****************************************************************************
56  * Modules descriptor
57  *****************************************************************************/
58 static int      Open(vlc_object_t *);
59 static void     Close(vlc_object_t *);
60
61 #define SW_IMPL_TEXT N_("Enable software mode")
62 #define SW_IMPL_LONGTEXT N_("Allow the use of the Intel Media SDK software " \
63      "implementation of the codecs if no QuickSync Video hardware " \
64      "acceleration is present on the system.")
65
66 #define PROFILE_TEXT N_("Codec Profile")
67 #define PROFILE_LONGTEXT N_( \
68     "Specify the codec profile explicitly. If you don't, the codec will " \
69     "determine the correct profile from other sources, such as resolution " \
70     "and bitrate. E.g. 'high'")
71
72 #define LEVEL_TEXT N_("Codec Level")
73 #define LEVEL_LONGTEXT N_( \
74     "Specify the codec level explicitly. If you don't, the codec will " \
75     "determine the correct profile from other sources, such as resolution " \
76     "and bitrate. E.g. '4.2' for mpeg4-part10 or 'low' for mpeg2")
77
78 #define GOP_SIZE_TEXT N_("Group of Picture size")
79 #define GOP_SIZE_LONGTEXT N_( \
80     "Number of pictures within the current GOP (Group of Pictures); if " \
81     "GopPicSize=0, then the GOP size is unspecified. If GopPicSize=1, " \
82     "only I-frames are used.")
83
84 #define GOP_REF_DIST_TEXT N_("Group of Picture Reference Distance")
85 #define GOP_REF_DIST_LONGTEXT N_( \
86     "Distance between I- or P- key frames; if it is zero, the GOP " \
87     "structure is unspecified. Note: If GopRefDist = 1, there are no B-" \
88     "frames used.")
89
90 #define TARGET_USAGE_TEXT N_("Target Usage")
91 #define TARGET_USAGE_LONGTEXT N_("The target usage allow to choose between " \
92     "different trade-offs between quality and speed. Allowed values are: " \
93     "'speed', 'balanced' and 'quality'.")
94
95 #define IDR_INTERVAL_TEXT N_("IDR interval")
96 #define IDR_INTERVAL_LONGTEXT N_( \
97     "For H.264, IdrInterval specifies IDR-frame interval in terms of I-" \
98     "frames; if IdrInterval=0, then every I-frame is an IDR-frame. If " \
99     "IdrInterval=1, then every other I-frame is an IDR-frame, etc. " \
100     "For MPEG2, IdrInterval defines sequence header interval in terms " \
101     "of I-frames. If IdrInterval=N, SDK inserts the sequence header " \
102     "before every Nth I-frame. If IdrInterval=0 (default), SDK inserts " \
103     "the sequence header once at the beginning of the stream.")
104
105 #define RATE_CONTROL_TEXT N_("Rate Control Method")
106 #define RATE_CONTROL_LONGTEXT N_( \
107     "The rate control method to use when encoding. Can be one of " \
108     "'cbr', 'vbr', 'qp', 'avbr'. 'qp' mode isn't supported for mpeg2.")
109
110 #define QP_TEXT N_("Quantization parameter")
111 #define QP_LONGTEXT N_("Quantization parameter for all types of frames. " \
112     "This parameters sets qpi, qpp and qpb. It has less precedence than " \
113     "the forementionned parameters. Used only if rc_method is 'qp'.")
114
115 #define QPI_TEXT N_("Quantization parameter for I-frames")
116 #define QPI_LONGTEXT N_("Quantization parameter for I-frames. This parameter " \
117     "overrides any qp set globally. Used only if rc_method is 'qp'.")
118
119 #define QPP_TEXT N_("Quantization parameter for P-frames")
120 #define QPP_LONGTEXT N_("Quantization parameter for P-frames. This parameter " \
121     "overrides any qp set globally. Used only if rc_method is 'qp'.")
122
123 #define QPB_TEXT N_("Quantization parameter for B-frames")
124 #define QPB_LONGTEXT N_("Quantization parameter for B-frames. This parameter " \
125     "overrides any qp set globally. Used only if rc_method is 'qp'.")
126
127 #define MAX_BITRATE_TEXT N_("Maximum Bitrate")
128 #define MAX_BITRATE_LONGTEXT N_("Defines the maximum bitrate in kbps " \
129     "(1000 bits/s) for VBR rate control method. If not set, this parameter" \
130     " is computed from other sources such as bitrate, profile, level, etc.")
131
132 #define ACCURACY_TEXT N_("Accuracy of RateControl")
133 #define ACCURACY_LONGTEXT N_("Tolerance in percentage of the 'avbr' " \
134     " (Average Variable BitRate) method. (e.g. 10 with a bitrate of 800 " \
135     " kbps means the encoder tries not to  go above 880 kbps and under " \
136     " 730 kbps. The targeted accuracy is only reached after a certained " \
137     " convergence period. See the convergence parameter")
138
139 #define CONVERGENCE_TEXT N_("Convergence time of 'avbr' RateControl")
140 #define CONVERGENCE_LONGTEXT N_("Number of 100 frames before the " \
141     "'avbr' rate control method reaches the requested bitrate with " \
142     "the requested accuracy. See the accuracy parameter.")
143
144 #define NUM_SLICE_TEXT N_("Number of slices per frame")
145 #define NUM_SLICE_LONGTEXT N_("Number of slices in each video frame; "\
146     "each slice contains one or more macro-block rows. If numslice is " \
147     "not set, the encoder may choose any slice partitioning allowed " \
148     "by the codec standard.")
149
150 #define NUM_REF_FRAME_TEXT N_("Number of reference frames")
151 #define NUM_REF_FRAME_LONGTEXT N_("Number of reference frames")
152
153 #define ASYNC_DEPTH_TEXT N_("Number of parallel operations")
154 #define ASYNC_DEPTH_LONGTEXT N_("Defines the number of parallel " \
155      "encoding operations before we synchronise the result. Higher " \
156      "numbers may result on better throughput depending on hardware. " \
157      "MPEG2 needs at least 1 here.")
158
159 static const int profile_h264_list[] =
160       { MFX_PROFILE_UNKNOWN, MFX_PROFILE_AVC_CONSTRAINED_BASELINE, MFX_PROFILE_AVC_MAIN,
161       MFX_PROFILE_AVC_EXTENDED, MFX_PROFILE_AVC_HIGH };
162 static const char *const profile_h264_text[] =
163     { "decide", "baseline", "main", "extended", "high" };
164
165 static const int profile_mpeg2_list[] =
166     { MFX_PROFILE_UNKNOWN, MFX_PROFILE_MPEG2_SIMPLE, MFX_PROFILE_MPEG2_MAIN,
167       MFX_PROFILE_MPEG2_HIGH };
168 static const char *const profile_mpeg2_text[] =
169     { "decide", "simple", "main", "high" };
170
171 static const int level_h264_list[] =
172     { MFX_LEVEL_UNKNOWN, MFX_LEVEL_AVC_1, MFX_LEVEL_AVC_1b, MFX_LEVEL_AVC_12,
173       MFX_LEVEL_AVC_13, MFX_LEVEL_AVC_2, MFX_LEVEL_AVC_21, MFX_LEVEL_AVC_22,
174       MFX_LEVEL_AVC_3, MFX_LEVEL_AVC_31, MFX_LEVEL_AVC_32, MFX_LEVEL_AVC_4,
175       MFX_LEVEL_AVC_41, MFX_LEVEL_AVC_42, MFX_LEVEL_AVC_5, MFX_LEVEL_AVC_51,
176       MFX_LEVEL_AVC_52};
177 static const char *const level_h264_text[] =
178     { "decide", "1", "1.1b", "1.2", "1.3", "2", "2.1", "2.2", "3", "3.1",
179       "3.2", "4", "4.1",   "4.2",   "5", "5.1", "5.2" };
180
181 static const int level_mpeg2_list[] =
182     { MFX_LEVEL_UNKNOWN, MFX_LEVEL_MPEG2_LOW, MFX_LEVEL_MPEG2_MAIN,
183       MFX_LEVEL_MPEG2_HIGH, MFX_LEVEL_MPEG2_HIGH1440 };
184 static const char *const level_mpeg2_text[] =
185     { "decide", "low", "main", "high", "high1440" };
186
187 static const int target_usage_list[] =
188     { MFX_TARGETUSAGE_UNKNOWN, MFX_TARGETUSAGE_BEST_QUALITY, MFX_TARGETUSAGE_BALANCED,
189       MFX_TARGETUSAGE_BEST_SPEED };
190 static const char *const target_usage_text[] =
191     { "decide", "quality", "balanced", "speed" };
192
193 static const int rc_method_list[] =
194     { MFX_RATECONTROL_CBR, MFX_RATECONTROL_VBR,
195       MFX_RATECONTROL_CQP, MFX_RATECONTROL_AVBR};
196 static const char *const rc_method_text[] =
197     { "cbr", "vbr", "qp", "avbr" };
198
199 vlc_module_begin ()
200     set_category(CAT_INPUT)
201     set_subcategory(SUBCAT_INPUT_VCODEC)
202     set_description(N_("Intel QuickSync Video encoder for MPEG4-Part10/MPEG2 (aka H.264/H.262)"))
203     set_shortname("qsv")
204     set_capability("encoder", 0)
205     set_callbacks(Open, Close)
206
207     add_bool(SOUT_CFG_PREFIX "software", false, SW_IMPL_TEXT, SW_IMPL_LONGTEXT, true)
208
209     add_string(SOUT_CFG_PREFIX "h264-profile", "unspecified" , PROFILE_TEXT, PROFILE_LONGTEXT, false)
210         change_string_list(profile_h264_text, profile_h264_text)
211
212     add_string(SOUT_CFG_PREFIX "h264-level", "unspecified", LEVEL_TEXT, LEVEL_LONGTEXT, false)
213         change_string_list(level_h264_text, level_h264_text)
214
215     add_string(SOUT_CFG_PREFIX "mpeg2-profile", "unspecified", PROFILE_TEXT, PROFILE_LONGTEXT, false)
216         change_string_list(profile_mpeg2_text, profile_mpeg2_text)
217
218     add_string(SOUT_CFG_PREFIX "mpeg2-level", "unspecified", LEVEL_TEXT, LEVEL_LONGTEXT, false)
219         change_string_list(level_mpeg2_text, level_mpeg2_text)
220
221     add_integer(SOUT_CFG_PREFIX "gop-size", 32, GOP_SIZE_TEXT, GOP_SIZE_LONGTEXT, true)
222     add_integer(SOUT_CFG_PREFIX "gop-refdist", 4, GOP_REF_DIST_TEXT, GOP_REF_DIST_LONGTEXT, true)
223     add_integer(SOUT_CFG_PREFIX "idr-interval", 0, IDR_INTERVAL_TEXT, IDR_INTERVAL_LONGTEXT, true)
224
225     add_string(SOUT_CFG_PREFIX "target-usage", "quality", TARGET_USAGE_TEXT, TARGET_USAGE_LONGTEXT, false)
226         change_string_list(target_usage_text, target_usage_text)
227
228     add_string(SOUT_CFG_PREFIX "rc-method", "vbr", RATE_CONTROL_TEXT, RATE_CONTROL_LONGTEXT, true)
229         change_string_list(rc_method_text, rc_method_text)
230
231     add_integer(SOUT_CFG_PREFIX "qp", 0, QP_TEXT, QP_LONGTEXT, true)
232         change_integer_range(0, 51)
233     add_integer(SOUT_CFG_PREFIX "qpi", 0, QPI_TEXT, QPI_LONGTEXT, true)
234         change_integer_range(0, 51)
235     add_integer(SOUT_CFG_PREFIX "qpp", 0, QPP_TEXT, QPP_LONGTEXT, true)
236         change_integer_range(0, 51)
237     add_integer(SOUT_CFG_PREFIX "qpb", 0, QPB_TEXT, QPB_LONGTEXT, true)
238         change_integer_range(0, 51)
239
240     add_integer(SOUT_CFG_PREFIX "bitrate-max", 0, MAX_BITRATE_TEXT, MAX_BITRATE_LONGTEXT, true)
241
242     add_integer(SOUT_CFG_PREFIX "accuracy", 0, ACCURACY_TEXT, ACCURACY_LONGTEXT, true)
243         change_integer_range(0, 100)
244
245     add_integer(SOUT_CFG_PREFIX "convergence", 0, CONVERGENCE_TEXT, CONVERGENCE_LONGTEXT, true)
246
247     add_integer(SOUT_CFG_PREFIX "num-slice", 0, NUM_SLICE_TEXT, NUM_SLICE_LONGTEXT, true)
248     add_integer(SOUT_CFG_PREFIX "num-ref-frame", 0, NUM_REF_FRAME_TEXT, NUM_REF_FRAME_LONGTEXT, true)
249
250     add_integer(SOUT_CFG_PREFIX "async-depth", 4, ASYNC_DEPTH_TEXT, ASYNC_DEPTH_LONGTEXT, true)
251         change_integer_range(1, 32)
252
253 vlc_module_end ()
254
255 /*****************************************************************************
256  * Local prototypes
257  *****************************************************************************/
258 static const char *const sout_options[] = {
259     "software", "h264-profile", "h264-level", "mpeg2-profile", "mpeg2-level",
260     "gop-size", "gop-refdist", "target-usage", "rc-method", "qp", "qpi", "qpp",
261     "qpb", "bitrate-max", "accuracy", "convergence", "num-slice",
262     "num-ref-frame", "async-depth",
263     NULL
264 };
265
266 // Frame pool for QuickSync video encoder with Intel Media SDK's format frames.
267 typedef struct _QSVFrame
268 {
269     struct _QSVFrame  *next;
270     picture_t         *pic;
271     mfxFrameSurface1  surface;
272     mfxEncodeCtrl     enc_ctrl;
273     int               used;
274 } QSVFrame;
275
276 typedef struct async_task_t
277 {
278     fifo_item_t      fifo;
279     mfxBitstream     bs;                  // Intel's bitstream structure.
280     mfxSyncPoint     *syncp;              // Async Task Sync Point.
281     block_t          *block;              // VLC's block structure to be returned by Encode.
282 } async_task_t;
283
284 TYPED_FIFO(async_task_t, async_task_t)
285
286 typedef struct
287 {
288     mfxSession       session;             // Intel Media SDK Session.
289     mfxVideoParam    params;              // Encoding parameters.
290     QSVFrame         *work_frames;        // IntelMediaSDK's frame pool.
291     uint64_t         dts_warn_counter;    // DTS warning counter for rate-limiting of msg;
292     uint64_t         busy_warn_counter;   // Device Busy warning counter for rate-limiting of msg;
293     uint64_t         async_depth;         // Number of parallel encoding operations.
294     fifo_t           packets;             // FIFO of queued packets
295     vlc_tick_t       offset_pts;          // The pts of the first frame, to avoid conversion overflow.
296     vlc_tick_t       last_dts;            // The dts of the last frame, to interpolate over buggy dts
297
298     picture_pool_t   *input_pool;         // pool of pictures to feed the decoder
299                                           //  as it doesn't like constantly changing buffers
300 } encoder_sys_t;
301
302 static block_t *Encode(encoder_t *, picture_t *);
303
304
305 static void clear_unused_frames(encoder_sys_t *sys)
306 {
307     QSVFrame *cur = sys->work_frames;
308     while (cur) {
309         if (cur->used && !cur->surface.Data.Locked) {
310             picture_Release(cur->pic);
311             cur->used = 0;
312         }
313         cur = cur->next;
314     }
315 }
316
317 /*
318  * Finds an unlocked frame, releases the associated picture if
319  * necessary associates the new picture with it and return the frame.
320  * Returns 0 if there's an error.
321  */
322 static int get_free_frame(encoder_sys_t *sys, QSVFrame **out)
323 {
324     QSVFrame *frame, **last;
325
326     clear_unused_frames(sys);
327
328     frame = sys->work_frames;
329     last  = &sys->work_frames;
330     while (frame) {
331         if (!frame->used) {
332             *out = frame;
333             frame->used = 1;
334             return VLC_SUCCESS;
335         }
336
337         last  = &frame->next;
338         frame = frame->next;
339     }
340
341     frame = calloc(1,sizeof(QSVFrame));
342     if (unlikely(frame==NULL))
343         return VLC_ENOMEM;
344     *last = frame;
345
346     *out = frame;
347     frame->used = 1;
348
349     return VLC_SUCCESS;
350 }
351
352 static uint64_t qsv_params_get_value(const char *const *text,
353                                      const int *list,
354                                      size_t size, char *sel)
355 {
356     size_t result = 0;
357
358     if (unlikely(!sel))
359         return list[0];
360
361     size /= sizeof(list[0]);
362     for (size_t i = 0; i < size; i++)
363         if (!strcmp(sel, text[i])) {
364             result = i;
365             break;
366         }
367
368     // sel comes from var_InheritString and must be freed.
369     free(sel);
370     // Returns the found item, or the default/first one if not found.
371     return list[result];
372 }
373
374 static int Open(vlc_object_t *this)
375 {
376     encoder_t *enc = (encoder_t *)this;
377     encoder_sys_t *sys = NULL;
378
379     mfxStatus sts = MFX_ERR_NONE;
380     mfxFrameAllocRequest alloc_request = { 0 };
381     uint8_t sps_buf[128];
382     uint8_t pps_buf[128];
383     mfxExtCodingOptionSPSPPS headers;
384     mfxExtCodingOption co = {
385         .Header.BufferId = MFX_EXTBUFF_CODING_OPTION,
386         .Header.BufferSz = sizeof(co),
387         .PicTimingSEI = MFX_CODINGOPTION_ON,
388     };
389 #if QSV_HAVE_CO2
390     mfxExtCodingOption2 co2 = {
391         .Header.BufferId = MFX_EXTBUFF_CODING_OPTION2,
392         .Header.BufferSz = sizeof(co2),
393     };
394 #endif
395     mfxExtBuffer *init_params[] =
396     {
397         (mfxExtBuffer*)&co,
398 #if QSV_HAVE_CO2
399         (mfxExtBuffer*)&co2,
400 #endif
401     };
402     mfxExtBuffer *extended_params[] = {
403         (mfxExtBuffer*)&headers,
404         (mfxExtBuffer*)&co,
405 #if QSV_HAVE_CO2
406         (mfxExtBuffer*)&co2,
407 #endif
408     };
409     mfxVersion    ver = { { 1, 1 } };
410     mfxIMPL       impl;
411     mfxVideoParam param_out = { 0 };
412
413     uint8_t *p_extra;
414     size_t i_extra;
415
416     if (enc->fmt_out.i_codec != VLC_CODEC_H264 &&
417         enc->fmt_out.i_codec != VLC_CODEC_MPGV && !enc->obj.force)
418         return VLC_EGENERIC;
419
420     if (!enc->fmt_in.video.i_visible_height || !enc->fmt_in.video.i_visible_width ||
421         !enc->fmt_in.video.i_frame_rate || !enc->fmt_in.video.i_frame_rate_base) {
422         msg_Err(enc, "Framerate and picture dimensions must be non-zero");
423         return VLC_EGENERIC;
424     }
425
426     /* Allocate the memory needed to store the decoder's structure */
427     sys = calloc(1, sizeof(encoder_sys_t));
428     if (unlikely(!sys))
429         return VLC_ENOMEM;
430
431     /* Initialize dispatcher, it will loads the actual SW/HW Implementation */
432     sts = MFXInit(MFX_IMPL_AUTO_ANY, &ver, &sys->session);
433
434     if (sts != MFX_ERR_NONE) {
435         if (sts == MFX_ERR_UNSUPPORTED)
436             msg_Err(enc, "Intel Media SDK implementation not supported, is your card plugged?");
437         else
438             msg_Err(enc, "Unable to find an Intel Media SDK implementation (%d).", sts);
439         free(sys);
440         return VLC_EGENERIC;
441     }
442
443     enc->p_sys = sys;
444
445     config_ChainParse(enc, SOUT_CFG_PREFIX, sout_options, enc->p_cfg);
446
447     /* Checking if we are on software and are allowing it */
448     MFXQueryIMPL(sys->session, &impl);
449     if (!var_InheritBool(enc, SOUT_CFG_PREFIX "software") && (impl & MFX_IMPL_SOFTWARE)) {
450         msg_Err(enc, "No hardware implementation found and software mode disabled");
451         goto error;
452     }
453
454     msg_Dbg(enc, "Using Intel QuickSync Video %s implementation",
455         impl & MFX_IMPL_HARDWARE ? "hardware" : "software");
456
457     /* Input picture format description */
458     sys->params.mfx.FrameInfo.FrameRateExtN = enc->fmt_in.video.i_frame_rate;
459     sys->params.mfx.FrameInfo.FrameRateExtD = enc->fmt_in.video.i_frame_rate_base;
460     sys->params.mfx.FrameInfo.FourCC        = MFX_FOURCC_NV12;
461     sys->params.mfx.FrameInfo.ChromaFormat  = MFX_CHROMAFORMAT_YUV420;
462     sys->params.mfx.FrameInfo.Width         = QSV_ALIGN(16, enc->fmt_in.video.i_width);
463     sys->params.mfx.FrameInfo.Height        = QSV_ALIGN(32, enc->fmt_in.video.i_height);
464     sys->params.mfx.FrameInfo.CropW         = enc->fmt_in.video.i_visible_width;
465     sys->params.mfx.FrameInfo.CropH         = enc->fmt_in.video.i_visible_height;
466     sys->params.mfx.FrameInfo.PicStruct     = MFX_PICSTRUCT_PROGRESSIVE;
467     sys->params.mfx.FrameInfo.AspectRatioH  = enc->fmt_in.video.i_sar_num;
468     sys->params.mfx.FrameInfo.AspectRatioW  = enc->fmt_in.video.i_sar_den;
469     sys->params.mfx.FrameInfo.BitDepthChroma = 8; /* for VLC_CODEC_NV12 */
470     sys->params.mfx.FrameInfo.BitDepthLuma   = 8; /* for VLC_CODEC_NV12 */
471
472     /* Parsing options common to all RC methods and codecs */
473     sys->params.IOPattern       = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
474     sys->params.AsyncDepth      = var_InheritInteger(enc, SOUT_CFG_PREFIX "async-depth");
475     sys->params.mfx.GopOptFlag  = 1; /* TODO */
476     sys->params.mfx.GopPicSize  = var_InheritInteger(enc, SOUT_CFG_PREFIX "gop-size");
477     sys->params.mfx.GopRefDist  = var_InheritInteger(enc, SOUT_CFG_PREFIX "gop-refdist");
478     sys->params.mfx.IdrInterval = var_InheritInteger(enc, SOUT_CFG_PREFIX "idr-interval");
479     sys->params.mfx.NumSlice    = var_InheritInteger(enc, SOUT_CFG_PREFIX "num-slice");
480     sys->params.mfx.NumRefFrame = var_InheritInteger(enc, SOUT_CFG_PREFIX "num-ref-frame");
481     sys->params.mfx.TargetUsage = qsv_params_get_value(target_usage_text,
482         target_usage_list, sizeof(target_usage_list),
483         var_InheritString(enc, SOUT_CFG_PREFIX "target-usage"));
484
485     if (enc->fmt_out.i_codec == VLC_CODEC_H264) {
486         sys->params.mfx.CodecId = MFX_CODEC_AVC;
487         sys->params.mfx.CodecProfile = qsv_params_get_value(profile_h264_text,
488             profile_h264_list, sizeof(profile_h264_list),
489             var_InheritString(enc, SOUT_CFG_PREFIX "h264-profile"));
490         sys->params.mfx.CodecLevel = qsv_params_get_value(level_h264_text,
491             level_h264_list, sizeof(level_h264_list),
492             var_InheritString(enc, SOUT_CFG_PREFIX "h264-level"));
493         msg_Dbg(enc, "Encoder in H264 mode, with profile %d and level %d",
494             sys->params.mfx.CodecProfile, sys->params.mfx.CodecLevel);
495
496     } else {
497         sys->params.mfx.CodecId = MFX_CODEC_MPEG2;
498         sys->params.mfx.CodecProfile = qsv_params_get_value(profile_mpeg2_text,
499             profile_mpeg2_list, sizeof(profile_mpeg2_list),
500             var_InheritString(enc, SOUT_CFG_PREFIX "mpeg2-profile"));
501         sys->params.mfx.CodecLevel = qsv_params_get_value(level_mpeg2_text,
502             level_mpeg2_list, sizeof(level_mpeg2_list),
503             var_InheritString(enc, SOUT_CFG_PREFIX "mpeg2-level"));
504         msg_Dbg(enc, "Encoder in MPEG2 mode, with profile %d and level %d",
505             sys->params.mfx.CodecProfile, sys->params.mfx.CodecLevel);
506     }
507     param_out.mfx.CodecId = sys->params.mfx.CodecId;
508
509     char *psz_rc = var_InheritString(enc, SOUT_CFG_PREFIX "rc-method");
510     msg_Dbg(enc, "Encoder using '%s' Rate Control method", psz_rc );
511     sys->params.mfx.RateControlMethod = qsv_params_get_value(rc_method_text,
512         rc_method_list, sizeof(rc_method_list), psz_rc );
513
514     if (sys->params.mfx.RateControlMethod == MFX_RATECONTROL_CQP) {
515         sys->params.mfx.QPI = sys->params.mfx.QPB = sys->params.mfx.QPP =
516             var_InheritInteger(enc, SOUT_CFG_PREFIX "qp");
517         sys->params.mfx.QPI = var_InheritInteger(enc, SOUT_CFG_PREFIX "qpi");
518         sys->params.mfx.QPB = var_InheritInteger(enc, SOUT_CFG_PREFIX "qpb");
519         sys->params.mfx.QPP = var_InheritInteger(enc, SOUT_CFG_PREFIX "qpp");
520     } else {
521         if (!enc->fmt_out.i_bitrate) {
522             msg_Warn(enc, "No bitrate specified, using default %d",
523                 QSV_BITRATE_DEFAULT);
524             sys->params.mfx.TargetKbps = QSV_BITRATE_DEFAULT;
525         } else
526             sys->params.mfx.TargetKbps = enc->fmt_out.i_bitrate / 1000;
527
528         if (sys->params.mfx.RateControlMethod == MFX_RATECONTROL_AVBR) {
529             sys->params.mfx.Accuracy = var_InheritInteger(enc, SOUT_CFG_PREFIX "accuracy");
530             sys->params.mfx.Convergence = var_InheritInteger(enc, SOUT_CFG_PREFIX "convergence");
531         } else if (sys->params.mfx.RateControlMethod == MFX_RATECONTROL_VBR)
532             sys->params.mfx.MaxKbps = var_InheritInteger(enc, SOUT_CFG_PREFIX "bitrate-max");
533     }
534
535     sts = MFXVideoENCODE_Query(sys->session, &sys->params, &param_out);
536     if ( sts < MFX_ERR_NONE )
537     {
538         msg_Err(enc, "Unsupported encoding parameters (%d)", sts);
539         goto error;
540     }
541
542     if ( sys->params.mfx.RateControlMethod != param_out.mfx.RateControlMethod )
543     {
544         msg_Err(enc, "Unsupported control method %d got %d", sys->params.mfx.RateControlMethod, param_out.mfx.RateControlMethod);
545         goto error;
546     }
547
548     if (MFXVideoENCODE_Query(sys->session, &sys->params, &sys->params) < 0)
549     {
550         msg_Err(enc, "Error querying encoder params");
551         goto error;
552     }
553
554     /* Request number of surface needed and creating frame pool */
555     if (MFXVideoENCODE_QueryIOSurf(sys->session, &sys->params, &alloc_request)!= MFX_ERR_NONE)
556     {
557         msg_Err(enc, "Failed to query for allocation");
558         goto error;
559     }
560
561     enc->fmt_in.video.i_chroma = VLC_CODEC_NV12;
562     video_format_t pool_fmt = enc->fmt_in.video;
563     pool_fmt.i_width  = sys->params.mfx.FrameInfo.Width;
564     pool_fmt.i_height = sys->params.mfx.FrameInfo.Height;
565     sys->input_pool = picture_pool_NewFromFormat( &pool_fmt, 18 );
566     if (sys->input_pool == NULL)
567     {
568         msg_Err(enc, "Failed to create the internal pool");
569         goto error;
570     }
571
572     sys->params.ExtParam    = (mfxExtBuffer**)&init_params;
573     sys->params.NumExtParam =
574 #if QSV_HAVE_CO2
575             2;
576 #else
577             1;
578 #endif
579
580     /* Initializing MFX_Encoder */
581     sts = MFXVideoENCODE_Init(sys->session, &sys->params);
582     if (sts == MFX_ERR_NONE)
583         msg_Dbg(enc, "Successfuly initialized video encoder");
584     else if (sts < MFX_ERR_NONE) {
585         msg_Err(enc, "Unable to initialize video encoder error (%d). " \
586             " Most likely because of provided encoding parameters", sts);
587         goto error;
588     } else
589         msg_Warn(enc, "Video encoder initialization : %d. The stream might be corrupted/invalid", sts);
590
591     /* Querying PPS/SPS Headers, BufferSizeInKB, ... */
592     memset(&headers, 0, sizeof(headers));
593     headers.Header.BufferId = MFX_EXTBUFF_CODING_OPTION_SPSPPS;
594     headers.Header.BufferSz = sizeof(headers);
595     headers.PPSBufSize      = sizeof(pps_buf);
596     headers.SPSBufSize      = sizeof(sps_buf);
597     headers.SPSBuffer       = sps_buf;
598     headers.PPSBuffer       = pps_buf;
599     sys->params.ExtParam    = (mfxExtBuffer **)&extended_params;
600     sys->params.NumExtParam =
601 #if QSV_HAVE_CO2
602             3;
603 #else
604             2;
605 #endif
606
607     MFXVideoENCODE_GetVideoParam(sys->session, &sys->params);
608
609     i_extra = headers.SPSBufSize + headers.PPSBufSize;
610     p_extra = malloc(i_extra);
611
612     if (unlikely(!p_extra))
613         goto nomem;
614
615     memcpy(p_extra, headers.SPSBuffer, headers.SPSBufSize);
616     memcpy(p_extra + headers.SPSBufSize, headers.PPSBuffer, headers.PPSBufSize);
617     enc->fmt_out.p_extra = p_extra;
618     enc->fmt_out.i_extra = i_extra;
619
620     sys->async_depth = sys->params.AsyncDepth;
621     async_task_t_fifo_Init(&sys->packets);
622
623     /* Vlc module configuration */
624     enc->fmt_in.i_codec                = VLC_CODEC_NV12; // Intel Media SDK requirement
625     enc->fmt_in.video.i_bits_per_pixel = 12;
626     enc->fmt_in.video.i_width          = sys->params.mfx.FrameInfo.Width;
627     enc->fmt_in.video.i_height         = sys->params.mfx.FrameInfo.Height;
628
629     enc->pf_encode_video = Encode;
630
631     return VLC_SUCCESS;
632
633  error:
634     Close(this);
635     enc->p_sys = NULL;
636     return VLC_EGENERIC;
637  nomem:
638     Close(this);
639     enc->p_sys = NULL;
640     return VLC_ENOMEM;
641 }
642
643 static void Close(vlc_object_t *this)
644 {
645     encoder_t *enc = (encoder_t *)this;
646     encoder_sys_t *sys = enc->p_sys;
647
648     MFXVideoENCODE_Close(sys->session);
649     MFXClose(sys->session);
650     /* if (enc->fmt_out.p_extra) */
651     /*     free(enc->fmt_out.p_extra); */
652     async_task_t_fifo_Release(&sys->packets);
653     if (sys->input_pool)
654         picture_pool_Release(sys->input_pool);
655     free(sys);
656 }
657
658 /*
659  * The behavior in the next function comes from x264.c
660  */
661 static void qsv_set_block_flags(block_t *block, uint16_t frame_type)
662 {
663     if (frame_type & MFX_FRAMETYPE_IDR)
664         block->i_flags = BLOCK_FLAG_TYPE_I;
665     else if ((frame_type & MFX_FRAMETYPE_P) || (frame_type & MFX_FRAMETYPE_I))
666         block->i_flags = BLOCK_FLAG_TYPE_P;
667     else if (frame_type & MFX_FRAMETYPE_B)
668         block->i_flags = BLOCK_FLAG_TYPE_B;
669     else
670         block->i_flags = BLOCK_FLAG_TYPE_PB;
671 }
672
673 /*
674  * Convert the Intel Media SDK's timestamps into VLC's format.
675  */
676 static void qsv_set_block_ts(encoder_t *enc, encoder_sys_t *sys, block_t *block, mfxBitstream *bs)
677 {
678     block->i_pts = FROM_SCALE_NZ(bs->TimeStamp) + sys->offset_pts;
679     block->i_dts = FROM_SCALE_NZ(bs->DecodeTimeStamp) + sys->offset_pts;
680
681     /* HW encoder (with old driver versions) and some parameters
682        combinations doesn't set the DecodeTimeStamp field so we warn
683        the user about it */
684     if (!bs->DecodeTimeStamp || bs->DecodeTimeStamp > (int64_t)bs->TimeStamp)
685         if (sys->dts_warn_counter++ % 16 == 0) // Rate limiting this message.
686             msg_Warn(enc, "Encode returning empty DTS or DTS > PTS. Your stream will be invalid. "
687                      " Please double-check they weren't any warning at encoder initialization "
688                      " and that you have the last version of Intel's drivers installed.");
689 }
690
691 static block_t *qsv_synchronize_block(encoder_t *enc, async_task_t *task)
692 {
693     encoder_sys_t *sys = enc->p_sys;
694     mfxStatus sts;
695
696     /* Synchronize and fill block_t. If the SyncOperation fails we leak :-/ (or we can segfault, ur choice) */
697     do {
698         sts = MFXVideoCORE_SyncOperation(sys->session, *task->syncp, QSV_SYNCPOINT_WAIT);
699     } while (sts == MFX_WRN_IN_EXECUTION);
700     if (sts != MFX_ERR_NONE) {
701         msg_Err(enc, "SyncOperation failed (%d), outputting garbage data. "
702                 "Updating your drivers and/or changing the encoding settings might resolve this", sts);
703         return NULL;
704     }
705     if (task->bs.DataLength == 0)
706     {
707         msg_Dbg(enc, "Empty encoded block");
708         return NULL;
709     }
710     block_t *block = task->block;
711     block->i_buffer = task->bs.DataLength;
712     block->p_buffer += task->bs.DataOffset;
713
714     qsv_set_block_ts(enc, sys, block, &task->bs);
715     qsv_set_block_flags(block, task->bs.FrameType);
716
717     /* msg_Dbg(enc, "block->i_pts = %lld, block->i_dts = %lld", block->i_pts, block->i_dts); */
718     /* msg_Dbg(enc, "FrameType = %#.4x, TimeStamp = %lld (pts %lld), DecodeTimeStamp = %lld syncp=0x%x",*/
719     /*         task->bs.FrameType, task->bs.TimeStamp, block->i_pts, task->bs.DecodeTimeStamp, *task->syncp); */
720
721     /* Copied from x264.c: This isn't really valid for streams with B-frames */
722     block->i_length = vlc_tick_from_samples( enc->fmt_in.video.i_frame_rate_base,
723                                              enc->fmt_in.video.i_frame_rate );
724
725     // Buggy DTS (value comes from experiments)
726     if (task->bs.DecodeTimeStamp < -10000)
727         block->i_dts = sys->last_dts + block->i_length;
728     sys->last_dts = block->i_dts;
729
730     task->bs.DataLength = task->bs.DataOffset = 0;
731     return block;
732 }
733
734 static int submit_frame(encoder_t *enc, picture_t *pic, QSVFrame **new_frame)
735 {
736     encoder_sys_t *sys = enc->p_sys;
737     QSVFrame *qf = NULL;
738     int ret = get_free_frame(sys, &qf);
739     if (ret != VLC_SUCCESS) {
740         msg_Warn(enc, "Unable to find an unlocked surface in the pool");
741         return ret;
742     }
743
744     qf->pic = picture_pool_Get( sys->input_pool );
745     if (unlikely(!qf->pic))
746     {
747         msg_Warn(enc, "Unable to find an unlocked surface in the pool");
748         qf->used = 0;
749         return ret;
750     }
751     picture_Copy( qf->pic, pic );
752
753     assert(qf->pic->p[0].p_pixels + (qf->pic->p[0].i_pitch * qf->pic->p[0].i_lines) == qf->pic->p[1].p_pixels);
754
755     qf->surface.Info = sys->params.mfx.FrameInfo;
756
757     // Specify picture structure at runtime.
758     if (pic->b_progressive)
759         qf->surface.Info.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
760     else if (pic->b_top_field_first)
761         qf->surface.Info.PicStruct = MFX_PICSTRUCT_FIELD_TFF;
762     else
763         qf->surface.Info.PicStruct = MFX_PICSTRUCT_FIELD_BFF;
764
765     //qf->surface.Data.Pitch = QSV_ALIGN(16, qf->surface.Info.Width);
766
767     qf->surface.Data.PitchLow  = qf->pic->p[0].i_pitch;
768     qf->surface.Data.Y         = qf->pic->p[0].p_pixels;
769     qf->surface.Data.UV        = qf->pic->p[1].p_pixels;
770
771     qf->surface.Data.TimeStamp = TO_SCALE_NZ(pic->date - sys->offset_pts);
772
773     *new_frame = qf;
774
775     return VLC_SUCCESS;
776 }
777
778 static async_task_t *encode_frame(encoder_t *enc, picture_t *pic)
779 {
780     encoder_sys_t *sys = enc->p_sys;
781     mfxStatus sts = MFX_ERR_MEMORY_ALLOC;
782     QSVFrame *qsv_frame = NULL;
783     mfxFrameSurface1 *surf = NULL;
784     async_task_t *task = calloc(1, sizeof(*task));
785     if (unlikely(task == NULL))
786         goto done;
787
788     if (pic) {
789         /* To avoid qsv -> vlc timestamp conversion overflow, we use timestamp relative
790            to the first picture received. That way, vlc will overflow before us.
791            (Thanks to funman for the idea) */
792         if (!sys->offset_pts) // First frame
793             sys->offset_pts = pic->date;
794
795         if (submit_frame(enc, pic, &qsv_frame) != VLC_SUCCESS)
796         {
797             msg_Warn(enc, "Unable to find an unlocked surface in the pool");
798             goto done;
799         }
800     }
801
802     if (!(task->syncp = calloc(1, sizeof(*task->syncp)))) {
803         msg_Err(enc, "Unable to allocate syncpoint for encoder output");
804         goto done;
805     }
806
807     /* Allocate block_t and prepare mfxBitstream for encoder */
808     if (!(task->block = block_Alloc(sys->params.mfx.BufferSizeInKB * 1000))) {
809         msg_Err(enc, "Unable to allocate block for encoder output");
810         goto done;
811     }
812     memset(&task->bs, 0, sizeof(task->bs));
813     task->bs.MaxLength = task->block->i_buffer;
814     task->bs.Data = task->block->p_buffer;
815
816     if (qsv_frame) {
817         surf = &qsv_frame->surface;
818     }
819
820     for (;;) {
821         sts = MFXVideoENCODE_EncodeFrameAsync(sys->session, 0, surf, &task->bs, task->syncp);
822         if (sts != MFX_WRN_DEVICE_BUSY && sts != MFX_WRN_IN_EXECUTION)
823             break;
824         if (sys->busy_warn_counter++ % 16 == 0)
825             msg_Dbg(enc, "Device is busy, let's wait and retry %d", sts);
826         if (sts == MFX_WRN_DEVICE_BUSY)
827             vlc_tick_sleep(QSV_BUSYWAIT_TIME);
828     }
829
830     // msg_Dbg(enc, "Encode async status: %d, Syncpoint = %tx", sts, (ptrdiff_t)task->syncp);
831
832     if (sts == MFX_ERR_MORE_DATA)
833         if (pic)
834             msg_Dbg(enc, "Encoder feeding phase, more data is needed.");
835         else
836             msg_Dbg(enc, "Encoder is empty");
837     else if (sts < MFX_ERR_NONE) {
838         msg_Err(enc, "Encoder not ready or error (%d), trying a reset...", sts);
839         MFXVideoENCODE_Reset(sys->session, &sys->params);
840     }
841
842 done:
843     if (sts < MFX_ERR_NONE || (task != NULL && !task->syncp)) {
844         if (task->block != NULL)
845             block_Release(task->block);
846         free(task);
847         task = NULL;
848     }
849     return task;
850 }
851
852 /*
853  * The Encode function has 3 encoding phases :
854  *   - Feed : We feed the encoder until it stops to return MFX_MORE_DATA_NEEDED
855  *     and the async_tasks are all in use (honouring the AsyncDepth)
856  *   - Main encoding phase : synchronizing the oldest task each call.
857  *   - Empty : pic = 0, we empty the decoder. Synchronizing the remaining tasks.
858  */
859 static block_t *Encode(encoder_t *this, picture_t *pic)
860 {
861     encoder_t     *enc = (encoder_t *)this;
862     encoder_sys_t *sys = enc->p_sys;
863     async_task_t     *task;
864     block_t       *block = NULL;
865
866     if (likely(pic != NULL))
867     {
868         task = encode_frame( enc, pic );
869         if (likely(task != NULL))
870             async_task_t_fifo_Put(&sys->packets, task);
871     }
872
873     if ( async_task_t_fifo_GetCount(&sys->packets) == (sys->async_depth + 1) ||
874          (!pic && async_task_t_fifo_GetCount(&sys->packets)))
875     {
876         assert(async_task_t_fifo_Show(&sys->packets)->syncp != 0);
877         async_task_t *task = async_task_t_fifo_Get(&sys->packets);
878         block = qsv_synchronize_block( enc, task );
879         free(task->syncp);
880         free(task);
881     }
882
883     return block;
884 }