This format is used for video output with a depth of 10 bits per channel. Decoding at 10-bit quality is not currently supported, but this patch makes video playable.
From: Conor McCarthy cmccarthy@codeweavers.com
Windows supports this. Media engine apparently performs a format conversion, because the session engine does not support R10G10B10A2 output. --- dlls/mfmediaengine/tests/mfmediaengine.c | 13 ++++++++----- dlls/mfmediaengine/tests/resource.rc | 4 ++++ dlls/mfmediaengine/tests/rgb32-10frame.bmp | Bin 0 -> 16438 bytes 3 files changed, 12 insertions(+), 5 deletions(-) create mode 100755 dlls/mfmediaengine/tests/rgb32-10frame.bmp
diff --git a/dlls/mfmediaengine/tests/mfmediaengine.c b/dlls/mfmediaengine/tests/mfmediaengine.c index fbaeff50710..2bd5ef3ff5f 100644 --- a/dlls/mfmediaengine/tests/mfmediaengine.c +++ b/dlls/mfmediaengine/tests/mfmediaengine.c @@ -1266,7 +1266,7 @@ static struct test_transfer_notify *create_transfer_notify(void) return object; }
-static void test_TransferVideoFrame(void) +static void test_TransferVideoFrame(DXGI_FORMAT format, const WCHAR *expected_frame) { struct test_transfer_notify *notify; ID3D11Texture2D *texture = NULL, *rb_texture; @@ -1299,7 +1299,7 @@ static void test_TransferVideoFrame(void) hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)device, token); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
- create_media_engine(¬ify->IMFMediaEngineNotify_iface, manager, DXGI_FORMAT_B8G8R8X8_UNORM, + create_media_engine(¬ify->IMFMediaEngineNotify_iface, manager, format, &IID_IMFMediaEngineEx, (void **)&media_engine);
IMFDXGIDeviceManager_Release(manager); @@ -1311,7 +1311,7 @@ static void test_TransferVideoFrame(void) desc.Width = 64; desc.Height = 64; desc.ArraySize = 1; - desc.Format = DXGI_FORMAT_B8G8R8X8_UNORM; + desc.Format = format; desc.BindFlags = D3D11_BIND_RENDER_TARGET; desc.SampleDesc.Count = 1; hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture); @@ -1366,7 +1366,9 @@ static void test_TransferVideoFrame(void) ok(!!map_desc.pData, "got pData %p\n", map_desc.pData); ok(map_desc.DepthPitch == 16384, "got DepthPitch %u\n", map_desc.DepthPitch); ok(map_desc.RowPitch == desc.Width * 4, "got RowPitch %u\n", map_desc.RowPitch); - res = check_rgb32_data(L"rgb32frame.bmp", map_desc.pData, map_desc.RowPitch * desc.Height, &dst_rect); + res = check_rgb32_data(expected_frame, map_desc.pData, map_desc.RowPitch * desc.Height, &dst_rect); + /* R10G10B10A2 equivalents in openGL and Vulkan are not binary compatible with R10G10B10A2 */ + todo_wine_if(format == DXGI_FORMAT_R10G10B10A2_UNORM) ok(res == 0, "Unexpected %lu%% diff\n", res); ID3D11DeviceContext_Unmap(context, (ID3D11Resource *)rb_texture, 0);
@@ -2712,7 +2714,8 @@ START_TEST(mfmediaengine) test_time_range(); test_SetSourceFromByteStream(); test_audio_configuration(); - test_TransferVideoFrame(); + test_TransferVideoFrame(DXGI_FORMAT_B8G8R8X8_UNORM, L"rgb32frame.bmp"); + test_TransferVideoFrame(DXGI_FORMAT_R10G10B10A2_UNORM, L"rgb32-10frame.bmp"); test_effect(); test_GetDuration(); test_GetSeekable(); diff --git a/dlls/mfmediaengine/tests/resource.rc b/dlls/mfmediaengine/tests/resource.rc index 960e5ffd73e..1b4db9df50c 100644 --- a/dlls/mfmediaengine/tests/resource.rc +++ b/dlls/mfmediaengine/tests/resource.rc @@ -31,3 +31,7 @@ i420-64x64.avi RCDATA i420-64x64.avi /* Generated from running the tests on Windows */ /* @makedep: rgb32frame.bmp */ rgb32frame.bmp RCDATA rgb32frame.bmp + +/* Generated from running the tests on Windows */ +/* @makedep: rgb32-10frame.bmp */ +rgb32-10frame.bmp RCDATA rgb32-10frame.bmp diff --git a/dlls/mfmediaengine/tests/rgb32-10frame.bmp b/dlls/mfmediaengine/tests/rgb32-10frame.bmp new file mode 100755 index 0000000000000000000000000000000000000000..c271b52ed9d390d1f082a24c48284e859c6e34ad GIT binary patch literal 16438 zcmZ?rHFID912YB&1`P%V1`rp785tD7;$Q&?3r?<Q|FLTnkA}f$8W>FjqiJ9?4UDFN z5tatpzwBB+g0WZok}V?|GcVlYHHt^WU^ESkrh(BkFq#HN)4+&I1FN!DX^rC1Fc?h( zqiJ9?4UDFN(KIl^(!jH2TB}Adc6}D6GNN%>u!`#_9u0%hG%%V5M$^D(8W>FjBPtE7 zTsh~~C>{-i(KIlc21e7sXc`zz10yUAsLs5#as*>n)yOL&8ZQmK;yQ{)!(cQGjHZFn sG%%V5M$^EEN&`!H{Jlo;Xc&y9fzdQDng&MGz-Ss6O#`E8VC19$0FQE02LJ#7
literal 0 HcmV?d00001
From: Conor McCarthy cmccarthy@codeweavers.com
This format is used for video output with a depth of 10 bits per channel. Decoding at 10-bit quality is not currently supported, but this patch makes video playable. --- dlls/mfmediaengine/main.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/dlls/mfmediaengine/main.c b/dlls/mfmediaengine/main.c index aab5fd64aa2..9ed86cddf35 100644 --- a/dlls/mfmediaengine/main.c +++ b/dlls/mfmediaengine/main.c @@ -182,6 +182,7 @@ struct media_engine BYTE *buffer; UINT buffer_size; DXGI_FORMAT output_format; + BOOL uses_10bit;
struct { @@ -1188,6 +1189,21 @@ static HRESULT media_engine_create_video_renderer(struct media_engine *engine, I return E_FAIL; }
+ switch (output_format) + { + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_R10G10B10A2_UINT: + /* IMFMediaSession doesn't support output to these formats. Create an 8-bit + * output and ensure the sampled texture is copied via a pixel shader. + * TODO: to actually have 10 bits per channel we should use DXGI_FORMAT_P010. */ + output_format = DXGI_FORMAT_B8G8R8A8_UNORM; + engine->video_frame.uses_10bit = TRUE; + break; + default: + break; + } + memcpy(&subtype, &MFVideoFormat_Base, sizeof(subtype)); if (!(subtype.Data1 = MFMapDXGIFormatToDX9Format(output_format))) { @@ -2722,7 +2738,9 @@ static HRESULT WINAPI media_engine_TransferVideoFrame(IMFMediaEngineEx *iface, I
if (SUCCEEDED(IUnknown_QueryInterface(surface, &IID_ID3D11Texture2D, (void **)&texture))) { - if (!engine->device_manager || FAILED(hr = media_engine_transfer_d3d11(engine, texture, src_rect, dst_rect, color))) + if (!engine->device_manager + || engine->video_frame.uses_10bit + || FAILED(hr = media_engine_transfer_d3d11(engine, texture, src_rect, dst_rect, color))) hr = media_engine_transfer_to_d3d11_texture(engine, texture, src_rect, dst_rect, color); ID3D11Texture2D_Release(texture); }