mp3dmod: Handle a NULL buffer passed to IMediaObject::ProcessOutput().

Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2020-02-26 00:19:23 -06:00 committed by Alexandre Julliard
parent 88357e92f1
commit 1673af4ce0
2 changed files with 55 additions and 0 deletions

View File

@ -456,6 +456,20 @@ static HRESULT WINAPI MediaObject_ProcessOutput(IMediaObject *iface, DWORD flags
buffers[0].dwStatus = 0; 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) if (!This->buffer)
return S_FALSE; return S_FALSE;

View File

@ -235,9 +235,50 @@ static void test_convert(void)
ok(hr == S_FALSE, "got %#x\n", hr); ok(hr == S_FALSE, "got %#x\n", hr);
ok(output.dwStatus == 0, "got %#x\n", output.dwStatus); 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); hr = IMediaObject_ProcessInput(dmo, 0, &inbuf.IMediaBuffer_iface, 0, 0, 0);
ok(hr == S_OK, "got %#x\n", hr); 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); IMediaObject_Release(dmo);
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); ok(outbuf.refcount == 1, "Got outstanding refcount %d.\n", outbuf.refcount);