📄 api.c
字号:
PAVISTREAM *ppas = &pInStreams[curStream];
int n = nStreams - (curStream + 1);
do {
*ppas = pInStreams[curStream + 1];
} while (--n);
}
nStreams--;
curStream--;
}
} /* create output streams for all input streams */
/* have we still something to write, or lost everything? */
if (nStreams <= 0)
goto error;
if (dwInterleave) {
LONG lCurFrame = -dwFileInitialFrames;
/* interleaved file */
if (dwInterleave == 1)
AVIFileEndRecord(pfile);
for (; lCurFrame < lFileLength; lCurFrame += lSampleInc) {
for (curStream = 0; curStream < nStreams; curStream++) {
LONG lLastSample;
hres = AVIStreamInfoW(pOutStreams[curStream], &sInfo, sizeof(sInfo));
if (FAILED(hres))
goto error;
/* initial frames phase at the end for this stream? */
if (-(LONG)sInfo.dwInitialFrames > lCurFrame)
continue;
if ((lFileLength - lSampleInc) <= lCurFrame) {
lLastSample = AVIStreamLength(pInStreams[curStream]);
lFirstVideo = lLastSample + AVIStreamStart(pInStreams[curStream]);
} else {
if (curStream != 0) {
lFirstVideo =
AVIStreamSampleToSample(pInStreams[curStream], pInStreams[0],
(sInfo.fccType == streamtypeVIDEO ?
(LONG)dwInterleave : lSampleInc) +
sInfo.dwInitialFrames + lCurFrame);
} else
lFirstVideo = lSampleInc + (sInfo.dwInitialFrames + lCurFrame);
lLastSample = AVIStreamEnd(pInStreams[curStream]);
if (lLastSample <= lFirstVideo)
lFirstVideo = lLastSample;
}
/* copy needed samples now */
WARN("copy from stream %d samples %d to %d...\n",curStream,
lStart[curStream],lFirstVideo);
while (lFirstVideo > lStart[curStream]) {
DWORD flags = 0;
/* copy format in case it can change */
lBufferSize = cbBuffer;
hres = AVIStreamReadFormat(pInStreams[curStream], lStart[curStream],
lpBuffer, &lBufferSize);
if (FAILED(hres))
goto error;
AVIStreamSetFormat(pOutStreams[curStream], lStart[curStream],
lpBuffer, lBufferSize);
/* try to read data until we got it, or error */
do {
hres = AVIStreamRead(pInStreams[curStream], lStart[curStream],
lFirstVideo - lStart[curStream], lpBuffer,
cbBuffer, &lReadBytes, &lReadSamples);
} while ((hres == AVIERR_BUFFERTOOSMALL) &&
(lpBuffer = HeapReAlloc(GetProcessHeap(), 0, lpBuffer, cbBuffer *= 2)) != NULL);
if (lpBuffer == NULL)
hres = AVIERR_MEMORY;
if (FAILED(hres))
goto error;
if (AVIStreamIsKeyFrame(pInStreams[curStream], (LONG)sInfo.dwStart))
flags = AVIIF_KEYFRAME;
hres = AVIStreamWrite(pOutStreams[curStream], -1, lReadSamples,
lpBuffer, lReadBytes, flags, NULL, NULL);
if (FAILED(hres))
goto error;
lStart[curStream] += lReadSamples;
}
lStart[curStream] = lFirstVideo;
} /* stream by stream */
/* need to close this block? */
if (dwInterleave == 1) {
hres = AVIFileEndRecord(pfile);
if (FAILED(hres))
break;
}
/* show progress */
if (lpfnCallback(MulDiv(dwFileInitialFrames + lCurFrame, 100,
dwFileInitialFrames + lFileLength))) {
hres = AVIERR_USERABORT;
break;
}
} /* copy frame by frame */
} else {
/* non-interleaved file */
for (curStream = 0; curStream < nStreams; curStream++) {
/* show progress */
if (lpfnCallback(MulDiv(curStream, 100, nStreams))) {
hres = AVIERR_USERABORT;
goto error;
}
AVIStreamInfoW(pInStreams[curStream], &sInfo, sizeof(sInfo));
if (sInfo.dwSampleSize != 0) {
/* sample-based data like audio */
while (sInfo.dwStart < sInfo.dwLength) {
LONG lSamples = cbBuffer / sInfo.dwSampleSize;
/* copy format in case it can change */
lBufferSize = cbBuffer;
hres = AVIStreamReadFormat(pInStreams[curStream], sInfo.dwStart,
lpBuffer, &lBufferSize);
if (FAILED(hres))
return hres;
AVIStreamSetFormat(pOutStreams[curStream], sInfo.dwStart,
lpBuffer, lBufferSize);
/* limit to stream boundaries */
if (lSamples != (LONG)(sInfo.dwLength - sInfo.dwStart))
lSamples = sInfo.dwLength - sInfo.dwStart;
/* now try to read until we get it, or an error occurs */
do {
lReadBytes = cbBuffer;
lReadSamples = 0;
hres = AVIStreamRead(pInStreams[curStream],sInfo.dwStart,lSamples,
lpBuffer,cbBuffer,&lReadBytes,&lReadSamples);
} while ((hres == AVIERR_BUFFERTOOSMALL) &&
(lpBuffer = HeapReAlloc(GetProcessHeap(), 0, lpBuffer, cbBuffer *= 2)) != NULL);
if (lpBuffer == NULL)
hres = AVIERR_MEMORY;
if (FAILED(hres))
goto error;
if (lReadSamples != 0) {
sInfo.dwStart += lReadSamples;
hres = AVIStreamWrite(pOutStreams[curStream], -1, lReadSamples,
lpBuffer, lReadBytes, 0, NULL , NULL);
if (FAILED(hres))
goto error;
/* show progress */
if (lpfnCallback(MulDiv(sInfo.dwStart,100,nStreams*sInfo.dwLength)+
MulDiv(curStream, 100, nStreams))) {
hres = AVIERR_USERABORT;
goto error;
}
} else {
if ((sInfo.dwLength - sInfo.dwStart) != 1) {
hres = AVIERR_FILEREAD;
goto error;
}
}
}
} else {
/* block-based data like video */
for (; sInfo.dwStart < sInfo.dwLength; sInfo.dwStart++) {
DWORD flags = 0;
/* copy format in case it can change */
lBufferSize = cbBuffer;
hres = AVIStreamReadFormat(pInStreams[curStream], sInfo.dwStart,
lpBuffer, &lBufferSize);
if (FAILED(hres))
goto error;
AVIStreamSetFormat(pOutStreams[curStream], sInfo.dwStart,
lpBuffer, lBufferSize);
/* try to read block and resize buffer if necessary */
do {
lReadSamples = 0;
lReadBytes = cbBuffer;
hres = AVIStreamRead(pInStreams[curStream], sInfo.dwStart, 1,
lpBuffer, cbBuffer,&lReadBytes,&lReadSamples);
} while ((hres == AVIERR_BUFFERTOOSMALL) &&
(lpBuffer = HeapReAlloc(GetProcessHeap(), 0, lpBuffer, cbBuffer *= 2)) != NULL);
if (lpBuffer == NULL)
hres = AVIERR_MEMORY;
if (FAILED(hres))
goto error;
if (lReadSamples != 1) {
hres = AVIERR_FILEREAD;
goto error;
}
if (AVIStreamIsKeyFrame(pInStreams[curStream], (LONG)sInfo.dwStart))
flags = AVIIF_KEYFRAME;
hres = AVIStreamWrite(pOutStreams[curStream], -1, lReadSamples,
lpBuffer, lReadBytes, flags, NULL, NULL);
if (FAILED(hres))
goto error;
/* show progress */
if (lpfnCallback(MulDiv(sInfo.dwStart,100,nStreams*sInfo.dwLength)+
MulDiv(curStream, 100, nStreams))) {
hres = AVIERR_USERABORT;
goto error;
}
} /* copy all blocks */
}
} /* copy data stream by stream */
}
error:
HeapFree(GetProcessHeap(), 0, lpBuffer);
if (pfile != NULL) {
for (curStream = 0; curStream < nStreams; curStream++) {
if (pOutStreams[curStream] != NULL)
AVIStreamRelease(pOutStreams[curStream]);
if (pInStreams[curStream] != NULL)
AVIStreamRelease(pInStreams[curStream]);
}
AVIFileRelease(pfile);
}
return hres;
}
/***********************************************************************
* CreateEditableStream (AVIFIL32.@)
*/
HRESULT WINAPI CreateEditableStream(PAVISTREAM *ppEditable, PAVISTREAM pSource)
{
IAVIEditStream *pEdit = NULL;
HRESULT hr;
TRACE("(%p,%p)\n", ppEditable, pSource);
if (ppEditable == NULL)
return AVIERR_BADPARAM;
*ppEditable = NULL;
if (pSource != NULL) {
hr = IAVIStream_QueryInterface(pSource, &IID_IAVIEditStream,
(LPVOID*)&pEdit);
if (SUCCEEDED(hr) && pEdit != NULL) {
hr = IAVIEditStream_Clone(pEdit, ppEditable);
IAVIEditStream_Release(pEdit);
return hr;
}
}
/* need own implementation of IAVIEditStream */
pEdit = AVIFILE_CreateEditStream(pSource);
if (pEdit == NULL)
return AVIERR_MEMORY;
hr = IAVIEditStream_QueryInterface(pEdit, &IID_IAVIStream,
(LPVOID*)ppEditable);
IAVIEditStream_Release(pEdit);
return hr;
}
/***********************************************************************
* EditStreamClone (AVIFIL32.@)
*/
HRESULT WINAPI EditStreamClone(PAVISTREAM pStream, PAVISTREAM *ppResult)
{
PAVIEDITSTREAM pEdit = NULL;
HRESULT hr;
TRACE("(%p,%p)\n", pStream, ppResult);
if (pStream == NULL)
return AVIERR_BADHANDLE;
if (ppResult == NULL)
return AVIERR_BADPARAM;
*ppResult = NULL;
hr = IAVIStream_QueryInterface(pStream, &IID_IAVIEditStream,(LPVOID*)&pEdit);
if (SUCCEEDED(hr) && pEdit != NULL) {
hr = IAVIEditStream_Clone(pEdit, ppResult);
IAVIEditStream_Release(pEdit);
} else
hr = AVIERR_UNSUPPORTED;
return hr;
}
/***********************************************************************
* EditStreamCopy (AVIFIL32.@)
*/
HRESULT WINAPI EditStreamCopy(PAVISTREAM pStream, LONG *plStart,
LONG *plLength, PAVISTREAM *ppResult)
{
PAVIEDITSTREAM pEdit = NULL;
HRESULT hr;
TRACE("(%p,%p,%p,%p)\n", pStream, plStart, plLength, ppResult);
if (pStream == NULL)
return AVIERR_BADHANDLE;
if (plStart == NULL || plLength == NULL || ppResult == NULL)
return AVIERR_BADPARAM;
*ppResult = NULL;
hr = IAVIStream_QueryInterface(pStream, &IID_IAVIEditStream,(LPVOID*)&pEdit);
if (SUCCEEDED(hr) && pEdit != NULL) {
hr = IAVIEditStream_Copy(pEdit, plStart, plLength, ppResult);
IAVIEditStream_Release(pEdit);
} else
hr = AVIERR_UNSUPPORTED;
return hr;
}
/***********************************************************************
* EditStreamCut (AVIFIL32.@)
*/
HRESULT WINAPI EditStreamCut(PAVISTREAM pStream, LONG *plStart,
LONG *plLength, PAVISTREAM *ppResult)
{
PAVIEDITSTREAM pEdit = NULL;
HRESULT hr;
TRACE("(%p,%p,%p,%p)\n", pStream, plStart, plLength, ppResult);
if (ppResult != NULL)
*ppResult = NULL;
if (pStream == NULL)
return AVIERR_BADHANDLE;
if (plStart == NULL || plLength == NULL)
return AVIERR_BADPARAM;
hr = IAVIStream_QueryInterface(pStream, &IID_IAVIEditStream,(LPVOID*)&pEdit);
if (SUCCEEDED(hr) && pEdit != NULL) {
hr = IAVIEditStream_Cut(pEdit, plStart, plLength, ppResult);
IAVIEditStream_Release(pEdit);
} else
hr = AVIERR_UNSUPPORTED;
return hr;
}
/***********************************************************************
* EditStreamPaste (AVIFIL32.@)
*/
HRESULT WINAPI EditStreamPaste(PAVISTREAM pDest, LONG *plStart, LONG *plLength,
PAVISTREAM pSource, LONG lStart, LONG lEnd)
{
PAVIEDITSTREAM pEdit = NULL;
HRESULT hr;
TRACE("(%p,%p,%p,%p,%d,%d)\n", pDest, plStart, plLength,
pSource, lStart, lEnd);
if (pDest == NULL || pSource == NULL)
return AVIERR_BADHANDLE;
if (plStart == NULL || plLength == NULL || lStart < 0)
return AVIERR_BADPARAM;
hr = IAVIStream_QueryInterface(pDest, &IID_IAVIEditStream,(LPVOID*)&pEdit);
if (SUCCEEDED(hr) && pEdit != NULL) {
hr = IAVIEditStream_Paste(pEdit, plStart, plLength, pSource, lStart, lEnd);
IAVIEditStream_Release(pEdit);
} else
hr = AVIERR_UNSUPPORTED;
return hr;
}
/***********************************************************************
* EditStreamSetInfoA (AVIFIL32.@)
*/
HRESULT WINAPI EditStreamSetInfoA(PAVISTREAM pstream, LPAVISTREAMINFOA asi,
LONG size)
{
AVISTREAMINFOW asiw;
TRACE("(%p,%p,%d)\n", pstream, asi, size);
if (pstream == NULL)
return AVIERR_BADHANDLE;
if ((DWORD)size < sizeof(AVISTREAMINFOA))
return AVIERR_BADSIZE;
memcpy(&asiw, asi, sizeof(asiw) - sizeof(asiw.szName));
MultiByteToWideChar(CP_ACP, 0, asi->szName, -1,
asiw.szName, sizeof(asiw.szName)/sizeof(WCHAR));
return EditStreamSetInfoW(pstream, &asiw, sizeof(asiw));
}
/***********************************************************************
* EditStreamSetInfoW (AVIFIL32.@)
*/
HRESULT WINAPI EditStreamSetInfoW(PAVISTREAM pstream, LPAVISTREAMINFOW asi,
LONG size)
{
PAVIEDITSTREAM pEdit = NULL;
HRESULT hr;
TRACE("(%p,%p,%d)\n", pstream, asi, size);
hr = IAVIStream_QueryInterface(pstream, &IID_IAVIEditStream,(LPVOID*)&pEdit);
if (SUCCEEDED(hr) && pEdit != NULL) {
hr = IAVIEditStream_SetInfo(pEdit, asi, size);
IAVIEditStream_Release(pEdit);
} else
hr = AVIERR_UNSUPPORTED;
return hr;
}
/***********************************************************************
* EditStreamSetNameA (AVIFIL32.@)
*/
HRESULT WINAPI EditStreamSetNameA(PAVISTREAM pstream, LPCSTR szName)
{
AVISTREAMINFOA asia;
HRESULT hres;
TRACE("(%p,%s)\n", pstream, debugstr_a(szName));
if (pstream == NULL)
return AVIERR_BADHANDLE;
if (szName == NULL)
return AVIERR_BADPARAM;
hres = AVIStreamInfoA(pstream, &
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -