quartz help needed

Robert Reif reif at earthlink.net
Sat Jan 6 07:36:50 CST 2007


I'm trying to get Windows Media Player 6.4 working again and am running 
into problems.  At first it was crashing while trying to read wave 
files.  I found 2 bugs that were preventing it from working: some minor 
memory corruption for questionable wave files and using a pointer before 
it was initialized.  With these fixed (patch attached) you can now play 
files once but the program gets confused at the end of the file.  There 
are a lot of fixmes and unimplemented stuff.  This program was rated 
gold at one point so I'm not sure my fixes are completely correct.  I 
have written dshow filters and programs in the past at work and it was 
an extremely frustrating experience so I would appreciate and help 
getting quarts working again.
-------------- next part --------------
Index: dlls/quartz/waveparser.c
===================================================================
RCS file: /home/wine/wine/dlls/quartz/waveparser.c,v
retrieving revision 1.5
diff -p -u -r1.5 waveparser.c
--- dlls/quartz/waveparser.c	13 Oct 2006 10:27:23 -0000	1.5
+++ dlls/quartz/waveparser.c	6 Jan 2007 13:09:25 -0000
@@ -63,6 +63,7 @@ static HRESULT WAVEParser_Sample(LPVOID 
     long cbDstStream;
     long chunk_remaining_bytes = 0;
     long offset_src = 0;
+    TRACE("(%p)->(%p)\n", iface, pSample);
  
     hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
 
@@ -202,6 +203,8 @@ static HRESULT WAVEParser_Sample(LPVOID 
 
 static HRESULT WAVEParser_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt)
 {
+    TRACE("(%p)->(%p)\n", iface, pmt);
+
     if (!IsEqualIID(&pmt->majortype, &MEDIATYPE_Stream))
 	return S_FALSE;
     if (IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_WAVE))
@@ -220,17 +223,21 @@ static HRESULT WAVEParser_InputPin_PreCo
     LONGLONG pos = 0; /* in bytes */
     PIN_INFO piOutput;
     ALLOCATOR_PROPERTIES props;
-    AM_MEDIA_TYPE amt;
+    AM_MEDIA_TYPE * pmt;
     float fSamplesPerSec = 0.0f;
     DWORD dwSampleSize = 0;
     DWORD dwLength = 0;
     WAVEParserImpl * pWAVEParser = (WAVEParserImpl *)This->pin.pinInfo.pFilter;
+    LPWAVEFORMATEX pwfx;
+    TRACE("(%p)->(%p)\n", iface, pConnectPin);
 
     piOutput.dir = PINDIR_OUTPUT;
     piOutput.pFilter = (IBaseFilter *)This;
     lstrcpynW(piOutput.achName, wcsOutputPinName, sizeof(piOutput.achName) / sizeof(piOutput.achName[0]));
     
     hr = IAsyncReader_SyncRead(This->pReader, pos, sizeof(list), (BYTE *)&list);
+    if (hr != S_OK)
+        return E_FAIL;
     pos += sizeof(list);
 
     if (list.fcc != ckidRIFF)
@@ -250,6 +257,8 @@ static HRESULT WAVEParser_InputPin_PreCo
     }
 
     hr = IAsyncReader_SyncRead(This->pReader, pos, sizeof(chunk), (BYTE *)&chunk);
+    if (hr != S_OK)
+        return E_FAIL;
     pos += sizeof(chunk);
     if (chunk.fcc != mmioFOURCC('f','m','t',' '))
     {
@@ -257,52 +266,79 @@ static HRESULT WAVEParser_InputPin_PreCo
         return E_FAIL;
     }
 
-    memcpy(&amt.majortype, &MEDIATYPE_Audio, sizeof(GUID));
-    memcpy(&amt.formattype, &FORMAT_WaveFormatEx, sizeof(GUID));
-    amt.cbFormat = chunk.cb;
-    amt.pbFormat = CoTaskMemAlloc(amt.cbFormat);
-    amt.pUnk = NULL;
-    hr = IAsyncReader_SyncRead(This->pReader, pos, amt.cbFormat, amt.pbFormat);
-    memcpy(&amt.subtype, &MEDIATYPE_Audio, sizeof(GUID));
-    amt.subtype.Data1 = ((WAVEFORMATEX*)amt.pbFormat)->wFormatTag;
-    /* CopyMediaType(&((OutputPin*)pWAVEParser->ppPins[1])->pin.mtCurrent, &amt); */
-    ((Parser_OutputPin*)pWAVEParser->Parser.ppPins[1])->pmt = (AM_MEDIA_TYPE*) CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
-    
-    CopyMediaType(((Parser_OutputPin*)pWAVEParser->Parser.ppPins[1])->pmt, &amt);
-
-    /* Update buffer alignment of media samples in output */
-    ((Parser_OutputPin*)pWAVEParser->Parser.ppPins[1])->pin.allocProps.cbAlign = ((WAVEFORMATEX*)amt.pbFormat)->nBlockAlign;
+    pwfx = (LPWAVEFORMATEX)CoTaskMemAlloc(max(chunk.cb, sizeof(WAVEFORMATEX)));
+    if (!pwfx)
+        return E_FAIL;
 
+    hr = IAsyncReader_SyncRead(This->pReader, pos, chunk.cb, (BYTE *)pwfx);
+    if (hr != S_OK) {
+        CoTaskMemFree(pwfx);
+        return E_FAIL;
+    }
     pos += chunk.cb;
+
+    if (pwfx->wFormatTag == WAVE_FORMAT_PCM)
+        pwfx->cbSize = 0;
+
+    fSamplesPerSec = pwfx->nSamplesPerSec;
+    dwSampleSize = pwfx->nBlockAlign;
+    dwLength = 4096;
+
     hr = IAsyncReader_SyncRead(This->pReader, pos, sizeof(chunk), (BYTE *)&chunk);
+    if (hr != S_OK)
+    {
+        CoTaskMemFree(pwfx);
+        return E_FAIL;
+    }
     if (chunk.fcc == mmioFOURCC('f','a','c','t'))
     {
         FIXME("'fact' chunk not supported yet\n");
 	pos += sizeof(chunk) + chunk.cb;
 	hr = IAsyncReader_SyncRead(This->pReader, pos, sizeof(chunk), (BYTE *)&chunk);
+        if (hr != S_OK)
+        {
+            CoTaskMemFree(pwfx);
+            return E_FAIL;
+        }
     }
     if (chunk.fcc != mmioFOURCC('d','a','t','a'))
     {
         ERR("Expected 'data' chunk, but got %.04s\n", (LPSTR)&chunk.fcc);
+        CoTaskMemFree(pwfx);
         return E_FAIL;
     }
 
-    if (hr == S_OK)
+    pmt = CoTaskMemAlloc(sizeof(*pmt));
+    if (!pmt)
     {
-        pWAVEParser->StartOfFile = MEDIATIME_FROM_BYTES(pos + sizeof(RIFFCHUNK));
-        pWAVEParser->EndOfFile = MEDIATIME_FROM_BYTES(pos + chunk.cb + sizeof(RIFFCHUNK));
+        CoTaskMemFree(pwfx);
+        return E_FAIL;
     }
 
-    if (hr != S_OK)
-        return E_FAIL;
+    memcpy(&pmt->majortype, &MEDIATYPE_Audio, sizeof(GUID));
+    memcpy(&pmt->subtype, &MEDIATYPE_Audio, sizeof(GUID));
+    pmt->subtype.Data1 = pwfx->wFormatTag;
+    pmt->bFixedSizeSamples = TRUE;
+    pmt->bTemporalCompression = FALSE;
+    pmt->lSampleSize = pwfx->nBlockAlign;
+    memcpy(&pmt->formattype, &FORMAT_WaveFormatEx, sizeof(GUID));
+    pmt->pUnk = NULL;
+    pmt->cbFormat = sizeof(*pwfx) + pwfx->cbSize;
+    pmt->pbFormat = (BYTE *)pwfx;
+
+    pWAVEParser->StartOfFile = MEDIATIME_FROM_BYTES(pos + sizeof(RIFFCHUNK));
+    pWAVEParser->EndOfFile = MEDIATIME_FROM_BYTES(pos + chunk.cb + sizeof(RIFFCHUNK));
 
     props.cbAlign = 1;
     props.cbPrefix = 0;
     props.cbBuffer = 4096;
     props.cBuffers = 2;
     
-    hr = Parser_AddPin(&(pWAVEParser->Parser), &piOutput, &props, &amt, fSamplesPerSec, dwSampleSize, dwLength);
-    
+    hr = Parser_AddPin(&(pWAVEParser->Parser), &piOutput, &props, pmt, fSamplesPerSec, dwSampleSize, dwLength);
+
+    /* Update buffer alignment of media samples in output */
+    ((Parser_OutputPin*)pWAVEParser->Parser.ppPins[1])->pin.allocProps.cbAlign = pwfx->nBlockAlign;
+
     TRACE("WAVE File ok\n");
 
     return hr;


More information about the wine-devel mailing list