From patchwork Fri Oct 21 18:17:00 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 1105 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.140.133 with SMTP id o127csp1177871vsd; Fri, 21 Oct 2016 11:17:13 -0700 (PDT) X-Received: by 10.28.69.214 with SMTP id l83mr11514469wmi.119.1477073833019; Fri, 21 Oct 2016 11:17:13 -0700 (PDT) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id j73si4823158wmf.136.2016.10.21.11.17.12; Fri, 21 Oct 2016 11:17:12 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@jkqxz-net.20150623.gappssmtp.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 901DD689C82; Fri, 21 Oct 2016 21:17:07 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm0-f52.google.com (mail-wm0-f52.google.com [74.125.82.52]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 6E6A8689BF4 for ; Fri, 21 Oct 2016 21:17:00 +0300 (EEST) Received: by mail-wm0-f52.google.com with SMTP id f193so717747wmg.1 for ; Fri, 21 Oct 2016 11:17:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jkqxz-net.20150623.gappssmtp.com; s=20150623; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-transfer-encoding; bh=hwfhm4D/0EL5XFhjia04YGwSP1Er70+PdBwVfq5RNB4=; b=B5pQ/peDzWKOuMcW6F5XQ+efEXdWEp5DHb/GL6VANnjz0jLg8AdD3bNHVXKUsTkfPM ecnZGwsfly8ltW8zMTbeQyQpmpH6YFsodtwqoR25G2McaxNnjyAw64+blvDL878T53SG 7G3QyIHISTQmSfCs85BXfmQ/E6iwsaK//vNte2FO2raUBqy16LvHxbNxJV9kzX85nR4a Uyib7pJD4NDRRXxTdMvnYDVnrG4DuV5Um9eYQMrOuL4/ZBqbQGNUazXlOIZbzdjr6hqW eihdu4IHnV+xyZSBDjdt00Z931Ol4ElKjtF4dv3E4sf3icaqw/1UvWRjx2Wmpw6LZZ9O W+CQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding; bh=hwfhm4D/0EL5XFhjia04YGwSP1Er70+PdBwVfq5RNB4=; b=jFoZmqHEwkvxNFMTg0Ou8vqZbc5SxIEgKvQMnOHBNL49YZzgf1yRm+v+8smadErtiZ cJv/1N93bgZB4vBhAUvIfMdCbGkrNMYI23GMF59nto5NWpz7A4iNin5SZrgbXmN6xEpl Rn485JTxy4hTB3wHEtG6mOJo5w5yGO07px89ZwcTI7bbvalFowFNGOAPZqySW/zRRChM O4tfN6BYzu3Ya0wu9tz5vPQvKAMWrMLKflmjis3WJydmZsgIX5oC/Qn/RxuD40PrG1aB Oshow5Ivb+thytGh15TBz4nBYR47mDB2hLfDp/t6MhldPfnrN/uvMHJffPFA+Fqg2GO+ 1yXQ== X-Gm-Message-State: ABUngvf4dxbOhJRDA7PSh1YQF4AfRYg24t4wyCee55GCBBhAn/g89mj1AU4CjwLs5rVTUg== X-Received: by 10.194.200.39 with SMTP id jp7mr2029310wjc.64.1477073822270; Fri, 21 Oct 2016 11:17:02 -0700 (PDT) Received: from [192.168.0.7] (cpc91242-cmbg18-2-0-cust650.5-4.cable.virginm.net. [82.8.130.139]) by smtp.gmail.com with ESMTPSA id 194sm499729wmj.0.2016.10.21.11.17.01 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 21 Oct 2016 11:17:01 -0700 (PDT) To: FFmpeg development discussions and patches References: From: Mark Thompson Message-ID: <35cfd60e-ce66-0279-6444-bf356ec6cc6e@jkqxz.net> Date: Fri, 21 Oct 2016 19:17:00 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Icedove/45.4.0 MIME-Version: 1.0 In-Reply-To: Subject: Re: [FFmpeg-devel] [PATCH] qsv: Merge libav implementation X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" 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 * - * 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);