From 1673af4ce01985664153623b6618ae8b6b25df18 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Wed, 26 Feb 2020 00:19:23 -0600 Subject: [PATCH] mp3dmod: Handle a NULL buffer passed to IMediaObject::ProcessOutput(). Signed-off-by: Zebediah Figura Signed-off-by: Alexandre Julliard --- 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);