Hallo. The following patch fixes the following issues: dlls/avifil32/avifile.c: - very slow loading of index dlls/avifil32/wavfile.c: - Fixed loading of wave files. - Corrected AVIFILEINFOW structure updates. - Implemented saving of wave files.
diff -dur wine-old/dlls/Makefile.in wine/dlls/Makefile.in --- wine-old/dlls/Makefile.in Fri Oct 18 15:55:43 2002 +++ wine/dlls/Makefile.in Fri Oct 18 15:38:57 2002 @@ -763,8 +763,8 @@ advapi32: kernel32.dll$(DLLEXT) ntdll.dll$(DLLEXT) avicap32: ntdll.dll$(DLLEXT) -avifil32: msvfw32.dll$(DLLEXT) shell32.dll$(DLLEXT) winmm.dll$(DLLEXT) user32.dll$(DLLEXT) \ - advapi32.dll$(DLLEXT) kernel32.dll$(DLLEXT) +avifil32: msacm32.dll$(DLLEXT) msvfw32.dll$(DLLEXT) shell32.dll$(DLLEXT) \ + winmm.dll$(DLLEXT) user32.dll$(DLLEXT) advapi32.dll$(DLLEXT) kernel32.dll$(DLLEXT) comcat: ole32.dll$(DLLEXT) user32.dll$(DLLEXT) advapi32.dll$(DLLEXT) kernel32.dll$(DLLEXT) comctl32: user32.dll$(DLLEXT) gdi32.dll$(DLLEXT) advapi32.dll$(DLLEXT) kernel32.dll$(DLLEXT) \ winmm.dll$(DLLEXT) diff -dur wine-old/dlls/avifil32/Makefile.in wine/dlls/avifil32/Makefile.in --- wine-old/dlls/avifil32/Makefile.in Fri Oct 18 15:55:00 2002 +++ wine/dlls/avifil32/Makefile.in Fri Oct 18 15:50:50 2002 @@ -3,7 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = avifil32.dll -IMPORTS = msvfw32 shell32 winmm user32 advapi32 kernel32 +IMPORTS = msacm32 msvfw32 shell32 winmm user32 advapi32 kernel32 ALTNAMES = avifile.dll EXTRALIBS = $(LIBUUID) diff -dur wine-old/dlls/avifil32/avifile.c wine/dlls/avifil32/avifile.c --- wine-old/dlls/avifil32/avifile.c Fri Oct 18 15:55:00 2002 +++ wine/dlls/avifil32/avifile.c Fri Oct 18 15:54:00 2002 @@ -1348,7 +1348,7 @@ This->sInfo.dwSuggestedBufferSize = size; /* get memory for index */ - if (This->idxFrames == NULL || This->dwLastFrame + 1 < This->nIdxFrames) { + if (This->idxFrames == NULL || This->dwLastFrame + 1 >= This->nIdxFrames) { This->nIdxFrames += 512; This->idxFrames = GlobalReAllocPtr(This->idxFrames, This->nIdxFrames * sizeof(AVIINDEXENTRY), GHND); if (This->idxFrames == NULL) @@ -1812,7 +1812,7 @@ if (pStream->sInfo.dwSampleSize != 0) { if (n > 0 && This->fInfo.dwFlags & AVIFILEINFO_ISINTERLEAVED) { - pStream->nIdxFrames = pStream->nIdxFrames; + pStream->nIdxFrames = This->ppStreams[0]->nIdxFrames; } else if (pStream->sInfo.dwSuggestedBufferSize) { pStream->nIdxFrames = pStream->sInfo.dwLength / pStream->sInfo.dwSuggestedBufferSize; diff -dur wine-old/dlls/avifil32/wavfile.c wine/dlls/avifil32/wavfile.c --- wine-old/dlls/avifil32/wavfile.c Fri Oct 18 15:55:00 2002 +++ wine/dlls/avifil32/wavfile.c Fri Oct 18 15:44:17 2002 @@ -25,6 +25,7 @@ #include "windowsx.h" #include "mmsystem.h" #include "vfw.h" +#include "msacm.h" #include "avifile_private.h" #include "extrachunk.h" @@ -285,11 +286,15 @@ This->fInfo.dwFlags = 0; This->fInfo.dwCaps = AVIFILECAPS_CANREAD|AVIFILECAPS_CANWRITE; if (This->lpFormat != NULL) { + assert(This->sInfo.dwScale != 0); + This->fInfo.dwStreams = 1; This->fInfo.dwScale = This->sInfo.dwScale; This->fInfo.dwRate = This->sInfo.dwRate; This->fInfo.dwLength = This->sInfo.dwLength; This->fInfo.dwSuggestedBufferSize = This->ckData.cksize; + This->fInfo.dwMaxBytesPerSec = + MulDiv(This->sInfo.dwSampleSize,This->sInfo.dwRate,This->sInfo.dwScale); } memcpy(afi, &This->fInfo, min(size, sizeof(This->fInfo))); @@ -1000,6 +1005,7 @@ This->fDirty = FALSE; /* search for RIFF chunk */ + ckRIFF.fccType = 0; /* find any */ if (mmioDescend(This->hmmio, &ckRIFF, NULL, MMIO_FINDRIFF) != S_OK) { return AVIFILE_LoadSunFile(This); } @@ -1010,7 +1016,7 @@ /* search WAVE format chunk */ ck.ckid = ckidWAVEFORMAT; if (FindChunkAndKeepExtras(&This->extra, This->hmmio, &ck, - &ckRIFF, MMIO_FINDCHUNK != S_OK)) + &ckRIFF, MMIO_FINDCHUNK) != S_OK) return AVIERR_FILEREAD; /* get memory for format and read it */ @@ -1024,14 +1030,9 @@ if (mmioAscend(This->hmmio, &ck, 0) != S_OK) return AVIERR_FILEREAD; - /* non-pcm formats have a fact chunk */ - if (This->lpFormat->wFormatTag != WAVE_FORMAT_PCM) { - ck.ckid = ckidWAVEFACT; - if (mmioDescend(This->hmmio, &ck, NULL, MMIO_FINDCHUNK) != S_OK) { - /* FIXME: if codec is installed could ask him */ - return AVIERR_BADFORMAT; - } - } + /* Non-pcm formats have a fact chunk. + * We don't need it, so simply add it to the extra chunks. + */ /* find the big data chunk */ This->ckData.ckid = ckidWAVEDATA; @@ -1047,6 +1048,8 @@ This->sInfo.dwLength = This->ckData.cksize / This->lpFormat->nBlockAlign; This->sInfo.dwSuggestedBufferSize = This->ckData.cksize; + This->fInfo.dwStreams = 1; + if (mmioAscend(This->hmmio, &This->ckData, 0) != S_OK) { /* seems to be truncated */ WARN(": file seems to be truncated!\n"); @@ -1064,12 +1067,109 @@ static HRESULT AVIFILE_LoadSunFile(IAVIFileImpl *This) { - FIXME(": pherhpas sun-audio file -- not implemented !\n"); + FIXME(": pherhaps sun-audio file -- not implemented !\n"); return AVIERR_UNSUPPORTED; } static HRESULT AVIFILE_SaveFile(IAVIFileImpl *This) { - return AVIERR_UNSUPPORTED; + MMCKINFO ckRIFF; + MMCKINFO ck; + + mmioSeek(This->hmmio, 0, SEEK_SET); + + /* create the RIFF chunk with formtype WAVE */ + ckRIFF.fccType = formtypeWAVE; + ckRIFF.cksize = 0; + if (mmioCreateChunk(This->hmmio, &ckRIFF, MMIO_CREATERIFF) != S_OK) + return AVIERR_FILEWRITE; + + /* the next chunk is the format */ + ck.ckid = ckidWAVEFORMAT; + ck.cksize = This->cbFormat; + if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK) + return AVIERR_FILEWRITE; + if (This->lpFormat != NULL && This->cbFormat > 0) { + if (mmioWrite(This->hmmio, (HPSTR)This->lpFormat, ck.cksize) != ck.cksize) + return AVIERR_FILEWRITE; + } + if (mmioAscend(This->hmmio, &ck, 0) != S_OK) + return AVIERR_FILEWRITE; + + /* fact chunk is needed for non-pcm waveforms */ + if (This->lpFormat != NULL && This->cbFormat > sizeof(PCMWAVEFORMAT) && + This->lpFormat->wFormatTag != WAVE_FORMAT_PCM) { + WAVEFORMATEX wfx; + DWORD dwFactLength; + HACMSTREAM has; + + /* try to open an appropriate audio codec to figure out + * data for fact-chunk */ + wfx.wFormatTag = WAVE_FORMAT_PCM; + if (acmFormatSuggest((HACMDRIVER)NULL, This->lpFormat, &wfx, + sizeof(wfx), ACM_FORMATSUGGESTF_WFORMATTAG)) { + acmStreamOpen(&has, (HACMDRIVER)NULL, This->lpFormat, &wfx, NULL, + 0, 0, ACM_STREAMOPENF_NONREALTIME); + acmStreamSize(has, This->ckData.cksize, &dwFactLength, + ACM_STREAMSIZEF_SOURCE); + dwFactLength /= wfx.nBlockAlign; + acmStreamClose(has, 0); + + /* crete the fact chunk */ + ck.ckid = ckidWAVEFACT; + ck.cksize = sizeof(dwFactLength); + + /* test for enough space before data chunk */ + if (mmioSeek(This->hmmio, 0, SEEK_CUR) > This->ckData.dwDataOffset + - ck.cksize - 4 * sizeof(DWORD)) + return AVIERR_FILEWRITE; + if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK) + return AVIERR_FILEWRITE; + if (mmioWrite(This->hmmio, (HPSTR)&dwFactLength, ck.cksize) != ck.cksize) + return AVIERR_FILEWRITE; + if (mmioAscend(This->hmmio, &ck, 0) != S_OK) + return AVIERR_FILEWRITE; + } else + ERR(": fact chunk is needed for non-pcm files -- currently no codec found, so skipped!\n"); + } + + /* if here was extra stuff, we need to fill it with JUNK */ + if (mmioSeek(This->hmmio, 0, SEEK_CUR) + 2 * sizeof(DWORD) < This->ckData.dwDataOffset) { + ck.ckid = ckidAVIPADDING; + ck.cksize = 0; + if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK) + return AVIERR_FILEWRITE; + + if (mmioSeek(This->hmmio, This->ckData.dwDataOffset + - 2 * sizeof(DWORD), SEEK_SET) == -1) + return AVIERR_FILEWRITE; + if (mmioAscend(This->hmmio, &ck, 0) != S_OK) + return AVIERR_FILEWRITE; + } + + /* crete the data chunk */ + ck.ckid = ckidWAVEDATA; + ck.cksize = This->ckData.cksize; + if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK) + return AVIERR_FILEWRITE; + if (mmioSeek(This->hmmio, This->ckData.cksize, SEEK_CUR) == -1) + return AVIERR_FILEWRITE; + if (mmioAscend(This->hmmio, &ck, 0) != S_OK) + return AVIERR_FILEWRITE; + + /* some optional extra chunks? */ + if (This->extra.lp != NULL && This->extra.cb > 0) { + /* chunk headers are already in structure */ + if (mmioWrite(This->hmmio, This->extra.lp, This->extra.cb) != This->extra.cb) + return AVIERR_FILEWRITE; + } + + /* close RIFF chunk */ + if (mmioAscend(This->hmmio, &ckRIFF, 0) != S_OK) + return AVIERR_FILEWRITE; + if (mmioFlush(This->hmmio, 0) != S_OK) + return AVIERR_FILEWRITE; + + return AVIERR_OK; }
Michael Günnewig