Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/mp3dmod/tests/mp3dmod.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-)
diff --git a/dlls/mp3dmod/tests/mp3dmod.c b/dlls/mp3dmod/tests/mp3dmod.c index 99d52e6fd77..1d404248cc1 100644 --- a/dlls/mp3dmod/tests/mp3dmod.c +++ b/dlls/mp3dmod/tests/mp3dmod.c @@ -40,8 +40,10 @@ static REFERENCE_TIME samplelen(DWORD samples, int rate) return (REFERENCE_TIME) 10000000 * samples / rate; }
-struct test_buffer { +struct test_buffer +{ IMediaBuffer IMediaBuffer_iface; + LONG refcount; BYTE data[5000]; DWORD len; DWORD maxlen; @@ -65,12 +67,14 @@ static HRESULT WINAPI Buffer_QueryInterface(IMediaBuffer *iface, REFIID iid, voi
static ULONG WINAPI Buffer_AddRef(IMediaBuffer *iface) { - return 2; + struct test_buffer *buffer = impl_from_IMediaBuffer(iface); + return InterlockedIncrement(&buffer->refcount); }
static ULONG WINAPI Buffer_Release(IMediaBuffer *iface) { - return 1; + struct test_buffer *buffer = impl_from_IMediaBuffer(iface); + return InterlockedDecrement(&buffer->refcount); }
static HRESULT WINAPI Buffer_SetLength(IMediaBuffer *iface, DWORD len) @@ -107,8 +111,8 @@ static IMediaBufferVtbl Buffer_vtbl = { static void test_convert(void) { static const BYTE mp3hdr[] = {0xff,0xfb,0x14,0xc4}; - struct test_buffer outbuf = {{&Buffer_vtbl}}; - struct test_buffer inbuf = {{&Buffer_vtbl}}; + struct test_buffer outbuf = {.IMediaBuffer_iface = {&Buffer_vtbl}, .refcount = 1}; + struct test_buffer inbuf = {.IMediaBuffer_iface = {&Buffer_vtbl}, .refcount = 1}; DMO_MEDIA_TYPE in = {{0}}, out = {{0}}; MPEGLAYER3WAVEFORMAT mp3fmt = {{0}}; DMO_OUTPUT_DATA_BUFFER output; @@ -169,6 +173,7 @@ static void test_convert(void) inbuf.len = 96 * 5; hr = IMediaObject_ProcessInput(dmo, 0, &inbuf.IMediaBuffer_iface, 0, 0, 0); ok(hr == S_OK, "got %#x\n", hr); + ok(inbuf.refcount == 2, "Got refcount %d.\n", inbuf.refcount);
hr = IMediaObject_ProcessInput(dmo, 0, &inbuf.IMediaBuffer_iface, 0, 0, 0); ok(hr == DMO_E_NOTACCEPTING, "got %#x\n", hr); @@ -194,6 +199,8 @@ static void test_convert(void) ok(output.rtTimestamp == 0, "got %s\n", wine_dbgstr_longlong(output.rtTimestamp)); ok(output.rtTimelength == samplelen(written, 48000), "got %s\n", wine_dbgstr_longlong(output.rtTimelength)); + ok(inbuf.refcount == 2, "Got refcount %d.\n", inbuf.refcount); + ok(outbuf.refcount == 1, "Got refcount %d.\n", inbuf.refcount);
hr = IMediaObject_ProcessOutput(dmo, 0, 1, &output, &status); ok(hr == S_FALSE, "got %#x\n", hr); @@ -205,6 +212,8 @@ static void test_convert(void)
hr = IMediaObject_ProcessInput(dmo, 0, &inbuf.IMediaBuffer_iface, 0, 0, 0); ok(hr == DMO_E_NOTACCEPTING, "got %#x\n", hr); + ok(inbuf.refcount == 2, "Got refcount %d.\n", inbuf.refcount); + ok(outbuf.refcount == 1, "Got refcount %d.\n", inbuf.refcount);
/* write the rest */ outbuf.len = 0; @@ -219,6 +228,8 @@ static void test_convert(void) "got %s\n", wine_dbgstr_longlong(output.rtTimestamp)); ok(output.rtTimelength == samplelen(outbuf.len, 48000), "got %s\n", wine_dbgstr_longlong(output.rtTimelength)); + ok(inbuf.refcount == 1, "Got refcount %d.\n", inbuf.refcount); + ok(outbuf.refcount == 1, "Got refcount %d.\n", inbuf.refcount);
hr = IMediaObject_ProcessOutput(dmo, 0, 1, &output, &status); ok(hr == S_FALSE, "got %#x\n", hr); @@ -228,6 +239,8 @@ static void test_convert(void) ok(hr == S_OK, "got %#x\n", hr);
IMediaObject_Release(dmo); + todo_wine ok(inbuf.refcount == 1, "Got outstanding refcount %d.\n", inbuf.refcount); + ok(outbuf.refcount == 1, "Got outstanding refcount %d.\n", outbuf.refcount); }
static const GUID IID_test_outer = {0xdeadbeef,0,0,{0,0,0,0,0,0,0,0x66}};
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/mp3dmod/mp3dmod.c | 2 ++ dlls/mp3dmod/tests/mp3dmod.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/dlls/mp3dmod/mp3dmod.c b/dlls/mp3dmod/mp3dmod.c index 592ee5482a1..65b48de7114 100644 --- a/dlls/mp3dmod/mp3dmod.c +++ b/dlls/mp3dmod/mp3dmod.c @@ -103,6 +103,8 @@ static ULONG WINAPI Unknown_Release(IUnknown *iface)
if (!refcount) { + if (This->buffer) + IMediaBuffer_Release(This->buffer); if (This->intype_set) MoFreeMediaType(&This->intype); MoFreeMediaType(&This->outtype); diff --git a/dlls/mp3dmod/tests/mp3dmod.c b/dlls/mp3dmod/tests/mp3dmod.c index 1d404248cc1..e66ad3ace05 100644 --- a/dlls/mp3dmod/tests/mp3dmod.c +++ b/dlls/mp3dmod/tests/mp3dmod.c @@ -239,7 +239,7 @@ static void test_convert(void) ok(hr == S_OK, "got %#x\n", hr);
IMediaObject_Release(dmo); - todo_wine ok(inbuf.refcount == 1, "Got outstanding refcount %d.\n", inbuf.refcount); + ok(inbuf.refcount == 1, "Got outstanding refcount %d.\n", inbuf.refcount); ok(outbuf.refcount == 1, "Got outstanding refcount %d.\n", outbuf.refcount); }
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/mp3dmod/mp3dmod.c | 14 ++++++++++++ dlls/mp3dmod/tests/mp3dmod.c | 41 ++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+)
diff --git a/dlls/mp3dmod/mp3dmod.c b/dlls/mp3dmod/mp3dmod.c index 65b48de7114..05d56eff725 100644 --- a/dlls/mp3dmod/mp3dmod.c +++ b/dlls/mp3dmod/mp3dmod.c @@ -456,6 +456,20 @@ static HRESULT WINAPI MediaObject_ProcessOutput(IMediaObject *iface, DWORD flags
buffers[0].dwStatus = 0;
+ if (!buffers[0].pBuffer) + { + while ((err = mpg123_read(This->mh, NULL, 0, &written)) == MPG123_NEW_FORMAT); + if (err == MPG123_NEED_MORE) + return S_OK; + else if (err == MPG123_ERR) + ERR("mpg123_read() failed: %s\n", mpg123_strerror(This->mh)); + else if (err != MPG123_OK) + ERR("mpg123_read() returned %d\n", err); + + buffers[0].dwStatus = DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE; + return S_OK; + } + if (!This->buffer) return S_FALSE;
diff --git a/dlls/mp3dmod/tests/mp3dmod.c b/dlls/mp3dmod/tests/mp3dmod.c index e66ad3ace05..9e845f59152 100644 --- a/dlls/mp3dmod/tests/mp3dmod.c +++ b/dlls/mp3dmod/tests/mp3dmod.c @@ -235,9 +235,50 @@ static void test_convert(void) ok(hr == S_FALSE, "got %#x\n", hr); ok(output.dwStatus == 0, "got %#x\n", output.dwStatus);
+ output.pBuffer = NULL; + output.dwStatus = 0xdeadbeef; + output.rtTimestamp = 0xdeadbeef; + output.rtTimelength = 0xdeadbeef; + hr = IMediaObject_ProcessOutput(dmo, DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER, 1, &output, &status); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!output.pBuffer, "Got buffer %p.\n", output.pBuffer); + ok(!output.dwStatus, "Got status %#x.\n", output.dwStatus); + ok(output.rtTimestamp == 0xdeadbeef, "Got timestamp %s.\n", wine_dbgstr_longlong(output.rtTimestamp)); + ok(output.rtTimelength == 0xdeadbeef, "Got length %s.\n", wine_dbgstr_longlong(output.rtTimelength)); + hr = IMediaObject_ProcessInput(dmo, 0, &inbuf.IMediaBuffer_iface, 0, 0, 0); ok(hr == S_OK, "got %#x\n", hr);
+ hr = IMediaObject_ProcessInput(dmo, 0, &inbuf.IMediaBuffer_iface, 0, 0, 0); + ok(hr == DMO_E_NOTACCEPTING, "Got hr %#x.\n", hr); + + output.pBuffer = NULL; + output.dwStatus = 0xdeadbeef; + output.rtTimestamp = 0xdeadbeef; + output.rtTimelength = 0xdeadbeef; + hr = IMediaObject_ProcessOutput(dmo, DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER, 1, &output, &status); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!output.pBuffer, "Got buffer %p.\n", output.pBuffer); + ok(output.dwStatus == O_INCOMPLETE, "Got status %#x.\n", output.dwStatus); + ok(output.rtTimestamp == 0xdeadbeef, "Got timestamp %s.\n", wine_dbgstr_longlong(output.rtTimestamp)); + ok(output.rtTimelength == 0xdeadbeef, "Got length %s.\n", wine_dbgstr_longlong(output.rtTimelength)); + ok(inbuf.refcount == 2, "Got refcount %d.\n", inbuf.refcount); + + hr = IMediaObject_ProcessOutput(dmo, 0, 1, &output, &status); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!output.pBuffer, "Got buffer %p.\n", output.pBuffer); + ok(output.dwStatus == O_INCOMPLETE, "Got status %#x.\n", output.dwStatus); + ok(output.rtTimestamp == 0xdeadbeef, "Got timestamp %s.\n", wine_dbgstr_longlong(output.rtTimestamp)); + ok(output.rtTimelength == 0xdeadbeef, "Got length %s.\n", wine_dbgstr_longlong(output.rtTimelength)); + ok(inbuf.refcount == 2, "Got refcount %d.\n", inbuf.refcount); + + output.pBuffer = &outbuf.IMediaBuffer_iface; + outbuf.len = 0; + outbuf.maxlen = 5000; + hr = IMediaObject_ProcessOutput(dmo, 0, 1, &output, &status); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(outbuf.len > 1152 && outbuf.len <= 5000, "got %u\n", written); + IMediaObject_Release(dmo); ok(inbuf.refcount == 1, "Got outstanding refcount %d.\n", inbuf.refcount); ok(outbuf.refcount == 1, "Got outstanding refcount %d.\n", outbuf.refcount);
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/mp3dmod/mp3dmod.c | 15 +++++++++++++-- dlls/mp3dmod/tests/mp3dmod.c | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 3 deletions(-)
diff --git a/dlls/mp3dmod/mp3dmod.c b/dlls/mp3dmod/mp3dmod.c index 05d56eff725..3dce02fa14c 100644 --- a/dlls/mp3dmod/mp3dmod.c +++ b/dlls/mp3dmod/mp3dmod.c @@ -358,9 +358,20 @@ static HRESULT WINAPI MediaObject_SetInputMaxLatency(IMediaObject *iface, DWORD
static HRESULT WINAPI MediaObject_Flush(IMediaObject *iface) { - FIXME("(%p)->() stub!\n", iface); + struct mp3_decoder *dmo = impl_from_IMediaObject(iface);
- return E_NOTIMPL; + TRACE("iface %p.\n", iface); + + if (dmo->buffer) + IMediaBuffer_Release(dmo->buffer); + dmo->buffer = NULL; + dmo->timestamp = 0; + + /* mpg123 doesn't give us a way to flush, so just close and reopen the feed. */ + mpg123_close(dmo->mh); + mpg123_open_feed(dmo->mh); + + return S_OK; }
static HRESULT WINAPI MediaObject_Discontinuity(IMediaObject *iface, DWORD index) diff --git a/dlls/mp3dmod/tests/mp3dmod.c b/dlls/mp3dmod/tests/mp3dmod.c index 9e845f59152..90398173819 100644 --- a/dlls/mp3dmod/tests/mp3dmod.c +++ b/dlls/mp3dmod/tests/mp3dmod.c @@ -277,7 +277,41 @@ static void test_convert(void) outbuf.maxlen = 5000; hr = IMediaObject_ProcessOutput(dmo, 0, 1, &output, &status); ok(hr == S_OK, "Got hr %#x.\n", hr); - ok(outbuf.len > 1152 && outbuf.len <= 5000, "got %u\n", written); + ok(outbuf.len > 1152 && outbuf.len <= 5000, "Got length %u.\n", outbuf.len); + ok(output.dwStatus == (O_SYNCPOINT | O_TIME | O_TIMELENGTH | O_INCOMPLETE), + "Got status %#x.\n", output.dwStatus); + ok(output.rtTimestamp == samplelen(1152 * 5, 48000), "Got timestamp %s.\n", + wine_dbgstr_longlong(output.rtTimestamp)); + ok(output.rtTimelength == samplelen(written, 48000), + "Got length %s.\n", wine_dbgstr_longlong(output.rtTimelength)); + ok(inbuf.refcount == 2, "Got refcount %d.\n", inbuf.refcount); + ok(outbuf.refcount == 1, "Got refcount %d.\n", inbuf.refcount); + + hr = IMediaObject_Flush(dmo); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(inbuf.refcount == 1, "Got refcount %d.\n", inbuf.refcount); + + outbuf.len = 0; + outbuf.maxlen = 5000; + hr = IMediaObject_ProcessOutput(dmo, 0, 1, &output, &status); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + hr = IMediaObject_Flush(dmo); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaObject_ProcessInput(dmo, 0, &inbuf.IMediaBuffer_iface, 0, 0, 0); + ok(hr == S_OK, "got %#x\n", hr); + + hr = IMediaObject_ProcessOutput(dmo, 0, 1, &output, &status); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(outbuf.len > 1152 && outbuf.len <= 5000, "Got length %u.\n", outbuf.len); + ok(output.dwStatus == (O_SYNCPOINT | O_TIME | O_TIMELENGTH | O_INCOMPLETE), + "Got status %#x.\n", output.dwStatus); + ok(!output.rtTimestamp, "Got timestamp %s.\n", wine_dbgstr_longlong(output.rtTimestamp)); + ok(output.rtTimelength == samplelen(written, 48000), + "Got length %s.\n", wine_dbgstr_longlong(output.rtTimelength)); + ok(inbuf.refcount == 2, "Got refcount %d.\n", inbuf.refcount); + ok(outbuf.refcount == 1, "Got refcount %d.\n", inbuf.refcount);
IMediaObject_Release(dmo); ok(inbuf.refcount == 1, "Got outstanding refcount %d.\n", inbuf.refcount);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=65809
Your paranoid android.
=== w1064v1507 (32 bit report) ===
mp3dmod: mp3dmod.c:283: Test failed: Got timestamp 10a1d0. mp3dmod.c:285: Test failed: Got length ea600.
=== w1064v1809 (32 bit report) ===
mp3dmod: mp3dmod.c:283: Test failed: Got timestamp 10a1d0. mp3dmod.c:285: Test failed: Got length ea600.
=== w1064v1809_2scr (32 bit report) ===
mp3dmod: mp3dmod.c:283: Test failed: Got timestamp 10a1d0. mp3dmod.c:285: Test failed: Got length ea600.
=== w1064v1809_ar (32 bit report) ===
mp3dmod: mp3dmod.c:283: Test failed: Got timestamp 10a1d0. mp3dmod.c:285: Test failed: Got length ea600.
=== w1064v1809_he (32 bit report) ===
mp3dmod: mp3dmod.c:283: Test failed: Got timestamp 10a1d0. mp3dmod.c:285: Test failed: Got length ea600.
=== w1064v1809_ja (32 bit report) ===
mp3dmod: mp3dmod.c:283: Test failed: Got timestamp 10a1d0. mp3dmod.c:285: Test failed: Got length ea600.
=== w1064v1809_zh_CN (32 bit report) ===
mp3dmod: mp3dmod.c:283: Test failed: Got timestamp 10a1d0. mp3dmod.c:285: Test failed: Got length ea600.
=== w1064v1507 (64 bit report) ===
mp3dmod: mp3dmod.c:283: Test failed: Got timestamp 10a1d0. mp3dmod.c:285: Test failed: Got length ea600.
=== w1064v1809 (64 bit report) ===
mp3dmod: mp3dmod.c:283: Test failed: Got timestamp 10a1d0. mp3dmod.c:285: Test failed: Got length ea600.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/mp3dmod/mp3dmod.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/mp3dmod/mp3dmod.c b/dlls/mp3dmod/mp3dmod.c index 3dce02fa14c..3ad3b785d29 100644 --- a/dlls/mp3dmod/mp3dmod.c +++ b/dlls/mp3dmod/mp3dmod.c @@ -376,9 +376,9 @@ static HRESULT WINAPI MediaObject_Flush(IMediaObject *iface)
static HRESULT WINAPI MediaObject_Discontinuity(IMediaObject *iface, DWORD index) { - FIXME("(%p)->(%d) stub!\n", iface, index); + TRACE("iface %p.\n", iface);
- return E_NOTIMPL; + return S_OK; }
static HRESULT WINAPI MediaObject_AllocateStreamingResources(IMediaObject *iface)