[PATCH 4/6] mp3dmod: Implement ProcessOutput().
Zebediah Figura
z.figura12 at gmail.com
Fri May 11 00:35:40 CDT 2018
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
dlls/mp3dmod/mp3dmod.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++--
include/mediaobj.idl | 7 +++++
2 files changed, 75 insertions(+), 2 deletions(-)
diff --git a/dlls/mp3dmod/mp3dmod.c b/dlls/mp3dmod/mp3dmod.c
index ccba5c0..0d97909 100644
--- a/dlls/mp3dmod/mp3dmod.c
+++ b/dlls/mp3dmod/mp3dmod.c
@@ -19,6 +19,7 @@
*/
#include <stdarg.h>
+#include <stdio.h>
#include <mpg123.h>
#include "windef.h"
#include "winbase.h"
@@ -289,11 +290,76 @@ static HRESULT WINAPI MediaObject_ProcessInput(IMediaObject *iface, DWORD index,
return S_OK;
}
+static DWORD get_framesize(DMO_MEDIA_TYPE *type)
+{
+ WAVEFORMATEX *format = (WAVEFORMATEX *)type->pbFormat;
+ return 1152 * format->nBlockAlign;
+}
+
static HRESULT WINAPI MediaObject_ProcessOutput(IMediaObject *iface, DWORD flags, DWORD count, DMO_OUTPUT_DATA_BUFFER *buffers, DWORD *status)
{
- FIXME("(%p)->(%x, %d, %p, %p) stub!\n", iface, flags, count, buffers, status);
+ struct mp3_decoder *This = impl_from_IMediaObject(iface);
+ DWORD len, maxlen, framesize;
+ int got_data = 0;
+ size_t written;
+ HRESULT hr;
+ BYTE *data;
+ int err;
- return E_NOTIMPL;
+ TRACE("(%p)->(%#x, %d, %p, %p)\n", iface, flags, count, buffers, status);
+
+ if (count > 1)
+ FIXME("Multiple buffers not handled.\n");
+
+ buffers[0].dwStatus = 0;
+
+ if (!This->buffer)
+ return S_FALSE;
+
+ buffers[0].dwStatus |= DMO_OUTPUT_DATA_BUFFERF_SYNCPOINT;
+
+ hr = IMediaBuffer_GetBufferAndLength(buffers[0].pBuffer, &data, &len);
+ if (FAILED(hr)) return hr;
+
+ hr = IMediaBuffer_GetMaxLength(buffers[0].pBuffer, &maxlen);
+ if (FAILED(hr)) return hr;
+
+ framesize = get_framesize(&This->outtype);
+
+ while (1)
+ {
+ if (maxlen - len < framesize)
+ {
+ buffers[0].dwStatus |= DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE;
+ break;
+ }
+
+ while ((err = mpg123_read(This->mh, data + len, framesize, &written)) == MPG123_NEW_FORMAT);
+ if (err == MPG123_NEED_MORE)
+ {
+ IMediaBuffer_Release(This->buffer);
+ This->buffer = NULL;
+ break;
+ }
+ 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);
+ if (written < framesize)
+ ERR("short write: %zd/%u\n", written, framesize);
+
+ got_data = 1;
+
+ len += framesize;
+ hr = IMediaBuffer_SetLength(buffers[0].pBuffer, len);
+ if (FAILED(hr)) return hr;
+ }
+
+ if (got_data)
+ {
+ return S_OK;
+ }
+ return S_FALSE;
}
static HRESULT WINAPI MediaObject_Lock(IMediaObject *iface, LONG lock)
diff --git a/include/mediaobj.idl b/include/mediaobj.idl
index b6ae236..7759921 100644
--- a/include/mediaobj.idl
+++ b/include/mediaobj.idl
@@ -107,6 +107,13 @@ enum _DMO_SET_TYPE_FLAGS {
DMO_SET_TYPEF_CLEAR = 0x00000002,
};
+enum _DMO_OUTPUT_DATA_BUFFERF_FLAGS {
+ DMO_OUTPUT_DATA_BUFFERF_SYNCPOINT = 0x00000001,
+ DMO_OUTPUT_DATA_BUFFERF_TIME = 0x00000002,
+ DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH = 0x00000004,
+ DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE = 0x01000000,
+};
+
/*****************************************************************************
* IMediaObject interface
*/
--
2.7.4
More information about the wine-devel
mailing list