From patchwork Tue Nov 13 23:43:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 11015 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 B41D844D8AE for ; Wed, 14 Nov 2018 01:43:31 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 2E0BF6899CD; Wed, 14 Nov 2018 01:43:03 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f68.google.com (mail-wm1-f68.google.com [209.85.128.68]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id B61F86883B6 for ; Wed, 14 Nov 2018 01:42:56 +0200 (EET) Received: by mail-wm1-f68.google.com with SMTP id p2-v6so13025052wmc.2 for ; Tue, 13 Nov 2018 15:43:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jkqxz-net.20150623.gappssmtp.com; s=20150623; h=subject:from:to:references:message-id:date:user-agent:mime-version :in-reply-to:content-language:content-transfer-encoding; bh=QSP04VoiAKubQK3KY1kckrwOr/xQMaG1KnMfwtc1jx8=; b=Eng+UIgXbyFRa/zVHrT0thWWLwZj0Fq9RHpoAZJ9mh6Ge0skm+heRe0fZs7HRL/2WN 1zpW2SDpCb1fM0T+UzX+vZA+R9G8nAe1jVbDYdx8kt930UCd8pq94z3aszs49gbQ/HXj WDjNFGbfqRqyM5DVRy4J8tTtmX2m9ThEkWLxB4/PD97yRBBm8kDFU4wzY8W8vQjqq40a 7GNernZH/3ICTJcHysYGWYP3Q9c1L6rcbnVsP0urChexyUijBgOKJ8wuEnpm82CKelCV G5VIUUOGj4V9M5zH7cicqE/GV0tI5dDswE1dVTC/r7Rfb8wAk8HdV6cKHy1oauYFg7dh TWNA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:references:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=QSP04VoiAKubQK3KY1kckrwOr/xQMaG1KnMfwtc1jx8=; b=tOU8L9D3FZtpzzS/LPM5v/meJdC54fzLvWB5c0hkzBcToC01j3iBmxLJwe9aEEdoyN hazavSpkanE9z4+zD0wTtxMXA1RwO12lWQrtPxvYBtjtwVnzhsIKsKJfseAd+fVD/U8G mEIAeuMo7leFDhSFqw36K9hAUaDMocT5g4mnW5kjgfycQSdtU2A0IIKlqUT9wrcsTBd5 +3vSG42xqoFuprbcRt3rrU/Q9J8vUmsdkcW+qcO4FmRzCzfcyMQl0TppIFmRqewRamST 6qqjFBOzArgXZ7PzNq4Z2iGnI/7brAR+i3lKrEio+nf3vDBX/2XGAv4J4OZ9zccXRZ5V ek+Q== X-Gm-Message-State: AGRZ1gLvheaXCCnVF327AFWtbt3byST6sf7iAdWVOYxHXRRXbIs+lc6K lIaX0lTx4PZa3bEWfqlcZHS7+yQerF0= X-Google-Smtp-Source: AJdET5cnTRJ+PzgkoZTIV6nSlzSVja/dzomVc3IcXIxvK9xb4+PdIDPrJRVr2Y5Oeiw8kzVhGbnYKw== X-Received: by 2002:a1c:3b56:: with SMTP id i83-v6mr25260wma.130.1542152613383; Tue, 13 Nov 2018 15:43:33 -0800 (PST) Received: from [192.168.0.4] (cpc91242-cmbg18-2-0-cust650.5-4.cable.virginm.net. [82.8.130.139]) by smtp.gmail.com with ESMTPSA id t13-v6sm13130026wrn.22.2018.11.13.15.43.32 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 13 Nov 2018 15:43:32 -0800 (PST) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org References: <20181111145441.4173-1-sw@jkqxz.net> <20181112202031.GG3343@michaelspb> Message-ID: Date: Tue, 13 Nov 2018 23:43:31 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 MIME-Version: 1.0 In-Reply-To: Content-Language: en-US Subject: [FFmpeg-devel] [PATCH v2] ffmpeg: Add option to force a specific decode format 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" Fixes #7519. --- doc/ffmpeg.texi | 13 ++++++++++++ fftools/ffmpeg.c | 10 ++++++++++ fftools/ffmpeg.h | 4 ++++ fftools/ffmpeg_opt.c | 47 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+) diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index 3717f22d42..d127bc0f0d 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -920,6 +920,19 @@ would be more efficient. When doing stream copy, copy also non-key frames found at the beginning. +@item -decode_format[:@var{stream_specifier}] @var{pixfmt}[,@var{pixfmt}...] (@emph{input,per-stream}) +Set the possible output formats to be used by the decoder for this stream. +If the decoder does not natively support any format in the given list for +the input stream then decoding will fail rather than continuing with a +different format. + +In general this should not be set - the decoder will select an output +format based on the input stream parameters and available components, and +that will be automatically converted to whatever the output requires. It +may be useful to force a hardware decoder supporting output in multiple +different memory types to pick a desired one, or to ensure that a hardware +decoder is used when software fallback is also available. + @item -init_hw_device @var{type}[=@var{name}][:@var{device}[,@var{key=value}...]] Initialise a new hardware device of type @var{type} called @var{name}, using the given device parameters. diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 38c21e944a..c651c8d3a8 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -598,6 +598,7 @@ static void ffmpeg_cleanup(int ret) avsubtitle_free(&ist->prev_sub.subtitle); av_frame_free(&ist->sub2video.frame); av_freep(&ist->filters); + av_freep(&ist->decode_formats); av_freep(&ist->hwaccel_device); av_freep(&ist->dts_buffer); @@ -2800,6 +2801,15 @@ static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat const AVCodecHWConfig *config = NULL; int i; + if (ist->decode_formats) { + for (i = 0; ist->decode_formats[i] != AV_PIX_FMT_NONE; i++) { + if (ist->decode_formats[i] == *p) + break; + } + if (ist->decode_formats[i] != *p) + continue; + } + if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) break; diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index eb1eaf6363..b06fd18b1c 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -125,6 +125,8 @@ typedef struct OptionsContext { int nb_ts_scale; SpecifierOpt *dump_attachment; int nb_dump_attachment; + SpecifierOpt *decode_formats; + int nb_decode_formats; SpecifierOpt *hwaccels; int nb_hwaccels; SpecifierOpt *hwaccel_devices; @@ -334,6 +336,8 @@ typedef struct InputStream { int top_field_first; int guess_layout_max; + enum AVPixelFormat *decode_formats; + int autorotate; int fix_sub_duration; diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c index d4851a2cd8..63bb05053b 100644 --- a/fftools/ffmpeg_opt.c +++ b/fftools/ffmpeg_opt.c @@ -701,6 +701,7 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) AVStream *st = ic->streams[i]; AVCodecParameters *par = st->codecpar; InputStream *ist = av_mallocz(sizeof(*ist)); + char *decode_formats = NULL; char *framerate = NULL, *hwaccel_device = NULL; const char *hwaccel = NULL; char *hwaccel_output_format = NULL; @@ -797,6 +798,49 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) ist->top_field_first = -1; MATCH_PER_STREAM_OPT(top_field_first, i, ist->top_field_first, ic, st); + MATCH_PER_STREAM_OPT(decode_formats, str, decode_formats, ic, st); + if (decode_formats) { + const char *p, *q; + int i, nb_formats; + char tmp[32]; + + nb_formats = 0; + for (p = decode_formats; p; p = strchr(p + 1, ',')) + ++nb_formats; + + ist->decode_formats = + av_malloc_array(nb_formats + 1, sizeof(*ist->decode_formats)); + if (!ist->decode_formats) + exit_program(1); + + p = decode_formats; + for (i = 0; i < nb_formats; i++) { + q = strchr(p, ','); + if (!q) { + ist->decode_formats[i] = av_get_pix_fmt(p); + if (ist->decode_formats[i] == AV_PIX_FMT_NONE) + break; + continue; + } + if (q - p > sizeof(tmp) - 1) + break; + memcpy(tmp, p, q - p); + tmp[q - p] = 0; + ist->decode_formats[i] = av_get_pix_fmt(tmp); + if (ist->decode_formats[i] == AV_PIX_FMT_NONE) + break; + p = q + 1; + } + if (i < nb_formats) { + av_log(NULL, AV_LOG_FATAL, + "Unrecognised decode format: %s.\n", p); + exit_program(1); + } + ist->decode_formats[nb_formats] = AV_PIX_FMT_NONE; + } else { + ist->decode_formats = NULL; + } + MATCH_PER_STREAM_OPT(hwaccels, str, hwaccel, ic, st); if (hwaccel) { // The NVDEC hwaccels use a CUDA device, so remap the name here. @@ -3583,6 +3627,9 @@ const OptionDef options[] = { "audio bitrate (please use -b:a)", "bitrate" }, { "b", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_bitrate }, "video bitrate (please use -b:v)", "bitrate" }, + { "decode_format", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT | + OPT_SPEC | OPT_INPUT, { .off = OFFSET(decode_formats) }, + "set output format(s) to be used by decoder, fail if none of these formats are available", "format" }, { "hwaccel", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT | OPT_SPEC | OPT_INPUT, { .off = OFFSET(hwaccels) }, "use HW accelerated decoding", "hwaccel name" },