From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.ffmpeg.org (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTPS id 40DC347332 for ; Tue, 15 Jul 2025 06:56:20 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTP id 163F768DB5E; Tue, 15 Jul 2025 09:56:16 +0300 (EEST) Received: from MA0PR01CU009.outbound.protection.outlook.com (mail-southindiaazon11020088.outbound.protection.outlook.com [52.101.227.88]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTPS id 1F6E068D886 for ; Tue, 15 Jul 2025 09:56:09 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=OwYOHeeazr0tSWHyhUeQmg2YhESpBvC0YDWfSwzmc5TygEZYeU47LJWqEzkCUtS7qE4SVUf6ukMkADItZ37rdkCwQppTjS30tUnRiePNjjHQ+G0h05mJFGbXk4Ul8XqRnCdyE5/K3vriorlm6oikNoGDy/HRaAc1EFWT1Gd+CFqJN/TW6SD8niGZD75Em+b7QToiQmHrizZV3B5mspvGG1JiVytc6LdHL2WN1OlnswgB1fXlo52vNXr2SHwZx3BcQP5EH9qbdAmeI6l0nM3TeOvGZ3w3GL8vIHP1VjXPoEE7xtGl2G4z4+HGQ6CryiWUt2Iuqiy99E0rYkXJeBng4Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=gA6kPE5a9j9NcCm1IAKosh5PyuLGWbRds0MbFYQkp9o=; b=J+pudVmQgx8/em1hHUMC7mouYjJA0lcKrHndz09IWLIbF0NhS0RBQ6hTvIa3zy32FKudMeAfTe5VGJmb382fh5m9CYlUVStipLz7KeZZRlC/WahWtueY1/BK+F5e3qP2V2qAoAW5bQHulcM7F0Z+3H4N8GyjD20CA0+ZxEMhkCrvVts6vZiyW7mUX92HmQRXghAmXB32AxKu14Sgzt70YsZJAE2pKxHoOIleMeqvPlofoIyrsEWv1hL1At3ffpM/5PDbNYMwgprzDKHki3KurHIBbrEiIQYoYkNxk9u9qEwo4nTRx8/kujGK94PxnGMalcx0NB9EUY31xk2jusphWA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=multicorewareinc.com; dmarc=pass action=none header.from=multicorewareinc.com; dkim=pass header.d=multicorewareinc.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=multicorewareinc.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=gA6kPE5a9j9NcCm1IAKosh5PyuLGWbRds0MbFYQkp9o=; b=wtoiUjOpztIO2YAZ0aRkwZbwiAohw+3CjXqDS5N++qwLg8wJ4+Mr6T5hi23U8wo2+MNyBoLH88/uGcb17IW9zGNmRuElyTmCa6RsLMYXo3vAzYFSYn0pgm87VfRSyua5QvfpZ01au2qbr86mYtMKZ9HHpjJprU/3PEMfQ0PnXi+MouljvXouj5kuF9f9oY3nWi6OcRfoo6OK8/xSII8hkOH/qb1wYQNiDtAD6h5ie+flT3hgFd7PStCCoYTwuzQ6JJSf9JuKzUhitDH/OcydDSWUI0nU2bgboFAU9wpLgZXsMTS15xo9eb7eHFN08f2QDu4pLxoEkF4aPLuUBKxbog== Received: from PN0P287MB1494.INDP287.PROD.OUTLOOK.COM (2603:1096:c01:186::9) by PN3P287MB1319.INDP287.PROD.OUTLOOK.COM (2603:1096:c01:195::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8922.32; Tue, 15 Jul 2025 06:56:04 +0000 Received: from PN0P287MB1494.INDP287.PROD.OUTLOOK.COM ([fe80::1a78:65d:b254:359]) by PN0P287MB1494.INDP287.PROD.OUTLOOK.COM ([fe80::1a78:65d:b254:359%5]) with mapi id 15.20.8922.028; Tue, 15 Jul 2025 06:56:04 +0000 From: Dash Santosh Sathyanarayanan To: FFmpeg development discussions and patches Thread-Topic: [PATCH v4 2/2] avcodec/mfenc: add support for D3D11 input surfaces Thread-Index: AQHb9VVoqazoCZQsWU+p2G3IXzR1jw== Date: Tue, 15 Jul 2025 06:56:04 +0000 Message-ID: Accept-Language: en-IN, en-US Content-Language: en-IN X-MS-Has-Attach: X-MS-TNEF-Correlator: msip_labels: authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=multicorewareinc.com; x-ms-publictraffictype: Email x-ms-traffictypediagnostic: PN0P287MB1494:EE_|PN3P287MB1319:EE_ x-ms-office365-filtering-correlation-id: b92bbed5-3b80-42d9-9156-08ddc36caa9f x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; ARA:13230040|376014|1800799024|366016|38070700018; x-microsoft-antispam-message-info: =?iso-8859-1?Q?PefcLujSaXwClqtbfKi2A4bjh9nmrUqaLrUC20LFQbfgauBLdCH0DOi4aP?= =?iso-8859-1?Q?2gmFvOKCTzIBFKdoeFvNvw9+XX37hcNbLL9VLvFOHeYgoOfvNbdg3IgYOq?= =?iso-8859-1?Q?Xw6x8wUWw+vFUK/32htLFrsHGbkpayQlpKWYUaIaF41NQZrmQwOJPnszdN?= =?iso-8859-1?Q?cEWCMR00UmHjDY545TuaoWlwwfy+EEEVCIxgAqmLSofCO94re+HQ4hPM3B?= =?iso-8859-1?Q?M5NYGKf93R8xknbJIRuCeBJPjf26FVbDTAvcEwCYyRpCMBDFPFmAhUJrq6?= =?iso-8859-1?Q?z0O+zcgAABtgXl5jpJiQJD2umYn3uBI9dgbBK4PW2Mbz3/Zhm1u0xncWxA?= =?iso-8859-1?Q?Nm64X4J8sl+ESjcy+kbNSzHDwKCLwTMkpvtgUxTCj0nyri1pHx5A6Nkr36?= =?iso-8859-1?Q?u8nt0uZgLWYD1I+og+UyIJnwgzfoXkVlHFK6oTWALyZMyb+llSMpaAylTS?= =?iso-8859-1?Q?sikZCrG5pORymJFe3YM50LVmr2DDGTUOozl0JkK6azQoPAM6i3ZipuQ3ru?= =?iso-8859-1?Q?fm3crp+NAAR1p8AoalLXWSCwUaK2gO1RdNemBlBQoJJuoFaV/yJtrsS+CK?= =?iso-8859-1?Q?kVwqBGuoiBKoL6oUV2q3jCpB2qX1CpsUdy0Mc9B7FXajeut0V7IWyVH4G6?= =?iso-8859-1?Q?50Z/4YRonl09UGGLqS9PaB3ohGFwoW5wVZyEa8lVSqS+Vg4tpU4dujtl/0?= =?iso-8859-1?Q?8fy0I3/AECqNrfPYPf5AiJByZK1lbvmtpsCTur2/wCZXo0fICu4NZqkvw3?= =?iso-8859-1?Q?tb5J0zTcH1CIyc2Ph7JGQRBAzasdztlQaV4aB2NywJxAlt8Bp4pxTFCpUs?= =?iso-8859-1?Q?hQ+0+OBHgfHi01Ybb5lFi/oPfnHWw/GfQN5ttdtBED/2hryZLxNWmGJWQx?= =?iso-8859-1?Q?Zzna1HjrgOnzz/8k5ZzPysazhxNW7HpRl8hRa79POqlOdfoWTM+6vEuGZi?= =?iso-8859-1?Q?ol+7GEc2Mrvc1TDn3vDPYA5KMoOWj0edX+YBoiR4e6hdP1CMrLfDdSLNQE?= =?iso-8859-1?Q?eNn2ziomTgFIYQSClgmuz+XWU0JE4hClMqoNC1kOOqfwJK3+Xrbo9leCEw?= =?iso-8859-1?Q?XVGYz2XoznMaEO8xvIBwvesV6paTfXeRR0BdpdTmpm1UhrRHkf5L8SXqSM?= =?iso-8859-1?Q?VSstcO2O9RITDiHVpZMrzlcGeO5/VqLIDDSasWZRJ+8fjNZzkjtN+4a6jo?= =?iso-8859-1?Q?Xbx3IrcBP1yKVKsjCEDmvf8hbHzQTSIpTj+memB+pNheVUwdD3RbpS0s3k?= =?iso-8859-1?Q?yizP+W5ZDyLJrsovEyM9GUOuU9XiuH/e0hujiuUlyiZEnghLBiwP6RZwgB?= =?iso-8859-1?Q?pm108B7IcbARGkeIWVOmhEjT9baYpLutxBPmjV4xbwx67y2Cq5D9BvumEV?= =?iso-8859-1?Q?SAKfyP0IgByD/af2vy/QeqmkplsN/z64a90oLGcuN1j7rFVVYErL5e3Rw/?= =?iso-8859-1?Q?VhuKiZXUM4k3tSmgRTx7A+QJkOhpRTVJtJbG/0rAp1IUOONx2EizXfrCuo?= =?iso-8859-1?Q?q8nTbvdAWxGimtgvG0g8FrshmDc5bwpkaqhDeBnm+YlA=3D=3D?= x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:PN0P287MB1494.INDP287.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230040)(376014)(1800799024)(366016)(38070700018); DIR:OUT; SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?iso-8859-1?Q?p++k+nzT5teeXE3Z9s+lHPCF6WQyQ+Dv1q5hJN+7rsvfOBSIqfhZtdqVVg?= =?iso-8859-1?Q?IpXsZlpgiYceh8SxPtRjFVQqDm3/DsWYVsDdvaXqC5wQ3lOXSXQ//q3/mp?= =?iso-8859-1?Q?gPL9q/In59JlkrE8vb1SsiwM0eosPzcXKVT0dc7ZuAU9y1MtU5Sapw9DJi?= =?iso-8859-1?Q?rbxxZS2MMESPEbkAAoAEZmwLooGQU4orBqKCTvjGoXOpeBqc+2XntRwteH?= =?iso-8859-1?Q?3KI+ZV72tg1Ih0k2LslTRlPpjmM/A1+lzeHbt4/E8FqTTLxhV3ll5Og6mn?= =?iso-8859-1?Q?nricPgMvWay+AOos4T4InHiV7UM4NBInjuMJ6GQkOYiTnHTCDkmsgrFYVP?= =?iso-8859-1?Q?cfIOuyUwqfmxGTWaPLeuVuJgNXJveXYqDlnXpealRyms8PY2/F3XbBlXc+?= =?iso-8859-1?Q?hUAsFMEzYIucI8vmA+27laa+SYmyEpgsKadRfbugpQn5Fi6+3SMn/hpGwA?= =?iso-8859-1?Q?WL9jAzLqHi5svZ9fU01L1qbr063S2yewKhEjyKERdS4I/oY71DKqsa9QsL?= =?iso-8859-1?Q?1rysPg7pkcOXGBrR1fA74I89CzqJQZ3Jt+5eOx7SoLZxASAhTRfEXf3V2q?= =?iso-8859-1?Q?wdKcYKfoiRAlW5tnVuYqpmaGzfvvMVzDDvmirQgb4M/lrEhVaAb1KLmsXy?= =?iso-8859-1?Q?ITcnCAiIEKWdTlkf+exHicUm3kcuoS3lO012JZXVxybGFESCuaD76b+84v?= =?iso-8859-1?Q?9jsiqMxVGLD+JwNZKtimCWQKnfu0cnq2rDww8DkFPJXdblyFY/Hy0l30uQ?= =?iso-8859-1?Q?5V4UmPzvfXkVGX+2vfoXABRmqasaZyMxDWqI91yX9x36oYdkpkCcfDBPfU?= =?iso-8859-1?Q?EtqNMSZO7i+GzCAFYOrG61zs4b8Zrr1s1mel7s1VYB2istmmPvSLI2sUV0?= =?iso-8859-1?Q?PUYqybwFU8oihQs8f7S0PJARdXTJkayRrO2iwIW9o2khtzbEBmD198rR1J?= =?iso-8859-1?Q?MheggXEWeUGQzyDUmrE0KMaXBp89O7jFV7Q+ZxBO1BmvzLn4Z5ZQ9NtUW7?= =?iso-8859-1?Q?yBfeTZtJj0YOvUtoMRAAW6fP99MfjMP48Ba5kr0Rrfn2t1EHCfGNvolw1Y?= =?iso-8859-1?Q?h4wfYjH7JcyJJstSyXiEQMdHuoUTYBw3GaDR++BYqsTKNvrRR9d7xrs0V1?= =?iso-8859-1?Q?rrwG4frbuqR+PYBBlMIpzhyeC81uqUldg8tIpJKwy9tPjAWPdsNui211NM?= =?iso-8859-1?Q?VVfCR3nKjjjJ3tmW293vzyrrU78w6WQpTGPtnVqPo+hQASedK2fXwg86+n?= =?iso-8859-1?Q?PLYu8yCYLhjhIp1BP6C1XvaqZkVH2qD5w9A8dmjQoS25njf5gN6rY5IWvc?= =?iso-8859-1?Q?SY4bMlWULL01TqXboQq1ePBMp6MuWAQ+t1H3UcaY1JEyvlK1/RkoQybqSY?= =?iso-8859-1?Q?3mVtmD5jB94r2gZGd6Fc94ftyLFt2GT0arCAWydJBMchrb9uyD3LHmCnuV?= =?iso-8859-1?Q?kESzuuGdn8ruaG7eL1pD1bmfomBcW38lXhl9ppYonC52X58zwNbcMYa3Ex?= =?iso-8859-1?Q?cp6+hW4XVSzIP86ncQ1DBTr5NZdICrsaXWShhb/gM354SaHBjWHuVVLKtb?= =?iso-8859-1?Q?6gzQ1YJzxNFehCIREy84cpCNjSvhlzSS01A+JvRfd9GK5a4LNJT5pV+En3?= =?iso-8859-1?Q?yUpqDh0hDv/P1TkWxPAUWpFuaDlFiypwLcDIhfIAGYZXimNT1ZLp5W+Xz8?= =?iso-8859-1?Q?+tKtFXBKs8DbQTkcK6Q=3D?= MIME-Version: 1.0 X-OriginatorOrg: multicorewareinc.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: PN0P287MB1494.INDP287.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-Network-Message-Id: b92bbed5-3b80-42d9-9156-08ddc36caa9f X-MS-Exchange-CrossTenant-originalarrivaltime: 15 Jul 2025 06:56:04.2636 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: ffc5e88b-3fa2-4d69-a468-344b6b766e7d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: 5Vk5xMhfT7Bb00fP6h3t6GAkewzqVyckiGB218toA95366HoOPJy+1zeWUaxQWqx/NFdITAWL7kZVjbqUg7+tYikByvm9ugUCRXIFq1KHL863yHscn0oLgluEVvvkgPnONSJldPUG8iRjBeO1vtBTQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PN3P287MB1319 Subject: [FFmpeg-devel] [PATCH v4 2/2] avcodec/mfenc: add support for D3D11 input surfaces X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: Adds D3D11 input surface support to the MediaFoundation encoder (mfenc), allowing direct encoding of GPU frames without readback to system memory. This improves performance and compatibility when used alongside scale_d3d11. Signed-off-by: Dash Santosh --- libavcodec/mf_utils.h | 7 ++ libavcodec/mfenc.c | 207 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 185 insertions(+), 29 deletions(-) diff --git a/libavcodec/mf_utils.h b/libavcodec/mf_utils.h index a59b36d015..ecebb6fcdf 100644 --- a/libavcodec/mf_utils.h +++ b/libavcodec/mf_utils.h @@ -53,6 +53,13 @@ typedef struct MFFunctions { IMFMediaBuffer **ppBuffer); HRESULT (WINAPI *MFCreateSample) (IMFSample **ppIMFSample); HRESULT (WINAPI *MFCreateMediaType) (IMFMediaType **ppMFType); + HRESULT (WINAPI *MFCreateDXGISurfaceBuffer) (REFIID riid, + IUnknown* punkSurface, + UINT uSubresourceIndex, + BOOL fBottomUpWhenLinear, + IMFMediaBuffer** ppBuffer); + HRESULT (WINAPI *MFCreateDXGIDeviceManager) (UINT* resetToken, + IMFDXGIDeviceManager** ppDeviceManager); // MFTEnumEx is missing in Windows Vista's mfplat.dll. HRESULT (WINAPI *MFTEnumEx)(GUID guidCategory, UINT32 Flags, const MFT_REGISTER_TYPE_INFO *pInputType, diff --git a/libavcodec/mfenc.c b/libavcodec/mfenc.c index c9e2191fde..912984c306 100644 --- a/libavcodec/mfenc.c +++ b/libavcodec/mfenc.c @@ -31,10 +31,18 @@ #include "codec_internal.h" #include "internal.h" #include "compat/w32dlfcn.h" +#if CONFIG_D3D11VA +#include "libavutil/hwcontext_d3d11va.h" +#endif typedef struct MFContext { AVClass *av_class; HMODULE library; + HMODULE d3d_dll; + ID3D11DeviceContext* d3d_context; + IMFDXGIDeviceManager *dxgiManager; + int resetToken; + MFFunctions functions; AVFrame *frame; int is_video, is_audio; @@ -47,6 +55,7 @@ typedef struct MFContext { int out_stream_provides_samples; int draining, draining_done; int sample_sent; + int stream_started; int async_need_input, async_have_output, async_marker; int64_t reorder_delay; ICodecAPI *codec_api; @@ -55,6 +64,7 @@ typedef struct MFContext { int opt_enc_quality; int opt_enc_scenario; int opt_enc_hw; + AVD3D11VADeviceContext* device_hwctx; } MFContext; static int mf_choose_output_type(AVCodecContext *avctx); @@ -303,36 +313,118 @@ static IMFSample *mf_a_avframe_to_sample(AVCodecContext *avctx, const AVFrame *f return sample; } -static IMFSample *mf_v_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame) +static int initialize_dxgi_manager(AVCodecContext *avctx) { MFContext *c = avctx->priv_data; - IMFSample *sample; - IMFMediaBuffer *buffer; - BYTE *data; + MFFunctions *func = &c->functions; HRESULT hr; - int ret; - int size; + + hr = func->MFCreateDXGIDeviceManager(&c->resetToken, &c->dxgiManager); + if (FAILED(hr)) { + av_log(avctx, AV_LOG_ERROR, "Failed to create DXGI device manager: %s\n", ff_hr_str(hr)); + return AVERROR_EXTERNAL; + } + + hr = IMFDXGIDeviceManager_ResetDevice(c->dxgiManager, c->device_hwctx->device, c->resetToken); + if (FAILED(hr)) { + av_log(avctx, AV_LOG_ERROR, "Failed to reset device: %s\n", ff_hr_str(hr)); + return AVERROR_EXTERNAL; + } + + hr = IMFTransform_ProcessMessage(c->mft, MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)c->dxgiManager); + if (FAILED(hr)) { + av_log(avctx, AV_LOG_ERROR, "Failed to set D3D manager: %s\n", ff_hr_str(hr)); + return AVERROR_EXTERNAL; + } + + return 0; +} + +static int process_d3d11_frame(AVCodecContext *avctx, const AVFrame *frame, IMFSample **out_sample) +{ + MFContext *c = avctx->priv_data; + MFFunctions *func = &c->functions; + AVHWFramesContext *frames_ctx = NULL; + ID3D11Texture2D *d3d11_texture = NULL; + IMFSample *sample = NULL; + IMFMediaBuffer *buffer = NULL; + int subIdx = 0; + HRESULT hr; + + frames_ctx = (AVHWFramesContext*)frame->hw_frames_ctx->data; + c->device_hwctx = (AVD3D11VADeviceContext*)frames_ctx->device_ctx->hwctx; + + if (!c->dxgiManager) { + hr = initialize_dxgi_manager(avctx); + if (FAILED(hr)) { + return AVERROR_EXTERNAL; + } + } + + d3d11_texture = (ID3D11Texture2D*)frame->data[0]; + subIdx = (int)(intptr_t)frame->data[1]; + + if (!d3d11_texture) { + av_log(avctx, AV_LOG_ERROR, "D3D11 texture not found\n"); + return AVERROR(EINVAL); + } + + hr = func->MFCreateSample(&sample); + if (FAILED(hr)) { + av_log(avctx, AV_LOG_ERROR, "Failed to create MF sample: %s\n", ff_hr_str(hr)); + return AVERROR_EXTERNAL; + } + + hr = func->MFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, d3d11_texture, subIdx, 0, &buffer); + if (FAILED(hr)) { + av_log(avctx, AV_LOG_ERROR, "Failed to create DXGI surface buffer: %s\n", ff_hr_str(hr)); + IMFSample_Release(sample); + return AVERROR_EXTERNAL; + } + + hr = IMFSample_AddBuffer(sample, buffer); + if (FAILED(hr)) { + av_log(avctx, AV_LOG_ERROR, "Failed to add buffer to sample: %s\n", ff_hr_str(hr)); + IMFMediaBuffer_Release(buffer); + IMFSample_Release(sample); + return AVERROR_EXTERNAL; + } + + IMFMediaBuffer_Release(buffer); + + *out_sample = sample; + return 0; +} + +static int process_software_frame(AVCodecContext *avctx, const AVFrame *frame, IMFSample **out_sample) +{ + MFContext *c = avctx->priv_data; + IMFSample *sample = NULL; + IMFMediaBuffer *buffer = NULL; + BYTE *data = NULL; + HRESULT hr; + int size, ret; size = av_image_get_buffer_size(avctx->pix_fmt, avctx->width, avctx->height, 1); if (size < 0) - return NULL; + return AVERROR_EXTERNAL; sample = ff_create_memory_sample(&c->functions, NULL, size, c->in_info.cbAlignment); if (!sample) - return NULL; + return AVERROR_EXTERNAL; hr = IMFSample_GetBufferByIndex(sample, 0, &buffer); if (FAILED(hr)) { IMFSample_Release(sample); - return NULL; + return AVERROR_EXTERNAL; } hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL); if (FAILED(hr)) { IMFMediaBuffer_Release(buffer); IMFSample_Release(sample); - return NULL; + return AVERROR_EXTERNAL; } ret = av_image_copy_to_buffer((uint8_t *)data, size, (void *)frame->data, frame->linesize, @@ -342,10 +434,43 @@ static IMFSample *mf_v_avframe_to_sample(AVCodecContext *avctx, const AVFrame *f IMFMediaBuffer_Release(buffer); if (ret < 0) { IMFSample_Release(sample); - return NULL; + return AVERROR_EXTERNAL; } IMFSample_SetSampleDuration(sample, mf_to_mf_time(avctx, frame->duration)); + *out_sample = sample; + + return 0; +} + +static IMFSample *mf_v_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame) +{ + MFContext *c = avctx->priv_data; + MFFunctions *func = &c->functions; + IMFSample *sample = NULL; + IMFMediaBuffer *buffer = NULL; + HRESULT hr; + int ret; + + if (frame->format == AV_PIX_FMT_D3D11) { + // Handle D3D11 hardware frames + ret = process_d3d11_frame(avctx, frame, &sample); + if (ret < 0) { + return NULL; + } + } else { + // Handle software frames + ret = process_software_frame(avctx, frame, &sample); + if (ret < 0) { + return NULL; + } + } + + // Set sample duration + hr = IMFSample_SetSampleDuration(sample, mf_to_mf_time(avctx, frame->duration)); + if (FAILED(hr)) { + av_log(avctx, AV_LOG_WARNING, "Failed to set sample duration: %s\n", ff_hr_str(hr)); + } return sample; } @@ -511,6 +636,23 @@ static int mf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) } } + if(!c->stream_started) + { + HRESULT hr = IMFTransform_ProcessMessage(c->mft, MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0); + if (FAILED(hr)) { + av_log(avctx, AV_LOG_ERROR, "could not start streaming (%s)\n", ff_hr_str(hr)); + return AVERROR(EBADMSG); + } + + hr = IMFTransform_ProcessMessage(c->mft, MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0); + if (FAILED(hr)) { + av_log(avctx, AV_LOG_ERROR, "could not start stream (%s)\n", ff_hr_str(hr)); + return AVERROR(EBADMSG); + } + + c->stream_started = 1; + } + ret = mf_send_sample(avctx, sample); if (sample) IMFSample_Release(sample); @@ -727,8 +869,16 @@ static int mf_encv_output_adjust(AVCodecContext *avctx, IMFMediaType *type) static int64_t mf_encv_input_score(AVCodecContext *avctx, IMFMediaType *type) { enum AVPixelFormat pix_fmt = ff_media_type_to_pix_fmt((IMFAttributes *)type); - if (pix_fmt != avctx->pix_fmt) - return -1; // can not use + + if (avctx->pix_fmt == AV_PIX_FMT_D3D11) { + if (pix_fmt != AV_PIX_FMT_NV12) { + return -1; // can not use + } + } + else { + if (pix_fmt != avctx->pix_fmt) + return -1; // can not use + } return 0; } @@ -736,9 +886,16 @@ static int64_t mf_encv_input_score(AVCodecContext *avctx, IMFMediaType *type) static int mf_encv_input_adjust(AVCodecContext *avctx, IMFMediaType *type) { enum AVPixelFormat pix_fmt = ff_media_type_to_pix_fmt((IMFAttributes *)type); - if (pix_fmt != avctx->pix_fmt) { - av_log(avctx, AV_LOG_ERROR, "unsupported input pixel format set\n"); - return AVERROR(EINVAL); + if (avctx->pix_fmt == AV_PIX_FMT_D3D11) { + if (pix_fmt != AV_PIX_FMT_NV12 && pix_fmt != AV_PIX_FMT_D3D11) { + av_log(avctx, AV_LOG_ERROR, "unsupported input pixel format set\n"); + return AVERROR(EINVAL); + } + } else { + if (pix_fmt != avctx->pix_fmt) { + av_log(avctx, AV_LOG_ERROR, "unsupported input pixel format set\n"); + return AVERROR(EINVAL); + } } //ff_MFSetAttributeSize((IMFAttributes *)type, &MF_MT_FRAME_SIZE, avctx->width, avctx->height); @@ -1106,18 +1263,6 @@ static int mf_init_encoder(AVCodecContext *avctx) if ((ret = mf_setup_context(avctx)) < 0) return ret; - hr = IMFTransform_ProcessMessage(c->mft, MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0); - if (FAILED(hr)) { - av_log(avctx, AV_LOG_ERROR, "could not start streaming (%s)\n", ff_hr_str(hr)); - return AVERROR_EXTERNAL; - } - - hr = IMFTransform_ProcessMessage(c->mft, MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0); - if (FAILED(hr)) { - av_log(avctx, AV_LOG_ERROR, "could not start stream (%s)\n", ff_hr_str(hr)); - return AVERROR_EXTERNAL; - } - if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER && c->async_events && c->is_video && !avctx->extradata) { int sleep = 10000, total = 0; @@ -1175,6 +1320,7 @@ static int mf_load_library(AVCodecContext *avctx) #if !HAVE_UWP c->library = dlopen("mfplat.dll", 0); + c->d3d_dll = dlopen("D3D11.dll", 0); if (!c->library) { av_log(c, AV_LOG_ERROR, "DLL mfplat.dll failed to open\n"); @@ -1187,6 +1333,8 @@ static int mf_load_library(AVCodecContext *avctx) LOAD_MF_FUNCTION(c, MFCreateAlignedMemoryBuffer); LOAD_MF_FUNCTION(c, MFCreateSample); LOAD_MF_FUNCTION(c, MFCreateMediaType); + LOAD_MF_FUNCTION(c, MFCreateDXGISurfaceBuffer); + LOAD_MF_FUNCTION(c, MFCreateDXGIDeviceManager); // MFTEnumEx is missing in Windows Vista's mfplat.dll. LOAD_MF_FUNCTION(c, MFTEnumEx); @@ -1208,6 +1356,7 @@ static int mf_close(AVCodecContext *avctx) ff_free_mf(&c->functions, &c->mft); dlclose(c->library); + dlclose(c->d3d_dll); c->library = NULL; #else ff_free_mf(&c->functions, &c->mft); @@ -1300,7 +1449,7 @@ static const FFCodecDefault defaults[] = { }; #define VFMTS \ - CODEC_PIXFMTS(AV_PIX_FMT_NV12, AV_PIX_FMT_YUV420P), + CODEC_PIXFMTS(AV_PIX_FMT_NV12, AV_PIX_FMT_YUV420P, AV_PIX_FMT_D3D11), #define VCAPS \ .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID | \ AV_CODEC_CAP_DR1, -- 2.34.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".