From patchwork Thu Apr 19 10:15:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Martin_D=C3=B8rum?= X-Patchwork-Id: 8501 Delivered-To: ffmpegpatchwork@gmail.com Received: by 2002:a02:155:0:0:0:0:0 with SMTP id c82-v6csp497265jad; Thu, 19 Apr 2018 03:21:17 -0700 (PDT) X-Google-Smtp-Source: AIpwx48O1cz4odKdJJpuwUPlmOWxzcNP3logw50jllSF5CkLuqQO8yILhmFRUWO+hdlkAuNMp3dT X-Received: by 2002:adf:9658:: with SMTP id c24-v6mr3951937wra.190.1524133277104; Thu, 19 Apr 2018 03:21:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1524133277; cv=none; d=google.com; s=arc-20160816; b=ud/Y6lxiARaHIJiXxaDCKQluaN18vBHuM58+vxEfzhqSFtT5a1FDEGagObX0lGbA5A KD5/GM9Z/Ps9rUjgMoqZRhXP2y9fQYtj7i4mokm/wZXaJUQYsMXX9HltTVgSeaLDqo6p hRaQTDY/m6zpwS0IvIduCIeW1HROUzTqX3J3BmLFJ1BQOsiRQU62OSU0JHXIodbYthrK MNi2hrX05RKwY3uIidbWRtk0VHeluxlZmGFsLk6vJqM4I030nAMYjwtxVPXM5Cu05m9S ssROg0zfNK9BQBYpYQD59spsuFdy6veernackB/tNtB3/KUu7rnkp7TI28rIRSPUYGqu bSZQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:content-language:mime-version:user-agent:date :message-id:from:to:dkim-signature:delivered-to :arc-authentication-results; bh=ReukW9x9ylwON0eQx9FVOnJFyZBdc8X+WEWzhwCzmFU=; b=cMzQ5uf/LOQdnyNs0M1cUk2ITvt9L4z1AeIRYCHd6GP6LJ8NFkEsAtNBTB3hNjf1yL 9GNGrb8h7Fi4Qzhzn1tvliBOkPR53iL0gEIZguXLkTATXGyXxI3fbzGMsn0GRO8h0FjD wfayzmdFo25re0t+HxWgsaY43rEwZbpnKtZYhkmRF0vM0PyUz4KmkR76+IqWSRFdFCXN kT5RM8NSo0fpsusRBOlGyhPrykUBtgkrn3rzKCnVyfhxadslXFJ0BZAp1RKOjKGgy4Wk VvbuSMRF6hnDbMaMNXXX2IApQkRzishrTHcLSbRjO65R8qZTyKn3y5sSVFX8eZ9qfQKU JV2g== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=orSbsJ+c; 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; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id f88si2571795wmh.42.2018.04.19.03.21.16; Thu, 19 Apr 2018 03:21:17 -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=@gmail.com header.s=20161025 header.b=orSbsJ+c; 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; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 938E068A303; Thu, 19 Apr 2018 13:20:47 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lf0-f46.google.com (mail-lf0-f46.google.com [209.85.215.46]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id A5A6F68A257 for ; Thu, 19 Apr 2018 13:20:41 +0300 (EEST) Received: by mail-lf0-f46.google.com with SMTP id i18-v6so12716lfc.7 for ; Thu, 19 Apr 2018 03:21:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=to:from:subject:message-id:date:user-agent:mime-version :content-language:content-transfer-encoding; bh=M6Qq7HYvxUvLx11IRdaPvfFLGaOgCb3UrQ5OlWbSpp0=; b=orSbsJ+cZJO2fWgA0nMTWbr76VWDdpcXd1nRgYzKOyImhasUb/TRd5++PJkH7kgzDU cWSwnLBZubU5s4mIKWsekGxn2/7RYyLetlFkb2IHr1F9Uo//7JY0YFbMOiXJRBBXN2P0 jbthlAEFBK9Fo0cRGgdpsow5/OgcBXbMZ3mCK1AmeO+BPlOjo0PYe+rdQZm0cpbP8eCp zqux8hLhqxWE9RyDvrfgTarEloGUf2jrJ7938z8X+BRhGvtju30tJdc470i6usK/T1Nx d43NgXG2tdhqNHJ1gPYRov4hp+g16tRtwS1j/iJIzp71XPGeWeJcf9N6foYshRAumFkO 4HlA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:to:from:subject:message-id:date:user-agent :mime-version:content-language:content-transfer-encoding; bh=M6Qq7HYvxUvLx11IRdaPvfFLGaOgCb3UrQ5OlWbSpp0=; b=i5dvagLANeOgCeesd8rHj1VVfK+1Phe/NfY1MXqL1evz0dXScYcN/cBWOVPa1gSk0a LwiFxfChAY+ixBoxdoI53ff9QyV1wdmwsX7aIFCZdxU4AmunqXqSZDtFBtkvZv1HG5Fo ln+ykYScBtnPJaqzwTYJ2rJBS44TPuwLyMwzfvZh6W8c74e9Qf2IbR1++98zVsJ1Hc1k EAaCYmR7DO/6nPTjxCGieImlTWib2WZDofDTGCyGV+X8XGyuTdZbLyO3WBIpzGb4ThX+ URJECif6LWNxeDwN5wTdX9s0gnfUatwNjo93Z3lntVzKB6SmzxKxcOCzc+CxnJF/zjX9 MoeQ== X-Gm-Message-State: ALQs6tC6L38uLmKjpaowVDg/qdqHnQeMVxqmmDquRLQhNJqL9EOvWFA9 FCXVnSB+3+nwTYFcbSgAAJa5ILUL X-Received: by 10.46.45.10 with SMTP id t10mr3726721ljt.110.1524132950745; Thu, 19 Apr 2018 03:15:50 -0700 (PDT) Received: from [192.168.1.19] ([195.139.214.6]) by smtp.gmail.com with ESMTPSA id p27sm174666lja.9.2018.04.19.03.15.49 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 19 Apr 2018 03:15:50 -0700 (PDT) To: ffmpeg-devel@ffmpeg.org From: =?UTF-8?Q?Martin_D=c3=b8rum?= Message-ID: Date: Thu, 19 Apr 2018 12:15:07 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.7.0 MIME-Version: 1.0 Content-Language: en-US Subject: [FFmpeg-devel] [PATCH] avcodec/allcodecs: add FFMPEG_PREFER_* env vars 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" When a program uses FFmpeg to decode or encode media, and uses `avcodec_find_decoder` or `avcodec_find_encoder`, I interpret that as the program not caring a whole lot what AVCodec is used; it just wants something which can encode or decode the desired format. I think it makes sense for the user to be able to specify what codec should be the default in that case, because the user might know that they're on a system with a fast hardware encoder or decoder. Currently, the only way to convince FFmpeg to default to a different codec is to recompile it without support for other codecs than the desired one, which feels unnecessary. An argument against this patch could be that it's the application's responsibility to add an -encoder or -decoder option like the ffmpeg CLI utilities do. If that's the "official" stance of FFmpeg, I'm fine with that, even though I don't necessarily agree. Anotehr point is that some applications make assumptions about the pix_fmt the decoder they get from `avcodec_find_decoder` uses. Chromium does this. I believe this is a problem with those applications (and I submitted an issue to the Chromium project: https://bugs.chromium.org/p/webrtc/issues/detail?id=9137#c2), but it should be considered. (I also haven't submitted a patch to FFmpeg before, or any open-source project which doesn't use GitHub pull requests, so I apologize if I have followed the process incorrectly.) This patch makes it possible to choose what codec avcodec_find_encoder and avcodec_find_decoder returns with environment variables. FFMPEG_PREFER_CODEC is an environment variable with a comma-separated list of codec names, and if it contains the name of an applicable codec, that codec will be returned instead of whatever av_codec_iterate happens to return first. There's also FFMPEG_PREFER_ENCODER and FFMPEG_PREFER_DECODER, which specifically apply to avcodec_find_encoder and avcodec_find_decoder respectively. These are prioritized above FFMPEG_PREFER_CODEC. Signed-off-by: Martin Dørum --- libavcodec/allcodecs.c | 59 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 5 deletions(-) diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 4d4ef530e4..3c85908969 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -833,25 +833,74 @@ static enum AVCodecID remap_deprecated_codec_id(enum AVCodecID id) } } +static int codec_matches_preferred(const AVCodec *p, const char *str) +{ + int pi = 0, stri = 0; + int match = 1; + + if (str == NULL) + return 0; + + while (1) { + if (str[stri] == '\0' || str[stri] == ',') { + if (match && p->name[pi] == '\0') { + return 1; + } else if (str[stri] == '\0') { + return 0; + } else { + match = 1; + pi = 0; + } + } else if (p->name[pi] == '\0') { + match = 0; + } else { + if (match && p->name[pi] != str[stri]) + match = 0; + pi += 1; + } + + stri += 1; + } +} + static AVCodec *find_codec(enum AVCodecID id, int (*x)(const AVCodec *)) { - const AVCodec *p, *experimental = NULL; + const AVCodec *p, *experimental = NULL, *fallback = NULL, *preferred = NULL; void *i = 0; + char *preferred_codec = getenv("FFMPEG_PREFER_CODEC"); + char *preferred_encdec = NULL; + if (x == av_codec_is_encoder) + preferred_encdec = getenv("FFMPEG_PREFER_ENCODER"); + else if (x == av_codec_is_decoder) + preferred_encdec = getenv("FFMPEG_PREFER_DECODER"); + id = remap_deprecated_codec_id(id); while ((p = av_codec_iterate(&i))) { if (!x(p)) continue; if (p->id == id) { - if (p->capabilities & AV_CODEC_CAP_EXPERIMENTAL && !experimental) { - experimental = p; - } else + if (codec_matches_preferred(p, preferred_encdec)) { return (AVCodec*)p; + } else if (codec_matches_preferred(p, preferred_codec) && !preferred) { + preferred = p; + } else if (p->capabilities & AV_CODEC_CAP_EXPERIMENTAL && !experimental) { + experimental = p; + } else if (!fallback) { + fallback = p; + } } } - return (AVCodec*)experimental; + if (preferred) + return (AVCodec*)preferred; + else if (fallback) + return (AVCodec*)fallback; + else if (experimental) + return (AVCodec*)experimental; + else + return NULL; } AVCodec *avcodec_find_encoder(enum AVCodecID id)