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 80C6150235 for ; Thu, 10 Jul 2025 05:20:17 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTP id 3C99868F99D; Thu, 10 Jul 2025 08:20:15 +0300 (EEST) Received: from MA0PR01CU009.outbound.protection.outlook.com (mail-southindiaazon11020093.outbound.protection.outlook.com [52.101.227.93]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTPS id 81C8868EB49 for ; Thu, 10 Jul 2025 08:20:13 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=Lt2+fMG5g/P3+vpGrwaWYTc3v7u/sFEq0epZkhHNUQIS6KoCl2OvsoAffGNYl+3aJxb8+24adLzVH1w6Enn2/bS2u+VVe0la8julj1HfpAJC3y/nXzPATXTAU0sIXe9Y2CzxsbORtT/h7p2urxpBFHYoTd8JbEhm6AwmssF+Ss3vtm8nei7Qg1s9C7U4V6dKwchedfyjfb0A0MDFB+XJMHD0Md/DAuNtcv4dmBMvISRSHSKJ+YYbA7w5cyb6Q4mKuwXrqUsVa+k1MT+9bq0+IkUv0BYHEI0DEHzql+qKpluC7fIakPbvhQgdfGV7D6qwCENhzkwmshqkaqsg2qfhuQ== 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=Pt39L4gcVVX6JjO0MH/kTOBHpqq5zLBNm5xPNFqbe72MdEyol57BLLFaOigmiIinTdNzrBQF3ZkghlALTSNnzaiuCuMgp9G9NwlWSI5jLWYydig5OyMarfo+NQLMj7PPzrYUMWFoN3sXfCce6gtk3/paaI/UNU+exI/jEGkxv08Z4eAcrz1r+7qn3FYGlRPFpWIN6u9vSMWiiB/TU3PNd7FGxu1uyfIlK+E/XG3K+/n7tDlVLWcF7wwt5Owu0MOXkGB7gcGtWC3tevcARV/bzCLydLWFgyLz2HjnDt3bVeyevuHgttmS0kiSYcaHUmZGE6H8xjYBlEVbWTVhFGKKwg== 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=PE/jWD5laAk0Caukv3WoeQ1KdErdgKIZ207xdOQ8rcj/rZIIZmQs+mpGB6+Ex8JBDRJxK9kh2jW5t8Jve5m08BEL4R1wtcv8vwOHWmbHrd7gP4FOgakBFxI1CxoCd+FqnEDIZh4wC/zxQ7neXsvMYLMb3V3zCW1yU8aeWDYZN2v/hb2s8SY2xvp0ZXAFRvZsYqYNibJGH85a8VpUNtOSxhrp5Mdplcjj4ntuf6YrCKDsWM06MqgHGpI3xPgqyGoZ1Q/kXZVpkYK+kh2ooRfjnogReWutN+F5ssetD9/MRcr8rcJOlg66NpMQq7pdOPbUH5+XoxEEoSQjR8PMn2v5Gg== Received: from PN0P287MB1494.INDP287.PROD.OUTLOOK.COM (2603:1096:c01:186::9) by PNXP287MB4097.INDP287.PROD.OUTLOOK.COM (2603:1096:c01:28c::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8901.29; Thu, 10 Jul 2025 05:20:08 +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.8901.028; Thu, 10 Jul 2025 05:20:08 +0000 From: Dash Santosh Sathyanarayanan To: FFmpeg development discussions and patches Thread-Topic: [PATCH v3 2/2] avcodec/mfenc: add support for D3D11 input surfaces Thread-Index: AQHb8Vo0GmlI5n7THUWcYgKydIpa/w== Date: Thu, 10 Jul 2025 05:20:08 +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_|PNXP287MB4097:EE_ x-ms-office365-filtering-correlation-id: 04e33167-568d-4bad-6340-08ddbf717015 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; ARA:13230040|1800799024|10070799003|366016|376014|38070700018; x-microsoft-antispam-message-info: =?iso-8859-1?Q?XHs8Rzk9lF208v6y4ELRFffYmsgE66kw04rg5No9QeBeV/VN5DQLxvWAKY?= =?iso-8859-1?Q?zoHlOJFYjz9/FDQ3sWiScX2ZmiXDPeeHNx+sBByqBbxWWo+m5ofhNs2Bnt?= =?iso-8859-1?Q?Y8UnkPuzuiR0pTvzvJ/C44ypGtQCMTbdh01cPTOwxWI3rTUH4vOJYuKBjK?= =?iso-8859-1?Q?TIz90HVadqVQnZhSEdhNysHU1qDy/vP7R6k7drVnUhftEeMTtqh2oC5gRo?= =?iso-8859-1?Q?T9V+oshLWYsVdlaFptFidJGcjhxfG2d3EalUOocplmmYQfAl+F+3HVC+KM?= =?iso-8859-1?Q?0iBB8JKb7dzkTIYnY4r5uJN8eSRInwNMOV9SYHtWb4pyMqhWlPzEjATU3K?= =?iso-8859-1?Q?LkzaWCVfJ4akFFBS1WLewGkr2d+eIt56se+7Kx3M5iPqlZ2GrVBzpYmcY2?= =?iso-8859-1?Q?jR4AoMU0SmaMKYHmk4qTQmzMc1uygmQPJAhxsx2Ck44VBJ/MkNou2LxauG?= =?iso-8859-1?Q?pyRC5bJmRz+7iU5hwrz0qXCJc+55m2EXRVLBam1X+1ubXHAsJXMfYxb2It?= =?iso-8859-1?Q?B2bvc2qDqXBqSGAtCAuGDNMmWRrs0xRP6n07E9uLWUK+fGwVXtC7CgOUYq?= =?iso-8859-1?Q?ba/e3WZD8ZP221ccvkIUCyw07l2mCEo16r5a93A/Dee/Noxh0x+NdP8/JG?= =?iso-8859-1?Q?0XWHPWeHr/Tavv0eZI/bBWJE/9EhA9Mnce7yE00x+jXET7o8dMdgBIyaHh?= =?iso-8859-1?Q?C4PQRUg2jPd/uFBWVixmN4RUcNgrcsMOySDl9FCcL9MGaiUpF00NgTTWrT?= =?iso-8859-1?Q?fu2BMgpmFYs2m1rUOA5R9ngDQjkmaFxRfEnqi35eAnGh+RFkvX2eKU0wcS?= =?iso-8859-1?Q?H8jPIiVWXDcGKJ7WqcOgLsb9hDaqTL6t6s64BRhj0lkEOePelYJbzn6PBG?= =?iso-8859-1?Q?2A/eWLBhCjkr8vXCtuivGmFy51vsLime6Zls1PJADICjhmR6HrnjbiGW8f?= =?iso-8859-1?Q?RRyIfe9NCAlzNAw+YGzv/Pr/stpQg0ojnWWkgyVa8cuhdMQWjCgT9LmTNd?= =?iso-8859-1?Q?0GxzPXHzlj2IRqQ4dXG9moe4BP5HFiv4lGJxEpVLub+PrWV0TMkC84LsKB?= =?iso-8859-1?Q?ZBocYCGyOnoRJSeK0z9IyHTxWTQbOlHJbo6t7vIOy1RhMPSaHUOxZY1inK?= =?iso-8859-1?Q?fALCl0+v2PGM0tPwhIccFL37z2fyYtTa7TjB3Cb8OCVyIuFs+V8rVtrGBq?= =?iso-8859-1?Q?C7ZsxfH1EcKJxrvl4Kiva0XR4uAXAJaiCqRAXgDXqFl8O07BusKoQ/sQjc?= =?iso-8859-1?Q?B5eyVOBwfka/qyKnraigQm30y1cLz0butzlmctVgkB08+9l3MZrchnSwE1?= =?iso-8859-1?Q?7iEV6bgm2MSQDcOdb2GpNGps4qTQrCmumfrDRTkMhIpx4+rl8LyJ7ATBNi?= =?iso-8859-1?Q?kKZPe99P4CGf5jOngIRuA6Ql7dADusgAg+xgFEtYPgNSKb0IV4S07Qipd5?= =?iso-8859-1?Q?kGIb6MRcWJYLJODrZMPOKKV02UhIdFK8mxDjga66JpMaZUL73M+8FUr0mA?= =?iso-8859-1?Q?//ILqndFBf+zOu5ImRarQVO7wFsbUW8694mH2cfQxx/w=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)(1800799024)(10070799003)(366016)(376014)(38070700018); DIR:OUT; SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?iso-8859-1?Q?ygYHRYgvBp6e68wpL5Lln8n+u466KKS6KP2E3ukswGnlqMjEBmyhxHYjhj?= =?iso-8859-1?Q?S9wdaEkAJQI7DpALq1ZKP0fv2IHEg0MD112Eqr1Jo33bn42+Tj5yoaA0hS?= =?iso-8859-1?Q?8/yxkqWiwIX7iWCqhk9E+un18C3rMDAg2E1rojT053XsYkM/2lJsjArPdN?= =?iso-8859-1?Q?YigforQkG21LHIGS0y2SU9XnmNqV+IovaUfEVa50vYX1zJgM/i43lHZB6t?= =?iso-8859-1?Q?BtisSm+aNSFAl7UAnGYOW8oN+7HpB6uTaP55fqA5EvYZ9qx8iFTtNISh9S?= =?iso-8859-1?Q?p6YAwnWIrnq9UbRPETy4YJiem2Xhwe7tJxRyRNlTQbeEJLq3kOQAJynLKN?= =?iso-8859-1?Q?csmcr+iHYHk0zgBnLNFYZ4YxbQnVXVkY/5t9U62/LwbcHExnUibWibwjdX?= =?iso-8859-1?Q?ctJsBxjAraPztGSTAwLR+bBEa34TNpojQ2KXh54X18dPG33ZsZekjzStrY?= =?iso-8859-1?Q?2dmNFmD+u+cW3YeRGtvY7AThsYi7F02UKODdBtOgsUV5iViyWf8yRtfoVT?= =?iso-8859-1?Q?uDemTI10r/v+czxFqlex9m2cHTTCxzJaK83BYf1gxQaJUVEFHgQ8zjS3I8?= =?iso-8859-1?Q?GSgIYB9S4cbSZQj6LKKq1XXE4Hz43lyybDQh/6u3mDNIxZaiycfOeD6iov?= =?iso-8859-1?Q?0ym2LI4ksCvWdgYOEvSNxxNdZg7vnefBjNg4ajKGaD94AVFvLnNseLdXyK?= =?iso-8859-1?Q?bX+91bfMrDV/apRCNrgOirXLyRPen1cV5jUr+fSg1TnAcx39LAvSvqRZnE?= =?iso-8859-1?Q?l/nCrHZh6GM+VcfQj8lVVs9QmF9SR97gFnKuQ2L/y8UK3UWYZBV5F1lLYi?= =?iso-8859-1?Q?V3IALzS4787QM1AceBEr2QWef+V7CxaGr6cjwI8uZb9GJXDqatVjmDYskd?= =?iso-8859-1?Q?COphVlwrKk9i8CQ4Qe1vbGAtxRXNGSFfJjGxWTXFbe0eIlL69X+tpA7kJE?= =?iso-8859-1?Q?qTIjmY1G//AzSuQtBK66RRDYz8mBDiA8GMeGTr703m3jpGqmDZPKt13nZz?= =?iso-8859-1?Q?oad27675T3aeLd8u7jgmfMKrMFAWvjh+GbmeGBF1iwzE9CaUEfM/guX9DU?= =?iso-8859-1?Q?zCo5tCpJvavawTOGhteUENvd08jWnXLZTd5M+2wK3jpJn3KcPDm5ljPDCc?= =?iso-8859-1?Q?OIkQTijm6mDdKEuoi1l7dV0KoCmFiObtcKFduEfNuLAWhsQpnTSGbmhG3r?= =?iso-8859-1?Q?lJHkDI6g7FFrJDXl9BCDUBKGAmJDrq5GQXorTssBtdfSqSntmaaWRtqpzJ?= =?iso-8859-1?Q?jzTXSPfZyynSE4PyMHVscNPzGpvv9BPmX291L4yNO44lQjLXQrcPz3ZFs5?= =?iso-8859-1?Q?t1hKdCH8nN1G6t9CgFeSe321DK0hjZBgouq3hZvhz8eaY7Mosa+wrJA7rG?= =?iso-8859-1?Q?ATvaiVJAyU+CeDkWb02t5nk+ZPaJq3OBhtTVzrmv0qwqg+WXyMU1N0S5Wl?= =?iso-8859-1?Q?/OwImKD+wDiWqcDWPv6XPYaySUF9iwBUVn8sz44fMRyo7yqiRayQzsnCza?= =?iso-8859-1?Q?Twfhxv9dIlHLYyC1WgfpeMy7hv3piS0Q6IA4nDww4LCJtgvYfla3F6gv5Z?= =?iso-8859-1?Q?kqx+i8EhL69u9IjqdAJflhYGtlTmpcoy9QMsXpMvyatb07SI/Usxkqyq3M?= =?iso-8859-1?Q?wpo14+rQtNdjdlNLn5cSTtP62riC1hL2kkNu1wYyMhROeRgyrTr+09l7pn?= =?iso-8859-1?Q?rXFor8r5Rd8NrEpkO3YXpo1u4jxNqtpPJKqV2nRUzvKQHfaRlUG+cZ4jp+?= =?iso-8859-1?Q?pyVtOYQHtDAkExevYtMgfP7xY=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: 04e33167-568d-4bad-6340-08ddbf717015 X-MS-Exchange-CrossTenant-originalarrivaltime: 10 Jul 2025 05:20:08.8623 (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: HdzTtBwYa2DBFwuhY7zcNsdz97Ud0zrATt8q9x+csGodoiZGmphbXwcMhyMM/gXAEdfNFMJsnMsoTY5jSODAItWQSPLVSh+4j6Hov+AdHkqeJYvVBluDqGpHKNBEQ5iAoYhsw5bLFvmexHYjlSsxNA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PNXP287MB4097 Subject: [FFmpeg-devel] [PATCH v3 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".