From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mf/tests/h264data-1.bin | Bin 0 -> 1597 bytes dlls/mf/tests/h264data-2.bin | Bin 0 -> 1717 bytes dlls/mf/tests/mf_test.h | 1 + dlls/mf/tests/resource.rc | 18 +++ dlls/mf/tests/transform.c | 243 +++++++++++++++++++++++++++++++++-- 5 files changed, 248 insertions(+), 14 deletions(-) create mode 100644 dlls/mf/tests/h264data-1.bin create mode 100644 dlls/mf/tests/h264data-2.bin
diff --git a/dlls/mf/tests/h264data-1.bin b/dlls/mf/tests/h264data-1.bin new file mode 100644 index 0000000000000000000000000000000000000000..047d97d06cc2da46c52ef6391ce4c3741a77251c GIT binary patch literal 1597 zcmZvcYiJx*6vt<g7z0ghi%Jk8S0W<1kD1wRvRNHvty|-x5E>9$3&Wk+yE~Je*Un6m z-C9h2AbwC(h@rN+Yd^%MQfal8R!GsP7^&iiSY;Dh+7bwa6pdBTrY7sTv*~8j?U$P~ z|9j5w{Lj62!!V4mX#)dmI?3E|WNK?iq0QI3Ze8=!4AVHt_|A^s^FWWE?kn?`KZn3~ zYeTtw<y>O!^z2mE$zgv9O|||0M~-igpa7Chn;;HCJIr=&MiM3@!m_Z@6@-M)w(i7} zfe4B}w*@kjM23wmrj^%7%0)cOh66my^B^j&YsEsLfq{WwznUbbhK-<Ur$e+$P;qq) za!kurO~Z*H8B16eIAoKQ5JpKNX{MYJxELE_5jL=vcZk5|!Z9|-abctrK_NNh^hpqP zAj`=^DXgNM6u2M@MX(@U&5@)?i5ygjHa5~k;M$R_*rtv}DCLlA6HQYch@!b@Qg$Jb zv%0{71)SV%8bshZKgXdIc3jbNGO9&0DuApdnyHjSTp_?CSFxeO0rQ$^X0QSu;&qKf zj;6}s<+{Kk!}fZ}s*YXiLp5AtYZ#J1m$W_`=SA7nE$qU#3`gYJSTz6vi8iJ=DI4pA z_LD>_53!mQc!+TlTXYIZlvM1{CaO)mxdw=uR$K}8Op6#|+O%M|B3e+IA$ed6d}rrM zDC(*KpU9DkLF7JHh_KYAjp>ov#8IH!mc{D0bl;W*S+bEX!MW10Bo*>uK%R|65sh3^ zqc?=IbU1+xwnJ#qM&4hX6WTjLa9m;u5!5gBi#pD&5~v{cr5trPz<EB3;AMykT)F`_ zg;J`f5qhqw1(yvE3p#-(oP~EpUj?%l9zJ>FHRkT}<!diL_R`izns;_CZPFI!BXi?d zCLS8RdSTZOt&@Z2H@=hZ`Sh2)`+E<SBVWwLUi`W1uG5LH55CuNX4lBfm)p<%`;5=| zpk+_$;jum02h0AqQP<Gi!tna&kGFi-F}ZYXllA@Ir<PlG^zZzxXUNRF+t~0^df#X( zGh^w_;q#>(mu62LZae-&!+*aX-S^qqq5jhC$G=T{_2}ZO(<c@$EY5!P*IVJSQfsF5 z8)2qvqI<)H^T`XN|1{i7f4)sDEb;yKY4M}W(;q*7|3y#irefjo+$&|Kd8(@T3fPUC zOv^%zBKK0|Pfw|!l&41H%KOjWwz=#9FIAJ{h1U}s{ViptF;LZfg%J-~0noO-!XXb? zX;MKR0i?EyyjU%d7tSQ^tV7PZ@j<4!RL$}g=6hF_3UXmBvc_d`eLb=m@Q^h}Q4HOP zJP=untZ`Y~eiLN&MwdmW4w+kvtaUlOg7p3gH+d&lJW=QJq=&5d_69#Nwu0o!%fF3u c*WPz=`X(-~*15b^hg@1gh5-5Iv2El313@eWG5`Po
literal 0 HcmV?d00001
diff --git a/dlls/mf/tests/h264data-2.bin b/dlls/mf/tests/h264data-2.bin new file mode 100644 index 0000000000000000000000000000000000000000..1169a6e94b29a165f32c147bf6036e0ed2b677ca GIT binary patch literal 1717 zcmZvcdrTBp6vhXL3ayYDHC2<A8^N?OusbumP*^&pTZ5>@g5ZPNG?P2CcXtP7XNH+U zcEO6)mfF??n;08jyM2JI6;slrv1zrYq*1hO(nn&1Y9MK9Yw<xb(O8u2nO%fM{O9hO z@1FBJ-?{f@DT+!;dyInB=b@JL4we>&vyy5SE==D*Q44;hQjY9-^69D^Yu`V5^$Q4+ z=Ff{p$1j##IeB?--SI;?7tmnV^&3Gp--&XOsOkhU5b6%PFb@fs5GPH;#yT4$*f&;` zl;%2-d+Qp=^bip?)~H%YCSDV<H0{V`X_f`iZ<?CRZf|I4u<ejMM3u2(Q+1!+>SFVo z0U2^s&6HHda3K*3SmYR_6EEjL9wNx9Sj#ak+C?L*U^!$Ejt)9pbdX^jC_p$r2_mCj zfan>d86hZzmDfESW22!678H<z#KT)e1}b<RD?Y+8`AGEZY5?<4${<rGvMd=86$A@B zq6vXm7vN~HfIW?>LO7PmVHo7ahRJJ2t)y8QaX_8Mt6r}`OfHv2reB8&1I){+T8sVg z!Qa;yWXO^TUhWGtQuJ64Q3_zw@*ycE(Pa!tpbK)njzhet1~hEKw+KgM>R3_$0f{=c za=bbY5UZcSYaxgw5641`Jy^4*5O_hthSfyUNo=kLBKiEL0DG!N6yB$5up1XOD6J(S zU~_qeg;OCPkQDethDa15)|;G@wruLyI#Qh&ekj*PetKMMUl%!1&{05ubG612B*=#W zS=w2EtjJVl>xNLBH5^CV@*&i$MzLQU<njwaFifIxPP9YV!3S_~hF}Roz1NT$0nV}o z2wn#7hf7!BrjS>XWn!JHq`_sw!-7uW3D?0pvR(zX8y-H{_Xf2hdUaw?@vgPcrf)Bt zcxx=#b$VDY-O`@@`})w9?4f^(in_<{R2@5(b>yq#{T*)(aFd_e&(@xKD(d+5R_lc> z@#TZxH7(kA^Wvt|kq-mR?&@0;8E3CVH&>pzmfYOkl;SH`@am6_k#{ya*s7Z&)w{M# zZvP<iLtj?3NB?_&^4?ARw+inDcaDdp$`>!W`(GPtH}AInxyar3Q%3o!?3Xf6oonf+ z7+$?}`1=*_U#>kkaJRWy{`#AS_iT?`LM!P<x1HW_WYvN3J8OTty;v?dQ#P<B{KxXQ z51)Uc{JB%}q-$&!$^7pZv$6B>(F5F#13l5B|F&cvm9MVudi|r6kBi&KZ%0-x?Dq9{ z_C@hh`>yiqspD}dw*^kShDKoD@8jyyZ-8L#mwy{QUNevewPZJZZ`{>u)2ChQ-~U zExSLT96DT`ni>-;EHV5-aBn7+QZ=n4g|X>wrskhWP{bNbIhla+um9BTZ!1g9i^hOy z)5-2|OUa^~WzpHlo)|I?u-YbtKZzmZP2%o)0V&TQ6Fr_QS(>vvN+lOfw@C_Lnd5SF z4svWZGQnjeV=gk1`=HB+{Xt}hb2c);Wu)>U$U4*AN~KiJ_>LGgGfHgmj^J!$qRT^5 yNLK>j%NR1@!Xn3G$hZ<mo|r;9qLb%)DiZHIGV~Cacjma9n1j4Gg=FH$wEqF^`7d(-
literal 0 HcmV?d00001
diff --git a/dlls/mf/tests/mf_test.h b/dlls/mf/tests/mf_test.h index 0f23e2aeb02..05aa34e3d28 100644 --- a/dlls/mf/tests/mf_test.h +++ b/dlls/mf/tests/mf_test.h @@ -94,6 +94,7 @@ struct sample_desc const struct buffer_desc *buffers; DWORD repeat_count; BOOL todo_length; + BOOL todo_duration; LONGLONG todo_time; };
diff --git a/dlls/mf/tests/resource.rc b/dlls/mf/tests/resource.rc index e3df92e375f..d9595c68980 100644 --- a/dlls/mf/tests/resource.rc +++ b/dlls/mf/tests/resource.rc @@ -63,6 +63,24 @@ mp3decdata.bin RCDATA mp3decdata.bin /* @makedep: h264data.bin */ h264data.bin RCDATA h264data.bin
+/* Generated with: + gst-launch-1.0 videotestsrc num-buffers=30 pattern=smpte100 ! \ + video/x-raw,format=I420,width=84,height=82,framerate=30000/1001 ! \ + videoflip method=clockwise ! videoconvert ! \ + x264enc ! filesink location=dlls/mf/tests/h264data-1.bin + */ +/* @makedep: h264data-1.bin */ +h264data-1.bin RCDATA h264data-1.bin + +/* Generated with: + gst-launch-1.0 videotestsrc num-buffers=30 pattern=smpte100 ! \ + video/x-raw,format=I420,width=100,height=98,framerate=60000/1001 ! \ + videoflip method=clockwise ! videoconvert ! \ + x264enc ! filesink location=dlls/mf/tests/h264data-2.bin + */ +/* @makedep: h264data-2.bin */ +h264data-2.bin RCDATA h264data-2.bin + /* Generated from running the tests on Windows */ /* @makedep: nv12frame.bmp */ nv12frame.bmp RCDATA nv12frame.bmp diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index b1ac3ffbb14..04c59bbdffc 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -1140,13 +1140,16 @@ static DWORD check_mf_media_buffer_(const char *file, int line, IMFMediaBuffer * todo_wine_if(expect->todo_length) ok_(file, line)(length == expect_length, "got length %#lx\n", length);
- if (*expect_data_len < length) - todo_wine_if(expect->todo_length) - ok_(file, line)(0, "missing %#lx bytes\n", length - *expect_data_len); - else if (!expect->compare) - diff = compare_bytes(data, &length, NULL, *expect_data); - else - diff = expect->compare(data, &length, &expect->rect, *expect_data); + if (*expect_data) + { + if (*expect_data_len < length) + todo_wine_if(expect->todo_length) + ok_(file, line)(0, "missing %#lx bytes\n", length - *expect_data_len); + else if (!expect->compare) + diff = compare_bytes(data, &length, NULL, *expect_data); + else + diff = expect->compare(data, &length, &expect->rect, *expect_data); + }
hr = IMFMediaBuffer_Unlock(buffer); ok_(file, line)(hr == S_OK, "Unlock returned %#lx\n", hr); @@ -1202,14 +1205,14 @@ static DWORD check_mf_sample_(const char *file, int line, IMFSample *sample, con timestamp = 0xdeadbeef; hr = IMFSample_GetSampleTime(sample, ×tamp); ok_(file, line)(hr == S_OK, "GetSampleTime returned %#lx\n", hr); - todo_wine_if(expect->todo_time && timestamp == expect->todo_time) + todo_wine_if(expect->todo_time && (timestamp == expect->todo_time || expect->todo_time == -1)) ok_(file, line)(llabs(timestamp - expect->sample_time) <= 50, "got sample time %I64d\n", timestamp);
timestamp = 0xdeadbeef; hr = IMFSample_GetSampleDuration(sample, ×tamp); ok_(file, line)(hr == S_OK, "GetSampleDuration returned %#lx\n", hr); - todo_wine_if(expect->todo_length) + todo_wine_if(expect->todo_duration && expect->todo_duration == timestamp) ok_(file, line)(llabs(timestamp - expect->sample_duration) <= 1, "got sample duration %I64d\n", timestamp);
@@ -1221,7 +1224,7 @@ static DWORD check_mf_sample_(const char *file, int line, IMFSample *sample, con todo_wine_if(expect->todo_length) ok_(file, line)(total_length == ctx.total_length, "got total length %#lx\n", total_length); - ok_(file, line)(*expect_data_len >= ctx.total_length, + ok_(file, line)(!*expect_data || *expect_data_len >= ctx.total_length, "missing %#lx data\n", ctx.total_length - *expect_data_len);
*expect_data = ctx.data; @@ -1243,10 +1246,10 @@ DWORD check_mf_sample_collection_(const char *file, int line, IMFCollection *sam DWORD count; HRESULT hr;
- load_resource(expect_data_filename, &ctx.data, &ctx.data_len); + if (expect_data_filename) load_resource(expect_data_filename, &ctx.data, &ctx.data_len); enum_mf_samples(samples, expect_samples, check_mf_sample_collection_enum, &ctx);
- dump_mf_sample_collection(samples, expect_samples, expect_data_filename); + if (expect_data_filename) dump_mf_sample_collection(samples, expect_samples, expect_data_filename);
hr = IMFCollection_GetElementCount(samples, &count); ok_(file, line)(hr == S_OK, "GetElementCount returned %#lx\n", hr); @@ -3159,7 +3162,7 @@ static void test_wma_decoder(void) }, { .attributes = output_sample_attributes + 1, /* not MFT_OUTPUT_DATA_BUFFER_INCOMPLETE */ - .sample_time = 2786394, .sample_duration = 464399, + .sample_time = 2786394, .sample_duration = 464399, .todo_duration = 928798, .buffer_count = 1, .buffers = output_buffer_desc + 1, .todo_length = TRUE, }, }; @@ -4016,6 +4019,217 @@ failed: CoUninitialize(); }
+static void test_h264_decoder_concat_streams(void) +{ + const struct buffer_desc output_buffer_desc[] = + { + {.length = 0x3600}, + {.length = 0x4980}, + {.length = 0x4980, .todo_length = TRUE}, + }; + const struct attribute_desc output_sample_attributes[] = + { + ATTR_UINT32(MFSampleExtension_CleanPoint, 1), + {0}, + }; + const struct sample_desc output_sample_desc[] = + { + { + .attributes = output_sample_attributes + 0, + .sample_time = 0, .sample_duration = 400000, + .todo_duration = 333666, + .buffer_count = 1, .buffers = output_buffer_desc + 0, + }, + { + .attributes = output_sample_attributes + 0, + .sample_time = 400000, .sample_duration = 400000, + .buffer_count = 1, .buffers = output_buffer_desc + 0, .repeat_count = 26, + .todo_time = -1, .todo_duration = 333666, + }, + { + .attributes = output_sample_attributes + 0, + .sample_time = 11200000, .sample_duration = 400000, + .buffer_count = 1, .buffers = output_buffer_desc + 0, .repeat_count = 1, + .todo_time = -1, .todo_duration = 333666, + }, + { + .attributes = output_sample_attributes + 0, + .sample_time = 12000000, .sample_duration = 400000, + .buffer_count = 1, .buffers = output_buffer_desc + 2, .repeat_count = 29, + .todo_time = -1, .todo_duration = 333666, .todo_length = TRUE, + }, + { + .attributes = output_sample_attributes + 0, + .sample_time = 0, .sample_duration = 400000, + .buffer_count = 1, .buffers = output_buffer_desc + 0, .repeat_count = 29, + }, + { + .attributes = output_sample_attributes + 0, + .sample_time = 12000000, .sample_duration = 400000, + .buffer_count = 1, .buffers = output_buffer_desc + 1, .repeat_count = 6, + }, + {0}, + }; + const WCHAR *filenames[] = + { + L"h264data-1.bin", + L"h264data-2.bin", + L"h264data-1.bin", + L"h264data-2.bin", + NULL, + }; + DWORD output_status, input_count, output_count; + const WCHAR **filename = filenames; + const BYTE *h264_encoded_data; + IMFCollection *output_samples; + ULONG h264_encoded_data_len; + IMFAttributes *attributes; + IMFMediaType *media_type; + IMFTransform *transform; + IMFSample *input_sample; + HRESULT hr; + LONG ret; + + hr = CoInitialize(NULL); + ok(hr == S_OK, "Failed to initialize, hr %#lx.\n", hr); + + if (FAILED(hr = CoCreateInstance(&CLSID_MSH264DecoderMFT, NULL, CLSCTX_INPROC_SERVER, + &IID_IMFTransform, (void **)&transform))) + goto failed; + ok(hr == S_OK, "hr %#lx\n", hr); + + hr = IMFTransform_GetAttributes(transform, &attributes); + ok(hr == S_OK, "GetAttributes returned %#lx\n", hr); + hr = IMFAttributes_SetUINT32(attributes, &MF_LOW_LATENCY, 1); + ok(hr == S_OK, "SetUINT32 returned %#lx\n", hr); + IMFAttributes_Release(attributes); + + hr = IMFTransform_GetInputAvailableType(transform, 0, 0, &media_type); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_RATE, (UINT64)25000 << 32 | 1000); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFTransform_SetInputType(transform, 0, media_type, 0); + ok(hr == S_OK, "got %#lx\n", hr); + IMFMediaType_Release(media_type); + + hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_RATE, (UINT64)50000 << 32 | 1000); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); + ok(hr == S_OK, "got %#lx\n", hr); + IMFMediaType_Release(media_type); + + load_resource(*filename, &h264_encoded_data, &h264_encoded_data_len); + + hr = MFCreateCollection(&output_samples); + ok(hr == S_OK, "MFCreateCollection returned %#lx\n", hr); + + input_count = 0; + input_sample = next_h264_sample(&h264_encoded_data, &h264_encoded_data_len); + while (input_sample) + { + MFT_OUTPUT_STREAM_INFO info = {0}; + + hr = IMFTransform_ProcessInput(transform, 0, input_sample, 0); + ok(hr == S_OK || hr == MF_E_NOTACCEPTING, "ProcessInput returned %#lx\n", hr); + + if (hr == S_OK && input_count < 2) + { + MFT_OUTPUT_DATA_BUFFER data = {.pSample = create_sample(NULL, 1)}; + hr = IMFTransform_ProcessOutput(transform, 0, 1, &data, &output_status); + todo_wine + ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#lx\n", hr); + IMFSample_Release(data.pSample); + hr = S_OK; + } + + if (hr == S_OK) + { + IMFSample_Release(input_sample); + + hr = IMFCollection_GetElementCount(output_samples, &output_count); + ok(hr == S_OK, "GetElementCount returned %#lx\n", hr); + + if (output_count == 96) + { + hr = IMFTransform_ProcessMessage(transform, MFT_MESSAGE_COMMAND_FLUSH, 0); + ok(hr == S_OK, "ProcessMessage returned %#lx\n", hr); + } + + if (h264_encoded_data_len <= 4 && *++filename) + { + load_resource(*filename, &h264_encoded_data, &h264_encoded_data_len); + + if (!wcscmp(*filename, L"h264data-1.bin")) + { + hr = IMFTransform_ProcessMessage(transform, MFT_MESSAGE_COMMAND_DRAIN, 0); + ok(hr == S_OK, "ProcessMessage returned %#lx\n", hr); + } + } + + if (h264_encoded_data_len > 4) + { + input_count++; + input_sample = next_h264_sample(&h264_encoded_data, &h264_encoded_data_len); + } + else + { + hr = IMFTransform_ProcessMessage(transform, MFT_MESSAGE_COMMAND_DRAIN, 0); + ok(hr == S_OK, "ProcessMessage returned %#lx\n", hr); + input_sample = NULL; + } + } + + hr = IMFTransform_GetOutputStreamInfo(transform, 0, &info); + ok(hr == S_OK, "GetOutputStreamInfo returned %#lx\n", hr); + + while (hr != MF_E_TRANSFORM_NEED_MORE_INPUT) + { + MFT_OUTPUT_DATA_BUFFER data = {.pSample = create_sample(NULL, info.cbSize)}; + + hr = IMFTransform_ProcessOutput(transform, 0, 1, &data, &output_status); + todo_wine_if(hr == 0xd0000001) + ok(hr == S_OK || hr == MF_E_TRANSFORM_NEED_MORE_INPUT || hr == MF_E_TRANSFORM_STREAM_CHANGE, + "ProcessOutput returned %#lx\n", hr); + + if (hr == S_OK) + { + hr = IMFCollection_AddElement(output_samples, (IUnknown *)data.pSample); + ok(hr == S_OK, "AddElement returned %#lx\n", hr); + } + if (hr == MF_E_TRANSFORM_STREAM_CHANGE) + { + hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_RATE, (UINT64)50000 << 32 | 1000); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); + ok(hr == S_OK, "got %#lx\n", hr); + IMFMediaType_Release(media_type); + hr = IMFTransform_GetOutputStreamInfo(transform, 0, &info); + ok(hr == S_OK, "GetOutputStreamInfo returned %#lx\n", hr); + } + + IMFSample_Release(data.pSample); + } + } + + hr = IMFCollection_GetElementCount(output_samples, &output_count); + ok(hr == S_OK, "GetElementCount returned %#lx\n", hr); + todo_wine + ok(output_count == 96, "GetElementCount returned %#lx\n", output_count); + + ret = check_mf_sample_collection(output_samples, output_sample_desc, NULL); + ok(ret == 0, "got %lu%% diff\n", ret); + + ret = IMFTransform_Release(transform); + ok(ret == 0, "Release returned %lu\n", ret); + +failed: + CoUninitialize(); +} + static void test_audio_convert(void) { const GUID *const class_id = &CLSID_CResamplerMediaObject; @@ -4180,7 +4394,7 @@ static void test_audio_convert(void) }, { .attributes = output_sample_attributes + 1, /* not MFT_OUTPUT_DATA_BUFFER_INCOMPLETE */ - .sample_time = 9287980, .sample_duration = 897506, + .sample_time = 9287980, .sample_duration = 897506, .todo_duration = 897280, .buffer_count = 1, .buffers = output_buffer_desc + 1, .todo_length = TRUE, }, { @@ -7691,4 +7905,5 @@ START_TEST(transform) test_iv50_decoder();
test_h264_with_dxgi_manager(); + test_h264_decoder_concat_streams(); }