input: add an input_item_t arg to input_CreateFilename()
[vlc.git] / modules / codec / qsv.c
blobf8fb2e7e59a143549c5f688cca854684297fa71c
1 /*****************************************************************************
2 * qsv.c: mpeg4-part10/mpeg2 video encoder using Intel Media SDK
3 *****************************************************************************
4 * Copyright (C) 2013 VideoLabs
5 * $Id$
7 * Authors: Julien 'Lta' BALLET <contact@lta.io>
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.
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.
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 *****************************************************************************/
24 /*****************************************************************************
25 * Preamble
26 *****************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
31 #include <vlc_common.h>
32 #include <vlc_plugin.h>
33 #include <vlc_picture.h>
34 #include <vlc_codec.h>
35 #include <vlc_picture_pool.h>
37 #include <vlc_fifo_helper.h>
39 #include <mfx/mfxvideo.h>
41 #define SOUT_CFG_PREFIX "sout-qsv-"
43 #define QSV_HAVE_CO2 (MFX_VERSION_MAJOR > 1 || (MFX_VERSION_MAJOR == 1 && MFX_VERSION_MINOR >= 6))
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)
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))
55 /*****************************************************************************
56 * Modules descriptor
57 *****************************************************************************/
58 static int Open(vlc_object_t *);
59 static void Close(vlc_object_t *);
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.")
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'")
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")
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.")
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.")
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'.")
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.")
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.")
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'.")
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'.")
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'.")
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'.")
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.")
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")
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.")
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.")
150 #define NUM_REF_FRAME_TEXT N_("Number of reference frames")
151 #define NUM_REF_FRAME_LONGTEXT N_("Number of reference frames")
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.")
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" };
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" };
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" };
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" };
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" };
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" };
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)
207 add_bool(SOUT_CFG_PREFIX "software", false, SW_IMPL_TEXT, SW_IMPL_LONGTEXT, true)
209 add_string(SOUT_CFG_PREFIX "h264-profile", "unspecified" , PROFILE_TEXT, PROFILE_LONGTEXT, false)
210 change_string_list(profile_h264_text, profile_h264_text)
212 add_string(SOUT_CFG_PREFIX "h264-level", "unspecified", LEVEL_TEXT, LEVEL_LONGTEXT, false)
213 change_string_list(level_h264_text, level_h264_text)
215 add_string(SOUT_CFG_PREFIX "mpeg2-profile", "unspecified", PROFILE_TEXT, PROFILE_LONGTEXT, false)
216 change_string_list(profile_mpeg2_text, profile_mpeg2_text)
218 add_string(SOUT_CFG_PREFIX "mpeg2-level", "unspecified", LEVEL_TEXT, LEVEL_LONGTEXT, false)
219 change_string_list(level_mpeg2_text, level_mpeg2_text)
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)
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)
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)
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)
240 add_integer(SOUT_CFG_PREFIX "bitrate-max", 0, MAX_BITRATE_TEXT, MAX_BITRATE_LONGTEXT, true)
242 add_integer(SOUT_CFG_PREFIX "accuracy", 0, ACCURACY_TEXT, ACCURACY_LONGTEXT, true)
243 change_integer_range(0, 100)
245 add_integer(SOUT_CFG_PREFIX "convergence", 0, CONVERGENCE_TEXT, CONVERGENCE_LONGTEXT, true)
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)
250 add_integer(SOUT_CFG_PREFIX "async-depth", 4, ASYNC_DEPTH_TEXT, ASYNC_DEPTH_LONGTEXT, true)
251 change_integer_range(1, 32)
253 vlc_module_end ()
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
266 // Frame pool for QuickSync video encoder with Intel Media SDK's format frames.
267 typedef struct _QSVFrame
269 struct _QSVFrame *next;
270 picture_t *pic;
271 mfxFrameSurface1 surface;
272 mfxEncodeCtrl enc_ctrl;
273 int used;
274 } QSVFrame;
276 typedef struct async_task_t
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;
284 TYPED_FIFO(async_task_t, async_task_t)
286 typedef struct
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
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;
302 static block_t *Encode(encoder_t *, picture_t *);
305 static inline vlc_tick_t qsv_timestamp_to_mtime(int64_t mfx_ts)
307 return mfx_ts / INT64_C(9) * INT64_C(100);
310 static inline uint64_t qsv_mtime_to_timestamp(vlc_tick_t vlc_ts)
312 return vlc_ts / UINT64_C(100) * UINT64_C(9);
315 static void clear_unused_frames(encoder_sys_t *sys)
317 QSVFrame *cur = sys->work_frames;
318 while (cur) {
319 if (cur->used && !cur->surface.Data.Locked) {
320 picture_Release(cur->pic);
321 cur->used = 0;
323 cur = cur->next;
328 * Finds an unlocked frame, releases the associated picture if
329 * necessary associates the new picture with it and return the frame.
330 * Returns 0 if there's an error.
332 static int get_free_frame(encoder_sys_t *sys, QSVFrame **out)
334 QSVFrame *frame, **last;
336 clear_unused_frames(sys);
338 frame = sys->work_frames;
339 last = &sys->work_frames;
340 while (frame) {
341 if (!frame->used) {
342 *out = frame;
343 frame->used = 1;
344 return VLC_SUCCESS;
347 last = &frame->next;
348 frame = frame->next;
351 frame = calloc(1,sizeof(QSVFrame));
352 if (unlikely(frame==NULL))
353 return VLC_ENOMEM;
354 *last = frame;
356 *out = frame;
357 frame->used = 1;
359 return VLC_SUCCESS;
362 static uint64_t qsv_params_get_value(const char *const *text,
363 const int *list,
364 size_t size, char *sel)
366 size_t result = 0;
368 if (unlikely(!sel))
369 return list[0];
371 size /= sizeof(list[0]);
372 for (size_t i = 0; i < size; i++)
373 if (!strcmp(sel, text[i])) {
374 result = i;
375 break;
378 // sel comes from var_InheritString and must be freed.
379 free(sel);
380 // Returns the found item, or the default/first one if not found.
381 return list[result];
384 static int Open(vlc_object_t *this)
386 encoder_t *enc = (encoder_t *)this;
387 encoder_sys_t *sys = NULL;
389 mfxStatus sts = MFX_ERR_NONE;
390 mfxFrameAllocRequest alloc_request = { 0 };
391 uint8_t sps_buf[128];
392 uint8_t pps_buf[128];
393 mfxExtCodingOptionSPSPPS headers;
394 mfxExtCodingOption co = {
395 .Header.BufferId = MFX_EXTBUFF_CODING_OPTION,
396 .Header.BufferSz = sizeof(co),
397 .PicTimingSEI = MFX_CODINGOPTION_ON,
399 #if QSV_HAVE_CO2
400 mfxExtCodingOption2 co2 = {
401 .Header.BufferId = MFX_EXTBUFF_CODING_OPTION2,
402 .Header.BufferSz = sizeof(co2),
404 #endif
405 mfxExtBuffer *init_params[] =
407 (mfxExtBuffer*)&co,
408 #if QSV_HAVE_CO2
409 (mfxExtBuffer*)&co2,
410 #endif
412 mfxExtBuffer *extended_params[] = {
413 (mfxExtBuffer*)&headers,
414 (mfxExtBuffer*)&co,
415 #if QSV_HAVE_CO2
416 (mfxExtBuffer*)&co2,
417 #endif
419 mfxVersion ver = { { 1, 1 } };
420 mfxIMPL impl;
421 mfxVideoParam param_out = { 0 };
423 uint8_t *p_extra;
424 size_t i_extra;
426 if (enc->fmt_out.i_codec != VLC_CODEC_H264 &&
427 enc->fmt_out.i_codec != VLC_CODEC_MPGV && !enc->obj.force)
428 return VLC_EGENERIC;
430 if (!enc->fmt_in.video.i_visible_height || !enc->fmt_in.video.i_visible_width ||
431 !enc->fmt_in.video.i_frame_rate || !enc->fmt_in.video.i_frame_rate_base) {
432 msg_Err(enc, "Framerate and picture dimensions must be non-zero");
433 return VLC_EGENERIC;
436 /* Allocate the memory needed to store the decoder's structure */
437 sys = calloc(1, sizeof(encoder_sys_t));
438 if (unlikely(!sys))
439 return VLC_ENOMEM;
441 /* Initialize dispatcher, it will loads the actual SW/HW Implementation */
442 sts = MFXInit(MFX_IMPL_AUTO_ANY, &ver, &sys->session);
444 if (sts != MFX_ERR_NONE) {
445 if (sts == MFX_ERR_UNSUPPORTED)
446 msg_Err(enc, "Intel Media SDK implementation not supported, is your card plugged?");
447 else
448 msg_Err(enc, "Unable to find an Intel Media SDK implementation (%d).", sts);
449 free(sys);
450 return VLC_EGENERIC;
453 enc->p_sys = sys;
455 config_ChainParse(enc, SOUT_CFG_PREFIX, sout_options, enc->p_cfg);
457 /* Checking if we are on software and are allowing it */
458 MFXQueryIMPL(sys->session, &impl);
459 if (!var_InheritBool(enc, SOUT_CFG_PREFIX "software") && (impl & MFX_IMPL_SOFTWARE)) {
460 msg_Err(enc, "No hardware implementation found and software mode disabled");
461 goto error;
464 msg_Dbg(enc, "Using Intel QuickSync Video %s implementation",
465 impl & MFX_IMPL_HARDWARE ? "hardware" : "software");
467 /* Input picture format description */
468 sys->params.mfx.FrameInfo.FrameRateExtN = enc->fmt_in.video.i_frame_rate;
469 sys->params.mfx.FrameInfo.FrameRateExtD = enc->fmt_in.video.i_frame_rate_base;
470 sys->params.mfx.FrameInfo.FourCC = MFX_FOURCC_NV12;
471 sys->params.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
472 sys->params.mfx.FrameInfo.Width = QSV_ALIGN(16, enc->fmt_in.video.i_width);
473 sys->params.mfx.FrameInfo.Height = QSV_ALIGN(32, enc->fmt_in.video.i_height);
474 sys->params.mfx.FrameInfo.CropW = enc->fmt_in.video.i_visible_width;
475 sys->params.mfx.FrameInfo.CropH = enc->fmt_in.video.i_visible_height;
476 sys->params.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
477 sys->params.mfx.FrameInfo.AspectRatioH = enc->fmt_in.video.i_sar_num;
478 sys->params.mfx.FrameInfo.AspectRatioW = enc->fmt_in.video.i_sar_den;
479 sys->params.mfx.FrameInfo.BitDepthChroma = 8; /* for VLC_CODEC_NV12 */
480 sys->params.mfx.FrameInfo.BitDepthLuma = 8; /* for VLC_CODEC_NV12 */
482 /* Parsing options common to all RC methods and codecs */
483 sys->params.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
484 sys->params.AsyncDepth = var_InheritInteger(enc, SOUT_CFG_PREFIX "async-depth");
485 sys->params.mfx.GopOptFlag = 1; /* TODO */
486 sys->params.mfx.GopPicSize = var_InheritInteger(enc, SOUT_CFG_PREFIX "gop-size");
487 sys->params.mfx.GopRefDist = var_InheritInteger(enc, SOUT_CFG_PREFIX "gop-refdist");
488 sys->params.mfx.IdrInterval = var_InheritInteger(enc, SOUT_CFG_PREFIX "idr-interval");
489 sys->params.mfx.NumSlice = var_InheritInteger(enc, SOUT_CFG_PREFIX "num-slice");
490 sys->params.mfx.NumRefFrame = var_InheritInteger(enc, SOUT_CFG_PREFIX "num-ref-frame");
491 sys->params.mfx.TargetUsage = qsv_params_get_value(target_usage_text,
492 target_usage_list, sizeof(target_usage_list),
493 var_InheritString(enc, SOUT_CFG_PREFIX "target-usage"));
495 if (enc->fmt_out.i_codec == VLC_CODEC_H264) {
496 sys->params.mfx.CodecId = MFX_CODEC_AVC;
497 sys->params.mfx.CodecProfile = qsv_params_get_value(profile_h264_text,
498 profile_h264_list, sizeof(profile_h264_list),
499 var_InheritString(enc, SOUT_CFG_PREFIX "h264-profile"));
500 sys->params.mfx.CodecLevel = qsv_params_get_value(level_h264_text,
501 level_h264_list, sizeof(level_h264_list),
502 var_InheritString(enc, SOUT_CFG_PREFIX "h264-level"));
503 msg_Dbg(enc, "Encoder in H264 mode, with profile %d and level %d",
504 sys->params.mfx.CodecProfile, sys->params.mfx.CodecLevel);
506 } else {
507 sys->params.mfx.CodecId = MFX_CODEC_MPEG2;
508 sys->params.mfx.CodecProfile = qsv_params_get_value(profile_mpeg2_text,
509 profile_mpeg2_list, sizeof(profile_mpeg2_list),
510 var_InheritString(enc, SOUT_CFG_PREFIX "mpeg2-profile"));
511 sys->params.mfx.CodecLevel = qsv_params_get_value(level_mpeg2_text,
512 level_mpeg2_list, sizeof(level_mpeg2_list),
513 var_InheritString(enc, SOUT_CFG_PREFIX "mpeg2-level"));
514 msg_Dbg(enc, "Encoder in MPEG2 mode, with profile %d and level %d",
515 sys->params.mfx.CodecProfile, sys->params.mfx.CodecLevel);
517 param_out.mfx.CodecId = sys->params.mfx.CodecId;
519 char *psz_rc = var_InheritString(enc, SOUT_CFG_PREFIX "rc-method");
520 msg_Dbg(enc, "Encoder using '%s' Rate Control method", psz_rc );
521 sys->params.mfx.RateControlMethod = qsv_params_get_value(rc_method_text,
522 rc_method_list, sizeof(rc_method_list), psz_rc );
524 if (sys->params.mfx.RateControlMethod == MFX_RATECONTROL_CQP) {
525 sys->params.mfx.QPI = sys->params.mfx.QPB = sys->params.mfx.QPP =
526 var_InheritInteger(enc, SOUT_CFG_PREFIX "qp");
527 sys->params.mfx.QPI = var_InheritInteger(enc, SOUT_CFG_PREFIX "qpi");
528 sys->params.mfx.QPB = var_InheritInteger(enc, SOUT_CFG_PREFIX "qpb");
529 sys->params.mfx.QPP = var_InheritInteger(enc, SOUT_CFG_PREFIX "qpp");
530 } else {
531 if (!enc->fmt_out.i_bitrate) {
532 msg_Warn(enc, "No bitrate specified, using default %d",
533 QSV_BITRATE_DEFAULT);
534 sys->params.mfx.TargetKbps = QSV_BITRATE_DEFAULT;
535 } else
536 sys->params.mfx.TargetKbps = enc->fmt_out.i_bitrate / 1000;
538 if (sys->params.mfx.RateControlMethod == MFX_RATECONTROL_AVBR) {
539 sys->params.mfx.Accuracy = var_InheritInteger(enc, SOUT_CFG_PREFIX "accuracy");
540 sys->params.mfx.Convergence = var_InheritInteger(enc, SOUT_CFG_PREFIX "convergence");
541 } else if (sys->params.mfx.RateControlMethod == MFX_RATECONTROL_VBR)
542 sys->params.mfx.MaxKbps = var_InheritInteger(enc, SOUT_CFG_PREFIX "bitrate-max");
545 sts = MFXVideoENCODE_Query(sys->session, &sys->params, &param_out);
546 if ( sts < MFX_ERR_NONE )
548 msg_Err(enc, "Unsupported encoding parameters (%d)", sts);
549 goto error;
552 if ( sys->params.mfx.RateControlMethod != param_out.mfx.RateControlMethod )
554 msg_Err(enc, "Unsupported control method %d got %d", sys->params.mfx.RateControlMethod, param_out.mfx.RateControlMethod);
555 goto error;
558 if (MFXVideoENCODE_Query(sys->session, &sys->params, &sys->params) < 0)
560 msg_Err(enc, "Error querying encoder params");
561 goto error;
564 /* Request number of surface needed and creating frame pool */
565 if (MFXVideoENCODE_QueryIOSurf(sys->session, &sys->params, &alloc_request)!= MFX_ERR_NONE)
567 msg_Err(enc, "Failed to query for allocation");
568 goto error;
571 enc->fmt_in.video.i_chroma = VLC_CODEC_NV12;
572 video_format_t pool_fmt = enc->fmt_in.video;
573 pool_fmt.i_width = sys->params.mfx.FrameInfo.Width;
574 pool_fmt.i_height = sys->params.mfx.FrameInfo.Height;
575 sys->input_pool = picture_pool_NewFromFormat( &pool_fmt, 18 );
576 if (sys->input_pool == NULL)
578 msg_Err(enc, "Failed to create the internal pool");
579 goto error;
582 sys->params.ExtParam = (mfxExtBuffer**)&init_params;
583 sys->params.NumExtParam =
584 #if QSV_HAVE_CO2
586 #else
588 #endif
590 /* Initializing MFX_Encoder */
591 sts = MFXVideoENCODE_Init(sys->session, &sys->params);
592 if (sts == MFX_ERR_NONE)
593 msg_Dbg(enc, "Successfuly initialized video encoder");
594 else if (sts < MFX_ERR_NONE) {
595 msg_Err(enc, "Unable to initialize video encoder error (%d). " \
596 " Most likely because of provided encoding parameters", sts);
597 goto error;
598 } else
599 msg_Warn(enc, "Video encoder initialization : %d. The stream might be corrupted/invalid", sts);
601 /* Querying PPS/SPS Headers, BufferSizeInKB, ... */
602 memset(&headers, 0, sizeof(headers));
603 headers.Header.BufferId = MFX_EXTBUFF_CODING_OPTION_SPSPPS;
604 headers.Header.BufferSz = sizeof(headers);
605 headers.PPSBufSize = sizeof(pps_buf);
606 headers.SPSBufSize = sizeof(sps_buf);
607 headers.SPSBuffer = sps_buf;
608 headers.PPSBuffer = pps_buf;
609 sys->params.ExtParam = (mfxExtBuffer **)&extended_params;
610 sys->params.NumExtParam =
611 #if QSV_HAVE_CO2
613 #else
615 #endif
617 MFXVideoENCODE_GetVideoParam(sys->session, &sys->params);
619 i_extra = headers.SPSBufSize + headers.PPSBufSize;
620 p_extra = malloc(i_extra);
622 if (unlikely(!p_extra))
623 goto nomem;
625 memcpy(p_extra, headers.SPSBuffer, headers.SPSBufSize);
626 memcpy(p_extra + headers.SPSBufSize, headers.PPSBuffer, headers.PPSBufSize);
627 enc->fmt_out.p_extra = p_extra;
628 enc->fmt_out.i_extra = i_extra;
630 sys->async_depth = sys->params.AsyncDepth;
631 async_task_t_fifo_Init(&sys->packets);
633 /* Vlc module configuration */
634 enc->fmt_in.i_codec = VLC_CODEC_NV12; // Intel Media SDK requirement
635 enc->fmt_in.video.i_bits_per_pixel = 12;
636 enc->fmt_in.video.i_width = sys->params.mfx.FrameInfo.Width;
637 enc->fmt_in.video.i_height = sys->params.mfx.FrameInfo.Height;
639 enc->pf_encode_video = Encode;
641 return VLC_SUCCESS;
643 error:
644 Close(this);
645 enc->p_sys = NULL;
646 return VLC_EGENERIC;
647 nomem:
648 Close(this);
649 enc->p_sys = NULL;
650 return VLC_ENOMEM;
653 static void Close(vlc_object_t *this)
655 encoder_t *enc = (encoder_t *)this;
656 encoder_sys_t *sys = enc->p_sys;
658 MFXVideoENCODE_Close(sys->session);
659 MFXClose(sys->session);
660 /* if (enc->fmt_out.p_extra) */
661 /* free(enc->fmt_out.p_extra); */
662 async_task_t_fifo_Release(&sys->packets);
663 if (sys->input_pool)
664 picture_pool_Release(sys->input_pool);
665 free(sys);
669 * The behavior in the next function comes from x264.c
671 static void qsv_set_block_flags(block_t *block, uint16_t frame_type)
673 if (frame_type & MFX_FRAMETYPE_IDR)
674 block->i_flags = BLOCK_FLAG_TYPE_I;
675 else if ((frame_type & MFX_FRAMETYPE_P) || (frame_type & MFX_FRAMETYPE_I))
676 block->i_flags = BLOCK_FLAG_TYPE_P;
677 else if (frame_type & MFX_FRAMETYPE_B)
678 block->i_flags = BLOCK_FLAG_TYPE_B;
679 else
680 block->i_flags = BLOCK_FLAG_TYPE_PB;
684 * Convert the Intel Media SDK's timestamps into VLC's format.
686 static void qsv_set_block_ts(encoder_t *enc, encoder_sys_t *sys, block_t *block, mfxBitstream *bs)
688 block->i_pts = qsv_timestamp_to_mtime(bs->TimeStamp) + sys->offset_pts;
689 block->i_dts = qsv_timestamp_to_mtime(bs->DecodeTimeStamp) + sys->offset_pts;
691 /* HW encoder (with old driver versions) and some parameters
692 combinations doesn't set the DecodeTimeStamp field so we warn
693 the user about it */
694 if (!bs->DecodeTimeStamp || bs->DecodeTimeStamp > (int64_t)bs->TimeStamp)
695 if (sys->dts_warn_counter++ % 16 == 0) // Rate limiting this message.
696 msg_Warn(enc, "Encode returning empty DTS or DTS > PTS. Your stream will be invalid. "
697 " Please double-check they weren't any warning at encoder initialization "
698 " and that you have the last version of Intel's drivers installed.");
701 static block_t *qsv_synchronize_block(encoder_t *enc, async_task_t *task)
703 encoder_sys_t *sys = enc->p_sys;
704 mfxStatus sts;
706 /* Synchronize and fill block_t. If the SyncOperation fails we leak :-/ (or we can segfault, ur choice) */
707 do {
708 sts = MFXVideoCORE_SyncOperation(sys->session, *task->syncp, QSV_SYNCPOINT_WAIT);
709 } while (sts == MFX_WRN_IN_EXECUTION);
710 if (sts != MFX_ERR_NONE) {
711 msg_Err(enc, "SyncOperation failed (%d), outputting garbage data. "
712 "Updating your drivers and/or changing the encoding settings might resolve this", sts);
713 return NULL;
715 if (task->bs.DataLength == 0)
717 msg_Dbg(enc, "Empty encoded block");
718 return NULL;
720 block_t *block = task->block;
721 block->i_buffer = task->bs.DataLength;
722 block->p_buffer += task->bs.DataOffset;
724 qsv_set_block_ts(enc, sys, block, &task->bs);
725 qsv_set_block_flags(block, task->bs.FrameType);
727 /* msg_Dbg(enc, "block->i_pts = %lld, block->i_dts = %lld", block->i_pts, block->i_dts); */
728 /* msg_Dbg(enc, "FrameType = %#.4x, TimeStamp = %lld (pts %lld), DecodeTimeStamp = %lld syncp=0x%x",*/
729 /* task->bs.FrameType, task->bs.TimeStamp, block->i_pts, task->bs.DecodeTimeStamp, *task->syncp); */
731 /* Copied from x264.c: This isn't really valid for streams with B-frames */
732 block->i_length = CLOCK_FREQ *
733 enc->fmt_in.video.i_frame_rate_base /
734 enc->fmt_in.video.i_frame_rate;
736 // Buggy DTS (value comes from experiments)
737 if (task->bs.DecodeTimeStamp < -10000)
738 block->i_dts = sys->last_dts + block->i_length;
739 sys->last_dts = block->i_dts;
741 task->bs.DataLength = task->bs.DataOffset = 0;
742 return block;
745 static int submit_frame(encoder_t *enc, picture_t *pic, QSVFrame **new_frame)
747 encoder_sys_t *sys = enc->p_sys;
748 QSVFrame *qf = NULL;
749 int ret = get_free_frame(sys, &qf);
750 if (ret != VLC_SUCCESS) {
751 msg_Warn(enc, "Unable to find an unlocked surface in the pool");
752 return ret;
755 qf->pic = picture_pool_Get( sys->input_pool );
756 if (unlikely(!qf->pic))
758 msg_Warn(enc, "Unable to find an unlocked surface in the pool");
759 qf->used = 0;
760 return ret;
762 picture_Copy( qf->pic, pic );
764 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);
766 qf->surface.Info = sys->params.mfx.FrameInfo;
768 // Specify picture structure at runtime.
769 if (pic->b_progressive)
770 qf->surface.Info.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
771 else if (pic->b_top_field_first)
772 qf->surface.Info.PicStruct = MFX_PICSTRUCT_FIELD_TFF;
773 else
774 qf->surface.Info.PicStruct = MFX_PICSTRUCT_FIELD_BFF;
776 //qf->surface.Data.Pitch = QSV_ALIGN(16, qf->surface.Info.Width);
778 qf->surface.Data.PitchLow = qf->pic->p[0].i_pitch;
779 qf->surface.Data.Y = qf->pic->p[0].p_pixels;
780 qf->surface.Data.UV = qf->pic->p[1].p_pixels;
782 qf->surface.Data.TimeStamp = qsv_mtime_to_timestamp(pic->date - sys->offset_pts);
784 *new_frame = qf;
786 return VLC_SUCCESS;
789 static async_task_t *encode_frame(encoder_t *enc, picture_t *pic)
791 encoder_sys_t *sys = enc->p_sys;
792 mfxStatus sts = MFX_ERR_MEMORY_ALLOC;
793 QSVFrame *qsv_frame = NULL;
794 mfxFrameSurface1 *surf = NULL;
795 async_task_t *task = calloc(1, sizeof(*task));
796 if (unlikely(task == NULL))
797 goto done;
799 if (pic) {
800 /* To avoid qsv -> vlc timestamp conversion overflow, we use timestamp relative
801 to the first picture received. That way, vlc will overflow before us.
802 (Thanks to funman for the idea) */
803 if (!sys->offset_pts) // First frame
804 sys->offset_pts = pic->date;
806 if (submit_frame(enc, pic, &qsv_frame) != VLC_SUCCESS)
808 msg_Warn(enc, "Unable to find an unlocked surface in the pool");
809 goto done;
813 if (!(task->syncp = calloc(1, sizeof(*task->syncp)))) {
814 msg_Err(enc, "Unable to allocate syncpoint for encoder output");
815 goto done;
818 /* Allocate block_t and prepare mfxBitstream for encoder */
819 if (!(task->block = block_Alloc(sys->params.mfx.BufferSizeInKB * 1000))) {
820 msg_Err(enc, "Unable to allocate block for encoder output");
821 goto done;
823 memset(&task->bs, 0, sizeof(task->bs));
824 task->bs.MaxLength = task->block->i_buffer;
825 task->bs.Data = task->block->p_buffer;
827 if (qsv_frame) {
828 surf = &qsv_frame->surface;
831 for (;;) {
832 sts = MFXVideoENCODE_EncodeFrameAsync(sys->session, 0, surf, &task->bs, task->syncp);
833 if (sts != MFX_WRN_DEVICE_BUSY && sts != MFX_WRN_IN_EXECUTION)
834 break;
835 if (sys->busy_warn_counter++ % 16 == 0)
836 msg_Dbg(enc, "Device is busy, let's wait and retry %d", sts);
837 if (sts == MFX_WRN_DEVICE_BUSY)
838 vlc_tick_sleep(QSV_BUSYWAIT_TIME);
841 // msg_Dbg(enc, "Encode async status: %d, Syncpoint = %tx", sts, (ptrdiff_t)task->syncp);
843 if (sts == MFX_ERR_MORE_DATA)
844 if (pic)
845 msg_Dbg(enc, "Encoder feeding phase, more data is needed.");
846 else
847 msg_Dbg(enc, "Encoder is empty");
848 else if (sts < MFX_ERR_NONE) {
849 msg_Err(enc, "Encoder not ready or error (%d), trying a reset...", sts);
850 MFXVideoENCODE_Reset(sys->session, &sys->params);
853 done:
854 if (sts < MFX_ERR_NONE || (task != NULL && !task->syncp)) {
855 if (task->block != NULL)
856 block_Release(task->block);
857 free(task);
858 task = NULL;
860 return task;
864 * The Encode function has 3 encoding phases :
865 * - Feed : We feed the encoder until it stops to return MFX_MORE_DATA_NEEDED
866 * and the async_tasks are all in use (honouring the AsyncDepth)
867 * - Main encoding phase : synchronizing the oldest task each call.
868 * - Empty : pic = 0, we empty the decoder. Synchronizing the remaining tasks.
870 static block_t *Encode(encoder_t *this, picture_t *pic)
872 encoder_t *enc = (encoder_t *)this;
873 encoder_sys_t *sys = enc->p_sys;
874 async_task_t *task;
875 block_t *block = NULL;
877 if (likely(pic != NULL))
879 task = encode_frame( enc, pic );
880 if (likely(task != NULL))
881 async_task_t_fifo_Put(&sys->packets, task);
884 if ( async_task_t_fifo_GetCount(&sys->packets) == (sys->async_depth + 1) ||
885 (!pic && async_task_t_fifo_GetCount(&sys->packets)))
887 assert(async_task_t_fifo_Show(&sys->packets)->syncp != 0);
888 async_task_t *task = async_task_t_fifo_Get(&sys->packets);
889 block = qsv_synchronize_block( enc, task );
890 free(task->syncp);
891 free(task);
894 return block;