From: Paul Gofman pgofman@codeweavers.com
--- dlls/avifil32/avifile.c | 17 +++++++++++++--- dlls/avifil32/tests/api.c | 43 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 3 deletions(-)
diff --git a/dlls/avifil32/avifile.c b/dlls/avifil32/avifile.c index 719d96edf86..6aae4736c4d 100644 --- a/dlls/avifil32/avifile.c +++ b/dlls/avifil32/avifile.c @@ -1399,9 +1399,19 @@ static HRESULT AVIFILE_AddFrame(IAVIStreamImpl *This, DWORD ckid, DWORD size, DW This->idxFrames[This->lLastFrame].dwChunkLength = size;
/* update AVISTREAMINFO structure if necessary */ - if (This->sInfo.dwLength <= This->lLastFrame) - This->sInfo.dwLength = This->lLastFrame + 1; + if (This->sInfo.dwSampleSize) + { + unsigned int block;
+ size = 0; + for (block = 0; block <= This->lLastFrame; block++) + size += This->idxFrames[block].dwChunkLength; + This->sInfo.dwLength = max(This->sInfo.dwLength, size / This->sInfo.dwSampleSize); + } + else + { + This->sInfo.dwLength = max(This->sInfo.dwLength, This->lLastFrame + 1); + } return AVIERR_OK; }
@@ -1989,7 +1999,8 @@ static HRESULT AVIFILE_ReadBlock(IAVIStreamImpl *This, DWORD pos, assert(This != NULL); assert(This->paf != NULL); assert(This->paf->hmmio != NULL); - assert(This->sInfo.dwStart <= pos && pos < This->sInfo.dwLength); + if (!This->sInfo.dwSampleSize) + assert(This->sInfo.dwStart <= pos && pos < This->sInfo.dwLength); assert(pos <= This->lLastFrame);
/* should we read as much as block gives us? */ diff --git a/dlls/avifil32/tests/api.c b/dlls/avifil32/tests/api.c index 9efba25fd56..227fd7a286d 100644 --- a/dlls/avifil32/tests/api.c +++ b/dlls/avifil32/tests/api.c @@ -775,7 +775,9 @@ static void test_avifile_write(void) { WCHAR fn[MAX_PATH]; IPersistFile *persist; + PCMWAVEFORMAT afmt; AVISTREAMINFOW si; + USHORT buffer[64]; PAVIFILE avifile; PAVISTREAM stm; HRESULT hr; @@ -811,6 +813,47 @@ static void test_avifile_write(void) ok(hr == S_OK, "got %#lx.\n", hr); hr = AVIFileCreateStreamW(avifile, &stm, &si); ok(hr == S_OK, "got %#lx.\n", hr); + + memset(&afmt, 0, sizeof(afmt)); + afmt.wBitsPerSample = 16; + afmt.wf.wFormatTag = WAVE_FORMAT_PCM; + afmt.wf.nChannels = 2; + afmt.wf.nSamplesPerSec = 44800; + afmt.wf.nAvgBytesPerSec = afmt.wf.nSamplesPerSec * afmt.wf.nChannels; + afmt.wf.nBlockAlign = afmt.wf.nChannels * 2; + hr = AVIStreamSetFormat(stm, 0, &afmt, sizeof(afmt)); + ok(hr == S_OK, "got %#lx.\n", hr); + + memset(buffer, 0xcc, sizeof(buffer)); + + hr = IAVIStream_Info(stm, &si, sizeof(si)); + ok(hr == S_OK, "got %#lx.\n", hr); + ok(!si.dwLength, "got %lu.\n", si.dwLength); + ok(!si.dwStart, "got %lu.\n", si.dwStart); + ok(!si.dwSuggestedBufferSize, "got %lu.\n", si.dwSuggestedBufferSize); + hr = AVIStreamWrite(stm, 0, 2, buffer, si.dwSampleSize * 2, 0, NULL, NULL); + ok(hr == S_OK, "got %#lx.\n", hr); + hr = IAVIStream_Info(stm, &si, sizeof(si)); + ok(hr == S_OK, "got %#lx.\n", hr); + ok(si.dwLength == 2, "got %lu.\n", si.dwLength); + ok(!si.dwStart, "got %lu.\n", si.dwStart); + ok(si.dwSuggestedBufferSize == 8, "got %lu.\n", si.dwSuggestedBufferSize); + hr = AVIStreamWrite(stm, 2, 2, buffer, si.dwSampleSize * 2, 0, NULL, NULL); + ok(hr == S_OK, "got %#lx.\n", hr); + hr = IAVIStream_Info(stm, &si, sizeof(si)); + ok(hr == S_OK, "got %#lx.\n", hr); + ok(si.dwLength == 4, "got %lu.\n", si.dwLength); + ok(!si.dwStart, "got %lu.\n", si.dwStart); + ok(si.dwSuggestedBufferSize == 8, "got %lu.\n", si.dwSuggestedBufferSize); + + hr = AVIStreamWrite(stm, 4, 4, buffer, si.dwSampleSize * 4, 0, NULL, NULL); + ok(hr == S_OK, "got %#lx.\n", hr); + hr = IAVIStream_Info(stm, &si, sizeof(si)); + ok(hr == S_OK, "got %#lx.\n", hr); + ok(si.dwLength == 8, "got %lu.\n", si.dwLength); + ok(!si.dwStart, "got %lu.\n", si.dwStart); + ok(si.dwSuggestedBufferSize == 16, "got %lu.\n", si.dwSuggestedBufferSize); + IAVIStream_Release(stm); IAVIFile_Release(avifile); ret = DeleteFileW(fn);