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;
Lørdag 06 januar 2007 14:36, skrev Robert Reif:
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.
It received the Gold rating because it worked with a lot of native dlls in earlier Wine versions. I have not tested it for a long time.
Alexander N. Sørnes