[FFmpeg-devel] [PATCH] qsv: Merge libav implementation
Mark Thompson
sw at jkqxz.net
Fri Oct 21 21:17:00 EEST 2016
On 21/10/16 19:14, Mark Thompson wrote:
> Merged as-at libav 398f015, and therefore includes outstanding skipped
> merges 04b17ff and 130e1f1.
>
> All features not in libav are preserved, and no options change.
For comparison, here is the resulting diff from libav at 398f015.
diff -ur libav/qsv_api.c ffmpeg/qsv_api.c
--- libav/qsv_api.c 2016-10-21 18:52:45.133412123 +0100
+++ ffmpeg/qsv_api.c 2016-10-21 19:02:57.273790522 +0100
@@ -1,20 +1,20 @@
/*
* Intel MediaSDK QSV public API functions
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff -ur libav/qsv.c ffmpeg/qsv.c
--- libav/qsv.c 2016-10-21 18:52:45.133412123 +0100
+++ ffmpeg/qsv.c 2016-10-21 19:02:57.273790522 +0100
@@ -1,20 +1,20 @@
/*
* Intel MediaSDK QSV encoder/decoder shared code
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff -ur libav/qsvdec.c ffmpeg/qsvdec.c
--- libav/qsvdec.c 2016-10-21 18:52:45.133412123 +0100
+++ ffmpeg/qsvdec.c 2016-10-21 19:02:57.273790522 +0100
@@ -4,20 +4,20 @@
* copyright (c) 2013 Luca Barbato
* copyright (c) 2015 Anton Khirnov <anton at khirnov.net>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -162,7 +162,13 @@
ret = MFXVideoDECODE_Init(q->session, ¶m);
if (ret < 0) {
- av_log(avctx, AV_LOG_ERROR, "Error initializing the MFX video decoder\n");
+ if (MFX_ERR_INVALID_VIDEO_PARAM==ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Error initializing the MFX video decoder, unsupported video\n");
+ } else {
+ av_log(avctx, AV_LOG_ERROR,
+ "Error initializing the MFX video decoder %d\n", ret);
+ }
return ff_qsv_error(ret);
}
@@ -293,7 +299,7 @@
ret = MFXVideoDECODE_DecodeFrameAsync(q->session, avpkt->size ? &bs : NULL,
insurf, &outsurf, sync);
if (ret == MFX_WRN_DEVICE_BUSY)
- av_usleep(1);
+ av_usleep(500);
} while (ret == MFX_WRN_DEVICE_BUSY || ret == MFX_ERR_MORE_SURFACE);
diff -ur libav/qsvdec.h ffmpeg/qsvdec.h
--- libav/qsvdec.h 2016-10-21 18:52:45.133412123 +0100
+++ ffmpeg/qsvdec.h 2016-10-21 19:02:57.273790522 +0100
@@ -3,20 +3,20 @@
*
* copyright (c) 2013 Luca Barbato
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff -ur libav/qsvdec_h2645.c ffmpeg/qsvdec_h2645.c
--- libav/qsvdec_h2645.c 2016-10-21 18:52:45.133412123 +0100
+++ ffmpeg/qsvdec_h2645.c 2016-10-21 19:02:57.273790522 +0100
@@ -4,20 +4,20 @@
* copyright (c) 2013 Luca Barbato
* copyright (c) 2015 Anton Khirnov
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff -ur libav/qsvdec_mpeg2.c ffmpeg/qsvdec_mpeg2.c
--- libav/qsvdec_mpeg2.c 2016-10-21 18:52:45.133412123 +0100
+++ ffmpeg/qsvdec_mpeg2.c 2016-10-21 19:02:57.273790522 +0100
@@ -3,20 +3,20 @@
*
* copyright (c) 2015 Anton Khirnov
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
Only in ffmpeg/: qsvdec_vc1.c
diff -ur libav/qsvenc.c ffmpeg/qsvenc.c
--- libav/qsvenc.c 2016-10-21 18:52:45.133412123 +0100
+++ ffmpeg/qsvenc.c 2016-10-21 19:02:57.273790522 +0100
@@ -4,20 +4,20 @@
* copyright (c) 2013 Yukinori Yamazoe
* copyright (c) 2015 Anton Khirnov
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -32,6 +32,7 @@
#include "libavutil/log.h"
#include "libavutil/time.h"
#include "libavutil/imgutils.h"
+#include "libavcodec/bytestream.h"
#include "avcodec.h"
#include "internal.h"
@@ -273,7 +274,7 @@
const char *rc_desc;
mfxU16 rc_mode;
- int want_la = q->la_depth >= 0;
+ int want_la = q->look_ahead;
int want_qscale = !!(avctx->flags & AV_CODEC_FLAG_QSCALE);
int want_vcm = q->vcm;
@@ -438,11 +439,11 @@
#if QSV_HAVE_LA
case MFX_RATECONTROL_LA:
q->param.mfx.TargetKbps = avctx->bit_rate / 1000;
- q->extco2.LookAheadDepth = q->la_depth;
+ q->extco2.LookAheadDepth = q->look_ahead_depth;
break;
#if QSV_HAVE_ICQ
case MFX_RATECONTROL_LA_ICQ:
- q->extco2.LookAheadDepth = q->la_depth;
+ q->extco2.LookAheadDepth = q->look_ahead_depth;
case MFX_RATECONTROL_ICQ:
q->param.mfx.ICQQuality = avctx->global_quality;
break;
@@ -464,6 +465,9 @@
q->extco.CAVLC = q->cavlc ? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_UNKNOWN;
+ q->extco.PicTimingSEI = q->pic_timing_sei ?
+ MFX_CODINGOPTION_ON : MFX_CODINGOPTION_UNKNOWN;
+
if (q->rdo >= 0)
q->extco.RateDistortionOpt = q->rdo > 0 ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
@@ -527,6 +531,10 @@
#endif
q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->extco2;
+
+#if QSV_HAVE_LA_DS
+ q->extco2.LookAheadDS = q->look_ahead_downsampling;
+#endif
}
#endif
}
@@ -781,7 +789,9 @@
}
ret = MFXVideoENCODE_Init(q->session, &q->param);
- if (ret < 0) {
+ if (ret == MFX_WRN_PARTIAL_ACCELERATION) {
+ av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
+ } else if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Error initializing the encoder\n");
return ff_qsv_error(ret);
}
@@ -797,12 +807,24 @@
return 0;
}
+static void free_encoder_ctrl_payloads(mfxEncodeCtrl* enc_ctrl)
+{
+ if (enc_ctrl) {
+ int i;
+ for (i = 0; i < enc_ctrl->NumPayload && i < QSV_MAX_ENC_PAYLOAD; i++) {
+ av_free(enc_ctrl->Payload[i]);
+ }
+ enc_ctrl->NumPayload = 0;
+ }
+}
+
static void clear_unused_frames(QSVEncContext *q)
{
QSVFrame *cur = q->work_frames;
while (cur) {
if (cur->surface && !cur->surface->Data.Locked) {
cur->surface = NULL;
+ free_encoder_ctrl_payloads(&cur->enc_ctrl);
av_frame_unref(cur->frame);
}
cur = cur->next;
@@ -835,6 +857,11 @@
av_freep(&frame);
return AVERROR(ENOMEM);
}
+ frame->enc_ctrl.Payload = av_mallocz(sizeof(mfxPayload*) * QSV_MAX_ENC_PAYLOAD);
+ if (!frame->enc_ctrl.Payload) {
+ av_freep(&frame);
+ return AVERROR(ENOMEM);
+ }
*last = frame;
*f = frame;
@@ -843,7 +870,7 @@
}
static int submit_frame(QSVEncContext *q, const AVFrame *frame,
- mfxFrameSurface1 **surface)
+ QSVFrame **new_frame)
{
QSVFrame *qf;
int ret;
@@ -903,7 +930,7 @@
qf->surface->Data.TimeStamp = av_rescale_q(frame->pts, q->avctx->time_base, (AVRational){1, 90000});
- *surface = qf->surface;
+ *new_frame = qf;
return 0;
}
@@ -927,16 +954,22 @@
mfxBitstream *bs;
mfxFrameSurface1 *surf = NULL;
- mfxSyncPoint *sync = NULL;
+ mfxSyncPoint *sync = NULL;
+ QSVFrame *qsv_frame = NULL;
+ mfxEncodeCtrl* enc_ctrl = NULL;
int ret;
if (frame) {
- ret = submit_frame(q, frame, &surf);
+ ret = submit_frame(q, frame, &qsv_frame);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Error submitting the frame for encoding.\n");
return ret;
}
}
+ if (qsv_frame) {
+ surf = qsv_frame->surface;
+ enc_ctrl = &qsv_frame->enc_ctrl;
+ }
ret = av_new_packet(&new_pkt, q->packet_size);
if (ret < 0) {
@@ -952,6 +985,10 @@
bs->Data = new_pkt.data;
bs->MaxLength = new_pkt.size;
+ if (q->set_encode_ctrl_cb) {
+ q->set_encode_ctrl_cb(avctx, frame, &qsv_frame->enc_ctrl);
+ }
+
sync = av_mallocz(sizeof(*sync));
if (!sync) {
av_freep(&bs);
@@ -960,9 +997,9 @@
}
do {
- ret = MFXVideoENCODE_EncodeFrameAsync(q->session, NULL, surf, bs, sync);
+ ret = MFXVideoENCODE_EncodeFrameAsync(q->session, enc_ctrl, surf, bs, sync);
if (ret == MFX_WRN_DEVICE_BUSY)
- av_usleep(1);
+ av_usleep(500);
} while (ret > 0);
if (ret < 0) {
@@ -1076,6 +1113,7 @@
while (cur) {
q->work_frames = cur->next;
av_frame_free(&cur->frame);
+ av_free(cur->enc_ctrl.Payload);
av_freep(&cur);
cur = q->work_frames;
}
diff -ur libav/qsvenc.h ffmpeg/qsvenc.h
--- libav/qsvenc.h 2016-10-21 18:52:45.137412178 +0100
+++ ffmpeg/qsvenc.h 2016-10-21 19:02:57.273790522 +0100
@@ -3,20 +3,20 @@
*
* copyright (c) 2013 Yukinori Yamazoe
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -42,32 +42,38 @@
#define QSV_HAVE_BREF_TYPE QSV_VERSION_ATLEAST(1, 8)
#define QSV_HAVE_LA QSV_VERSION_ATLEAST(1, 7)
+#define QSV_HAVE_LA_DS QSV_VERSION_ATLEAST(1, 8)
#define QSV_HAVE_LA_HRD QSV_VERSION_ATLEAST(1, 11)
#define QSV_HAVE_ICQ QSV_VERSION_ATLEAST(1, 8)
#define QSV_HAVE_VCM QSV_VERSION_ATLEAST(1, 8)
#define QSV_HAVE_QVBR QSV_VERSION_ATLEAST(1, 11)
#define QSV_COMMON_OPTS \
-{ "async_depth", "Maximum processing parallelism", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = ASYNC_DEPTH_DEFAULT }, 0, INT_MAX, VE }, \
-{ "avbr_accuracy", "Accuracy of the AVBR ratecontrol", OFFSET(qsv.avbr_accuracy), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, \
-{ "avbr_convergence", "Convergence of the AVBR ratecontrol", OFFSET(qsv.avbr_convergence), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, \
-{ "preset", NULL, OFFSET(qsv.preset), AV_OPT_TYPE_INT, { .i64 = MFX_TARGETUSAGE_BALANCED }, 0, 7, VE, "preset" }, \
-{ "fast", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_BEST_SPEED }, INT_MIN, INT_MAX, VE, "preset" }, \
-{ "medium", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_BALANCED }, INT_MIN, INT_MAX, VE, "preset" }, \
-{ "slow", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_BEST_QUALITY }, INT_MIN, INT_MAX, VE, "preset" }, \
-{ "la_depth", "Number of frames to analyze before encoding.", OFFSET(qsv.la_depth), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT16_MAX, VE }, \
-{ "vcm", "Use the video conferencing mode ratecontrol", OFFSET(qsv.vcm), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, \
-{ "rdo", "Enable rate distortion optimization", OFFSET(qsv.rdo), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, \
-{ "max_frame_size", "Maximum encoded frame size in bytes", OFFSET(qsv.max_frame_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, UINT16_MAX, VE }, \
-{ "max_slice_size", "Maximum encoded slice size in bytes", OFFSET(qsv.max_slice_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, UINT16_MAX, VE }, \
-{ "bitrate_limit", "Toggle bitrate limitations", OFFSET(qsv.bitrate_limit), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, \
-{ "mbbrc", "MB level bitrate control", OFFSET(qsv.mbbrc), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, \
-{ "extbrc", "Extended bitrate control", OFFSET(qsv.extbrc), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, \
-{ "adaptive_i", "Adaptive I-frame placement", OFFSET(qsv.adaptive_i), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, \
-{ "adaptive_b", "Adaptive B-frame placement", OFFSET(qsv.adaptive_b), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, \
-{ "b_strategy", "Strategy to choose between I/P/B-frames", OFFSET(qsv.b_strategy), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, \
-{ "cavlc", "Enable CAVLC", OFFSET(qsv.cavlc), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, \
+{ "async_depth", "Maximum processing parallelism", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = ASYNC_DEPTH_DEFAULT }, 0, INT_MAX, VE }, \
+{ "avbr_accuracy", "Accuracy of the AVBR ratecontrol", OFFSET(qsv.avbr_accuracy), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, \
+{ "avbr_convergence", "Convergence of the AVBR ratecontrol", OFFSET(qsv.avbr_convergence), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, \
+{ "preset", NULL, OFFSET(qsv.preset), AV_OPT_TYPE_INT, { .i64 = MFX_TARGETUSAGE_BALANCED }, MFX_TARGETUSAGE_BEST_QUALITY, MFX_TARGETUSAGE_BEST_SPEED, VE, "preset" }, \
+{ "veryfast", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_BEST_SPEED }, INT_MIN, INT_MAX, VE, "preset" }, \
+{ "faster", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_6 }, INT_MIN, INT_MAX, VE, "preset" }, \
+{ "fast", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_5 }, INT_MIN, INT_MAX, VE, "preset" }, \
+{ "medium", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_BALANCED }, INT_MIN, INT_MAX, VE, "preset" }, \
+{ "slow", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_3 }, INT_MIN, INT_MAX, VE, "preset" }, \
+{ "slower", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_2 }, INT_MIN, INT_MAX, VE, "preset" }, \
+{ "veryslow", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_BEST_QUALITY }, INT_MIN, INT_MAX, VE, "preset" }, \
+{ "vcm", "Use the video conferencing mode ratecontrol", OFFSET(qsv.vcm), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, \
+{ "rdo", "Enable rate distortion optimization", OFFSET(qsv.rdo), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, \
+{ "max_frame_size", "Maximum encoded frame size in bytes", OFFSET(qsv.max_frame_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, UINT16_MAX, VE }, \
+{ "max_slice_size", "Maximum encoded slice size in bytes", OFFSET(qsv.max_slice_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, UINT16_MAX, VE }, \
+{ "bitrate_limit", "Toggle bitrate limitations", OFFSET(qsv.bitrate_limit), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, \
+{ "mbbrc", "MB level bitrate control", OFFSET(qsv.mbbrc), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, \
+{ "extbrc", "Extended bitrate control", OFFSET(qsv.extbrc), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, \
+{ "adaptive_i", "Adaptive I-frame placement", OFFSET(qsv.adaptive_i), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, \
+{ "adaptive_b", "Adaptive B-frame placement", OFFSET(qsv.adaptive_b), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, \
+{ "b_strategy", "Strategy to choose between I/P/B-frames", OFFSET(qsv.b_strategy), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, \
+{ "cavlc", "Enable CAVLC", OFFSET(qsv.cavlc), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, \
+typedef int SetEncodeCtrlCB (AVCodecContext *avctx,
+ const AVFrame *frame, mfxEncodeCtrl* enc_ctrl);
typedef struct QSVEncContext {
AVCodecContext *avctx;
@@ -107,7 +113,10 @@
int preset;
int avbr_accuracy;
int avbr_convergence;
- int la_depth;
+ int pic_timing_sei;
+ int look_ahead;
+ int look_ahead_depth;
+ int look_ahead_downsampling;
int vcm;
int rdo;
int max_frame_size;
@@ -130,7 +139,9 @@
int int_ref_qp_delta;
int recovery_point_sei;
+ int a53_cc;
char *load_plugins;
+ SetEncodeCtrlCB *set_encode_ctrl_cb;
} QSVEncContext;
int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q);
diff -ur libav/qsvenc_h264.c ffmpeg/qsvenc_h264.c
--- libav/qsvenc_h264.c 2016-10-21 18:52:45.137412178 +0100
+++ ffmpeg/qsvenc_h264.c 2016-10-21 19:02:57.273790522 +0100
@@ -3,20 +3,20 @@
*
* copyright (c) 2013 Yukinori Yamazoe
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -40,10 +40,45 @@
QSVEncContext qsv;
} QSVH264EncContext;
+static int qsv_h264_set_encode_ctrl(AVCodecContext *avctx,
+ const AVFrame *frame, mfxEncodeCtrl* enc_ctrl)
+{
+ QSVH264EncContext *qh264 = avctx->priv_data;
+ QSVEncContext *q = &qh264->qsv;
+
+ if (q->a53_cc && frame) {
+ mfxPayload* payload;
+ mfxU8* sei_data;
+ size_t sei_size;
+ int res;
+
+ res = ff_alloc_a53_sei(frame, sizeof(mfxPayload) + 2, (void**)&payload, &sei_size);
+ if (res < 0 || !payload)
+ return res;
+
+ sei_data = (mfxU8*)(payload + 1);
+ // SEI header
+ sei_data[0] = 4;
+ sei_data[1] = (mfxU8)sei_size; // size of SEI data
+ // SEI data filled in by ff_alloc_a53_sei
+
+ payload->BufSize = sei_size + 2;
+ payload->NumBit = payload->BufSize * 8;
+ payload->Type = 4;
+ payload->Data = sei_data;
+
+ enc_ctrl->NumExtParam = 0;
+ enc_ctrl->NumPayload = 1;
+ enc_ctrl->Payload[0] = payload;
+ }
+ return 0;
+}
+
static av_cold int qsv_enc_init(AVCodecContext *avctx)
{
QSVH264EncContext *q = avctx->priv_data;
+ q->qsv.set_encode_ctrl_cb = qsv_h264_set_encode_ctrl;
return ff_qsv_enc_init(avctx, &q->qsv);
}
@@ -68,9 +103,21 @@
QSV_COMMON_OPTS
{ "idr_interval", "Distance (in I-frames) between IDR frames", OFFSET(qsv.idr_interval), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
+ { "pic_timing_sei", "Insert picture timing SEI with pic_struct_syntax element", OFFSET(qsv.pic_timing_sei), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, VE },
{ "single_sei_nal_unit", "Put all the SEI messages into one NALU", OFFSET(qsv.single_sei_nal_unit), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE },
{ "max_dec_frame_buffering", "Maximum number of frames buffered in the DPB", OFFSET(qsv.max_dec_frame_buffering), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, UINT16_MAX, VE },
+#if QSV_HAVE_LA
+ { "look_ahead", "Use VBR algorithm with look ahead", OFFSET(qsv.look_ahead), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, VE },
+ { "look_ahead_depth", "Depth of look ahead in number frames", OFFSET(qsv.look_ahead_depth), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, VE },
+#endif
+#if QSV_HAVE_LA_DS
+ { "look_ahead_downsampling", NULL, OFFSET(qsv.look_ahead_downsampling), AV_OPT_TYPE_INT, { .i64 = MFX_LOOKAHEAD_DS_UNKNOWN }, MFX_LOOKAHEAD_DS_UNKNOWN, MFX_LOOKAHEAD_DS_2x, VE, "look_ahead_downsampling" },
+ { "unknown" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_LOOKAHEAD_DS_UNKNOWN }, INT_MIN, INT_MAX, VE, "look_ahead_downsampling" },
+ { "off" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_LOOKAHEAD_DS_OFF }, INT_MIN, INT_MAX, VE, "look_ahead_downsampling" },
+ { "2x" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_LOOKAHEAD_DS_2x }, INT_MIN, INT_MAX, VE, "look_ahead_downsampling" },
+#endif
+
{ "int_ref_type", "Intra refresh type", OFFSET(qsv.int_ref_type), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, UINT16_MAX, VE, "int_ref_type" },
{ "none", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, .flags = VE, "int_ref_type" },
{ "vertical", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, .flags = VE, "int_ref_type" },
@@ -90,6 +137,7 @@
{ "main" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_PROFILE_AVC_MAIN }, INT_MIN, INT_MAX, VE, "profile" },
{ "high" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_PROFILE_AVC_HIGH }, INT_MIN, INT_MAX, VE, "profile" },
+ { "a53cc" , "Use A53 Closed Captions (if available)", OFFSET(qsv.a53_cc), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, VE},
{ NULL },
};
diff -ur libav/qsvenc_hevc.c ffmpeg/qsvenc_hevc.c
--- libav/qsvenc_hevc.c 2016-10-21 18:52:45.137412178 +0100
+++ ffmpeg/qsvenc_hevc.c 2016-10-21 19:02:57.273790522 +0100
@@ -1,20 +1,20 @@
/*
* Intel MediaSDK QSV based HEVC encoder
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -69,7 +69,7 @@
}
/* parse the SPS */
- ret = ff_h2645_extract_rbsp(avctx->extradata + 4, avctx->extradata_size - 4, &sps_nal);
+ ret = ff_h2645_extract_rbsp(avctx->extradata + 4, avctx->extradata_size - 4, &sps_nal, 1);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Error unescaping the SPS buffer\n");
return ret;
diff -ur libav/qsvenc_mpeg2.c ffmpeg/qsvenc_mpeg2.c
--- libav/qsvenc_mpeg2.c 2016-10-21 18:52:45.137412178 +0100
+++ ffmpeg/qsvenc_mpeg2.c 2016-10-21 19:02:57.273790522 +0100
@@ -1,20 +1,20 @@
/*
* Intel MediaSDK QSV based MPEG-2 encoder
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff -ur libav/qsv.h ffmpeg/qsv.h
--- libav/qsv.h 2016-10-21 18:52:45.137412178 +0100
+++ ffmpeg/qsv.h 2016-10-21 19:02:57.273790522 +0100
@@ -1,20 +1,20 @@
/*
* Intel MediaSDK QSV public API
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff -ur libav/qsv_internal.h ffmpeg/qsv_internal.h
--- libav/qsv_internal.h 2016-10-21 18:52:45.137412178 +0100
+++ ffmpeg/qsv_internal.h 2016-10-21 19:02:57.273790522 +0100
@@ -1,20 +1,20 @@
/*
* Intel MediaSDK QSV encoder/decoder shared code
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -32,6 +32,8 @@
#define ASYNC_DEPTH_DEFAULT 4 // internal parallelism
+#define QSV_MAX_ENC_PAYLOAD 2 // # of mfxEncodeCtrl payloads supported
+
#define QSV_VERSION_ATLEAST(MAJOR, MINOR) \
(MFX_VERSION_MAJOR > (MAJOR) || \
MFX_VERSION_MAJOR == (MAJOR) && MFX_VERSION_MINOR >= (MINOR))
@@ -39,6 +41,7 @@
typedef struct QSVFrame {
AVFrame *frame;
mfxFrameSurface1 *surface;
+ mfxEncodeCtrl enc_ctrl;
mfxFrameSurface1 surface_internal;
@@ -55,7 +58,7 @@
} QSVFramesContext;
/**
- * Convert a libmfx error code into a libav error code.
+ * Convert a libmfx error code into a ffmpeg error code.
*/
int ff_qsv_error(int mfx_err);
More information about the ffmpeg-devel
mailing list