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