From patchwork Mon Apr 13 15:33:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 18923 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 703A5449F3D for ; Mon, 13 Apr 2020 18:33:42 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 5B42468B96D; Mon, 13 Apr 2020 18:33:42 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr1-f66.google.com (mail-wr1-f66.google.com [209.85.221.66]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8963068B954 for ; Mon, 13 Apr 2020 18:33:34 +0300 (EEST) Received: by mail-wr1-f66.google.com with SMTP id p10so10567338wrt.6 for ; Mon, 13 Apr 2020 08:33:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jkqxz-net.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=pjNdpAEnnMQSkms6arCjp718jia7pzj7OyEd1tSdcoI=; b=w3eNN7Bq7nDk1aFj3JRcaj75i3Qzr0XKnT30BeUmlAMpay6VyRIxCpp5vNMYAUyPFY +vHTi6vAYmnhtobMeKMbWkb/HC98N5bZe6aRRdU/31b7n/ZbMNuusZIjalANH8JSJXiA O1DSCP7BegNkLpJUFJeG8/thjk6FxmOvG18eRCKhJ/KdNqBn4nHCrqGrsPBCE+0C0CXd Ogs3DtvuS73z6hI3sBFfb7byjc2/fVTw+oqUjJFLDDVYwT/WcO1GnzQeLlPYl63ncRb8 Af2z7QNm+/ZIcw2B5SSHladcvwtdjeOL3Lyy+Q9xAxL4z8V3XxRygRf+HjI2HW1hsqaH 5Lfw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=pjNdpAEnnMQSkms6arCjp718jia7pzj7OyEd1tSdcoI=; b=PzSln0Ia2vOLG2CdLUwP2yyam0u2g/Q5cOh0jrVnPIAJx4P2qnni2IV1P8rbwfwEXa alxfQI6w0YzRWpbDxMQ2YRrTBnWt/7yBMHZAkKTO62Zjd5kaHaRaTZTTlVlAmwQ1pzaI 4MALVaKgqvXHGi+VOa8rPvx/QSb6zjtQJKqTBpmpkPBVRuV2qdEbFFchCdvu0xzkKv90 kNz5IuOn7uzUgyI+IdaN5aB9Z1S1ENz9s3V8BtlXGxf+5nhv9J5wIe1vuFGkIr70zPZF U2kx7nohKVVvPoq9zy71syEWV4Okiv5QAbVVMRH5d2ef2gSk90tV7mvYgO2pOlzFhXcX T0aA== X-Gm-Message-State: AGi0PuYrbVYzVSo6QDJDxNsgt8uXlFLPyRgCfHFPNrBMbC0TZQcPebXS UjyYATWKVFqFB5dwQoD0T+IMB8ulsRo= X-Google-Smtp-Source: APiQypJ+wnontPY5wW4P1IwNn0dbQ1GTKp34U/7s+Er493TlU9chPRSEjd8v8SkWulp5oO66QrSF8g== X-Received: by 2002:a5d:654f:: with SMTP id z15mr16463021wrv.338.1586792013661; Mon, 13 Apr 2020 08:33:33 -0700 (PDT) Received: from rywe.jkqxz.net (cpc91242-cmbg18-2-0-cust650.5-4.cable.virginm.net. [82.8.130.139]) by smtp.gmail.com with ESMTPSA id t8sm15157557wrq.88.2020.04.13.08.33.32 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Apr 2020 08:33:32 -0700 (PDT) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org Date: Mon, 13 Apr 2020 16:33:20 +0100 Message-Id: <20200413153321.5956-7-sw@jkqxz.net> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200413153321.5956-1-sw@jkqxz.net> References: <20200413153321.5956-1-sw@jkqxz.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 7/8] ffmpeg: Use hardware config metadata with encoders 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" This can support encoders which want frames and/or device contexts. For the device case, it currently picks the first initialised device of the desired type to give to the encoder - a new option would be needed if it were necessary to choose between multiple devices of the same type. --- fftools/ffmpeg.c | 19 ++++++------------ fftools/ffmpeg_hw.c | 48 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 46 insertions(+), 21 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 0578265c1e..5089443c9d 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -3476,21 +3476,14 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len) !av_dict_get(ost->encoder_opts, "ab", NULL, 0)) av_dict_set(&ost->encoder_opts, "b", "128000", 0); - if (ost->filter && av_buffersink_get_hw_frames_ctx(ost->filter->filter) && - ((AVHWFramesContext*)av_buffersink_get_hw_frames_ctx(ost->filter->filter)->data)->format == - av_buffersink_get_format(ost->filter->filter)) { - ost->enc_ctx->hw_frames_ctx = av_buffer_ref(av_buffersink_get_hw_frames_ctx(ost->filter->filter)); - if (!ost->enc_ctx->hw_frames_ctx) - return AVERROR(ENOMEM); - } else { - ret = hw_device_setup_for_encode(ost); - if (ret < 0) { - snprintf(error, error_len, "Device setup failed for " - "encoder on output stream #%d:%d : %s", + ret = hw_device_setup_for_encode(ost); + if (ret < 0) { + snprintf(error, error_len, "Device setup failed for " + "encoder on output stream #%d:%d : %s", ost->file_index, ost->index, av_err2str(ret)); - return ret; - } + return ret; } + if (ist && ist->dec->type == AVMEDIA_TYPE_SUBTITLE && ost->enc->type == AVMEDIA_TYPE_SUBTITLE) { int input_props = 0, output_props = 0; AVCodecDescriptor const *input_descriptor = diff --git a/fftools/ffmpeg_hw.c b/fftools/ffmpeg_hw.c index 40739fc320..c5c8aa97ef 100644 --- a/fftools/ffmpeg_hw.c +++ b/fftools/ffmpeg_hw.c @@ -19,6 +19,7 @@ #include #include "libavutil/avstring.h" +#include "libavfilter/buffersink.h" #include "ffmpeg.h" @@ -281,7 +282,10 @@ void hw_device_free_all(void) nb_hw_devices = 0; } -static HWDevice *hw_device_match_by_codec(const AVCodec *codec) +static HWDevice *hw_device_match_by_codec(const AVCodec *codec, + enum AVPixelFormat format, + int possible_methods, + int *matched_methods) { const AVCodecHWConfig *config; HWDevice *dev; @@ -290,11 +294,18 @@ static HWDevice *hw_device_match_by_codec(const AVCodec *codec) config = avcodec_get_hw_config(codec, i); if (!config) return NULL; - if (!(config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX)) + if (format != AV_PIX_FMT_NONE && + config->pix_fmt != AV_PIX_FMT_NONE && + config->pix_fmt != format) + continue; + if (!(config->methods & possible_methods)) continue; dev = hw_device_get_by_type(config->device_type); - if (dev) + if (dev) { + if (matched_methods) + *matched_methods = config->methods & possible_methods; return dev; + } } } @@ -340,7 +351,9 @@ int hw_device_setup_for_decode(InputStream *ist) if (!dev) err = hw_device_init_from_type(type, NULL, &dev); } else { - dev = hw_device_match_by_codec(ist->dec); + dev = hw_device_match_by_codec(ist->dec, AV_PIX_FMT_NONE, + AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX, + NULL); if (!dev) { // No device for this codec, but not using generic hwaccel // and therefore may well not need one - ignore. @@ -417,12 +430,31 @@ int hw_device_setup_for_decode(InputStream *ist) int hw_device_setup_for_encode(OutputStream *ost) { HWDevice *dev; + AVBufferRef *frames_ref; + int methods = AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX; + int matched_methods; + + if (ost->filter) { + frames_ref = av_buffersink_get_hw_frames_ctx(ost->filter->filter); + if (frames_ref && + ((AVHWFramesContext*)frames_ref->data)->format == + ost->enc_ctx->pix_fmt) + methods |= AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX; + } - dev = hw_device_match_by_codec(ost->enc); + dev = hw_device_match_by_codec(ost->enc, ost->enc_ctx->pix_fmt, + methods, &matched_methods); if (dev) { - ost->enc_ctx->hw_device_ctx = av_buffer_ref(dev->device_ref); - if (!ost->enc_ctx->hw_device_ctx) - return AVERROR(ENOMEM); + if (matched_methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX) { + ost->enc_ctx->hw_device_ctx = av_buffer_ref(dev->device_ref); + if (!ost->enc_ctx->hw_device_ctx) + return AVERROR(ENOMEM); + } + if (matched_methods & AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX) { + ost->enc_ctx->hw_frames_ctx = av_buffer_ref(frames_ref); + if (!ost->enc_ctx->hw_frames_ctx) + return AVERROR(ENOMEM); + } return 0; } else { // No device required, or no device available.