From: Rémi Bernon rbernon@codeweavers.com
Allowing easier preview of NV12 / I420 images as well. --- dlls/mf/tests/i420frame.bmp | Bin 13824 -> 50742 bytes dlls/mf/tests/nv12frame-grabber.bmp | Bin 0 -> 22582 bytes dlls/mf/tests/nv12frame.bmp | Bin 13824 -> 50742 bytes dlls/mf/tests/rgb32frame-grabber.bmp | Bin 0 -> 16438 bytes dlls/mf/tests/rgb32frame-vp.bmp | Bin 36864 -> 36918 bytes dlls/mf/tests/rgb32frame.bmp | Bin 36864 -> 36918 bytes dlls/mf/tests/transform.c | 141 +++++++++++++++++++++++---- 7 files changed, 122 insertions(+), 19 deletions(-) create mode 100644 dlls/mf/tests/nv12frame-grabber.bmp create mode 100644 dlls/mf/tests/rgb32frame-grabber.bmp
diff --git a/dlls/mf/tests/i420frame.bmp b/dlls/mf/tests/i420frame.bmp index 58cefb87913d03728d293154aaa5fc82ce0fb64c..d56f2c502b5cbbcc8e683947b8dc75ebf9b7072c 100644 GIT binary patch literal 50742 zcmeI!p{>GD7>41F&=Cj<7U%$Y1hxu|V1|wW41wq<l?>1YFx}wL0Qxr-CmfzH`5SJU zYu-HJ-rc^rRPQzOb2H!ZdsVfXKh68T|NQWIKD#bC4H#g60R|XgfB^;=V1NMz7+`>b zat%D{TXGsOzyJdbFu(u<3^2d|0}L?000ZS3=<juM8Zf{B0}L?000Rs#zyJdbFu(u< z<r=s)>*O?GfB^;=V1NMz7+`<_1{h#~0S3x7a2m$sG+=-M1{h#~0R|XgfB^;=V1NMz z$~ACkr{pwXfB^;=V1NMz7+`<_1{h#~0S3x7u$|7yX}|yj3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu=fX8hDxl3Mi1Nz{3<!K!HpJdQ(6F1u_-5ngR+a zkg34Q6i`5cOa%_6fC36+DzG&L6i`3`1r$)=&kA%F7N{*OaJR5PV_|{8!UC;@1twEq lL4oj(zn9(3!UEwxM_$%z3k!@E7Fh7r{ujS`HU$<GcmWa@Bi#T1
literal 13824 zcmeH}u?>Sz3`AF82D&W39<+>*f*Du=hM-^+q%;{I3;c!=(zr1ar$e%SVeT4)e7g9a zEQL~{^>K<$FU7@wlz%25K4&8SU3@%`^IKg$-*EZ;!{fio$4tdXd@un#t$ROPxcvU% z@tg87Q}GcWOaM>o-p?E^zkhiAtbEK=e8dM6z|*?-^A4BaKRo`ee9TmQ#0L|=)4KQ5 zhs*CD9^We;GZi24!36NM?)|*N<@XPde<>d`6(8}z1n{)({rF$gn+S-22-G7mv9gs| z`;^4ru(H0ay-DI<Sy^A!z9#W^tgJ6<?~?d;R@Rrb?@9avE9=YJha~=kmGx!qM-so) z(Bp!@)4pf!_FY&RU)H`P@jvZ*?{43gmE8ktZ<F|ctgJ6<|0VH1?f?32-;tHw18X0X K_^pN>7X<!9H+|Ir
diff --git a/dlls/mf/tests/nv12frame-grabber.bmp b/dlls/mf/tests/nv12frame-grabber.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2acd5d9992330c5b71afd7ffb5d34a3770eb1dee GIT binary patch literal 22582 zcmeIwp%H^n5QJe$z~VBf(7@A76ea>o2?%PyBB2Nbr64H)i@?yq<qZ=PeIjE2z1cTd zcD~m;l*yeC-)C(3ZIV3VS4?@oKhN3sM%e%Z7{CAqFd$~28tfGA7XMwk>0}#a0}NmQ z0~o-7l!0YVjj{m-Fn|FJU_i`3m)RoRG5))BLvABw0}NmQ0~o-7l!12Ljj{m-Fn|FJ zU_i{kbXY6gI{v$Ko6Bm-1{lBq1~7mDDFemT8D#?uU;qOczyJm?pkv@9EZ|sRBP`%p zU?D8vSYRY9;8>s~EZ|t6CM@7spdc*p#|3)vRD<u*N&Dth`?}0`A=kcj*S_iSU2|#Q I)p4E$KCEGdKL7v#
literal 0 HcmV?d00001
diff --git a/dlls/mf/tests/nv12frame.bmp b/dlls/mf/tests/nv12frame.bmp index d6640023fb9f7382de5251b39eb54cf693a1dad8..dadece8b145379a2a6fbdd990809524c357d9f00 100644 GIT binary patch literal 50742 zcmeI5v5g`@5Jd@LLO5X^2}}UzpMi^YHU=>e!a@)jgo1=a03?7j8O+VxuCa|#(*6Ew zX-cnKjcB#%Q}y=w`|EfAvHG|A>GS7w{(PO)>c{kLT3_#<m(S1F@i=no8QkypQ8}=$ zXFoGk*v~cahkphK@ZaOH>H_@Xuey_=4*&5#gU9L&_>cdpI~nTmf0_P2y7S1XXQ28I z`+D{>L->0*sy@OW{;E3}>hK@`GkC1dfdBZfx|5*}|M5SA$Lb9DzfAwHmu}?LGf@49 zeLee`A^bfYRUhFGf7P7~b@-3}89Y{Jz<>N#-N{gg|M;K5V|51nU#9=3em!#P8L0ll zzMlQe5dI#Hs*mu8zv@ngI{e4~3?8d9;6MJW?qsOLfBetju{s0(FVp}1?KyJl8L0ll zzMlQe5dI#Hs*mu8zv@ngI{e4~3?8d9;6MJW?qsOLfBetju{s0(FVp|+ZWuZB3{?MN zU(bGK2!9Vp)kpZlUv(!#9sc8g29MPl@E`wGcQVxBKmKR%Se*g?m+AjzIE<Wn2CDzC zuV+6qgujQQ>LdK&uey_=4*&5#gU9L&_>cdpI~nTmAOACWtj>V{%k*FUyHTh8zjwI7 z4F_-l2XFufZ~zBz00(dY2XFufaG<pVFZ-G%__plvuW#YgSMuKpz~`Mvd52HQ<Nel_ z&%?gT{_XJ(@?)m(flo{zer@Z|)xOI9?eSOgW2W$dPfQ?wZR^j;zRLdX@h9?QrtpDJ zOdx)3>(Ac4%Kq)~d-7wZ@PSWEAbxG@&(^-m{_XKw@?)m(flo{zer@Z|#=gq_?eQD( zW2W$dPfQ?wZR=0@Yuq3J0SL4saI~+ocYFMi{FrH5KHb^9%l_Tz-I@HDX<I&*&b`b2 z-RYN({FrH5KK<Ig%l_Tz{hIukX<I(Gr+b(EyVGw^@?)lL`RoSwF8g<<?*{T?rfvBQ Z2lp=fcc%{r@?)lL`INuL4Fdm1;4i8^`3(R7
delta 18 acmdni!`zTF*<pgm<bVlWn>!|~GX(%k@CXP1
diff --git a/dlls/mf/tests/rgb32frame-grabber.bmp b/dlls/mf/tests/rgb32frame-grabber.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b5a5960b96481bd01a5cc1a1fe9358127ca370bb GIT binary patch literal 16438 zcmeI&JxW7C6o%n9h=OPq5K*x35A0LNprtlhf-6X$CL72CbO&~pqN~s*DT8qVYDCc7 zJ03zB*YKW!XSnS-=NlL<)4gnWSgv;LC!w<f`|%a4v)un}bzPIP2bqD)KxV*~ftOM+ zn@0U+w^6@Y@9P7zi|;vRlnS$Ey}-;o`>eg<u*}r#8F(rK%(|~b%;Nfs+2pr{nR)hE zJG_^Mnmq##WfQZzvW408Cz$QV?+>%nA21{CzbSi=8E|Hxf8WRK`0WU@@y-OZ(bWjE zikg%?$P73$@Vrqlo36$CAF-Qe!K_ET{}DT9ju~<LG23Q=nR)hEd&R-}OwFEw$Grh& dXACi`8(=o3g_(KwS-bn}=lpa2nE`hO{s5dR2pIqX
literal 0 HcmV?d00001
diff --git a/dlls/mf/tests/rgb32frame-vp.bmp b/dlls/mf/tests/rgb32frame-vp.bmp index 46d93a9c40b5d875c821580dd1db984d3b97217a..3361ed3f4a0a6d5df0d345b02afc327e2ca1ba49 100644 GIT binary patch delta 70 xcmZozz_e`vlbMsR*#rhKFawerK%4-@3=9fD77#$?Ash&~k@3Ia=Kq3>bpT{%3D^Jt
delta 17 ZcmdnCfT>{t(?*AHf)fL{7Mlsx0RTdu2FCyZ
diff --git a/dlls/mf/tests/rgb32frame.bmp b/dlls/mf/tests/rgb32frame.bmp index 3ad7556ef7886011bce680f90127f150b081502d..0e50c30b8d02f3b6f226b21a1b51423c7115c980 100644 GIT binary patch delta 63 qcmZozz_e`vlbMsR*#rhKFawerK%4-@3=9fD77#$?Ash&~U;+Rqod*N}
delta 18 acmdnCfT>{t(?&Z7#)*C$o9h^N^Z@`v$p;Dm
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 30a39c6667f..2f1e7c60cc6 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -375,12 +375,16 @@ static HRESULT check_mft_process_output_(int line, IMFTransform *transform, IMFS return ret; }
-typedef DWORD (*compare_cb)(const BYTE *data, DWORD length, const RECT *rect, const BYTE *expect); +typedef DWORD (*compare_cb)(const BYTE *data, DWORD *length, const RECT *rect, const BYTE *expect);
-static DWORD compare_nv12(const BYTE *data, DWORD length, const RECT *rect, const BYTE *expect) +static DWORD compare_nv12(const BYTE *data, DWORD *length, const RECT *rect, const BYTE *expect) { DWORD x, y, size, diff = 0, width = (rect->right + 0xf) & ~0xf, height = (rect->bottom + 0xf) & ~0xf;
+ /* skip BMP header and RGB data from the dump */ + expect = expect + *(DWORD *)(expect + 2); + *length = *length + *(DWORD *)(expect + 2); + for (y = 0; y < height; y++, data += width, expect += width) { if (y < rect->top || y >= rect->bottom) continue; @@ -406,10 +410,14 @@ static DWORD compare_nv12(const BYTE *data, DWORD length, const RECT *rect, cons return diff * 100 / 256 / size; }
-static DWORD compare_i420(const BYTE *data, DWORD length, const RECT *rect, const BYTE *expect) +static DWORD compare_i420(const BYTE *data, DWORD *length, const RECT *rect, const BYTE *expect) { DWORD i, x, y, size, diff = 0, width = (rect->right + 0xf) & ~0xf, height = (rect->bottom + 0xf) & ~0xf;
+ /* skip BMP header and RGB data from the dump */ + expect = expect + *(DWORD *)(expect + 2); + *length = *length + *(DWORD *)(expect + 2); + for (y = 0; y < height; y++, data += width, expect += width) { if (y < rect->top || y >= rect->bottom) continue; @@ -434,10 +442,14 @@ static DWORD compare_i420(const BYTE *data, DWORD length, const RECT *rect, cons return diff * 100 / 256 / size; }
-static DWORD compare_rgb32(const BYTE *data, DWORD length, const RECT *rect, const BYTE *expect) +static DWORD compare_rgb32(const BYTE *data, DWORD *length, const RECT *rect, const BYTE *expect) { DWORD x, y, size, diff = 0, width = (rect->right + 0xf) & ~0xf, height = (rect->bottom + 0xf) & ~0xf;
+ /* skip BMP header from the dump */ + expect = expect + *(DWORD *)(expect + 2 + 2 * sizeof(DWORD)); + *length = *length + *(DWORD *)(expect + 2 + 2 * sizeof(DWORD)); + for (y = 0; y < height; y++, data += width * 4, expect += width * 4) { if (y < rect->top || y >= rect->bottom) continue; @@ -454,10 +466,10 @@ static DWORD compare_rgb32(const BYTE *data, DWORD length, const RECT *rect, con return diff * 100 / 256 / size; }
-static DWORD compare_pcm16(const BYTE *data, DWORD length, const RECT *rect, const BYTE *expect) +static DWORD compare_pcm16(const BYTE *data, DWORD *length, const RECT *rect, const BYTE *expect) { const INT16 *data_pcm = (INT16 *)data, *expect_pcm = (INT16 *)expect; - DWORD i, size = length / 2, diff = 0; + DWORD i, size = *length / 2, diff = 0;
for (i = 0; i < size; i++) diff += abs((int)*expect_pcm++ - (int)*data_pcm++); @@ -465,14 +477,93 @@ static DWORD compare_pcm16(const BYTE *data, DWORD length, const RECT *rect, con return diff * 100 / 65536 / size; }
-static DWORD compare_bytes(const BYTE *data, DWORD length, const RECT *rect, const BYTE *expect) +static DWORD compare_bytes(const BYTE *data, DWORD *length, const RECT *rect, const BYTE *expect) { - DWORD i, diff = 0; + DWORD i, size = *length, diff = 0;
- for (i = 0; i < length; i++) + for (i = 0; i < size; i++) diff += abs((int)*expect++ - (int)*data++);
- return diff * 100 / 256 / length; + return diff * 100 / 256 / size; +} + +typedef void (*dump_cb)(const BYTE *data, DWORD length, const RECT *rect, HANDLE output); + +static void dump_rgb32(const BYTE *data, DWORD length, const RECT *rect, HANDLE output) +{ + DWORD width = (rect->right + 0xf) & ~0xf, height = (rect->bottom + 0xf) & ~0xf; + static const char magic[2] = "BM"; + struct + { + DWORD length; + DWORD reserved; + DWORD offset; + BITMAPINFOHEADER biHeader; + } header = + { + .length = length + sizeof(header) + 2, .offset = sizeof(header) + 2, + .biHeader = + { + .biSize = sizeof(BITMAPINFOHEADER), .biWidth = width, .biHeight = height, + .biBitCount = 32, .biCompression = BI_RGB, .biSizeImage = width * height * 4, + }, + }; + DWORD written; + BOOL ret; + + ret = WriteFile(output, magic, sizeof(magic), &written, NULL); + ok(ret, "WriteFile failed, error %lu\n", GetLastError()); + ok(written == sizeof(magic), "written %lu bytes\n", written); + ret = WriteFile(output, &header, sizeof(header), &written, NULL); + ok(ret, "WriteFile failed, error %lu\n", GetLastError()); + ok(written == sizeof(header), "written %lu bytes\n", written); + ret = WriteFile(output, data, length, &written, NULL); + ok(ret, "WriteFile failed, error %lu\n", GetLastError()); + ok(written == length, "written %lu bytes\n", written); +} + +static void dump_nv12(const BYTE *data, DWORD length, const RECT *rect, HANDLE output) +{ + DWORD written, x, y, width = (rect->right + 0xf) & ~0xf, height = (rect->bottom + 0xf) & ~0xf; + BYTE *rgb32_data = malloc(width * height * 4), *rgb32 = rgb32_data; + BOOL ret; + + for (y = 0; y < height; y++) for (x = 0; x < width; x++) + { + *rgb32++ = data[width * y + x]; + *rgb32++ = data[width * height + width * (y / 2) + (x & ~1) + 0]; + *rgb32++ = data[width * height + width * (y / 2) + (x & ~1) + 1]; + *rgb32++ = 0xff; + } + + dump_rgb32(rgb32_data, width * height * 4, rect, output); + free(rgb32_data); + + ret = WriteFile(output, data, length, &written, NULL); + ok(ret, "WriteFile failed, error %lu\n", GetLastError()); + ok(written == length, "written %lu bytes\n", written); +} + +static void dump_i420(const BYTE *data, DWORD length, const RECT *rect, HANDLE output) +{ + DWORD written, x, y, width = (rect->right + 0xf) & ~0xf, height = (rect->bottom + 0xf) & ~0xf; + BYTE *rgb32_data = malloc(width * height * 4), *rgb32 = rgb32_data; + BOOL ret; + + for (y = 0; y < height; y++) for (x = 0; x < width; x++) + { + *rgb32++ = data[width * y + x]; + *rgb32++ = data[width * height + (width / 2) * (y / 2) + x / 2]; + *rgb32++ = data[width * height + (width / 2) * (y / 2) + (width / 2) * (height / 2) + x / 2]; + *rgb32++ = 0xff; + } + + dump_rgb32(rgb32_data, width * height * 4, rect, output); + free(rgb32_data); + + ret = WriteFile(output, data, length, &written, NULL); + ok(ret, "WriteFile failed, error %lu\n", GetLastError()); + ok(written == length, "written %lu bytes\n", written); }
struct buffer_desc @@ -480,6 +571,7 @@ struct buffer_desc DWORD length; BOOL todo_length; compare_cb compare; + dump_cb dump; RECT rect; };
@@ -558,9 +650,14 @@ static void dump_mf_media_buffer(IMFMediaBuffer *buffer, const struct buffer_des hr = IMFMediaBuffer_Lock(buffer, &data, NULL, &length); ok(hr == S_OK, "Lock returned %#lx\n", hr);
- ret = WriteFile(output, data, length, &written, NULL); - ok(ret, "WriteFile failed, error %lu\n", GetLastError()); - ok(written == length, "written %lu bytes\n", written); + if (buffer_desc->dump) + buffer_desc->dump(data, length, &buffer_desc->rect, output); + else + { + ret = WriteFile(output, data, length, &written, NULL); + ok(ret, "WriteFile failed, error %lu\n", GetLastError()); + ok(written == length, "written %lu bytes\n", written); + }
hr = IMFMediaBuffer_Unlock(buffer); ok(hr == S_OK, "Unlock returned %#lx\n", hr); @@ -606,9 +703,9 @@ static DWORD check_mf_media_buffer_(int line, IMFMediaBuffer *buffer, const stru 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); + diff = compare_bytes(data, &length, NULL, *expect_data); else - diff = expect->compare(data, length, &expect->rect, *expect_data); + diff = expect->compare(data, &length, &expect->rect, *expect_data);
hr = IMFMediaBuffer_Unlock(buffer); ok_(__FILE__, line)(hr == S_OK, "Unlock returned %#lx\n", hr); @@ -2538,7 +2635,7 @@ static void test_h264_decoder(void) const struct buffer_desc output_buffer_desc_nv12 = { .length = actual_width * actual_height * 3 / 2, - .compare = compare_nv12, .rect = {.right = 82, .bottom = 84}, + .compare = compare_nv12, .dump = dump_nv12, .rect = {.right = 82, .bottom = 84}, }; const struct sample_desc output_sample_desc_nv12 = { @@ -2549,7 +2646,7 @@ static void test_h264_decoder(void) const struct buffer_desc output_buffer_desc_i420 = { .length = actual_width * actual_height * 3 / 2, - .compare = compare_i420, .rect = {.right = 82, .bottom = 84}, + .compare = compare_i420, .dump = dump_i420, .rect = {.right = 82, .bottom = 84}, }; const struct sample_desc expect_output_sample_i420 = { @@ -3427,7 +3524,7 @@ static void test_color_convert(void) const struct buffer_desc output_buffer_desc = { .length = actual_width * actual_height * 4, - .compare = compare_rgb32, .rect = {.right = 82, .bottom = 84}, + .compare = compare_rgb32, .dump = dump_rgb32, .rect = {.right = 82, .bottom = 84}, }; const struct attribute_desc output_sample_attributes[] = { @@ -3556,6 +3653,9 @@ static void test_color_convert(void) ok(output_info.cbAlignment == 1, "got cbAlignment %#lx\n", output_info.cbAlignment);
load_resource(L"nv12frame.bmp", &nv12frame_data, &nv12frame_data_len); + /* skip BMP header and RGB data from the dump */ + nv12frame_data_len = nv12frame_data_len - *(DWORD *)(nv12frame_data + 2); + nv12frame_data = nv12frame_data + *(DWORD *)(nv12frame_data + 2); ok(nv12frame_data_len == 13824, "got length %lu\n", nv12frame_data_len);
input_sample = create_sample(nv12frame_data, nv12frame_data_len); @@ -3770,7 +3870,7 @@ static void test_video_processor(void) const struct buffer_desc output_buffer_desc = { .length = actual_width * actual_height * 4, - .compare = compare_rgb32, .rect = {.top = 12, .right = 82, .bottom = 96}, + .compare = compare_rgb32, .dump = dump_rgb32, .rect = {.top = 12, .right = 82, .bottom = 96}, }; const struct attribute_desc output_sample_attributes[] = { @@ -4223,6 +4323,9 @@ todo_wine { ok(output_info.cbAlignment == 0, "got cbAlignment %#lx\n", output_info.cbAlignment);
load_resource(L"nv12frame.bmp", &nv12frame_data, &nv12frame_data_len); + /* skip BMP header and RGB data from the dump */ + nv12frame_data_len = nv12frame_data_len - *(DWORD *)(nv12frame_data + 2); + nv12frame_data = nv12frame_data + *(DWORD *)(nv12frame_data + 2); ok(nv12frame_data_len == 13824, "got length %lu\n", nv12frame_data_len);
input_sample = create_sample(nv12frame_data, nv12frame_data_len);