LONG block = start;
LONG offset = 0;
+ if (!buffer)
+ {
+ if (bytesread)
+ *bytesread = samples*This->sInfo.dwSampleSize;
+ if (samplesread)
+ *samplesread = samples;
+ return AVIERR_OK;
+ }
+
/* convert start sample to block,offset pair */
AVIFILE_SamplesToBlock(This, &block, &offset);
samples *= This->sInfo.dwSampleSize;
while (samples > 0 && buffersize > 0) {
+ LONG blocksize;
if (block != This->dwCurrentFrame) {
hr = AVIFILE_ReadBlock(This, block, NULL, 0);
if (FAILED(hr))
}
size = min((DWORD)samples, (DWORD)buffersize);
- size = min(size, This->cbBuffer - offset);
+ blocksize = This->lpBuffer[1];
+ TRACE("blocksize = %u\n",blocksize);
+ size = min(size, blocksize - offset);
memcpy(buffer, ((BYTE*)&This->lpBuffer[2]) + offset, size);
block++;
static HRESULT AVIFILE_AddFrame(IAVIStreamImpl *This, DWORD ckid, DWORD size, DWORD offset, DWORD flags)
{
+ UINT n;
+
/* pre-conditions */
assert(This != NULL);
ERR(": found palette change in non-video stream!\n");
return AVIERR_BADFORMAT;
}
- This->sInfo.dwFlags |= AVISTREAMINFO_FORMATCHANGES;
- This->sInfo.dwFormatChangeCount++;
- if (This->idxFmtChanges == NULL || This->sInfo.dwFormatChangeCount < This->nIdxFmtChanges) {
- UINT n = This->sInfo.dwFormatChangeCount;
+ if (This->idxFmtChanges == NULL || This->nIdxFmtChanges <= This->sInfo.dwFormatChangeCount) {
+ DWORD new_count = This->nIdxFmtChanges + 16;
+ void *new_buffer;
- This->nIdxFmtChanges += 16;
- if (This->idxFmtChanges == NULL)
+ if (This->idxFmtChanges == NULL) {
This->idxFmtChanges =
- HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->nIdxFmtChanges * sizeof(AVIINDEXENTRY));
- else
- This->idxFmtChanges =
- HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->idxFmtChanges,
- This->nIdxFmtChanges * sizeof(AVIINDEXENTRY));
- if (This->idxFmtChanges == NULL)
- return AVIERR_MEMORY;
+ HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, new_count * sizeof(AVIINDEXENTRY));
+ if (!This->idxFmtChanges) return AVIERR_MEMORY;
+ } else {
+ new_buffer = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->idxFmtChanges,
+ new_count * sizeof(AVIINDEXENTRY));
+ if (!new_buffer) return AVIERR_MEMORY;
+ This->idxFmtChanges = new_buffer;
+ }
+ This->nIdxFmtChanges = new_count;
+ }
- This->idxFmtChanges[n].ckid = This->lLastFrame;
- This->idxFmtChanges[n].dwFlags = 0;
- This->idxFmtChanges[n].dwChunkOffset = offset;
- This->idxFmtChanges[n].dwChunkLength = size;
+ This->sInfo.dwFlags |= AVISTREAMINFO_FORMATCHANGES;
+ n = ++This->sInfo.dwFormatChangeCount;
+ This->idxFmtChanges[n].ckid = This->lLastFrame;
+ This->idxFmtChanges[n].dwFlags = 0;
+ This->idxFmtChanges[n].dwChunkOffset = offset;
+ This->idxFmtChanges[n].dwChunkLength = size;
- return AVIERR_OK;
- }
- break;
+ return AVIERR_OK;
case cktypeWAVEbytes:
if (This->paf->fInfo.dwFlags & AVIFILEINFO_TRUSTCKTYPE)
flags |= AVIIF_KEYFRAME;
This->fInfo.dwCaps = AVIFILECAPS_CANREAD|AVIFILECAPS_CANWRITE;
This->fInfo.dwLength = MainAVIHdr.dwTotalFrames;
This->fInfo.dwStreams = MainAVIHdr.dwStreams;
- This->fInfo.dwSuggestedBufferSize = MainAVIHdr.dwSuggestedBufferSize;
+ This->fInfo.dwSuggestedBufferSize = 0;
This->fInfo.dwWidth = MainAVIHdr.dwWidth;
This->fInfo.dwHeight = MainAVIHdr.dwHeight;
LoadStringW(AVIFILE_hModule, IDS_AVIFILETYPE, This->fInfo.szFileType,
pStream->sInfo.dwRate = streamHdr.dwRate;
pStream->sInfo.dwStart = streamHdr.dwStart;
pStream->sInfo.dwLength = streamHdr.dwLength;
- pStream->sInfo.dwSuggestedBufferSize =
- streamHdr.dwSuggestedBufferSize;
+ pStream->sInfo.dwSuggestedBufferSize = 0;
pStream->sInfo.dwQuality = streamHdr.dwQuality;
pStream->sInfo.dwSampleSize = streamHdr.dwSampleSize;
pStream->sInfo.rcFrame.left = streamHdr.rcFrame.left;
if (FAILED(hr))
return hr;
};
-
+ if (pStream->lpFormat != NULL && pStream->sInfo.fccType == streamtypeAUDIO)
+ {
+ WAVEFORMATEX *wfx = pStream->lpFormat; /* wfx->nBlockAlign = wfx->nChannels * wfx->wBitsPerSample / 8; could be added */
+ pStream->sInfo.dwSampleSize = wfx->nBlockAlign; /* to deal with corrupt wfx->nBlockAlign but Windows doesn't do this */
+ TRACE("Block size reset to %u, chan=%u bpp=%u\n", wfx->nBlockAlign, wfx->nChannels, wfx->wBitsPerSample);
+ pStream->sInfo.dwScale = 1;
+ pStream->sInfo.dwRate = wfx->nSamplesPerSec;
+ }
if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
return AVIERR_FILEREAD;
}
}
}
+ for (nStream = 0; nStream < This->fInfo.dwStreams; nStream++)
+ {
+ DWORD sugbuf = This->ppStreams[nStream]->sInfo.dwSuggestedBufferSize;
+ if (This->fInfo.dwSuggestedBufferSize < sugbuf)
+ This->fInfo.dwSuggestedBufferSize = sugbuf;
+ }
+
/* find other chunks */
FindChunkAndKeepExtras(&This->fileextra, This->hmmio, &ck, &ckRIFF, 0);
size += 2 * sizeof(DWORD);
/* check that buffer is big enough -- don't trust dwSuggestedBufferSize */
- if (This->lpBuffer == NULL || size < This->cbBuffer) {
+ if (This->lpBuffer == NULL || This->cbBuffer < size) {
DWORD maxSize = max(size, This->sInfo.dwSuggestedBufferSize);
- if (This->lpBuffer == NULL)
+ if (This->lpBuffer == NULL) {
This->lpBuffer = HeapAlloc(GetProcessHeap(), 0, maxSize);
- else
- This->lpBuffer = HeapReAlloc(GetProcessHeap(), 0, This->lpBuffer, maxSize);
- if (This->lpBuffer == NULL)
- return AVIERR_MEMORY;
- This->cbBuffer = max(size, This->sInfo.dwSuggestedBufferSize);
+ if (!This->lpBuffer) return AVIERR_MEMORY;
+ } else {
+ void *new_buffer = HeapReAlloc(GetProcessHeap(), 0, This->lpBuffer, maxSize);
+ if (!new_buffer) return AVIERR_MEMORY;
+ This->lpBuffer = new_buffer;
+ }
+ This->cbBuffer = maxSize;
}
/* now read the complete chunk into our buffer */