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(); }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winegstreamer/h264_decoder.c | 93 ++++++++++++++++--------------- 1 file changed, 49 insertions(+), 44 deletions(-)
diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c index 1e18aff2635..8eeeb52fd60 100644 --- a/dlls/winegstreamer/h264_decoder.c +++ b/dlls/winegstreamer/h264_decoder.c @@ -57,8 +57,8 @@ struct h264_decoder MFT_INPUT_STREAM_INFO input_info; IMFMediaType *output_type; MFT_OUTPUT_STREAM_INFO output_info; + IMFMediaType *stream_type;
- struct wg_format wg_format; struct wg_transform *wg_transform; struct wg_sample_queue *wg_sample_queue;
@@ -107,8 +107,8 @@ static HRESULT try_create_wg_transform(struct h264_decoder *decoder) static HRESULT fill_output_media_type(struct h264_decoder *decoder, IMFMediaType *media_type) { IMFMediaType *default_type = decoder->output_type; - struct wg_format *wg_format = &decoder->wg_format; UINT32 value, width, height; + MFVideoArea aperture; UINT64 ratio; GUID subtype; HRESULT hr; @@ -118,7 +118,8 @@ static HRESULT fill_output_media_type(struct h264_decoder *decoder, IMFMediaType
if (FAILED(hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &ratio))) { - ratio = (UINT64)wg_format->u.video.width << 32 | wg_format->u.video.height; + if (FAILED(IMFMediaType_GetUINT64(decoder->stream_type, &MF_MT_FRAME_SIZE, &ratio))) + ratio = (UINT64)1920 << 32 | 1080; if (FAILED(hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, ratio))) return hr; } @@ -127,14 +128,16 @@ static HRESULT fill_output_media_type(struct h264_decoder *decoder, IMFMediaType
if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_FRAME_RATE, NULL))) { - ratio = (UINT64)wg_format->u.video.fps_n << 32 | wg_format->u.video.fps_d; + if (FAILED(IMFMediaType_GetUINT64(decoder->stream_type, &MF_MT_FRAME_RATE, &ratio))) + ratio = (UINT64)30000 << 32 | 1001; if (FAILED(hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_RATE, ratio))) return hr; }
if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_PIXEL_ASPECT_RATIO, NULL))) { - ratio = (UINT64)1 << 32 | 1; /* FIXME: read it from format */ + if (FAILED(IMFMediaType_GetUINT64(decoder->stream_type, &MF_MT_PIXEL_ASPECT_RATIO, &ratio))) + ratio = (UINT64)1 << 32 | 1; if (FAILED(hr = IMFMediaType_SetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, ratio))) return hr; } @@ -188,17 +191,9 @@ static HRESULT fill_output_media_type(struct h264_decoder *decoder, IMFMediaType }
if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, NULL)) - && (wg_format->u.video.padding.left || wg_format->u.video.padding.right || wg_format->u.video.padding.top - || wg_format->u.video.padding.bottom)) + && SUCCEEDED(hr = IMFMediaType_GetBlob(decoder->stream_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, + (BYTE *)&aperture, sizeof(aperture), &value))) { - MFVideoArea aperture = - { - .OffsetX = {.value = wg_format->u.video.padding.left}, - .OffsetY = {.value = wg_format->u.video.padding.top}, - .Area.cx = wg_format->u.video.width - wg_format->u.video.padding.right - wg_format->u.video.padding.left, - .Area.cy = wg_format->u.video.height - wg_format->u.video.padding.bottom - wg_format->u.video.padding.top, - }; - if (FAILED(hr = IMFMediaType_SetBlob(media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, (BYTE *)&aperture, sizeof(aperture)))) return hr; @@ -482,10 +477,9 @@ static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFM
if (SUCCEEDED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size))) { - decoder->wg_format.u.video.width = frame_size >> 32; - decoder->wg_format.u.video.height = (UINT32)frame_size; - decoder->output_info.cbSize = decoder->wg_format.u.video.width - * decoder->wg_format.u.video.height * 2; + if (FAILED(hr = IMFMediaType_SetUINT64(decoder->stream_type, &MF_MT_FRAME_SIZE, frame_size))) + WARN("Failed to update stream type frame size, hr %#lx\n", hr); + decoder->output_info.cbSize = (frame_size >> 32) * (UINT32)frame_size * 2; }
return S_OK; @@ -494,8 +488,8 @@ static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFM static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) { struct h264_decoder *decoder = impl_from_IMFTransform(iface); + UINT64 frame_size, stream_frame_size; GUID major, subtype; - UINT64 frame_size; HRESULT hr; ULONG i;
@@ -517,9 +511,10 @@ static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMF if (i == ARRAY_SIZE(h264_decoder_output_types)) return MF_E_INVALIDMEDIATYPE;
- if (FAILED(hr = IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size)) - || (frame_size >> 32) != decoder->wg_format.u.video.width - || (UINT32)frame_size != decoder->wg_format.u.video.height) + if (FAILED(hr = IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size))) + return MF_E_INVALIDMEDIATYPE; + if (SUCCEEDED(IMFMediaType_GetUINT64(decoder->stream_type, &MF_MT_FRAME_SIZE, &stream_frame_size)) + && frame_size != stream_frame_size) return MF_E_INVALIDMEDIATYPE; if (flags & MFT_SET_TYPE_TEST_ONLY) return S_OK; @@ -677,6 +672,28 @@ static HRESULT output_sample(struct h264_decoder *decoder, IMFSample **out, IMFS return S_OK; }
+static HRESULT handle_stream_type_change(struct h264_decoder *decoder, const struct wg_format *format) +{ + UINT64 frame_size, frame_rate; + HRESULT hr; + + if (decoder->stream_type) + IMFMediaType_Release(decoder->stream_type); + if (!(decoder->stream_type = mf_media_type_from_wg_format(format))) + return E_OUTOFMEMORY; + + if (SUCCEEDED(IMFMediaType_GetUINT64(decoder->output_type, &MF_MT_FRAME_RATE, &frame_rate)) + && FAILED(hr = IMFMediaType_SetUINT64(decoder->stream_type, &MF_MT_FRAME_RATE, frame_rate))) + WARN("Failed to update stream type frame size, hr %#lx\n", hr); + + if (FAILED(hr = IMFMediaType_GetUINT64(decoder->stream_type, &MF_MT_FRAME_SIZE, &frame_size))) + return hr; + decoder->output_info.cbSize = (frame_size >> 32) * (UINT32)frame_size * 2; + uninit_allocator(decoder); + + return MF_E_TRANSFORM_STREAM_CHANGE; +} + static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count, MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status) { @@ -684,7 +701,7 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags, struct wg_format wg_format; UINT32 sample_size; IMFSample *sample; - UINT64 frame_rate; + UINT64 frame_size; GUID subtype; DWORD size; HRESULT hr; @@ -703,8 +720,9 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags,
if (FAILED(hr = IMFMediaType_GetGUID(decoder->output_type, &MF_MT_SUBTYPE, &subtype))) return hr; - if (FAILED(hr = MFCalculateImageSize(&subtype, decoder->wg_format.u.video.width, - decoder->wg_format.u.video.height, &sample_size))) + if (FAILED(hr = IMFMediaType_GetUINT64(decoder->output_type, &MF_MT_FRAME_SIZE, &frame_size))) + return hr; + if (FAILED(hr = MFCalculateImageSize(&subtype, frame_size >> 32, (UINT32)frame_size, &sample_size))) return hr;
if (decoder->output_info.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES) @@ -734,21 +752,9 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags,
if (hr == MF_E_TRANSFORM_STREAM_CHANGE) { - decoder->wg_format = wg_format; - decoder->output_info.cbSize = ALIGN_SIZE(decoder->wg_format.u.video.width, 0xf) - * ALIGN_SIZE(decoder->wg_format.u.video.height, 0xf) * 2; - - /* keep the frame rate that was requested, GStreamer doesn't provide any */ - if (SUCCEEDED(IMFMediaType_GetUINT64(decoder->output_type, &MF_MT_FRAME_RATE, &frame_rate))) - { - decoder->wg_format.u.video.fps_n = frame_rate >> 32; - decoder->wg_format.u.video.fps_d = (UINT32)frame_rate; - } - samples[0].dwStatus |= MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE; *status |= MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE; - - uninit_allocator(decoder); + hr = handle_stream_type_change(decoder, &wg_format); }
if (decoder->output_info.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES) @@ -822,11 +828,6 @@ HRESULT h264_decoder_create(REFIID riid, void **ret)
decoder->IMFTransform_iface.lpVtbl = &transform_vtbl; decoder->refcount = 1; - decoder->wg_format.u.video.format = WG_VIDEO_FORMAT_UNKNOWN; - decoder->wg_format.u.video.width = 1920; - decoder->wg_format.u.video.height = 1080; - decoder->wg_format.u.video.fps_n = 30000; - decoder->wg_format.u.video.fps_d = 1001;
decoder->input_info.dwFlags = MFT_INPUT_STREAM_WHOLE_SAMPLES | MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER | MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE; @@ -835,6 +836,8 @@ HRESULT h264_decoder_create(REFIID riid, void **ret) | MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE; decoder->output_info.cbSize = 1920 * 1088 * 2;
+ if (FAILED(hr = MFCreateMediaType(&decoder->stream_type))) + goto failed; if (FAILED(hr = MFCreateAttributes(&decoder->attributes, 16))) goto failed; if (FAILED(hr = IMFAttributes_SetUINT32(decoder->attributes, &MF_LOW_LATENCY, 0))) @@ -863,6 +866,8 @@ failed: IMFAttributes_Release(decoder->output_attributes); if (decoder->attributes) IMFAttributes_Release(decoder->attributes); + if (decoder->stream_type) + IMFMediaType_Release(decoder->stream_type); free(decoder); return hr; }
From: Rémi Bernon rbernon@codeweavers.com
And remove h264parse element requirement. --- dlls/mf/tests/mf_test.h | 1 - dlls/mf/tests/transform.c | 20 +++----------------- dlls/winegstreamer/h264_decoder.c | 16 +++++++++++++++- dlls/winegstreamer/wg_transform.c | 3 --- 4 files changed, 18 insertions(+), 22 deletions(-)
diff --git a/dlls/mf/tests/mf_test.h b/dlls/mf/tests/mf_test.h index 05aa34e3d28..e48204224b4 100644 --- a/dlls/mf/tests/mf_test.h +++ b/dlls/mf/tests/mf_test.h @@ -95,7 +95,6 @@ struct sample_desc DWORD repeat_count; BOOL todo_length; BOOL todo_duration; - LONGLONG todo_time; };
#define check_mf_sample_collection(a, b, c) check_mf_sample_collection_(__FILE__, __LINE__, a, b, c) diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 04c59bbdffc..c7b001bfb11 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -1205,7 +1205,6 @@ 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 || expect->todo_time == -1)) ok_(file, line)(llabs(timestamp - expect->sample_time) <= 50, "got sample time %I64d\n", timestamp);
@@ -3711,7 +3710,7 @@ static void test_h264_decoder(void) const struct sample_desc expect_output_sample_i420 = { .attributes = output_sample_attributes, - .sample_time = 333667, .sample_duration = 333667, .todo_time = 1334666 /* with VA-API */, + .sample_time = 333667, .sample_duration = 333667, .buffer_count = 1, .buffers = &output_buffer_desc_i420, };
@@ -4037,26 +4036,13 @@ static void test_h264_decoder_concat_streams(void) { .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, + .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 + 2, .repeat_count = 29, - .todo_time = -1, .todo_duration = 333666, .todo_length = TRUE, + .todo_length = TRUE, }, { .attributes = output_sample_attributes + 0, diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c index 8eeeb52fd60..97289f69a4d 100644 --- a/dlls/winegstreamer/h264_decoder.c +++ b/dlls/winegstreamer/h264_decoder.c @@ -53,6 +53,7 @@ struct h264_decoder IMFAttributes *attributes; IMFAttributes *output_attributes;
+ UINT64 sample_time; IMFMediaType *input_type; MFT_INPUT_STREAM_INFO input_info; IMFMediaType *output_type; @@ -700,8 +701,9 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags, struct h264_decoder *decoder = impl_from_IMFTransform(iface); struct wg_format wg_format; UINT32 sample_size; + LONGLONG duration; IMFSample *sample; - UINT64 frame_size; + UINT64 frame_size, frame_rate; GUID subtype; DWORD size; HRESULT hr; @@ -748,8 +750,20 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags,
if (SUCCEEDED(hr = wg_transform_read_mf(decoder->wg_transform, sample, sample_size, &wg_format, &samples->dwStatus))) + { wg_sample_queue_flush(decoder->wg_sample_queue, false);
+ if (FAILED(IMFMediaType_GetUINT64(decoder->input_type, &MF_MT_FRAME_RATE, &frame_rate))) + frame_rate = (UINT64)30000 << 32 | 1001; + + duration = (UINT64)10000000 * (UINT32)frame_rate / (frame_rate >> 32); + if (FAILED(IMFSample_SetSampleTime(sample, decoder->sample_time))) + WARN("Failed to set sample time\n"); + if (FAILED(IMFSample_SetSampleDuration(sample, duration))) + WARN("Failed to set sample duration\n"); + decoder->sample_time += duration; + } + if (hr == MF_E_TRANSFORM_STREAM_CHANGE) { samples[0].dwStatus |= MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE; diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c index f75d1b4b6df..15db8bbf6a2 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -342,9 +342,6 @@ NTSTATUS wg_transform_create(void *args) */ transform->input_max_length = 16; transform->output_plane_align = 15; - if (!(element = create_element("h264parse", "base")) - || !append_element(transform->container, element, &first, &last)) - goto out; /* fallthrough */ case WG_MAJOR_TYPE_AUDIO_MPEG1: case WG_MAJOR_TYPE_AUDIO_MPEG4:
From: Rémi Bernon rbernon@codeweavers.com
Instead of constraining the output caps to the current resolution, which breaks when streams with different resolutions are concatenated. --- dlls/mf/tests/mf_test.h | 1 + dlls/mf/tests/transform.c | 15 ++++++++++++--- dlls/winegstreamer/wg_transform.c | 6 +++++- 3 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/dlls/mf/tests/mf_test.h b/dlls/mf/tests/mf_test.h index e48204224b4..47b05e14777 100644 --- a/dlls/mf/tests/mf_test.h +++ b/dlls/mf/tests/mf_test.h @@ -95,6 +95,7 @@ struct sample_desc DWORD repeat_count; BOOL todo_length; BOOL todo_duration; + BOOL todo_time; };
#define check_mf_sample_collection(a, b, c) check_mf_sample_collection_(__FILE__, __LINE__, a, b, c) diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index c7b001bfb11..85102bee70d 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -1205,6 +1205,7 @@ 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) ok_(file, line)(llabs(timestamp - expect->sample_time) <= 50, "got sample time %I64d\n", timestamp);
@@ -4024,7 +4025,7 @@ static void test_h264_decoder_concat_streams(void) { {.length = 0x3600}, {.length = 0x4980}, - {.length = 0x4980, .todo_length = TRUE}, + {.length = 0, .todo_length = TRUE}, }; const struct attribute_desc output_sample_attributes[] = { @@ -4041,18 +4042,26 @@ static void test_h264_decoder_concat_streams(void) { .attributes = output_sample_attributes + 0, .sample_time = 12000000, .sample_duration = 400000, - .buffer_count = 1, .buffers = output_buffer_desc + 2, .repeat_count = 29, - .todo_length = TRUE, + .buffer_count = 1, .buffers = output_buffer_desc + 1, .repeat_count = 29, }, { .attributes = output_sample_attributes + 0, .sample_time = 0, .sample_duration = 400000, .buffer_count = 1, .buffers = output_buffer_desc + 0, .repeat_count = 29, + .todo_time = TRUE, }, { .attributes = output_sample_attributes + 0, .sample_time = 12000000, .sample_duration = 400000, .buffer_count = 1, .buffers = output_buffer_desc + 1, .repeat_count = 6, + .todo_time = TRUE, + }, + { + /* Wine outputs spurious buffers */ + .attributes = output_sample_attributes + 0, + .sample_time = 0, .sample_duration = 400000, + .buffer_count = 1, .buffers = output_buffer_desc + 2, .repeat_count = 22, + .todo_time = TRUE, .todo_length = TRUE, }, {0}, }; diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c index 15db8bbf6a2..25ef7d35118 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -56,6 +56,7 @@ struct wg_transform GstElement *video_flip;
guint output_plane_align; + struct wg_format output_format; struct wg_sample *output_wg_sample; GstAtomicQueue *output_queue; GstSample *output_sample; @@ -174,7 +175,8 @@ static gboolean transform_sink_query_cb(GstPad *pad, GstObject *parent, GstQuery gchar *str;
gst_query_parse_caps(query, &filter); - caps = gst_caps_ref(transform->output_caps); + if (!(caps = wg_format_to_caps(&transform->output_format))) + break;
if (filter) { @@ -300,6 +302,7 @@ NTSTATUS wg_transform_create(void *args) goto out; transform->input_max_length = 1; transform->output_plane_align = 0; + transform->output_format = output_format;
if (!(src_caps = wg_format_to_caps(&input_format))) goto out; @@ -493,6 +496,7 @@ NTSTATUS wg_transform_set_output_format(void *args) GST_ERROR("Failed to convert format %p to caps.", format); return STATUS_UNSUCCESSFUL; } + transform->output_format = *format;
if (gst_caps_is_always_compatible(transform->output_caps, caps)) {
From: Paul Gofman pgofman@codeweavers.com
--- dlls/mf/tests/transform.c | 1 - dlls/winegstreamer/wg_sample.c | 5 ---- dlls/winegstreamer/wg_transform.c | 38 +++++++++++++++++-------------- 3 files changed, 21 insertions(+), 23 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 85102bee70d..8d01a7480a2 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -4133,7 +4133,6 @@ static void test_h264_decoder_concat_streams(void) { 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; diff --git a/dlls/winegstreamer/wg_sample.c b/dlls/winegstreamer/wg_sample.c index ea83440d9ad..c7d79b5b575 100644 --- a/dlls/winegstreamer/wg_sample.c +++ b/dlls/winegstreamer/wg_sample.c @@ -358,11 +358,6 @@ HRESULT wg_transform_read_mf(struct wg_transform *transform, IMFSample *sample, return hr;
wg_sample->size = 0; - if (wg_sample->max_size < sample_size) - { - wg_sample_release(wg_sample); - return MF_E_BUFFERTOOSMALL; - }
if (FAILED(hr = wg_transform_read_data(transform, wg_sample, format))) { diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c index 25ef7d35118..3a3ba35eaf9 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -594,19 +594,19 @@ NTSTATUS wg_transform_push_data(void *args) return STATUS_SUCCESS; }
-static bool copy_video_buffer(GstBuffer *buffer, GstCaps *caps, gsize plane_align, +static NTSTATUS copy_video_buffer(GstBuffer *buffer, GstCaps *caps, gsize plane_align, struct wg_sample *sample, gsize *total_size) { + NTSTATUS status = STATUS_UNSUCCESSFUL; GstVideoFrame src_frame, dst_frame; GstVideoInfo src_info, dst_info; GstVideoAlignment align; GstBuffer *dst_buffer; - bool ret = false;
if (!gst_video_info_from_caps(&src_info, caps)) { GST_ERROR("Failed to get video info from caps."); - return false; + return STATUS_UNSUCCESSFUL; }
dst_info = src_info; @@ -615,14 +615,14 @@ static bool copy_video_buffer(GstBuffer *buffer, GstCaps *caps, gsize plane_alig if (sample->max_size < dst_info.size) { GST_ERROR("Output buffer is too small."); - return false; + return STATUS_BUFFER_TOO_SMALL; }
if (!(dst_buffer = gst_buffer_new_wrapped_full(0, sample->data, sample->max_size, 0, sample->max_size, 0, NULL))) { GST_ERROR("Failed to wrap wg_sample into GstBuffer"); - return false; + return STATUS_UNSUCCESSFUL; } gst_buffer_set_size(dst_buffer, dst_info.size); *total_size = sample->size = dst_info.size; @@ -635,7 +635,9 @@ static bool copy_video_buffer(GstBuffer *buffer, GstCaps *caps, gsize plane_alig GST_ERROR("Failed to map destination frame."); else { - if (!(ret = gst_video_frame_copy(&dst_frame, &src_frame))) + if (gst_video_frame_copy(&dst_frame, &src_frame)) + status = STATUS_SUCCESS; + else GST_ERROR("Failed to copy video frame."); gst_video_frame_unmap(&dst_frame); } @@ -643,16 +645,16 @@ static bool copy_video_buffer(GstBuffer *buffer, GstCaps *caps, gsize plane_alig }
gst_buffer_unref(dst_buffer); - return ret; + return status; }
-static bool copy_buffer(GstBuffer *buffer, GstCaps *caps, struct wg_sample *sample, +static NTSTATUS copy_buffer(GstBuffer *buffer, GstCaps *caps, struct wg_sample *sample, gsize *total_size) { GstMapInfo info;
if (!gst_buffer_map(buffer, &info, GST_MAP_READ)) - return false; + return STATUS_UNSUCCESSFUL;
if (sample->max_size >= info.size) sample->size = info.size; @@ -669,14 +671,15 @@ static bool copy_buffer(GstBuffer *buffer, GstCaps *caps, struct wg_sample *samp gst_buffer_resize(buffer, sample->size, -1);
*total_size = info.size; - return true; + return STATUS_SUCCESS; }
static NTSTATUS read_transform_output_data(GstBuffer *buffer, GstCaps *caps, gsize plane_align, struct wg_sample *sample) { - bool ret, needs_copy; gsize total_size; + bool needs_copy; + NTSTATUS status; GstMapInfo info;
if (!gst_buffer_map(buffer, &info, GST_MAP_READ)) @@ -686,20 +689,21 @@ static NTSTATUS read_transform_output_data(GstBuffer *buffer, GstCaps *caps, gsi return STATUS_UNSUCCESSFUL; } needs_copy = info.data != sample->data; + total_size = sample->size = info.size; gst_buffer_unmap(buffer, &info);
- if ((ret = !needs_copy)) - total_size = sample->size = info.size; + if (!needs_copy) + status = STATUS_SUCCESS; else if (stream_type_from_caps(caps) == GST_STREAM_TYPE_VIDEO) - ret = copy_video_buffer(buffer, caps, plane_align, sample, &total_size); + status = copy_video_buffer(buffer, caps, plane_align, sample, &total_size); else - ret = copy_buffer(buffer, caps, sample, &total_size); + status = copy_buffer(buffer, caps, sample, &total_size);
- if (!ret) + if (status) { GST_ERROR("Failed to copy buffer %p", buffer); sample->size = 0; - return STATUS_UNSUCCESSFUL; + return status; }
if (GST_BUFFER_PTS_IS_VALID(buffer))
Split from https://gitlab.winehq.org/wine/wine/-/merge_requests/2893, with more tests and fixes from @gofman.
This merge request was approved by Rémi Bernon.
I modified the commit slightly compared to what's in Proton, mainly to remove the E_FAIL status in favor of just returning STATUS_BUFFER_TOO_SMALL, I assumed that the exact error code didn't matter.