From patchwork Mon Jun 12 22:40:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 3937 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.22.4 with SMTP id 4csp77907vsw; Mon, 12 Jun 2017 15:42:19 -0700 (PDT) X-Received: by 10.223.164.80 with SMTP id e16mr776336wra.100.1497307339056; Mon, 12 Jun 2017 15:42:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1497307339; cv=none; d=google.com; s=arc-20160816; b=SRSYEYlAViu9OYP56yrZRExeFbBdGjDyIul3ApKGyE7B+/xSKlNyUiP5/BJFrTg9so 8XqUtE+1CjJEQ5hsjX97XhL0hy5a9A6wxAyxJ/tVjrI72cP9gH+g8ODxAGuN9ZiIWe1i gls/xJLvfAeZXnMHE26SAtRSQgd91hJHwNiqRgteYpRenv5GSVJyRVDoFgABq+1h8WjE YZYiNlBULkTMI3bG0BkKQEHTiBGA9rux+X+MTyGY2Pu7oAkB2wVl61T3geYtV3NdNCyD fUoK9qs8HAncI2lJTXZ8uWzMXJ4lM/Edbym1zMJO16zsKDLDN0Je3fOUO7IvLLxPNPYP mkuw== 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=UXUHYf+vVoEZbkOtuiU161tqr/dSs7sIAVQMOzVKNDg=; b=0eX2LVjcmWTpyKpi/bFqvbKGmw7ZPs4oDAQ29UrDu5fUgRoMnebxRjuUVVrTmTZ/S7 YsiGxbJDU+R/Zkyvwh68AhmpxjAGChw238ow07Iy4LaIHR+ktn7i5XIpkCtEROd2dtGl tQXBCBYl6TMwiua5he0YM06mgFMXUOn381f+3hBnjcwyPKuYxfLP8R4AEBJI375foAuv C2VJRGqbZoD/3O8lIr/EE77WxciVm4ov06SpHMguHkW7ytOxzBOnEF6WsKDp+AAJ9wQf kOgOvPXWI6hxHW2OYsW87RferrAlnmu3qEpf0SwozStm2cwquDKJi+/xgxQtBf9s6Uwr kZaA== ARC-Authentication-Results: i=1; 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id j7si10374377wrb.265.2017.06.12.15.42.18; Mon, 12 Jun 2017 15:42:19 -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 CA39168A05A; Tue, 13 Jun 2017 01:41:10 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr0-f171.google.com (mail-wr0-f171.google.com [209.85.128.171]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id D6B96680A18 for ; Tue, 13 Jun 2017 01:41:02 +0300 (EEST) Received: by mail-wr0-f171.google.com with SMTP id v104so113613527wrb.0 for ; Mon, 12 Jun 2017 15:41:05 -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; bh=M4cbyY1/2ohMEtokQi1IWq3jyDQg7KmGs5HQHlTVPMA=; b=FfvG4Keffmj9kaoccmB0CXm2NZjUoC2gf6v7ETg5vApOruaSIWIVoEU3f2awlCD7pj ZtsHLyD6mZsRg7pUsxbY7VcEyo0zzUTAmXBtZ/Sv0K14IeAaHaJbdC+5e8td5RybvaoG /ThXAtYwLiAlrYtxUY/xztTzivoAMCactn0N+4Uo0qIc8nNEsR2S9YfbtP9nEQ4lBZXL yLNFpofp/tDEmvj/FNK0wcFoZjz8x01cYzBNSS3Kh6FvRuKT+LNkDdqS9Z8p8mCXwleu /42rmvhSgp1RStJoOMNvwOOqzDuIUviwvjfyVTIYOxmxB4Ib1HrsulYVEHv4H/cRRKXb dnNA== 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=M4cbyY1/2ohMEtokQi1IWq3jyDQg7KmGs5HQHlTVPMA=; b=OgQQaZjDjOClmSW1Bd7r2yjBjEYHDY9y15Vz8Q+k40yGnBLG1aPR14z9xJFhfACZUK DYC7SAHQbDiA4GNPMm8/5D5Kk2/pTmg370yQd6JhmhLIt691FhtFCN9540CHdZDQrdEK NeCk1ZD2/Ii1nuyR4Y568QF8vcKCTeVkT8bPMEq2hjXw4df8gdM/H3AAVtICqFKYNQ7D /a0I/Si1xvgTyU3k8zL5jPDqEr2KSYBpl7zua3jx69jU+V1KJUhMxDnl8ni0foVSl2l/ PWda4lKfw7IwwIferGAoZPr7tPpVtHXoYFyYUX0lvMrkP0B3I47NKLhFA6qoh5eyO6Wp cYiA== X-Gm-Message-State: AKS2vOwVcInoDl8ONkmjB48L3xMyw/CAbtjA6C/e6XoRiE7tYhKBAJmm +xaCgG+z/UCqfrWtXtw= X-Received: by 10.223.164.80 with SMTP id e16mr773643wra.100.1497307264289; Mon, 12 Jun 2017 15:41:04 -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 m191sm13098233wmg.30.2017.06.12.15.41.03 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 12 Jun 2017 15:41:03 -0700 (PDT) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org Date: Mon, 12 Jun 2017 23:40:23 +0100 Message-Id: <20170612224041.6750-7-sw@jkqxz.net> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170612224041.6750-1-sw@jkqxz.net> References: <20170612224041.6750-1-sw@jkqxz.net> Subject: [FFmpeg-devel] [PATCH 06/24] ffmpeg: Enable generic hwaccel support for VAAPI 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" (cherry picked from commit 62a1ef9f26c654a3e988aa465c4ac1d776c4c356) --- Makefile | 1 - ffmpeg.h | 2 - ffmpeg_opt.c | 20 ++++- ffmpeg_vaapi.c | 233 --------------------------------------------------------- 4 files changed, 16 insertions(+), 240 deletions(-) delete mode 100644 ffmpeg_vaapi.c diff --git a/Makefile b/Makefile index 913a890a78..26f9d93d85 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,6 @@ $(foreach prog,$(AVBASENAMES),$(eval OBJS-$(prog)-$(CONFIG_OPENCL) += cmdutils_o OBJS-ffmpeg += ffmpeg_opt.o ffmpeg_filter.o ffmpeg_hw.o OBJS-ffmpeg-$(CONFIG_VIDEOTOOLBOX) += ffmpeg_videotoolbox.o OBJS-ffmpeg-$(CONFIG_LIBMFX) += ffmpeg_qsv.o -OBJS-ffmpeg-$(CONFIG_VAAPI) += ffmpeg_vaapi.o ifndef CONFIG_VIDEOTOOLBOX OBJS-ffmpeg-$(CONFIG_VDA) += ffmpeg_videotoolbox.o endif diff --git a/ffmpeg.h b/ffmpeg.h index 5c115cf9a3..231d362f5f 100644 --- a/ffmpeg.h +++ b/ffmpeg.h @@ -665,8 +665,6 @@ int dxva2_init(AVCodecContext *s); int vda_init(AVCodecContext *s); int videotoolbox_init(AVCodecContext *s); int qsv_init(AVCodecContext *s); -int vaapi_decode_init(AVCodecContext *avctx); -int vaapi_device_init(const char *device); int cuvid_init(AVCodecContext *s); HWDevice *hw_device_get_by_name(const char *name); diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c index 6755e09e47..51671e0dd4 100644 --- a/ffmpeg_opt.c +++ b/ffmpeg_opt.c @@ -87,8 +87,8 @@ const HWAccel hwaccels[] = { AV_HWDEVICE_TYPE_NONE }, #endif #if CONFIG_VAAPI - { "vaapi", vaapi_decode_init, HWACCEL_VAAPI, AV_PIX_FMT_VAAPI, - AV_HWDEVICE_TYPE_NONE }, + { "vaapi", hwaccel_decode_init, HWACCEL_VAAPI, AV_PIX_FMT_VAAPI, + AV_HWDEVICE_TYPE_VAAPI }, #endif #if CONFIG_CUVID { "cuvid", cuvid_init, HWACCEL_CUVID, AV_PIX_FMT_CUDA, @@ -462,10 +462,22 @@ static int opt_sdp_file(void *optctx, const char *opt, const char *arg) #if CONFIG_VAAPI static int opt_vaapi_device(void *optctx, const char *opt, const char *arg) { + HWDevice *dev; + const char *prefix = "vaapi:"; + char *tmp; int err; - err = vaapi_device_init(arg); + tmp = av_malloc(strlen(prefix) + strlen(arg) + 1); + if (!tmp) + return AVERROR(ENOMEM); + strcpy(tmp, prefix); + strcat(tmp, arg); + err = hw_device_init_from_string(tmp, &dev); + av_free(tmp); if (err < 0) - exit_program(1); + return err; + hw_device_ctx = av_buffer_ref(dev->device_ref); + if (!hw_device_ctx) + return AVERROR(ENOMEM); return 0; } #endif diff --git a/ffmpeg_vaapi.c b/ffmpeg_vaapi.c deleted file mode 100644 index d011cacef7..0000000000 --- a/ffmpeg_vaapi.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * 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. - * - * 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" - -#include "libavutil/avassert.h" -#include "libavutil/frame.h" -#include "libavutil/hwcontext.h" -#include "libavutil/log.h" - -#include "ffmpeg.h" - - -static AVClass vaapi_class = { - .class_name = "vaapi", - .item_name = av_default_item_name, - .version = LIBAVUTIL_VERSION_INT, -}; - -#define DEFAULT_SURFACES 20 - -typedef struct VAAPIDecoderContext { - const AVClass *class; - - AVBufferRef *device_ref; - AVHWDeviceContext *device; - AVBufferRef *frames_ref; - AVHWFramesContext *frames; - - // The output need not have the same format, width and height as the - // decoded frames - the copy for non-direct-mapped access is actually - // a whole vpp instance which can do arbitrary scaling and format - // conversion. - enum AVPixelFormat output_format; -} VAAPIDecoderContext; - - -static int vaapi_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) -{ - InputStream *ist = avctx->opaque; - VAAPIDecoderContext *ctx = ist->hwaccel_ctx; - int err; - - err = av_hwframe_get_buffer(ctx->frames_ref, frame, 0); - if (err < 0) { - av_log(ctx, AV_LOG_ERROR, "Failed to allocate decoder surface.\n"); - } else { - av_log(ctx, AV_LOG_DEBUG, "Decoder given surface %#x.\n", - (unsigned int)(uintptr_t)frame->data[3]); - } - return err; -} - -static int vaapi_retrieve_data(AVCodecContext *avctx, AVFrame *input) -{ - InputStream *ist = avctx->opaque; - VAAPIDecoderContext *ctx = ist->hwaccel_ctx; - AVFrame *output = 0; - int err; - - av_assert0(input->format == AV_PIX_FMT_VAAPI); - - if (ctx->output_format == AV_PIX_FMT_VAAPI) { - // Nothing to do. - return 0; - } - - av_log(ctx, AV_LOG_DEBUG, "Retrieve data from surface %#x.\n", - (unsigned int)(uintptr_t)input->data[3]); - - output = av_frame_alloc(); - if (!output) - return AVERROR(ENOMEM); - - output->format = ctx->output_format; - - err = av_hwframe_transfer_data(output, input, 0); - if (err < 0) { - av_log(ctx, AV_LOG_ERROR, "Failed to transfer data to " - "output frame: %d.\n", err); - goto fail; - } - - err = av_frame_copy_props(output, input); - if (err < 0) { - av_frame_unref(output); - goto fail; - } - - av_frame_unref(input); - av_frame_move_ref(input, output); - av_frame_free(&output); - - return 0; - -fail: - if (output) - av_frame_free(&output); - return err; -} - -static void vaapi_decode_uninit(AVCodecContext *avctx) -{ - InputStream *ist = avctx->opaque; - VAAPIDecoderContext *ctx = ist->hwaccel_ctx; - - if (ctx) { - av_buffer_unref(&ctx->frames_ref); - av_buffer_unref(&ctx->device_ref); - av_free(ctx); - } - - av_buffer_unref(&ist->hw_frames_ctx); - - ist->hwaccel_ctx = NULL; - ist->hwaccel_uninit = NULL; - ist->hwaccel_get_buffer = NULL; - ist->hwaccel_retrieve_data = NULL; -} - -int vaapi_decode_init(AVCodecContext *avctx) -{ - InputStream *ist = avctx->opaque; - VAAPIDecoderContext *ctx; - int err; - int loglevel = (ist->hwaccel_id != HWACCEL_VAAPI ? AV_LOG_VERBOSE - : AV_LOG_ERROR); - - if (ist->hwaccel_ctx) - vaapi_decode_uninit(avctx); - - // We have -hwaccel without -vaapi_device, so just initialise here with - // the device passed as -hwaccel_device (if -vaapi_device was passed, it - // will always have been called before now). - if (!hw_device_ctx) { - err = vaapi_device_init(ist->hwaccel_device); - if (err < 0) - return err; - } - - ctx = av_mallocz(sizeof(*ctx)); - if (!ctx) - return AVERROR(ENOMEM); - ctx->class = &vaapi_class; - ist->hwaccel_ctx = ctx; - - ctx->device_ref = av_buffer_ref(hw_device_ctx); - ctx->device = (AVHWDeviceContext*)ctx->device_ref->data; - - ctx->output_format = ist->hwaccel_output_format; - avctx->pix_fmt = ctx->output_format; - - ctx->frames_ref = av_hwframe_ctx_alloc(ctx->device_ref); - if (!ctx->frames_ref) { - av_log(ctx, loglevel, "Failed to create VAAPI frame context.\n"); - err = AVERROR(ENOMEM); - goto fail; - } - - ctx->frames = (AVHWFramesContext*)ctx->frames_ref->data; - - ctx->frames->format = AV_PIX_FMT_VAAPI; - ctx->frames->width = avctx->coded_width; - ctx->frames->height = avctx->coded_height; - - // It would be nice if we could query the available formats here, - // but unfortunately we don't have a VAConfigID to do it with. - // For now, just assume an NV12 format (or P010 if 10-bit). - ctx->frames->sw_format = (avctx->sw_pix_fmt == AV_PIX_FMT_YUV420P10 ? - AV_PIX_FMT_P010 : AV_PIX_FMT_NV12); - - // For frame-threaded decoding, at least one additional surface - // is needed for each thread. - ctx->frames->initial_pool_size = DEFAULT_SURFACES; - if (avctx->active_thread_type & FF_THREAD_FRAME) - ctx->frames->initial_pool_size += avctx->thread_count; - - err = av_hwframe_ctx_init(ctx->frames_ref); - if (err < 0) { - av_log(ctx, loglevel, "Failed to initialise VAAPI frame " - "context: %d\n", err); - goto fail; - } - - ist->hw_frames_ctx = av_buffer_ref(ctx->frames_ref); - if (!ist->hw_frames_ctx) { - err = AVERROR(ENOMEM); - goto fail; - } - - ist->hwaccel_uninit = &vaapi_decode_uninit; - ist->hwaccel_get_buffer = &vaapi_get_buffer; - ist->hwaccel_retrieve_data = &vaapi_retrieve_data; - - return 0; - -fail: - vaapi_decode_uninit(avctx); - return err; -} - -static AVClass *vaapi_log = &vaapi_class; - -av_cold int vaapi_device_init(const char *device) -{ - int err; - - av_buffer_unref(&hw_device_ctx); - - err = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI, - device, NULL, 0); - if (err < 0) { - av_log(&vaapi_log, AV_LOG_ERROR, "Failed to create a VAAPI device\n"); - return err; - } - - return 0; -}