[PATCH v2 6/6] mp3dmod: Return timestamp and length from ProcessOutput().

Zebediah Figura z.figura12 at gmail.com
Fri May 11 10:18:15 CDT 2018


Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/mp3dmod/mp3dmod.c       | 15 +++++++++++++++
 dlls/mp3dmod/tests/mp3dmod.c | 26 +++++++++++++++++++++++---
 2 files changed, 38 insertions(+), 3 deletions(-)

diff --git a/dlls/mp3dmod/mp3dmod.c b/dlls/mp3dmod/mp3dmod.c
index 0d97909..cdc8fa3 100644
--- a/dlls/mp3dmod/mp3dmod.c
+++ b/dlls/mp3dmod/mp3dmod.c
@@ -43,6 +43,7 @@ struct mp3_decoder {
     mpg123_handle *mh;
     DMO_MEDIA_TYPE outtype;
     IMediaBuffer *buffer;
+    REFERENCE_TIME timestamp;
 };
 
 static inline struct mp3_decoder *impl_from_IMediaObject(IMediaObject *iface)
@@ -296,9 +297,16 @@ static DWORD get_framesize(DMO_MEDIA_TYPE *type)
     return 1152 * format->nBlockAlign;
 }
 
+static REFERENCE_TIME get_frametime(DMO_MEDIA_TYPE *type)
+{
+    WAVEFORMATEX *format = (WAVEFORMATEX *)type->pbFormat;
+    return (REFERENCE_TIME) 10000000 * 1152 / format->nSamplesPerSec;
+}
+
 static HRESULT WINAPI MediaObject_ProcessOutput(IMediaObject *iface, DWORD flags, DWORD count, DMO_OUTPUT_DATA_BUFFER *buffers, DWORD *status)
 {
     struct mp3_decoder *This = impl_from_IMediaObject(iface);
+    REFERENCE_TIME time = 0, frametime;
     DWORD len, maxlen, framesize;
     int got_data = 0;
     size_t written;
@@ -325,6 +333,7 @@ static HRESULT WINAPI MediaObject_ProcessOutput(IMediaObject *iface, DWORD flags
     if (FAILED(hr)) return hr;
 
     framesize = get_framesize(&This->outtype);
+    frametime = get_frametime(&This->outtype);
 
     while (1)
     {
@@ -353,10 +362,16 @@ static HRESULT WINAPI MediaObject_ProcessOutput(IMediaObject *iface, DWORD flags
         len += framesize;
         hr = IMediaBuffer_SetLength(buffers[0].pBuffer, len);
         if (FAILED(hr)) return hr;
+
+        time += frametime;
     }
 
     if (got_data)
     {
+        buffers[0].dwStatus |= (DMO_OUTPUT_DATA_BUFFERF_TIME | DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH);
+        buffers[0].rtTimelength = time;
+        buffers[0].rtTimestamp = This->timestamp;
+        This->timestamp += time;
         return S_OK;
     }
     return S_FALSE;
diff --git a/dlls/mp3dmod/tests/mp3dmod.c b/dlls/mp3dmod/tests/mp3dmod.c
index efa77de..c0aa32f 100644
--- a/dlls/mp3dmod/tests/mp3dmod.c
+++ b/dlls/mp3dmod/tests/mp3dmod.c
@@ -35,6 +35,11 @@ DEFINE_GUID(WMMEDIASUBTYPE_MP3, 0x00000055, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0x
 #define O_TIMELENGTH DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH
 #define O_INCOMPLETE DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE
 
+static REFERENCE_TIME framelen(int frames, int rate)
+{
+    return (REFERENCE_TIME) frames * 10000000 * 1152 / rate;
+}
+
 struct test_buffer {
     IMediaBuffer IMediaBuffer_iface;
     BYTE data[1152 * 2 * 3];
@@ -147,10 +152,14 @@ static void test_convert(void)
     outbuf.maxlen = sizeof(outbuf.data);
     output.pBuffer = &outbuf.IMediaBuffer_iface;
     output.dwStatus = 0xdeadbeef;
+    output.rtTimestamp = 0xdeadbeef;
+    output.rtTimelength = 0xdeadbeef;
     hr = IMediaObject_ProcessOutput(dmo, 0, 1, &output, &status);
     ok(hr == S_FALSE, "got %#x\n", hr);
     ok(outbuf.len == 0, "got %u\n", outbuf.len);
     ok(output.dwStatus == 0, "got %#x\n", output.dwStatus);
+    ok(output.rtTimestamp == 0xdeadbeef, "got %s\n", wine_dbgstr_longlong(output.rtTimestamp));
+    ok(output.rtTimelength == 0xdeadbeef, "got %s\n", wine_dbgstr_longlong(output.rtTimestamp));
 
     /* write several frames of mp3 data */
     for (i = 0; i < 5; i++)
@@ -179,11 +188,14 @@ static void test_convert(void)
 
     outbuf.len = 0;
     outbuf.maxlen = 1152 * 2;
+    output.rtTimestamp = 0xdeadbeef;
+    output.rtTimelength = 0xdeadbeef;
     hr = IMediaObject_ProcessOutput(dmo, 0, 1, &output, &status);
     ok(hr == S_OK, "got %#x\n", hr);
     ok(outbuf.len == 1152 * 2, "got %u\n", outbuf.len);
-todo_wine
     ok(output.dwStatus == (O_SYNCPOINT | O_TIME | O_TIMELENGTH | O_INCOMPLETE), "got %#x\n", output.dwStatus);
+    ok(output.rtTimestamp == 0, "got %s\n", wine_dbgstr_longlong(output.rtTimestamp));
+    ok(output.rtTimelength == framelen(1, 48000), "got %s\n", wine_dbgstr_longlong(output.rtTimelength));
 
     hr = IMediaObject_ProcessOutput(dmo, 0, 1, &output, &status);
     ok(hr == S_FALSE, "got %#x\n", hr);
@@ -194,16 +206,20 @@ todo_wine
     hr = IMediaObject_ProcessOutput(dmo, 0, 1, &output, &status);
     ok(hr == S_OK, "got %#x\n", hr);
     ok(outbuf.len == 1152 * 2 * 2, "got %u\n", outbuf.len);
-todo_wine
     ok(output.dwStatus == (O_SYNCPOINT | O_TIME | O_TIMELENGTH | O_INCOMPLETE), "got %#x\n", output.dwStatus);
+    ok(output.rtTimestamp == framelen(1, 48000), "got %s\n", wine_dbgstr_longlong(output.rtTimestamp));
+    ok(output.rtTimelength == framelen(1, 48000), "got %s\n", wine_dbgstr_longlong(output.rtTimelength));
 
     outbuf.len = 0;
     outbuf.maxlen = 1152 * 2 * 3;
+    output.rtTimestamp = 0xdeadbeef;
+    output.rtTimelength = 0xdeadbeef;
     hr = IMediaObject_ProcessOutput(dmo, 0, 1, &output, &status);
     ok(hr == S_OK, "got %#x\n", hr);
     ok(outbuf.len == 1152 * 2 * 3, "got %u\n", outbuf.len);
-todo_wine
     ok(output.dwStatus == (O_SYNCPOINT | O_TIME | O_TIMELENGTH | O_INCOMPLETE), "got %#x\n", output.dwStatus);
+    ok(output.rtTimestamp == framelen(2, 48000), "got %s\n", wine_dbgstr_longlong(output.rtTimestamp));
+    ok(output.rtTimelength == framelen(3, 48000), "got %s\n", wine_dbgstr_longlong(output.rtTimelength));
 
     hr = IMediaObject_ProcessOutput(dmo, 0, 1, &output, &status);
     ok(hr == S_FALSE, "got %#x\n", hr);
@@ -216,10 +232,14 @@ todo_wine
     /* native requires one more frame's worth of space before it'll finish processing input */
     outbuf.len = 0;
     outbuf.maxlen = 1152 * 2;
+    output.rtTimestamp = 0xdeadbeef;
+    output.rtTimelength = 0xdeadbeef;
     hr = IMediaObject_ProcessOutput(dmo, 0, 1, &output, &status);
     ok(hr == S_FALSE, "got %#x\n", hr);
     ok(outbuf.len == 0, "got %u\n", outbuf.len);
     ok(output.dwStatus == O_SYNCPOINT, "got %#x\n", output.dwStatus);
+    ok(output.rtTimestamp == 0xdeadbeef, "got %s\n", wine_dbgstr_longlong(output.rtTimestamp));
+    ok(output.rtTimelength == 0xdeadbeef, "got %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);
-- 
2.7.4




More information about the wine-devel mailing list