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.
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;