From patchwork Mon Feb 19 23:28:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 7668 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.150.33 with SMTP id c30csp2073896jai; Mon, 19 Feb 2018 15:34:42 -0800 (PST) X-Google-Smtp-Source: AH8x227fnhwxinaJdJkQZNAbo89jjh9yhy/UZc12L/BC7LfOQT9gwGa6+dfDPSWElFBMtHCIGjiN X-Received: by 10.223.150.41 with SMTP id b38mr14380890wra.229.1519083282802; Mon, 19 Feb 2018 15:34:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519083282; cv=none; d=google.com; s=arc-20160816; b=A+M206H2FmqGesCRz0P4g/QE1nwjwJN8ME6yfqLF1fiY0AnG2QPakwCpCwMiCducr9 cOfBUYpfo6hbGe5F7f9IYoLIIlkRgP7H5R7pjWSJ7JA3bzThb9Ihx36zYRXnnyiBzFFi cNBTcy2JjDNP/Q8CglV6sS3cj0ivq69tQv3U/xmJHQmAKpTxqIqGu5Rc5mrCBNPYQgmS aFq+EdwivTYByIQ+m4u8Sb1F/HtKHQqWjnsbTM/qMamf/5KxKLUjcAcH1i3tBrcD6vZT YSpp879puHqFuvPf2DbD8BIGJ6oYfdm+/feqYsM0TGUyKi5fswFh0yFmRDqRzZcjfr58 pFWA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:dkim-signature:delivered-to:arc-authentication-results; bh=X1dMX92dT/MtANWMqKpwYbkAlUH4of38fBLH+U3HBCs=; b=NdlW9IbrmjuqhYmlTYZgrKdxIGMHDdCy9WgamDVcuIYVQrGgMLHsHlewqX/fj4wQNH ttC/9Usx+Su7X5luIAgru3lIt6h+GVlFAaFv81nQAlB8oeK8GZDrFmETl2gj/LiMbYys CBgbt+xlx2WcJlLo+GglRZuM3iqh+r/SNQFKlZf+k4TEXqngEz6FEc06HLhoKi5qC4bA FJu28Nbsarnkk7gIU2DHtxGMqSSnL/J42zHQ/ULr5IrGilHM5wR7JhX0DUiTFdYWnTmW eKIw8WaHO7EO1slJHWCPl6E4GmcIQmJQEgy+l6JM71Zhl7Es5Lg9dgR1VF6SDyImNt7y kwqA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@jkqxz-net.20150623.gappssmtp.com header.s=20150623 header.b=e/zUPWzD; 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id l18si2882448wmd.16.2018.02.19.15.34.42; Mon, 19 Feb 2018 15:34:42 -0800 (PST) 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 header.s=20150623 header.b=e/zUPWzD; 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 26E9368A0EA; Tue, 20 Feb 2018 01:34:40 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr0-f195.google.com (mail-wr0-f195.google.com [209.85.128.195]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 1161A68A060 for ; Tue, 20 Feb 2018 01:34:33 +0200 (EET) Received: by mail-wr0-f195.google.com with SMTP id u49so6643626wrc.10 for ; Mon, 19 Feb 2018 15:34:34 -0800 (PST) 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; bh=1wNrgpHKrjFCxLA5knbNIbbu1SaMGzFccZ946hFGqGc=; b=e/zUPWzDaBX8Jq8CjmIUmFmp9vwLI4CYRAYIxU/KadRu9pyrbqa6SyOcE7lI47r614 BOFgQpSNf5VOfkDzN85bmK6UKRX6Qrp+q26Tw3naIm3rizE5VDRYnZwcPngnVMQt17iF t5b2EP3F/jyoeL7S/PDH5En9afJVCCiXGfDmm/EUypoxoBl+pYTmDAyPHoIWEpK9p/Kz PlG/Rj1OhC5XVDENs7AGk79WaoazJ+8Qdjxo+7CzG4TPIOmKCwQjv3oqeG4h6SrAUB65 CModC18Q5eNI597lqeYFg6Caec2PvDYV+y8CjaGDgwvuy30rptP0KjS8SznMLDau9EIx GjdQ== 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; bh=1wNrgpHKrjFCxLA5knbNIbbu1SaMGzFccZ946hFGqGc=; b=gpYmrtrGz/F419dGHd/TjsYTLXsz0ByUaSjtSrd/ySP5uxqYKMdwk7uawtAm+BnkLR EaDTWU3QpJjVGAdZCKqtLfS4VWkNBaVpAoWoY2HjrNuWHEFMFmupbvKV3/C1qLnT2ySP 7bd0hdRJqy7jvJmJq5MZkKD3dmqzFK7JJsAF4dm5znvRVnFW12zUwPCNcOCbkRGm2A1G 3GApABfu0xUTTK6rqIHoCuUxcIPydNio+yZ55YkMMrvoDavJ4Sqz+CrfW3sBE22ZtVFm pRRJv0giG5DMfFMQ/9jojB/IZdzi+03EFsbZIUI84fL/mHdud9mw7LxUg6YjoDeD4uJK cBwQ== X-Gm-Message-State: APf1xPAUyu3YNn0UPJ85ltwpWFCkvUBD+J2QoaTcRuinKN0nYRjruXI/ K9Nccn/ApsKq7dXZLx1zUOv25wy5 X-Received: by 10.223.177.132 with SMTP id q4mr11493048wra.27.1519082938907; Mon, 19 Feb 2018 15:28:58 -0800 (PST) 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 77sm31646687wmt.37.2018.02.19.15.28.58 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 19 Feb 2018 15:28:58 -0800 (PST) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org Date: Mon, 19 Feb 2018 23:28:47 +0000 Message-Id: <20180219232849.29436-5-sw@jkqxz.net> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180219232849.29436-1-sw@jkqxz.net> References: <20180219232849.29436-1-sw@jkqxz.net> Subject: [FFmpeg-devel] [PATCH 5/7] vaapi_decode: Make the frames context format selection more general 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 MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Examine the supported fourcc list manually and make the best choice, then use the external attribute on the frames context to force that fourcc. --- libavcodec/vaapi_decode.c | 152 +++++++++++++++++++++++++++++++++++++++------- libavcodec/vaapi_decode.h | 2 + 2 files changed, 132 insertions(+), 22 deletions(-) diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c index 572b3a40ac..28c6eeb801 100644 --- a/libavcodec/vaapi_decode.c +++ b/libavcodec/vaapi_decode.c @@ -232,6 +232,132 @@ int ff_vaapi_decode_cancel(AVCodecContext *avctx, return 0; } +static const struct { + uint32_t fourcc; + enum AVPixelFormat pix_fmt; +} vaapi_format_map[] = { +#define MAP(va, av) { VA_FOURCC_ ## va, AV_PIX_FMT_ ## av } + // 4:0:0 + MAP(Y800, GRAY8), + // 4:2:0 + MAP(NV12, NV12), + MAP(YV12, YUV420P), + MAP(IYUV, YUV420P), +#ifdef VA_FOURCC_I420 + MAP(I420, YUV420P), +#endif + MAP(IMC3, YUV420P), + // 4:1:1 + MAP(411P, YUV411P), + // 4:2:2 + MAP(422H, YUV422P), +#ifdef VA_FOURCC_YV16 + MAP(YV16, YUV422P), +#endif + // 4:4:0 + MAP(422V, YUV440P), + // 4:4:4 + MAP(444P, YUV444P), + // 4:2:0 10-bit +#ifdef VA_FOURCC_P010 + MAP(P010, P010), +#endif +#ifdef VA_FOURCC_I010 + MAP(I010, YUV420P10), +#endif +#undef MAP +}; + +static int vaapi_decode_find_best_format(AVCodecContext *avctx, + AVHWDeviceContext *device, + VAConfigID config_id, + AVHWFramesContext *frames) +{ + AVVAAPIDeviceContext *hwctx = device->hwctx; + VAStatus vas; + VASurfaceAttrib *attr; + enum AVPixelFormat source_format, best_format, format; + uint32_t best_fourcc, fourcc; + int i, j, nb_attr; + + source_format = avctx->sw_pix_fmt; + av_assert0(source_format != AV_PIX_FMT_NONE); + + vas = vaQuerySurfaceAttributes(hwctx->display, config_id, + NULL, &nb_attr); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to query surface attributes: " + "%d (%s).\n", vas, vaErrorStr(vas)); + return AVERROR(ENOSYS); + } + + attr = av_malloc_array(nb_attr, sizeof(*attr)); + if (!attr) + return AVERROR(ENOMEM); + + vas = vaQuerySurfaceAttributes(hwctx->display, config_id, + attr, &nb_attr); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to query surface attributes: " + "%d (%s).\n", vas, vaErrorStr(vas)); + av_freep(&attr); + return AVERROR(ENOSYS); + } + + best_format = AV_PIX_FMT_NONE; + + for (i = 0; i < nb_attr; i++) { + if (attr[i].type != VASurfaceAttribPixelFormat) + continue; + + fourcc = attr[i].value.value.i; + for (j = 0; j < FF_ARRAY_ELEMS(vaapi_format_map); j++) { + if (fourcc == vaapi_format_map[j].fourcc) + break; + } + if (j >= FF_ARRAY_ELEMS(vaapi_format_map)) { + av_log(avctx, AV_LOG_DEBUG, "Ignoring unknown format %#x.\n", + fourcc); + continue; + } + format = vaapi_format_map[j].pix_fmt; + av_log(avctx, AV_LOG_DEBUG, "Considering format %#x -> %s.\n", + fourcc, av_get_pix_fmt_name(format)); + + best_format = av_find_best_pix_fmt_of_2(format, best_format, + source_format, 0, NULL); + if (format == best_format) + best_fourcc = fourcc; + } + + av_freep(&attr); + + if (best_format == AV_PIX_FMT_NONE) { + av_log(avctx, AV_LOG_ERROR, "No usable formats for decoding!\n"); + return AVERROR(EINVAL); + } + + av_log(avctx, AV_LOG_DEBUG, "Picked %s (%#x) as best match for %s.\n", + av_get_pix_fmt_name(best_format), best_fourcc, + av_get_pix_fmt_name(source_format)); + + frames->sw_format = best_format; + if (avctx->internal->hwaccel_priv_data) { + VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data; + AVVAAPIFramesContext *avfc = frames->hwctx; + + ctx->pixel_format_attribute = (VASurfaceAttrib) { + .type = VASurfaceAttribPixelFormat, + .value.value.i = best_fourcc, + }; + + avfc->attributes = &ctx->pixel_format_attribute; + avfc->nb_attributes = 1; + } + + return 0; +} + static const struct { enum AVCodecID codec_id; int codec_profile; @@ -289,7 +415,6 @@ static int vaapi_decode_make_config(AVCodecContext *avctx, const AVCodecDescriptor *codec_desc; VAProfile *profile_list = NULL, matched_va_profile; int profile_count, exact_match, matched_ff_profile; - const AVPixFmtDescriptor *sw_desc, *desc; AVHWDeviceContext *device = (AVHWDeviceContext*)device_ref->data; AVVAAPIDeviceContext *hwctx = device->hwctx; @@ -417,27 +542,10 @@ static int vaapi_decode_make_config(AVCodecContext *avctx, frames->width = avctx->coded_width; frames->height = avctx->coded_height; - // Find the first format in the list which matches the expected - // bit depth and subsampling. If none are found (this can happen - // when 10-bit streams are decoded to 8-bit surfaces, for example) - // then just take the first format on the list. - frames->sw_format = constraints->valid_sw_formats[0]; - sw_desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt); - for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) { - desc = av_pix_fmt_desc_get(constraints->valid_sw_formats[i]); - if (desc->nb_components != sw_desc->nb_components || - desc->log2_chroma_w != sw_desc->log2_chroma_w || - desc->log2_chroma_h != sw_desc->log2_chroma_h) - continue; - for (j = 0; j < desc->nb_components; j++) { - if (desc->comp[j].depth != sw_desc->comp[j].depth) - break; - } - if (j < desc->nb_components) - continue; - frames->sw_format = constraints->valid_sw_formats[i]; - break; - } + err = vaapi_decode_find_best_format(avctx, device, + *va_config, frames); + if (err < 0) + goto fail; frames->initial_pool_size = 1; // Add per-codec number of surfaces used for storing reference frames. diff --git a/libavcodec/vaapi_decode.h b/libavcodec/vaapi_decode.h index 1fcecac468..6b415dd1d3 100644 --- a/libavcodec/vaapi_decode.h +++ b/libavcodec/vaapi_decode.h @@ -72,6 +72,8 @@ FF_ENABLE_DEPRECATION_WARNINGS enum AVPixelFormat surface_format; int surface_count; + + VASurfaceAttrib pixel_format_attribute; } VAAPIDecodeContext;