Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenapi.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 1999 Marcus Meissner 00003 * Copyright 2002-2003 Michael Günnewig 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public 00016 * License along with this library; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00018 */ 00019 00020 #include <stdarg.h> 00021 00022 #define COBJMACROS 00023 00024 #include "windef.h" 00025 #include "winbase.h" 00026 #include "winnls.h" 00027 #include "wingdi.h" 00028 #include "winuser.h" 00029 #include "winreg.h" 00030 #include "winerror.h" 00031 00032 #include "ole2.h" 00033 #include "shellapi.h" 00034 #include "shlobj.h" 00035 #include "vfw.h" 00036 #include "msacm.h" 00037 00038 #include "avifile_private.h" 00039 00040 #include "wine/debug.h" 00041 #include "wine/unicode.h" 00042 00043 WINE_DEFAULT_DEBUG_CHANNEL(avifile); 00044 00045 00046 /*********************************************************************** 00047 * for AVIBuildFilterW -- uses fixed size table 00048 */ 00049 #define MAX_FILTERS 30 /* 30 => 7kB */ 00050 00051 typedef struct _AVIFilter { 00052 WCHAR szClsid[40]; 00053 WCHAR szExtensions[MAX_FILTERS * 7]; 00054 } AVIFilter; 00055 00056 /*********************************************************************** 00057 * for AVISaveOptions 00058 */ 00059 static struct { 00060 UINT uFlags; 00061 INT nStreams; 00062 PAVISTREAM *ppavis; 00063 LPAVICOMPRESSOPTIONS *ppOptions; 00064 INT nCurrent; 00065 } SaveOpts; 00066 00067 /*********************************************************************** 00068 * copied from dlls/ole32/compobj.c 00069 */ 00070 static HRESULT AVIFILE_CLSIDFromString(LPCSTR idstr, LPCLSID id) 00071 { 00072 BYTE const *s; 00073 BYTE *p; 00074 INT i; 00075 BYTE table[256]; 00076 00077 if (!idstr) { 00078 memset(id, 0, sizeof(CLSID)); 00079 return S_OK; 00080 } 00081 00082 /* validate the CLSID string */ 00083 if (lstrlenA(idstr) != 38) 00084 return CO_E_CLASSSTRING; 00085 00086 s = (BYTE const*)idstr; 00087 if ((s[0]!='{') || (s[9]!='-') || (s[14]!='-') || (s[19]!='-') || 00088 (s[24]!='-') || (s[37]!='}')) 00089 return CO_E_CLASSSTRING; 00090 00091 for (i = 1; i < 37; i++) { 00092 if ((i == 9) || (i == 14) || (i == 19) || (i == 24)) 00093 continue; 00094 if (!(((s[i] >= '0') && (s[i] <= '9')) || 00095 ((s[i] >= 'a') && (s[i] <= 'f')) || 00096 ((s[i] >= 'A') && (s[i] <= 'F'))) 00097 ) 00098 return CO_E_CLASSSTRING; 00099 } 00100 00101 TRACE("%s -> %p\n", s, id); 00102 00103 /* quick lookup table */ 00104 memset(table, 0, 256); 00105 00106 for (i = 0; i < 10; i++) 00107 table['0' + i] = i; 00108 00109 for (i = 0; i < 6; i++) { 00110 table['A' + i] = i+10; 00111 table['a' + i] = i+10; 00112 } 00113 00114 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */ 00115 p = (BYTE *) id; 00116 00117 s++; /* skip leading brace */ 00118 for (i = 0; i < 4; i++) { 00119 p[3 - i] = table[*s]<<4 | table[*(s+1)]; 00120 s += 2; 00121 } 00122 p += 4; 00123 s++; /* skip - */ 00124 00125 for (i = 0; i < 2; i++) { 00126 p[1-i] = table[*s]<<4 | table[*(s+1)]; 00127 s += 2; 00128 } 00129 p += 2; 00130 s++; /* skip - */ 00131 00132 for (i = 0; i < 2; i++) { 00133 p[1-i] = table[*s]<<4 | table[*(s+1)]; 00134 s += 2; 00135 } 00136 p += 2; 00137 s++; /* skip - */ 00138 00139 /* these are just sequential bytes */ 00140 for (i = 0; i < 2; i++) { 00141 *p++ = table[*s]<<4 | table[*(s+1)]; 00142 s += 2; 00143 } 00144 s++; /* skip - */ 00145 00146 for (i = 0; i < 6; i++) { 00147 *p++ = table[*s]<<4 | table[*(s+1)]; 00148 s += 2; 00149 } 00150 00151 return S_OK; 00152 } 00153 00154 static BOOL AVIFILE_GetFileHandlerByExtension(LPCWSTR szFile, LPCLSID lpclsid) 00155 { 00156 CHAR szRegKey[25]; 00157 CHAR szValue[100]; 00158 LPWSTR szExt = strrchrW(szFile, '.'); 00159 LONG len = sizeof(szValue) / sizeof(szValue[0]); 00160 00161 if (szExt == NULL) 00162 return FALSE; 00163 00164 szExt++; 00165 00166 wsprintfA(szRegKey, "AVIFile\\Extensions\\%.3ls", szExt); 00167 if (RegQueryValueA(HKEY_CLASSES_ROOT, szRegKey, szValue, &len) != ERROR_SUCCESS) 00168 return FALSE; 00169 00170 return (AVIFILE_CLSIDFromString(szValue, lpclsid) == S_OK); 00171 } 00172 00173 /*********************************************************************** 00174 * AVIFileInit (AVIFIL32.@) 00175 */ 00176 void WINAPI AVIFileInit(void) { 00177 OleInitialize(NULL); 00178 } 00179 00180 /*********************************************************************** 00181 * AVIFileExit (AVIFIL32.@) 00182 */ 00183 void WINAPI AVIFileExit(void) { 00184 /* need to free ole32.dll if we are the last exit call */ 00185 /* OleUninitialize() */ 00186 FIXME("(): stub!\n"); 00187 } 00188 00189 /*********************************************************************** 00190 * AVIFileOpen (AVIFIL32.@) 00191 * AVIFileOpenA (AVIFIL32.@) 00192 */ 00193 HRESULT WINAPI AVIFileOpenA(PAVIFILE *ppfile, LPCSTR szFile, UINT uMode, 00194 LPCLSID lpHandler) 00195 { 00196 LPWSTR wszFile = NULL; 00197 HRESULT hr; 00198 int len; 00199 00200 TRACE("(%p,%s,0x%08X,%s)\n", ppfile, debugstr_a(szFile), uMode, 00201 debugstr_guid(lpHandler)); 00202 00203 /* check parameters */ 00204 if (ppfile == NULL || szFile == NULL) 00205 return AVIERR_BADPARAM; 00206 00207 /* convert ASCII string to Unicode and call unicode function */ 00208 len = MultiByteToWideChar(CP_ACP, 0, szFile, -1, NULL, 0); 00209 if (len <= 0) 00210 return AVIERR_BADPARAM; 00211 00212 wszFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 00213 if (wszFile == NULL) 00214 return AVIERR_MEMORY; 00215 00216 MultiByteToWideChar(CP_ACP, 0, szFile, -1, wszFile, len); 00217 00218 hr = AVIFileOpenW(ppfile, wszFile, uMode, lpHandler); 00219 00220 HeapFree(GetProcessHeap(), 0, wszFile); 00221 00222 return hr; 00223 } 00224 00225 /*********************************************************************** 00226 * AVIFileOpenW (AVIFIL32.@) 00227 */ 00228 HRESULT WINAPI AVIFileOpenW(PAVIFILE *ppfile, LPCWSTR szFile, UINT uMode, 00229 LPCLSID lpHandler) 00230 { 00231 IPersistFile *ppersist = NULL; 00232 CLSID clsidHandler; 00233 HRESULT hr; 00234 00235 TRACE("(%p,%s,0x%X,%s)\n", ppfile, debugstr_w(szFile), uMode, 00236 debugstr_guid(lpHandler)); 00237 00238 /* check parameters */ 00239 if (ppfile == NULL || szFile == NULL) 00240 return AVIERR_BADPARAM; 00241 00242 *ppfile = NULL; 00243 00244 /* if no handler then try guessing it by extension */ 00245 if (lpHandler == NULL) { 00246 if (! AVIFILE_GetFileHandlerByExtension(szFile, &clsidHandler)) 00247 clsidHandler = CLSID_AVIFile; 00248 } else 00249 clsidHandler = *lpHandler; 00250 00251 /* create instance of handler */ 00252 hr = CoCreateInstance(&clsidHandler, NULL, CLSCTX_INPROC, &IID_IAVIFile, (LPVOID*)ppfile); 00253 if (FAILED(hr) || *ppfile == NULL) 00254 return hr; 00255 00256 /* ask for IPersistFile interface for loading/creating the file */ 00257 hr = IAVIFile_QueryInterface(*ppfile, &IID_IPersistFile, (LPVOID*)&ppersist); 00258 if (FAILED(hr) || ppersist == NULL) { 00259 IAVIFile_Release(*ppfile); 00260 *ppfile = NULL; 00261 return hr; 00262 } 00263 00264 hr = IPersistFile_Load(ppersist, szFile, uMode); 00265 IPersistFile_Release(ppersist); 00266 if (FAILED(hr)) { 00267 IAVIFile_Release(*ppfile); 00268 *ppfile = NULL; 00269 } 00270 00271 return hr; 00272 } 00273 00274 /*********************************************************************** 00275 * AVIFileAddRef (AVIFIL32.@) 00276 */ 00277 ULONG WINAPI AVIFileAddRef(PAVIFILE pfile) 00278 { 00279 TRACE("(%p)\n", pfile); 00280 00281 if (pfile == NULL) { 00282 ERR(": bad handle passed!\n"); 00283 return 0; 00284 } 00285 00286 return IAVIFile_AddRef(pfile); 00287 } 00288 00289 /*********************************************************************** 00290 * AVIFileRelease (AVIFIL32.@) 00291 */ 00292 ULONG WINAPI AVIFileRelease(PAVIFILE pfile) 00293 { 00294 TRACE("(%p)\n", pfile); 00295 00296 if (pfile == NULL) { 00297 ERR(": bad handle passed!\n"); 00298 return 0; 00299 } 00300 00301 return IAVIFile_Release(pfile); 00302 } 00303 00304 /*********************************************************************** 00305 * AVIFileInfo (AVIFIL32.@) 00306 * AVIFileInfoA (AVIFIL32.@) 00307 */ 00308 HRESULT WINAPI AVIFileInfoA(PAVIFILE pfile, LPAVIFILEINFOA afi, LONG size) 00309 { 00310 AVIFILEINFOW afiw; 00311 HRESULT hres; 00312 00313 TRACE("(%p,%p,%d)\n", pfile, afi, size); 00314 00315 if (pfile == NULL) 00316 return AVIERR_BADHANDLE; 00317 if ((DWORD)size < sizeof(AVIFILEINFOA)) 00318 return AVIERR_BADSIZE; 00319 00320 hres = IAVIFile_Info(pfile, &afiw, sizeof(afiw)); 00321 00322 memcpy(afi, &afiw, sizeof(*afi) - sizeof(afi->szFileType)); 00323 WideCharToMultiByte(CP_ACP, 0, afiw.szFileType, -1, afi->szFileType, 00324 sizeof(afi->szFileType), NULL, NULL); 00325 afi->szFileType[sizeof(afi->szFileType) - 1] = 0; 00326 00327 return hres; 00328 } 00329 00330 /*********************************************************************** 00331 * AVIFileInfoW (AVIFIL32.@) 00332 */ 00333 HRESULT WINAPI AVIFileInfoW(PAVIFILE pfile, LPAVIFILEINFOW afiw, LONG size) 00334 { 00335 TRACE("(%p,%p,%d)\n", pfile, afiw, size); 00336 00337 if (pfile == NULL) 00338 return AVIERR_BADHANDLE; 00339 00340 return IAVIFile_Info(pfile, afiw, size); 00341 } 00342 00343 /*********************************************************************** 00344 * AVIFileGetStream (AVIFIL32.@) 00345 */ 00346 HRESULT WINAPI AVIFileGetStream(PAVIFILE pfile, PAVISTREAM *avis, 00347 DWORD fccType, LONG lParam) 00348 { 00349 TRACE("(%p,%p,'%4.4s',%d)\n", pfile, avis, (char*)&fccType, lParam); 00350 00351 if (pfile == NULL) 00352 return AVIERR_BADHANDLE; 00353 00354 return IAVIFile_GetStream(pfile, avis, fccType, lParam); 00355 } 00356 00357 /*********************************************************************** 00358 * AVIFileCreateStream (AVIFIL32.@) 00359 * AVIFileCreateStreamA (AVIFIL32.@) 00360 */ 00361 HRESULT WINAPI AVIFileCreateStreamA(PAVIFILE pfile, PAVISTREAM *ppavi, 00362 LPAVISTREAMINFOA psi) 00363 { 00364 AVISTREAMINFOW psiw; 00365 00366 TRACE("(%p,%p,%p)\n", pfile, ppavi, psi); 00367 00368 if (pfile == NULL) 00369 return AVIERR_BADHANDLE; 00370 00371 /* Only the szName at the end is different */ 00372 memcpy(&psiw, psi, sizeof(*psi) - sizeof(psi->szName)); 00373 MultiByteToWideChar(CP_ACP, 0, psi->szName, -1, psiw.szName, 00374 sizeof(psiw.szName) / sizeof(psiw.szName[0])); 00375 00376 return IAVIFile_CreateStream(pfile, ppavi, &psiw); 00377 } 00378 00379 /*********************************************************************** 00380 * AVIFileCreateStreamW (AVIFIL32.@) 00381 */ 00382 HRESULT WINAPI AVIFileCreateStreamW(PAVIFILE pfile, PAVISTREAM *avis, 00383 LPAVISTREAMINFOW asi) 00384 { 00385 TRACE("(%p,%p,%p)\n", pfile, avis, asi); 00386 00387 if (pfile == NULL) 00388 return AVIERR_BADHANDLE; 00389 00390 return IAVIFile_CreateStream(pfile, avis, asi); 00391 } 00392 00393 /*********************************************************************** 00394 * AVIFileWriteData (AVIFIL32.@) 00395 */ 00396 HRESULT WINAPI AVIFileWriteData(PAVIFILE pfile,DWORD fcc,LPVOID lp,LONG size) 00397 { 00398 TRACE("(%p,'%4.4s',%p,%d)\n", pfile, (char*)&fcc, lp, size); 00399 00400 if (pfile == NULL) 00401 return AVIERR_BADHANDLE; 00402 00403 return IAVIFile_WriteData(pfile, fcc, lp, size); 00404 } 00405 00406 /*********************************************************************** 00407 * AVIFileReadData (AVIFIL32.@) 00408 */ 00409 HRESULT WINAPI AVIFileReadData(PAVIFILE pfile,DWORD fcc,LPVOID lp,LPLONG size) 00410 { 00411 TRACE("(%p,'%4.4s',%p,%p)\n", pfile, (char*)&fcc, lp, size); 00412 00413 if (pfile == NULL) 00414 return AVIERR_BADHANDLE; 00415 00416 return IAVIFile_ReadData(pfile, fcc, lp, size); 00417 } 00418 00419 /*********************************************************************** 00420 * AVIFileEndRecord (AVIFIL32.@) 00421 */ 00422 HRESULT WINAPI AVIFileEndRecord(PAVIFILE pfile) 00423 { 00424 TRACE("(%p)\n", pfile); 00425 00426 if (pfile == NULL) 00427 return AVIERR_BADHANDLE; 00428 00429 return IAVIFile_EndRecord(pfile); 00430 } 00431 00432 /*********************************************************************** 00433 * AVIStreamAddRef (AVIFIL32.@) 00434 */ 00435 ULONG WINAPI AVIStreamAddRef(PAVISTREAM pstream) 00436 { 00437 TRACE("(%p)\n", pstream); 00438 00439 if (pstream == NULL) { 00440 ERR(": bad handle passed!\n"); 00441 return 0; 00442 } 00443 00444 return IAVIStream_AddRef(pstream); 00445 } 00446 00447 /*********************************************************************** 00448 * AVIStreamRelease (AVIFIL32.@) 00449 */ 00450 ULONG WINAPI AVIStreamRelease(PAVISTREAM pstream) 00451 { 00452 TRACE("(%p)\n", pstream); 00453 00454 if (pstream == NULL) { 00455 ERR(": bad handle passed!\n"); 00456 return 0; 00457 } 00458 00459 return IAVIStream_Release(pstream); 00460 } 00461 00462 /*********************************************************************** 00463 * AVIStreamCreate (AVIFIL32.@) 00464 */ 00465 HRESULT WINAPI AVIStreamCreate(PAVISTREAM *ppavi, LONG lParam1, LONG lParam2, 00466 LPCLSID pclsidHandler) 00467 { 00468 HRESULT hr; 00469 00470 TRACE("(%p,0x%08X,0x%08X,%s)\n", ppavi, lParam1, lParam2, 00471 debugstr_guid(pclsidHandler)); 00472 00473 if (ppavi == NULL) 00474 return AVIERR_BADPARAM; 00475 00476 *ppavi = NULL; 00477 if (pclsidHandler == NULL) 00478 return AVIERR_UNSUPPORTED; 00479 00480 hr = CoCreateInstance(pclsidHandler, NULL, CLSCTX_INPROC, &IID_IAVIStream, (LPVOID*)ppavi); 00481 if (FAILED(hr) || *ppavi == NULL) 00482 return hr; 00483 00484 hr = IAVIStream_Create(*ppavi, lParam1, lParam2); 00485 if (FAILED(hr)) { 00486 IAVIStream_Release(*ppavi); 00487 *ppavi = NULL; 00488 } 00489 00490 return hr; 00491 } 00492 00493 /*********************************************************************** 00494 * AVIStreamInfo (AVIFIL32.@) 00495 * AVIStreamInfoA (AVIFIL32.@) 00496 */ 00497 HRESULT WINAPI AVIStreamInfoA(PAVISTREAM pstream, LPAVISTREAMINFOA asi, 00498 LONG size) 00499 { 00500 AVISTREAMINFOW asiw; 00501 HRESULT hres; 00502 00503 TRACE("(%p,%p,%d)\n", pstream, asi, size); 00504 00505 if (pstream == NULL) 00506 return AVIERR_BADHANDLE; 00507 if ((DWORD)size < sizeof(AVISTREAMINFOA)) 00508 return AVIERR_BADSIZE; 00509 00510 hres = IAVIStream_Info(pstream, &asiw, sizeof(asiw)); 00511 00512 memcpy(asi, &asiw, sizeof(asiw) - sizeof(asiw.szName)); 00513 WideCharToMultiByte(CP_ACP, 0, asiw.szName, -1, asi->szName, 00514 sizeof(asi->szName), NULL, NULL); 00515 asi->szName[sizeof(asi->szName) - 1] = 0; 00516 00517 return hres; 00518 } 00519 00520 /*********************************************************************** 00521 * AVIStreamInfoW (AVIFIL32.@) 00522 */ 00523 HRESULT WINAPI AVIStreamInfoW(PAVISTREAM pstream, LPAVISTREAMINFOW asi, 00524 LONG size) 00525 { 00526 TRACE("(%p,%p,%d)\n", pstream, asi, size); 00527 00528 if (pstream == NULL) 00529 return AVIERR_BADHANDLE; 00530 00531 return IAVIStream_Info(pstream, asi, size); 00532 } 00533 00534 /*********************************************************************** 00535 * AVIStreamFindSample (AVIFIL32.@) 00536 */ 00537 LONG WINAPI AVIStreamFindSample(PAVISTREAM pstream, LONG pos, LONG flags) 00538 { 00539 TRACE("(%p,%d,0x%X)\n", pstream, pos, flags); 00540 00541 if (pstream == NULL) 00542 return -1; 00543 00544 return IAVIStream_FindSample(pstream, pos, flags); 00545 } 00546 00547 /*********************************************************************** 00548 * AVIStreamReadFormat (AVIFIL32.@) 00549 */ 00550 HRESULT WINAPI AVIStreamReadFormat(PAVISTREAM pstream, LONG pos, 00551 LPVOID format, LPLONG formatsize) 00552 { 00553 TRACE("(%p,%d,%p,%p)\n", pstream, pos, format, formatsize); 00554 00555 if (pstream == NULL) 00556 return AVIERR_BADHANDLE; 00557 00558 return IAVIStream_ReadFormat(pstream, pos, format, formatsize); 00559 } 00560 00561 /*********************************************************************** 00562 * AVIStreamSetFormat (AVIFIL32.@) 00563 */ 00564 HRESULT WINAPI AVIStreamSetFormat(PAVISTREAM pstream, LONG pos, 00565 LPVOID format, LONG formatsize) 00566 { 00567 TRACE("(%p,%d,%p,%d)\n", pstream, pos, format, formatsize); 00568 00569 if (pstream == NULL) 00570 return AVIERR_BADHANDLE; 00571 00572 return IAVIStream_SetFormat(pstream, pos, format, formatsize); 00573 } 00574 00575 /*********************************************************************** 00576 * AVIStreamRead (AVIFIL32.@) 00577 */ 00578 HRESULT WINAPI AVIStreamRead(PAVISTREAM pstream, LONG start, LONG samples, 00579 LPVOID buffer, LONG buffersize, 00580 LPLONG bytesread, LPLONG samplesread) 00581 { 00582 TRACE("(%p,%d,%d,%p,%d,%p,%p)\n", pstream, start, samples, buffer, 00583 buffersize, bytesread, samplesread); 00584 00585 if (pstream == NULL) 00586 return AVIERR_BADHANDLE; 00587 00588 return IAVIStream_Read(pstream, start, samples, buffer, buffersize, 00589 bytesread, samplesread); 00590 } 00591 00592 /*********************************************************************** 00593 * AVIStreamWrite (AVIFIL32.@) 00594 */ 00595 HRESULT WINAPI AVIStreamWrite(PAVISTREAM pstream, LONG start, LONG samples, 00596 LPVOID buffer, LONG buffersize, DWORD flags, 00597 LPLONG sampwritten, LPLONG byteswritten) 00598 { 00599 TRACE("(%p,%d,%d,%p,%d,0x%X,%p,%p)\n", pstream, start, samples, buffer, 00600 buffersize, flags, sampwritten, byteswritten); 00601 00602 if (pstream == NULL) 00603 return AVIERR_BADHANDLE; 00604 00605 return IAVIStream_Write(pstream, start, samples, buffer, buffersize, 00606 flags, sampwritten, byteswritten); 00607 } 00608 00609 /*********************************************************************** 00610 * AVIStreamReadData (AVIFIL32.@) 00611 */ 00612 HRESULT WINAPI AVIStreamReadData(PAVISTREAM pstream, DWORD fcc, LPVOID lp, 00613 LPLONG lpread) 00614 { 00615 TRACE("(%p,'%4.4s',%p,%p)\n", pstream, (char*)&fcc, lp, lpread); 00616 00617 if (pstream == NULL) 00618 return AVIERR_BADHANDLE; 00619 00620 return IAVIStream_ReadData(pstream, fcc, lp, lpread); 00621 } 00622 00623 /*********************************************************************** 00624 * AVIStreamWriteData (AVIFIL32.@) 00625 */ 00626 HRESULT WINAPI AVIStreamWriteData(PAVISTREAM pstream, DWORD fcc, LPVOID lp, 00627 LONG size) 00628 { 00629 TRACE("(%p,'%4.4s',%p,%d)\n", pstream, (char*)&fcc, lp, size); 00630 00631 if (pstream == NULL) 00632 return AVIERR_BADHANDLE; 00633 00634 return IAVIStream_WriteData(pstream, fcc, lp, size); 00635 } 00636 00637 /*********************************************************************** 00638 * AVIStreamGetFrameOpen (AVIFIL32.@) 00639 */ 00640 PGETFRAME WINAPI AVIStreamGetFrameOpen(PAVISTREAM pstream, 00641 LPBITMAPINFOHEADER lpbiWanted) 00642 { 00643 PGETFRAME pg = NULL; 00644 00645 TRACE("(%p,%p)\n", pstream, lpbiWanted); 00646 00647 if (FAILED(IAVIStream_QueryInterface(pstream, &IID_IGetFrame, (LPVOID*)&pg)) || 00648 pg == NULL) { 00649 pg = AVIFILE_CreateGetFrame(pstream); 00650 if (pg == NULL) 00651 return NULL; 00652 } 00653 00654 if (FAILED(IGetFrame_SetFormat(pg, lpbiWanted, NULL, 0, 0, -1, -1))) { 00655 IGetFrame_Release(pg); 00656 return NULL; 00657 } 00658 00659 return pg; 00660 } 00661 00662 /*********************************************************************** 00663 * AVIStreamGetFrame (AVIFIL32.@) 00664 */ 00665 LPVOID WINAPI AVIStreamGetFrame(PGETFRAME pg, LONG pos) 00666 { 00667 TRACE("(%p,%d)\n", pg, pos); 00668 00669 if (pg == NULL) 00670 return NULL; 00671 00672 return IGetFrame_GetFrame(pg, pos); 00673 } 00674 00675 /*********************************************************************** 00676 * AVIStreamGetFrameClose (AVIFIL32.@) 00677 */ 00678 HRESULT WINAPI AVIStreamGetFrameClose(PGETFRAME pg) 00679 { 00680 TRACE("(%p)\n", pg); 00681 00682 if (pg != NULL) 00683 return IGetFrame_Release(pg); 00684 return 0; 00685 } 00686 00687 /*********************************************************************** 00688 * AVIMakeCompressedStream (AVIFIL32.@) 00689 */ 00690 HRESULT WINAPI AVIMakeCompressedStream(PAVISTREAM *ppsCompressed, 00691 PAVISTREAM psSource, 00692 LPAVICOMPRESSOPTIONS aco, 00693 LPCLSID pclsidHandler) 00694 { 00695 AVISTREAMINFOW asiw; 00696 CHAR szRegKey[25]; 00697 CHAR szValue[100]; 00698 CLSID clsidHandler; 00699 HRESULT hr; 00700 LONG size = sizeof(szValue); 00701 00702 TRACE("(%p,%p,%p,%s)\n", ppsCompressed, psSource, aco, 00703 debugstr_guid(pclsidHandler)); 00704 00705 if (ppsCompressed == NULL) 00706 return AVIERR_BADPARAM; 00707 if (psSource == NULL) 00708 return AVIERR_BADHANDLE; 00709 00710 *ppsCompressed = NULL; 00711 00712 /* if no handler given get default ones based on streamtype */ 00713 if (pclsidHandler == NULL) { 00714 hr = IAVIStream_Info(psSource, &asiw, sizeof(asiw)); 00715 if (FAILED(hr)) 00716 return hr; 00717 00718 wsprintfA(szRegKey, "AVIFile\\Compressors\\%4.4s", (char*)&asiw.fccType); 00719 if (RegQueryValueA(HKEY_CLASSES_ROOT, szRegKey, szValue, &size) != ERROR_SUCCESS) 00720 return AVIERR_UNSUPPORTED; 00721 if (AVIFILE_CLSIDFromString(szValue, &clsidHandler) != S_OK) 00722 return AVIERR_UNSUPPORTED; 00723 } else 00724 clsidHandler = *pclsidHandler; 00725 00726 hr = CoCreateInstance(&clsidHandler, NULL, CLSCTX_INPROC, &IID_IAVIStream, (LPVOID*)ppsCompressed); 00727 if (FAILED(hr) || *ppsCompressed == NULL) 00728 return hr; 00729 00730 hr = IAVIStream_Create(*ppsCompressed, (LPARAM)psSource, (LPARAM)aco); 00731 if (FAILED(hr)) { 00732 IAVIStream_Release(*ppsCompressed); 00733 *ppsCompressed = NULL; 00734 } 00735 00736 return hr; 00737 } 00738 00739 /*********************************************************************** 00740 * AVIMakeFileFromStreams (AVIFIL32.@) 00741 */ 00742 HRESULT WINAPI AVIMakeFileFromStreams(PAVIFILE *ppfile, int nStreams, 00743 PAVISTREAM *ppStreams) 00744 { 00745 TRACE("(%p,%d,%p)\n", ppfile, nStreams, ppStreams); 00746 00747 if (nStreams < 0 || ppfile == NULL || ppStreams == NULL) 00748 return AVIERR_BADPARAM; 00749 00750 *ppfile = AVIFILE_CreateAVITempFile(nStreams, ppStreams); 00751 if (*ppfile == NULL) 00752 return AVIERR_MEMORY; 00753 00754 return AVIERR_OK; 00755 } 00756 00757 /*********************************************************************** 00758 * AVIStreamOpenFromFile (AVIFIL32.@) 00759 * AVIStreamOpenFromFileA (AVIFIL32.@) 00760 */ 00761 HRESULT WINAPI AVIStreamOpenFromFileA(PAVISTREAM *ppavi, LPCSTR szFile, 00762 DWORD fccType, LONG lParam, 00763 UINT mode, LPCLSID pclsidHandler) 00764 { 00765 PAVIFILE pfile = NULL; 00766 HRESULT hr; 00767 00768 TRACE("(%p,%s,'%4.4s',%d,0x%X,%s)\n", ppavi, debugstr_a(szFile), 00769 (char*)&fccType, lParam, mode, debugstr_guid(pclsidHandler)); 00770 00771 if (ppavi == NULL || szFile == NULL) 00772 return AVIERR_BADPARAM; 00773 00774 *ppavi = NULL; 00775 00776 hr = AVIFileOpenA(&pfile, szFile, mode, pclsidHandler); 00777 if (FAILED(hr) || pfile == NULL) 00778 return hr; 00779 00780 hr = IAVIFile_GetStream(pfile, ppavi, fccType, lParam); 00781 IAVIFile_Release(pfile); 00782 00783 return hr; 00784 } 00785 00786 /*********************************************************************** 00787 * AVIStreamOpenFromFileW (AVIFIL32.@) 00788 */ 00789 HRESULT WINAPI AVIStreamOpenFromFileW(PAVISTREAM *ppavi, LPCWSTR szFile, 00790 DWORD fccType, LONG lParam, 00791 UINT mode, LPCLSID pclsidHandler) 00792 { 00793 PAVIFILE pfile = NULL; 00794 HRESULT hr; 00795 00796 TRACE("(%p,%s,'%4.4s',%d,0x%X,%s)\n", ppavi, debugstr_w(szFile), 00797 (char*)&fccType, lParam, mode, debugstr_guid(pclsidHandler)); 00798 00799 if (ppavi == NULL || szFile == NULL) 00800 return AVIERR_BADPARAM; 00801 00802 *ppavi = NULL; 00803 00804 hr = AVIFileOpenW(&pfile, szFile, mode, pclsidHandler); 00805 if (FAILED(hr) || pfile == NULL) 00806 return hr; 00807 00808 hr = IAVIFile_GetStream(pfile, ppavi, fccType, lParam); 00809 IAVIFile_Release(pfile); 00810 00811 return hr; 00812 } 00813 00814 /*********************************************************************** 00815 * AVIStreamBeginStreaming (AVIFIL32.@) 00816 */ 00817 LONG WINAPI AVIStreamBeginStreaming(PAVISTREAM pavi, LONG lStart, LONG lEnd, LONG lRate) 00818 { 00819 IAVIStreaming* pstream = NULL; 00820 HRESULT hr; 00821 00822 TRACE("(%p,%d,%d,%d)\n", pavi, lStart, lEnd, lRate); 00823 00824 if (pavi == NULL) 00825 return AVIERR_BADHANDLE; 00826 00827 hr = IAVIStream_QueryInterface(pavi, &IID_IAVIStreaming, (LPVOID*)&pstream); 00828 if (SUCCEEDED(hr) && pstream != NULL) { 00829 hr = IAVIStreaming_Begin(pstream, lStart, lEnd, lRate); 00830 IAVIStreaming_Release(pstream); 00831 } else 00832 hr = AVIERR_OK; 00833 00834 return hr; 00835 } 00836 00837 /*********************************************************************** 00838 * AVIStreamEndStreaming (AVIFIL32.@) 00839 */ 00840 LONG WINAPI AVIStreamEndStreaming(PAVISTREAM pavi) 00841 { 00842 IAVIStreaming* pstream = NULL; 00843 HRESULT hr; 00844 00845 TRACE("(%p)\n", pavi); 00846 00847 hr = IAVIStream_QueryInterface(pavi, &IID_IAVIStreaming, (LPVOID*)&pstream); 00848 if (SUCCEEDED(hr) && pstream != NULL) { 00849 IAVIStreaming_End(pstream); 00850 IAVIStreaming_Release(pstream); 00851 } 00852 00853 return AVIERR_OK; 00854 } 00855 00856 /*********************************************************************** 00857 * AVIStreamStart (AVIFIL32.@) 00858 */ 00859 LONG WINAPI AVIStreamStart(PAVISTREAM pstream) 00860 { 00861 AVISTREAMINFOW asiw; 00862 00863 TRACE("(%p)\n", pstream); 00864 00865 if (pstream == NULL) 00866 return 0; 00867 00868 if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw)))) 00869 return 0; 00870 00871 return asiw.dwStart; 00872 } 00873 00874 /*********************************************************************** 00875 * AVIStreamLength (AVIFIL32.@) 00876 */ 00877 LONG WINAPI AVIStreamLength(PAVISTREAM pstream) 00878 { 00879 AVISTREAMINFOW asiw; 00880 00881 TRACE("(%p)\n", pstream); 00882 00883 if (pstream == NULL) 00884 return 0; 00885 00886 if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw)))) 00887 return 0; 00888 00889 return asiw.dwLength; 00890 } 00891 00892 /*********************************************************************** 00893 * AVIStreamSampleToTime (AVIFIL32.@) 00894 */ 00895 LONG WINAPI AVIStreamSampleToTime(PAVISTREAM pstream, LONG lSample) 00896 { 00897 AVISTREAMINFOW asiw; 00898 LONG time; 00899 00900 TRACE("(%p,%d)\n", pstream, lSample); 00901 00902 if (pstream == NULL) 00903 return -1; 00904 00905 if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw)))) 00906 return -1; 00907 if (asiw.dwRate == 0) 00908 return -1; 00909 00910 /* limit to stream bounds */ 00911 if (lSample < asiw.dwStart) 00912 lSample = asiw.dwStart; 00913 if (lSample > asiw.dwStart + asiw.dwLength) 00914 lSample = asiw.dwStart + asiw.dwLength; 00915 00916 if (asiw.dwRate / asiw.dwScale < 1000) 00917 time = (LONG)(((float)lSample * asiw.dwScale * 1000) / asiw.dwRate); 00918 else 00919 time = (LONG)(((float)lSample * asiw.dwScale * 1000 + (asiw.dwRate - 1)) / asiw.dwRate); 00920 00921 TRACE(" -> %d\n",time); 00922 return time; 00923 } 00924 00925 /*********************************************************************** 00926 * AVIStreamTimeToSample (AVIFIL32.@) 00927 */ 00928 LONG WINAPI AVIStreamTimeToSample(PAVISTREAM pstream, LONG lTime) 00929 { 00930 AVISTREAMINFOW asiw; 00931 ULONG sample; 00932 00933 TRACE("(%p,%d)\n", pstream, lTime); 00934 00935 if (pstream == NULL || lTime < 0) 00936 return -1; 00937 00938 if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw)))) 00939 return -1; 00940 if (asiw.dwScale == 0) 00941 return -1; 00942 00943 if (asiw.dwRate / asiw.dwScale < 1000) 00944 sample = (LONG)((((float)asiw.dwRate * lTime) / (asiw.dwScale * 1000))); 00945 else 00946 sample = (LONG)(((float)asiw.dwRate * lTime + (asiw.dwScale * 1000 - 1)) / (asiw.dwScale * 1000)); 00947 00948 /* limit to stream bounds */ 00949 if (sample < asiw.dwStart) 00950 sample = asiw.dwStart; 00951 if (sample > asiw.dwStart + asiw.dwLength) 00952 sample = asiw.dwStart + asiw.dwLength; 00953 00954 TRACE(" -> %d\n", sample); 00955 return sample; 00956 } 00957 00958 /*********************************************************************** 00959 * AVIBuildFilter (AVIFIL32.@) 00960 * AVIBuildFilterA (AVIFIL32.@) 00961 */ 00962 HRESULT WINAPI AVIBuildFilterA(LPSTR szFilter, LONG cbFilter, BOOL fSaving) 00963 { 00964 LPWSTR wszFilter; 00965 HRESULT hr; 00966 00967 TRACE("(%p,%d,%d)\n", szFilter, cbFilter, fSaving); 00968 00969 /* check parameters */ 00970 if (szFilter == NULL) 00971 return AVIERR_BADPARAM; 00972 if (cbFilter < 2) 00973 return AVIERR_BADSIZE; 00974 00975 szFilter[0] = 0; 00976 szFilter[1] = 0; 00977 00978 wszFilter = HeapAlloc(GetProcessHeap(), 0, cbFilter * sizeof(WCHAR)); 00979 if (wszFilter == NULL) 00980 return AVIERR_MEMORY; 00981 00982 hr = AVIBuildFilterW(wszFilter, cbFilter, fSaving); 00983 if (SUCCEEDED(hr)) { 00984 WideCharToMultiByte(CP_ACP, 0, wszFilter, cbFilter, 00985 szFilter, cbFilter, NULL, NULL); 00986 } 00987 00988 HeapFree(GetProcessHeap(), 0, wszFilter); 00989 00990 return hr; 00991 } 00992 00993 /*********************************************************************** 00994 * AVIBuildFilterW (AVIFIL32.@) 00995 */ 00996 HRESULT WINAPI AVIBuildFilterW(LPWSTR szFilter, LONG cbFilter, BOOL fSaving) 00997 { 00998 static const WCHAR all_files[] = { '*','.','*',0,0 }; 00999 static const WCHAR szClsid[] = {'C','L','S','I','D',0}; 01000 static const WCHAR szExtensionFmt[] = {';','*','.','%','s',0}; 01001 static const WCHAR szAVIFileExtensions[] = 01002 {'A','V','I','F','i','l','e','\\','E','x','t','e','n','s','i','o','n','s',0}; 01003 01004 AVIFilter *lp; 01005 WCHAR szAllFiles[40]; 01006 WCHAR szFileExt[10]; 01007 WCHAR szValue[128]; 01008 HKEY hKey; 01009 DWORD n, i; 01010 LONG size; 01011 DWORD count = 0; 01012 01013 TRACE("(%p,%d,%d)\n", szFilter, cbFilter, fSaving); 01014 01015 /* check parameters */ 01016 if (szFilter == NULL) 01017 return AVIERR_BADPARAM; 01018 if (cbFilter < 2) 01019 return AVIERR_BADSIZE; 01020 01021 lp = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_FILTERS * sizeof(AVIFilter)); 01022 if (lp == NULL) 01023 return AVIERR_MEMORY; 01024 01025 /* 01026 * 1. iterate over HKEY_CLASSES_ROOT\\AVIFile\\Extensions and collect 01027 * extensions and CLSIDs 01028 * 2. iterate over collected CLSIDs and copy its description and its 01029 * extensions to szFilter if it fits 01030 * 01031 * First filter is named "All multimedia files" and its filter is a 01032 * collection of all possible extensions except "*.*". 01033 */ 01034 if (RegOpenKeyW(HKEY_CLASSES_ROOT, szAVIFileExtensions, &hKey) != ERROR_SUCCESS) { 01035 HeapFree(GetProcessHeap(), 0, lp); 01036 return AVIERR_ERROR; 01037 } 01038 for (n = 0;RegEnumKeyW(hKey, n, szFileExt, sizeof(szFileExt)/sizeof(szFileExt[0])) == ERROR_SUCCESS;n++) { 01039 /* get CLSID to extension */ 01040 size = sizeof(szValue); 01041 if (RegQueryValueW(hKey, szFileExt, szValue, &size) != ERROR_SUCCESS) 01042 break; 01043 01044 /* search if the CLSID is already known */ 01045 for (i = 1; i <= count; i++) { 01046 if (lstrcmpW(lp[i].szClsid, szValue) == 0) 01047 break; /* a new one */ 01048 } 01049 01050 if (i == count + 1) { 01051 /* it's a new CLSID */ 01052 01053 /* FIXME: How do we get info's about read/write capabilities? */ 01054 01055 if (count >= MAX_FILTERS) { 01056 /* try to inform user of our full fixed size table */ 01057 ERR(": More than %d filters found! Adjust MAX_FILTERS in dlls/avifil32/api.c\n", MAX_FILTERS); 01058 break; 01059 } 01060 01061 lstrcpyW(lp[i].szClsid, szValue); 01062 01063 count++; 01064 } 01065 01066 /* append extension to the filter */ 01067 wsprintfW(szValue, szExtensionFmt, szFileExt); 01068 if (lp[i].szExtensions[0] == 0) 01069 lstrcatW(lp[i].szExtensions, szValue + 1); 01070 else 01071 lstrcatW(lp[i].szExtensions, szValue); 01072 01073 /* also append to the "all multimedia"-filter */ 01074 if (lp[0].szExtensions[0] == 0) 01075 lstrcatW(lp[0].szExtensions, szValue + 1); 01076 else 01077 lstrcatW(lp[0].szExtensions, szValue); 01078 } 01079 RegCloseKey(hKey); 01080 01081 /* 2. get descriptions for the CLSIDs and fill out szFilter */ 01082 if (RegOpenKeyW(HKEY_CLASSES_ROOT, szClsid, &hKey) != ERROR_SUCCESS) { 01083 HeapFree(GetProcessHeap(), 0, lp); 01084 return AVIERR_ERROR; 01085 } 01086 for (n = 0; n <= count; n++) { 01087 /* first the description */ 01088 if (n != 0) { 01089 size = sizeof(szValue); 01090 if (RegQueryValueW(hKey, lp[n].szClsid, szValue, &size) == ERROR_SUCCESS) { 01091 size = lstrlenW(szValue); 01092 lstrcpynW(szFilter, szValue, cbFilter); 01093 } 01094 } else 01095 size = LoadStringW(AVIFILE_hModule,IDS_ALLMULTIMEDIA,szFilter,cbFilter); 01096 01097 /* check for enough space */ 01098 size++; 01099 if (cbFilter < size + lstrlenW(lp[n].szExtensions) + 2) { 01100 szFilter[0] = 0; 01101 szFilter[1] = 0; 01102 HeapFree(GetProcessHeap(), 0, lp); 01103 RegCloseKey(hKey); 01104 return AVIERR_BUFFERTOOSMALL; 01105 } 01106 cbFilter -= size; 01107 szFilter += size; 01108 01109 /* and then the filter */ 01110 lstrcpynW(szFilter, lp[n].szExtensions, cbFilter); 01111 size = lstrlenW(lp[n].szExtensions) + 1; 01112 cbFilter -= size; 01113 szFilter += size; 01114 } 01115 01116 RegCloseKey(hKey); 01117 HeapFree(GetProcessHeap(), 0, lp); 01118 01119 /* add "All files" "*.*" filter if enough space left */ 01120 size = LoadStringW(AVIFILE_hModule, IDS_ALLFILES, 01121 szAllFiles, (sizeof(szAllFiles) - sizeof(all_files))/sizeof(WCHAR)) + 1; 01122 memcpy( szAllFiles + size, all_files, sizeof(all_files) ); 01123 size += sizeof(all_files) / sizeof(WCHAR); 01124 01125 if (cbFilter > size) { 01126 memcpy(szFilter, szAllFiles, size * sizeof(szAllFiles[0])); 01127 return AVIERR_OK; 01128 } else { 01129 szFilter[0] = 0; 01130 return AVIERR_BUFFERTOOSMALL; 01131 } 01132 } 01133 01134 static BOOL AVISaveOptionsFmtChoose(HWND hWnd) 01135 { 01136 LPAVICOMPRESSOPTIONS pOptions = SaveOpts.ppOptions[SaveOpts.nCurrent]; 01137 AVISTREAMINFOW sInfo; 01138 01139 TRACE("(%p)\n", hWnd); 01140 01141 if (pOptions == NULL || SaveOpts.ppavis[SaveOpts.nCurrent] == NULL) { 01142 ERR(": bad state!\n"); 01143 return FALSE; 01144 } 01145 01146 if (FAILED(AVIStreamInfoW(SaveOpts.ppavis[SaveOpts.nCurrent], 01147 &sInfo, sizeof(sInfo)))) { 01148 ERR(": AVIStreamInfoW failed!\n"); 01149 return FALSE; 01150 } 01151 01152 if (sInfo.fccType == streamtypeVIDEO) { 01153 COMPVARS cv; 01154 BOOL ret; 01155 01156 memset(&cv, 0, sizeof(cv)); 01157 01158 if ((pOptions->dwFlags & AVICOMPRESSF_VALID) == 0) { 01159 memset(pOptions, 0, sizeof(AVICOMPRESSOPTIONS)); 01160 pOptions->fccType = streamtypeVIDEO; 01161 pOptions->fccHandler = comptypeDIB; 01162 pOptions->dwQuality = (DWORD)ICQUALITY_DEFAULT; 01163 } 01164 01165 cv.cbSize = sizeof(cv); 01166 cv.dwFlags = ICMF_COMPVARS_VALID; 01167 /*cv.fccType = pOptions->fccType; */ 01168 cv.fccHandler = pOptions->fccHandler; 01169 cv.lQ = pOptions->dwQuality; 01170 cv.lpState = pOptions->lpParms; 01171 cv.cbState = pOptions->cbParms; 01172 if (pOptions->dwFlags & AVICOMPRESSF_KEYFRAMES) 01173 cv.lKey = pOptions->dwKeyFrameEvery; 01174 else 01175 cv.lKey = 0; 01176 if (pOptions->dwFlags & AVICOMPRESSF_DATARATE) 01177 cv.lDataRate = pOptions->dwBytesPerSecond / 1024; /* need kBytes */ 01178 else 01179 cv.lDataRate = 0; 01180 01181 ret = ICCompressorChoose(hWnd, SaveOpts.uFlags, NULL, 01182 SaveOpts.ppavis[SaveOpts.nCurrent], &cv, NULL); 01183 01184 if (ret) { 01185 pOptions->fccHandler = cv.fccHandler; 01186 pOptions->lpParms = cv.lpState; 01187 pOptions->cbParms = cv.cbState; 01188 pOptions->dwQuality = cv.lQ; 01189 if (cv.lKey != 0) { 01190 pOptions->dwKeyFrameEvery = cv.lKey; 01191 pOptions->dwFlags |= AVICOMPRESSF_KEYFRAMES; 01192 } else 01193 pOptions->dwFlags &= ~AVICOMPRESSF_KEYFRAMES; 01194 if (cv.lDataRate != 0) { 01195 pOptions->dwBytesPerSecond = cv.lDataRate * 1024; /* need bytes */ 01196 pOptions->dwFlags |= AVICOMPRESSF_DATARATE; 01197 } else 01198 pOptions->dwFlags &= ~AVICOMPRESSF_DATARATE; 01199 pOptions->dwFlags |= AVICOMPRESSF_VALID; 01200 } 01201 ICCompressorFree(&cv); 01202 01203 return ret; 01204 } else if (sInfo.fccType == streamtypeAUDIO) { 01205 ACMFORMATCHOOSEW afmtc; 01206 MMRESULT ret; 01207 LONG size; 01208 01209 /* FIXME: check ACM version -- Which version is needed? */ 01210 01211 memset(&afmtc, 0, sizeof(afmtc)); 01212 afmtc.cbStruct = sizeof(afmtc); 01213 afmtc.fdwStyle = 0; 01214 afmtc.hwndOwner = hWnd; 01215 01216 acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FORMAT, &size); 01217 if ((pOptions->cbFormat == 0 || pOptions->lpFormat == NULL) && size != 0) { 01218 pOptions->lpFormat = HeapAlloc(GetProcessHeap(), 0, size); 01219 if (!pOptions->lpFormat) return FALSE; 01220 pOptions->cbFormat = size; 01221 } else if (pOptions->cbFormat < (DWORD)size) { 01222 void *new_buffer = HeapReAlloc(GetProcessHeap(), 0, pOptions->lpFormat, size); 01223 if (!new_buffer) return FALSE; 01224 pOptions->lpFormat = new_buffer; 01225 pOptions->cbFormat = size; 01226 } 01227 afmtc.pwfx = pOptions->lpFormat; 01228 afmtc.cbwfx = pOptions->cbFormat; 01229 01230 size = 0; 01231 AVIStreamFormatSize(SaveOpts.ppavis[SaveOpts.nCurrent], 01232 sInfo.dwStart, &size); 01233 if (size < (LONG)sizeof(PCMWAVEFORMAT)) 01234 size = sizeof(PCMWAVEFORMAT); 01235 afmtc.pwfxEnum = HeapAlloc(GetProcessHeap(), 0, size); 01236 if (afmtc.pwfxEnum != NULL) { 01237 AVIStreamReadFormat(SaveOpts.ppavis[SaveOpts.nCurrent], 01238 sInfo.dwStart, afmtc.pwfxEnum, &size); 01239 afmtc.fdwEnum = ACM_FORMATENUMF_CONVERT; 01240 } 01241 01242 ret = acmFormatChooseW(&afmtc); 01243 if (ret == S_OK) 01244 pOptions->dwFlags |= AVICOMPRESSF_VALID; 01245 01246 HeapFree(GetProcessHeap(), 0, afmtc.pwfxEnum); 01247 return (ret == S_OK ? TRUE : FALSE); 01248 } else { 01249 ERR(": unknown streamtype 0x%08X\n", sInfo.fccType); 01250 return FALSE; 01251 } 01252 } 01253 01254 static void AVISaveOptionsUpdate(HWND hWnd) 01255 { 01256 static const WCHAR szVideoFmt[]={'%','l','d','x','%','l','d','x','%','d',0}; 01257 static const WCHAR szAudioFmt[]={'%','s',' ','%','s',0}; 01258 01259 WCHAR szFormat[128]; 01260 AVISTREAMINFOW sInfo; 01261 LPVOID lpFormat; 01262 LONG size; 01263 01264 TRACE("(%p)\n", hWnd); 01265 01266 SaveOpts.nCurrent = SendDlgItemMessageW(hWnd,IDC_STREAM,CB_GETCURSEL,0,0); 01267 if (SaveOpts.nCurrent < 0) 01268 return; 01269 01270 if (FAILED(AVIStreamInfoW(SaveOpts.ppavis[SaveOpts.nCurrent], &sInfo, sizeof(sInfo)))) 01271 return; 01272 01273 AVIStreamFormatSize(SaveOpts.ppavis[SaveOpts.nCurrent],sInfo.dwStart,&size); 01274 if (size > 0) { 01275 szFormat[0] = 0; 01276 01277 /* read format to build format description string */ 01278 lpFormat = HeapAlloc(GetProcessHeap(), 0, size); 01279 if (lpFormat != NULL) { 01280 if (SUCCEEDED(AVIStreamReadFormat(SaveOpts.ppavis[SaveOpts.nCurrent],sInfo.dwStart,lpFormat, &size))) { 01281 if (sInfo.fccType == streamtypeVIDEO) { 01282 LPBITMAPINFOHEADER lpbi = lpFormat; 01283 ICINFO icinfo; 01284 01285 wsprintfW(szFormat, szVideoFmt, lpbi->biWidth, 01286 lpbi->biHeight, lpbi->biBitCount); 01287 01288 if (lpbi->biCompression != BI_RGB) { 01289 HIC hic; 01290 01291 hic = ICLocate(ICTYPE_VIDEO, sInfo.fccHandler, lpFormat, 01292 NULL, ICMODE_DECOMPRESS); 01293 if (hic != NULL) { 01294 if (ICGetInfo(hic, &icinfo, sizeof(icinfo)) == S_OK) 01295 lstrcatW(szFormat, icinfo.szDescription); 01296 ICClose(hic); 01297 } 01298 } else { 01299 LoadStringW(AVIFILE_hModule, IDS_UNCOMPRESSED, 01300 icinfo.szDescription, 01301 sizeof(icinfo.szDescription)/sizeof(icinfo.szDescription[0])); 01302 lstrcatW(szFormat, icinfo.szDescription); 01303 } 01304 } else if (sInfo.fccType == streamtypeAUDIO) { 01305 ACMFORMATTAGDETAILSW aftd; 01306 ACMFORMATDETAILSW afd; 01307 01308 memset(&aftd, 0, sizeof(aftd)); 01309 memset(&afd, 0, sizeof(afd)); 01310 01311 aftd.cbStruct = sizeof(aftd); 01312 aftd.dwFormatTag = afd.dwFormatTag = 01313 ((PWAVEFORMATEX)lpFormat)->wFormatTag; 01314 aftd.cbFormatSize = afd.cbwfx = size; 01315 01316 afd.cbStruct = sizeof(afd); 01317 afd.pwfx = lpFormat; 01318 01319 if (acmFormatTagDetailsW(NULL, &aftd, 01320 ACM_FORMATTAGDETAILSF_FORMATTAG) == S_OK) { 01321 if (acmFormatDetailsW(NULL,&afd,ACM_FORMATDETAILSF_FORMAT) == S_OK) 01322 wsprintfW(szFormat, szAudioFmt, afd.szFormat, aftd.szFormatTag); 01323 } 01324 } 01325 } 01326 HeapFree(GetProcessHeap(), 0, lpFormat); 01327 } 01328 01329 /* set text for format description */ 01330 SetDlgItemTextW(hWnd, IDC_FORMATTEXT, szFormat); 01331 01332 /* Disable option button for unsupported streamtypes */ 01333 if (sInfo.fccType == streamtypeVIDEO || 01334 sInfo.fccType == streamtypeAUDIO) 01335 EnableWindow(GetDlgItem(hWnd, IDC_OPTIONS), TRUE); 01336 else 01337 EnableWindow(GetDlgItem(hWnd, IDC_OPTIONS), FALSE); 01338 } 01339 01340 } 01341 01342 static INT_PTR CALLBACK AVISaveOptionsDlgProc(HWND hWnd, UINT uMsg, 01343 WPARAM wParam, LPARAM lParam) 01344 { 01345 DWORD dwInterleave; 01346 BOOL bIsInterleaved; 01347 INT n; 01348 01349 /*TRACE("(%p,%u,0x%04X,0x%08lX)\n", hWnd, uMsg, wParam, lParam);*/ 01350 01351 switch (uMsg) { 01352 case WM_INITDIALOG: 01353 SaveOpts.nCurrent = 0; 01354 if (SaveOpts.nStreams == 1) { 01355 EndDialog(hWnd, AVISaveOptionsFmtChoose(hWnd)); 01356 return TRUE; 01357 } 01358 01359 /* add streams */ 01360 for (n = 0; n < SaveOpts.nStreams; n++) { 01361 AVISTREAMINFOW sInfo; 01362 01363 AVIStreamInfoW(SaveOpts.ppavis[n], &sInfo, sizeof(sInfo)); 01364 SendDlgItemMessageW(hWnd, IDC_STREAM, CB_ADDSTRING, 01365 0L, (LPARAM)sInfo.szName); 01366 } 01367 01368 /* select first stream */ 01369 SendDlgItemMessageW(hWnd, IDC_STREAM, CB_SETCURSEL, 0, 0); 01370 SendMessageW(hWnd, WM_COMMAND, MAKELONG(IDC_STREAM, CBN_SELCHANGE), (LPARAM)hWnd); 01371 01372 /* initialize interleave */ 01373 if (SaveOpts.ppOptions[0] != NULL && 01374 (SaveOpts.ppOptions[0]->dwFlags & AVICOMPRESSF_VALID)) { 01375 bIsInterleaved = (SaveOpts.ppOptions[0]->dwFlags & AVICOMPRESSF_INTERLEAVE); 01376 dwInterleave = SaveOpts.ppOptions[0]->dwInterleaveEvery; 01377 } else { 01378 bIsInterleaved = TRUE; 01379 dwInterleave = 0; 01380 } 01381 CheckDlgButton(hWnd, IDC_INTERLEAVE, bIsInterleaved); 01382 SetDlgItemInt(hWnd, IDC_INTERLEAVEEVERY, dwInterleave, FALSE); 01383 EnableWindow(GetDlgItem(hWnd, IDC_INTERLEAVEEVERY), bIsInterleaved); 01384 break; 01385 case WM_COMMAND: 01386 switch (LOWORD(wParam)) { 01387 case IDOK: 01388 /* get data from controls and save them */ 01389 dwInterleave = GetDlgItemInt(hWnd, IDC_INTERLEAVEEVERY, NULL, 0); 01390 bIsInterleaved = IsDlgButtonChecked(hWnd, IDC_INTERLEAVE); 01391 for (n = 0; n < SaveOpts.nStreams; n++) { 01392 if (SaveOpts.ppOptions[n] != NULL) { 01393 if (bIsInterleaved) { 01394 SaveOpts.ppOptions[n]->dwFlags |= AVICOMPRESSF_INTERLEAVE; 01395 SaveOpts.ppOptions[n]->dwInterleaveEvery = dwInterleave; 01396 } else 01397 SaveOpts.ppOptions[n]->dwFlags &= ~AVICOMPRESSF_INTERLEAVE; 01398 } 01399 } 01400 /* fall through */ 01401 case IDCANCEL: 01402 EndDialog(hWnd, LOWORD(wParam) == IDOK); 01403 break; 01404 case IDC_INTERLEAVE: 01405 EnableWindow(GetDlgItem(hWnd, IDC_INTERLEAVEEVERY), 01406 IsDlgButtonChecked(hWnd, IDC_INTERLEAVE)); 01407 break; 01408 case IDC_STREAM: 01409 if (HIWORD(wParam) == CBN_SELCHANGE) { 01410 /* update control elements */ 01411 AVISaveOptionsUpdate(hWnd); 01412 } 01413 break; 01414 case IDC_OPTIONS: 01415 AVISaveOptionsFmtChoose(hWnd); 01416 break; 01417 }; 01418 return TRUE; 01419 }; 01420 01421 return FALSE; 01422 } 01423 01424 /*********************************************************************** 01425 * AVISaveOptions (AVIFIL32.@) 01426 */ 01427 BOOL WINAPI AVISaveOptions(HWND hWnd, UINT uFlags, INT nStreams, 01428 PAVISTREAM *ppavi, LPAVICOMPRESSOPTIONS *ppOptions) 01429 { 01430 LPAVICOMPRESSOPTIONS pSavedOptions = NULL; 01431 INT ret, n; 01432 01433 TRACE("(%p,0x%X,%d,%p,%p)\n", hWnd, uFlags, nStreams, 01434 ppavi, ppOptions); 01435 01436 /* check parameters */ 01437 if (nStreams <= 0 || ppavi == NULL || ppOptions == NULL) 01438 return AVIERR_BADPARAM; 01439 01440 /* save options in case the user presses cancel */ 01441 if (nStreams > 1) { 01442 pSavedOptions = HeapAlloc(GetProcessHeap(), 0, nStreams * sizeof(AVICOMPRESSOPTIONS)); 01443 if (pSavedOptions == NULL) 01444 return FALSE; 01445 01446 for (n = 0; n < nStreams; n++) { 01447 if (ppOptions[n] != NULL) 01448 memcpy(pSavedOptions + n, ppOptions[n], sizeof(AVICOMPRESSOPTIONS)); 01449 } 01450 } 01451 01452 SaveOpts.uFlags = uFlags; 01453 SaveOpts.nStreams = nStreams; 01454 SaveOpts.ppavis = ppavi; 01455 SaveOpts.ppOptions = ppOptions; 01456 01457 ret = DialogBoxW(AVIFILE_hModule, MAKEINTRESOURCEW(IDD_SAVEOPTIONS), 01458 hWnd, AVISaveOptionsDlgProc); 01459 01460 if (ret == -1) 01461 ret = FALSE; 01462 01463 /* restore options when user pressed cancel */ 01464 if (pSavedOptions != NULL) { 01465 if (ret == FALSE) { 01466 for (n = 0; n < nStreams; n++) { 01467 if (ppOptions[n] != NULL) 01468 memcpy(ppOptions[n], pSavedOptions + n, sizeof(AVICOMPRESSOPTIONS)); 01469 } 01470 } 01471 HeapFree(GetProcessHeap(), 0, pSavedOptions); 01472 } 01473 01474 return ret; 01475 } 01476 01477 /*********************************************************************** 01478 * AVISaveOptionsFree (AVIFIL32.@) 01479 */ 01480 HRESULT WINAPI AVISaveOptionsFree(INT nStreams,LPAVICOMPRESSOPTIONS*ppOptions) 01481 { 01482 TRACE("(%d,%p)\n", nStreams, ppOptions); 01483 01484 if (nStreams < 0 || ppOptions == NULL) 01485 return AVIERR_BADPARAM; 01486 01487 for (nStreams--; nStreams >= 0; nStreams--) { 01488 if (ppOptions[nStreams] != NULL) { 01489 ppOptions[nStreams]->dwFlags &= ~AVICOMPRESSF_VALID; 01490 01491 if (ppOptions[nStreams]->lpParms != NULL) { 01492 HeapFree(GetProcessHeap(), 0, ppOptions[nStreams]->lpParms); 01493 ppOptions[nStreams]->lpParms = NULL; 01494 ppOptions[nStreams]->cbParms = 0; 01495 } 01496 if (ppOptions[nStreams]->lpFormat != NULL) { 01497 HeapFree(GetProcessHeap(), 0, ppOptions[nStreams]->lpFormat); 01498 ppOptions[nStreams]->lpFormat = NULL; 01499 ppOptions[nStreams]->cbFormat = 0; 01500 } 01501 } 01502 } 01503 01504 return AVIERR_OK; 01505 } 01506 01507 /*********************************************************************** 01508 * AVISaveVA (AVIFIL32.@) 01509 */ 01510 HRESULT WINAPI AVISaveVA(LPCSTR szFile, CLSID *pclsidHandler, 01511 AVISAVECALLBACK lpfnCallback, int nStream, 01512 PAVISTREAM *ppavi, LPAVICOMPRESSOPTIONS *plpOptions) 01513 { 01514 LPWSTR wszFile = NULL; 01515 HRESULT hr; 01516 int len; 01517 01518 TRACE("%s,%p,%p,%d,%p,%p)\n", debugstr_a(szFile), pclsidHandler, 01519 lpfnCallback, nStream, ppavi, plpOptions); 01520 01521 if (szFile == NULL || ppavi == NULL || plpOptions == NULL) 01522 return AVIERR_BADPARAM; 01523 01524 /* convert ASCII string to Unicode and call Unicode function */ 01525 len = MultiByteToWideChar(CP_ACP, 0, szFile, -1, NULL, 0); 01526 if (len <= 0) 01527 return AVIERR_BADPARAM; 01528 01529 wszFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 01530 if (wszFile == NULL) 01531 return AVIERR_MEMORY; 01532 01533 MultiByteToWideChar(CP_ACP, 0, szFile, -1, wszFile, len); 01534 01535 hr = AVISaveVW(wszFile, pclsidHandler, lpfnCallback, 01536 nStream, ppavi, plpOptions); 01537 01538 HeapFree(GetProcessHeap(), 0, wszFile); 01539 01540 return hr; 01541 } 01542 01543 /*********************************************************************** 01544 * AVIFILE_AVISaveDefaultCallback (internal) 01545 */ 01546 static BOOL WINAPI AVIFILE_AVISaveDefaultCallback(INT progress) 01547 { 01548 TRACE("(%d)\n", progress); 01549 01550 return FALSE; 01551 } 01552 01553 /*********************************************************************** 01554 * AVISaveVW (AVIFIL32.@) 01555 */ 01556 HRESULT WINAPI AVISaveVW(LPCWSTR szFile, CLSID *pclsidHandler, 01557 AVISAVECALLBACK lpfnCallback, int nStreams, 01558 PAVISTREAM *ppavi, LPAVICOMPRESSOPTIONS *plpOptions) 01559 { 01560 LONG lStart[MAX_AVISTREAMS]; 01561 PAVISTREAM pOutStreams[MAX_AVISTREAMS]; 01562 PAVISTREAM pInStreams[MAX_AVISTREAMS]; 01563 AVIFILEINFOW fInfo; 01564 AVISTREAMINFOW sInfo; 01565 01566 PAVIFILE pfile = NULL; /* the output AVI file */ 01567 LONG lFirstVideo = -1; 01568 int curStream; 01569 01570 /* for interleaving ... */ 01571 DWORD dwInterleave = 0; /* interleave rate */ 01572 DWORD dwFileInitialFrames; 01573 LONG lFileLength; 01574 LONG lSampleInc; 01575 01576 /* for reading/writing the data ... */ 01577 LPVOID lpBuffer = NULL; 01578 LONG cbBuffer; /* real size of lpBuffer */ 01579 LONG lBufferSize; /* needed bytes for format(s), etc. */ 01580 LONG lReadBytes; 01581 LONG lReadSamples; 01582 HRESULT hres; 01583 01584 TRACE("(%s,%p,%p,%d,%p,%p)\n", debugstr_w(szFile), pclsidHandler, 01585 lpfnCallback, nStreams, ppavi, plpOptions); 01586 01587 if (szFile == NULL || ppavi == NULL || plpOptions == NULL) 01588 return AVIERR_BADPARAM; 01589 if (nStreams >= MAX_AVISTREAMS) { 01590 WARN("Can't write AVI with %d streams only supports %d -- change MAX_AVISTREAMS!\n", nStreams, MAX_AVISTREAMS); 01591 return AVIERR_INTERNAL; 01592 } 01593 01594 if (lpfnCallback == NULL) 01595 lpfnCallback = AVIFILE_AVISaveDefaultCallback; 01596 01597 /* clear local variable(s) */ 01598 for (curStream = 0; curStream < nStreams; curStream++) { 01599 pInStreams[curStream] = NULL; 01600 pOutStreams[curStream] = NULL; 01601 } 01602 01603 /* open output AVI file (create it if it doesn't exist) */ 01604 hres = AVIFileOpenW(&pfile, szFile, OF_CREATE|OF_SHARE_EXCLUSIVE|OF_WRITE, 01605 pclsidHandler); 01606 if (FAILED(hres)) 01607 return hres; 01608 AVIFileInfoW(pfile, &fInfo, sizeof(fInfo)); /* for dwCaps */ 01609 01610 /* initialize our data structures part 1 */ 01611 for (curStream = 0; curStream < nStreams; curStream++) { 01612 PAVISTREAM pCurStream = ppavi[curStream]; 01613 01614 hres = AVIStreamInfoW(pCurStream, &sInfo, sizeof(sInfo)); 01615 if (FAILED(hres)) 01616 goto error; 01617 01618 /* search first video stream and check for interleaving */ 01619 if (sInfo.fccType == streamtypeVIDEO) { 01620 /* remember first video stream -- needed for interleaving */ 01621 if (lFirstVideo < 0) 01622 lFirstVideo = curStream; 01623 } else if (!dwInterleave) { 01624 /* check if any non-video stream wants to be interleaved */ 01625 WARN("options.flags=0x%X options.dwInterleave=%u\n",plpOptions[curStream]->dwFlags,plpOptions[curStream]->dwInterleaveEvery); 01626 if (plpOptions[curStream] != NULL && 01627 plpOptions[curStream]->dwFlags & AVICOMPRESSF_INTERLEAVE) 01628 dwInterleave = plpOptions[curStream]->dwInterleaveEvery; 01629 } 01630 01631 /* create de-/compressed stream interface if needed */ 01632 pInStreams[curStream] = NULL; 01633 if (plpOptions[curStream] != NULL) { 01634 if (plpOptions[curStream]->fccHandler || 01635 plpOptions[curStream]->lpFormat != NULL) { 01636 DWORD dwKeySave = plpOptions[curStream]->dwKeyFrameEvery; 01637 01638 if (fInfo.dwCaps & AVIFILECAPS_ALLKEYFRAMES) 01639 plpOptions[curStream]->dwKeyFrameEvery = 1; 01640 01641 hres = AVIMakeCompressedStream(&pInStreams[curStream], pCurStream, 01642 plpOptions[curStream], NULL); 01643 plpOptions[curStream]->dwKeyFrameEvery = dwKeySave; 01644 if (FAILED(hres) || pInStreams[curStream] == NULL) { 01645 pInStreams[curStream] = NULL; 01646 goto error; 01647 } 01648 01649 /* test stream interface and update stream-info */ 01650 hres = AVIStreamInfoW(pInStreams[curStream], &sInfo, sizeof(sInfo)); 01651 if (FAILED(hres)) 01652 goto error; 01653 } 01654 } 01655 01656 /* now handle streams which will only be copied */ 01657 if (pInStreams[curStream] == NULL) { 01658 pCurStream = pInStreams[curStream] = ppavi[curStream]; 01659 AVIStreamAddRef(pCurStream); 01660 } else 01661 pCurStream = pInStreams[curStream]; 01662 01663 lStart[curStream] = sInfo.dwStart; 01664 } /* for all streams */ 01665 01666 /* check that first video stream is the first stream */ 01667 if (lFirstVideo > 0) { 01668 PAVISTREAM pTmp = pInStreams[lFirstVideo]; 01669 LONG lTmp = lStart[lFirstVideo]; 01670 01671 pInStreams[lFirstVideo] = pInStreams[0]; 01672 pInStreams[0] = pTmp; 01673 lStart[lFirstVideo] = lStart[0]; 01674 lStart[0] = lTmp; 01675 lFirstVideo = 0; 01676 } 01677 01678 /* allocate buffer for formats, data, etc. of an initial size of 64 kBytes*/ 01679 cbBuffer = 0x00010000; 01680 lpBuffer = HeapAlloc(GetProcessHeap(), 0, cbBuffer); 01681 if (lpBuffer == NULL) { 01682 hres = AVIERR_MEMORY; 01683 goto error; 01684 } 01685 01686 AVIStreamInfoW(pInStreams[0], &sInfo, sizeof(sInfo)); 01687 lFileLength = sInfo.dwLength; 01688 dwFileInitialFrames = 0; 01689 if (lFirstVideo >= 0) { 01690 /* check for correct version of the format 01691 * -- need at least BITMAPINFOHEADER or newer 01692 */ 01693 lSampleInc = 1; 01694 lBufferSize = cbBuffer; 01695 hres = AVIStreamReadFormat(pInStreams[lFirstVideo], AVIStreamStart(pInStreams[lFirstVideo]), lpBuffer, &lBufferSize); 01696 if (lBufferSize < (LONG)sizeof(BITMAPINFOHEADER)) 01697 hres = AVIERR_INTERNAL; 01698 if (FAILED(hres)) 01699 goto error; 01700 } else /* use one second blocks for interleaving if no video present */ 01701 lSampleInc = AVIStreamTimeToSample(pInStreams[0], 1000000); 01702 01703 /* create output streams */ 01704 for (curStream = 0; curStream < nStreams; curStream++) { 01705 AVIStreamInfoW(pInStreams[curStream], &sInfo, sizeof(sInfo)); 01706 01707 sInfo.dwInitialFrames = 0; 01708 if (dwInterleave != 0 && curStream > 0 && sInfo.fccType != streamtypeVIDEO) { 01709 /* 750 ms initial frames for non-video streams */ 01710 sInfo.dwInitialFrames = AVIStreamTimeToSample(pInStreams[0], 750); 01711 } 01712 01713 hres = AVIFileCreateStreamW(pfile, &pOutStreams[curStream], &sInfo); 01714 if (pOutStreams[curStream] != NULL && SUCCEEDED(hres)) { 01715 /* copy initial format for this stream */ 01716 lBufferSize = cbBuffer; 01717 hres = AVIStreamReadFormat(pInStreams[curStream], sInfo.dwStart, 01718 lpBuffer, &lBufferSize); 01719 if (FAILED(hres)) 01720 goto error; 01721 hres = AVIStreamSetFormat(pOutStreams[curStream], 0, lpBuffer, lBufferSize); 01722 if (FAILED(hres)) 01723 goto error; 01724 01725 /* try to copy stream handler data */ 01726 lBufferSize = cbBuffer; 01727 hres = AVIStreamReadData(pInStreams[curStream], ckidSTREAMHANDLERDATA, 01728 lpBuffer, &lBufferSize); 01729 if (SUCCEEDED(hres) && lBufferSize > 0) { 01730 hres = AVIStreamWriteData(pOutStreams[curStream],ckidSTREAMHANDLERDATA, 01731 lpBuffer, lBufferSize); 01732 if (FAILED(hres)) 01733 goto error; 01734 } 01735 01736 if (dwFileInitialFrames < sInfo.dwInitialFrames) 01737 dwFileInitialFrames = sInfo.dwInitialFrames; 01738 lReadBytes = 01739 AVIStreamSampleToSample(pOutStreams[0], pInStreams[curStream], 01740 sInfo.dwLength); 01741 if (lFileLength < lReadBytes) 01742 lFileLength = lReadBytes; 01743 } else { 01744 /* creation of de-/compression stream interface failed */ 01745 WARN("creation of (de-)compression stream failed for stream %d\n",curStream); 01746 AVIStreamRelease(pInStreams[curStream]); 01747 if (curStream + 1 >= nStreams) { 01748 /* move the others one up */ 01749 PAVISTREAM *ppas = &pInStreams[curStream]; 01750 int n = nStreams - (curStream + 1); 01751 01752 do { 01753 *ppas = pInStreams[curStream + 1]; 01754 } while (--n); 01755 } 01756 nStreams--; 01757 curStream--; 01758 } 01759 } /* create output streams for all input streams */ 01760 01761 /* have we still something to write, or lost everything? */ 01762 if (nStreams <= 0) 01763 goto error; 01764 01765 if (dwInterleave) { 01766 LONG lCurFrame = -dwFileInitialFrames; 01767 01768 /* interleaved file */ 01769 if (dwInterleave == 1) 01770 AVIFileEndRecord(pfile); 01771 01772 for (; lCurFrame < lFileLength; lCurFrame += lSampleInc) { 01773 for (curStream = 0; curStream < nStreams; curStream++) { 01774 LONG lLastSample; 01775 01776 hres = AVIStreamInfoW(pOutStreams[curStream], &sInfo, sizeof(sInfo)); 01777 if (FAILED(hres)) 01778 goto error; 01779 01780 /* initial frames phase at the end for this stream? */ 01781 if (-(LONG)sInfo.dwInitialFrames > lCurFrame) 01782 continue; 01783 01784 if ((lFileLength - lSampleInc) <= lCurFrame) { 01785 lLastSample = AVIStreamLength(pInStreams[curStream]); 01786 lFirstVideo = lLastSample + AVIStreamStart(pInStreams[curStream]); 01787 } else { 01788 if (curStream != 0) { 01789 lFirstVideo = 01790 AVIStreamSampleToSample(pInStreams[curStream], pInStreams[0], 01791 (sInfo.fccType == streamtypeVIDEO ? 01792 (LONG)dwInterleave : lSampleInc) + 01793 sInfo.dwInitialFrames + lCurFrame); 01794 } else 01795 lFirstVideo = lSampleInc + (sInfo.dwInitialFrames + lCurFrame); 01796 01797 lLastSample = AVIStreamEnd(pInStreams[curStream]); 01798 if (lLastSample <= lFirstVideo) 01799 lFirstVideo = lLastSample; 01800 } 01801 01802 /* copy needed samples now */ 01803 WARN("copy from stream %d samples %d to %d...\n",curStream, 01804 lStart[curStream],lFirstVideo); 01805 while (lFirstVideo > lStart[curStream]) { 01806 DWORD flags = 0; 01807 01808 /* copy format in case it can change */ 01809 lBufferSize = cbBuffer; 01810 hres = AVIStreamReadFormat(pInStreams[curStream], lStart[curStream], 01811 lpBuffer, &lBufferSize); 01812 if (FAILED(hres)) 01813 goto error; 01814 AVIStreamSetFormat(pOutStreams[curStream], lStart[curStream], 01815 lpBuffer, lBufferSize); 01816 01817 /* try to read data until we got it, or error */ 01818 do { 01819 hres = AVIStreamRead(pInStreams[curStream], lStart[curStream], 01820 lFirstVideo - lStart[curStream], lpBuffer, 01821 cbBuffer, &lReadBytes, &lReadSamples); 01822 } while ((hres == AVIERR_BUFFERTOOSMALL) && 01823 (lpBuffer = HeapReAlloc(GetProcessHeap(), 0, lpBuffer, cbBuffer *= 2)) != NULL); 01824 if (lpBuffer == NULL) 01825 hres = AVIERR_MEMORY; 01826 if (FAILED(hres)) 01827 goto error; 01828 01829 if (AVIStreamIsKeyFrame(pInStreams[curStream], (LONG)sInfo.dwStart)) 01830 flags = AVIIF_KEYFRAME; 01831 hres = AVIStreamWrite(pOutStreams[curStream], -1, lReadSamples, 01832 lpBuffer, lReadBytes, flags, NULL, NULL); 01833 if (FAILED(hres)) 01834 goto error; 01835 01836 lStart[curStream] += lReadSamples; 01837 } 01838 lStart[curStream] = lFirstVideo; 01839 } /* stream by stream */ 01840 01841 /* need to close this block? */ 01842 if (dwInterleave == 1) { 01843 hres = AVIFileEndRecord(pfile); 01844 if (FAILED(hres)) 01845 break; 01846 } 01847 01848 /* show progress */ 01849 if (lpfnCallback(MulDiv(dwFileInitialFrames + lCurFrame, 100, 01850 dwFileInitialFrames + lFileLength))) { 01851 hres = AVIERR_USERABORT; 01852 break; 01853 } 01854 } /* copy frame by frame */ 01855 } else { 01856 /* non-interleaved file */ 01857 01858 for (curStream = 0; curStream < nStreams; curStream++) { 01859 /* show progress */ 01860 if (lpfnCallback(MulDiv(curStream, 100, nStreams))) { 01861 hres = AVIERR_USERABORT; 01862 goto error; 01863 } 01864 01865 AVIStreamInfoW(pInStreams[curStream], &sInfo, sizeof(sInfo)); 01866 01867 if (sInfo.dwSampleSize != 0) { 01868 /* sample-based data like audio */ 01869 while (sInfo.dwStart < sInfo.dwLength) { 01870 LONG lSamples = cbBuffer / sInfo.dwSampleSize; 01871 01872 /* copy format in case it can change */ 01873 lBufferSize = cbBuffer; 01874 hres = AVIStreamReadFormat(pInStreams[curStream], sInfo.dwStart, 01875 lpBuffer, &lBufferSize); 01876 if (FAILED(hres)) 01877 goto error; 01878 AVIStreamSetFormat(pOutStreams[curStream], sInfo.dwStart, 01879 lpBuffer, lBufferSize); 01880 01881 /* limit to stream boundaries */ 01882 if (lSamples != (LONG)(sInfo.dwLength - sInfo.dwStart)) 01883 lSamples = sInfo.dwLength - sInfo.dwStart; 01884 01885 /* now try to read until we get it, or an error occurs */ 01886 do { 01887 lReadBytes = cbBuffer; 01888 lReadSamples = 0; 01889 hres = AVIStreamRead(pInStreams[curStream],sInfo.dwStart,lSamples, 01890 lpBuffer,cbBuffer,&lReadBytes,&lReadSamples); 01891 } while ((hres == AVIERR_BUFFERTOOSMALL) && 01892 (lpBuffer = HeapReAlloc(GetProcessHeap(), 0, lpBuffer, cbBuffer *= 2)) != NULL); 01893 if (lpBuffer == NULL) 01894 hres = AVIERR_MEMORY; 01895 if (FAILED(hres)) 01896 goto error; 01897 if (lReadSamples != 0) { 01898 sInfo.dwStart += lReadSamples; 01899 hres = AVIStreamWrite(pOutStreams[curStream], -1, lReadSamples, 01900 lpBuffer, lReadBytes, 0, NULL , NULL); 01901 if (FAILED(hres)) 01902 goto error; 01903 01904 /* show progress */ 01905 if (lpfnCallback(MulDiv(sInfo.dwStart,100,nStreams*sInfo.dwLength)+ 01906 MulDiv(curStream, 100, nStreams))) { 01907 hres = AVIERR_USERABORT; 01908 goto error; 01909 } 01910 } else { 01911 if ((sInfo.dwLength - sInfo.dwStart) != 1) { 01912 hres = AVIERR_FILEREAD; 01913 goto error; 01914 } 01915 } 01916 } 01917 } else { 01918 /* block-based data like video */ 01919 for (; sInfo.dwStart < sInfo.dwLength; sInfo.dwStart++) { 01920 DWORD flags = 0; 01921 01922 /* copy format in case it can change */ 01923 lBufferSize = cbBuffer; 01924 hres = AVIStreamReadFormat(pInStreams[curStream], sInfo.dwStart, 01925 lpBuffer, &lBufferSize); 01926 if (FAILED(hres)) 01927 goto error; 01928 AVIStreamSetFormat(pOutStreams[curStream], sInfo.dwStart, 01929 lpBuffer, lBufferSize); 01930 01931 /* try to read block and resize buffer if necessary */ 01932 do { 01933 lReadSamples = 0; 01934 lReadBytes = cbBuffer; 01935 hres = AVIStreamRead(pInStreams[curStream], sInfo.dwStart, 1, 01936 lpBuffer, cbBuffer,&lReadBytes,&lReadSamples); 01937 } while ((hres == AVIERR_BUFFERTOOSMALL) && 01938 (lpBuffer = HeapReAlloc(GetProcessHeap(), 0, lpBuffer, cbBuffer *= 2)) != NULL); 01939 if (lpBuffer == NULL) 01940 hres = AVIERR_MEMORY; 01941 if (FAILED(hres)) 01942 goto error; 01943 if (lReadSamples != 1) { 01944 hres = AVIERR_FILEREAD; 01945 goto error; 01946 } 01947 01948 if (AVIStreamIsKeyFrame(pInStreams[curStream], (LONG)sInfo.dwStart)) 01949 flags = AVIIF_KEYFRAME; 01950 hres = AVIStreamWrite(pOutStreams[curStream], -1, lReadSamples, 01951 lpBuffer, lReadBytes, flags, NULL, NULL); 01952 if (FAILED(hres)) 01953 goto error; 01954 01955 /* show progress */ 01956 if (lpfnCallback(MulDiv(sInfo.dwStart,100,nStreams*sInfo.dwLength)+ 01957 MulDiv(curStream, 100, nStreams))) { 01958 hres = AVIERR_USERABORT; 01959 goto error; 01960 } 01961 } /* copy all blocks */ 01962 } 01963 } /* copy data stream by stream */ 01964 } 01965 01966 error: 01967 HeapFree(GetProcessHeap(), 0, lpBuffer); 01968 if (pfile != NULL) { 01969 for (curStream = 0; curStream < nStreams; curStream++) { 01970 if (pOutStreams[curStream] != NULL) 01971 AVIStreamRelease(pOutStreams[curStream]); 01972 if (pInStreams[curStream] != NULL) 01973 AVIStreamRelease(pInStreams[curStream]); 01974 } 01975 01976 AVIFileRelease(pfile); 01977 } 01978 01979 return hres; 01980 } 01981 01982 /*********************************************************************** 01983 * CreateEditableStream (AVIFIL32.@) 01984 */ 01985 HRESULT WINAPI CreateEditableStream(PAVISTREAM *ppEditable, PAVISTREAM pSource) 01986 { 01987 IAVIEditStream *pEdit = NULL; 01988 HRESULT hr; 01989 01990 TRACE("(%p,%p)\n", ppEditable, pSource); 01991 01992 if (ppEditable == NULL) 01993 return AVIERR_BADPARAM; 01994 01995 *ppEditable = NULL; 01996 01997 if (pSource != NULL) { 01998 hr = IAVIStream_QueryInterface(pSource, &IID_IAVIEditStream, 01999 (LPVOID*)&pEdit); 02000 if (SUCCEEDED(hr) && pEdit != NULL) { 02001 hr = IAVIEditStream_Clone(pEdit, ppEditable); 02002 IAVIEditStream_Release(pEdit); 02003 02004 return hr; 02005 } 02006 } 02007 02008 /* need own implementation of IAVIEditStream */ 02009 pEdit = AVIFILE_CreateEditStream(pSource); 02010 if (pEdit == NULL) 02011 return AVIERR_MEMORY; 02012 02013 hr = IAVIEditStream_QueryInterface(pEdit, &IID_IAVIStream, 02014 (LPVOID*)ppEditable); 02015 IAVIEditStream_Release(pEdit); 02016 02017 return hr; 02018 } 02019 02020 /*********************************************************************** 02021 * EditStreamClone (AVIFIL32.@) 02022 */ 02023 HRESULT WINAPI EditStreamClone(PAVISTREAM pStream, PAVISTREAM *ppResult) 02024 { 02025 PAVIEDITSTREAM pEdit = NULL; 02026 HRESULT hr; 02027 02028 TRACE("(%p,%p)\n", pStream, ppResult); 02029 02030 if (pStream == NULL) 02031 return AVIERR_BADHANDLE; 02032 if (ppResult == NULL) 02033 return AVIERR_BADPARAM; 02034 02035 *ppResult = NULL; 02036 02037 hr = IAVIStream_QueryInterface(pStream, &IID_IAVIEditStream,(LPVOID*)&pEdit); 02038 if (SUCCEEDED(hr) && pEdit != NULL) { 02039 hr = IAVIEditStream_Clone(pEdit, ppResult); 02040 02041 IAVIEditStream_Release(pEdit); 02042 } else 02043 hr = AVIERR_UNSUPPORTED; 02044 02045 return hr; 02046 } 02047 02048 /*********************************************************************** 02049 * EditStreamCopy (AVIFIL32.@) 02050 */ 02051 HRESULT WINAPI EditStreamCopy(PAVISTREAM pStream, LONG *plStart, 02052 LONG *plLength, PAVISTREAM *ppResult) 02053 { 02054 PAVIEDITSTREAM pEdit = NULL; 02055 HRESULT hr; 02056 02057 TRACE("(%p,%p,%p,%p)\n", pStream, plStart, plLength, ppResult); 02058 02059 if (pStream == NULL) 02060 return AVIERR_BADHANDLE; 02061 if (plStart == NULL || plLength == NULL || ppResult == NULL) 02062 return AVIERR_BADPARAM; 02063 02064 *ppResult = NULL; 02065 02066 hr = IAVIStream_QueryInterface(pStream, &IID_IAVIEditStream,(LPVOID*)&pEdit); 02067 if (SUCCEEDED(hr) && pEdit != NULL) { 02068 hr = IAVIEditStream_Copy(pEdit, plStart, plLength, ppResult); 02069 02070 IAVIEditStream_Release(pEdit); 02071 } else 02072 hr = AVIERR_UNSUPPORTED; 02073 02074 return hr; 02075 } 02076 02077 /*********************************************************************** 02078 * EditStreamCut (AVIFIL32.@) 02079 */ 02080 HRESULT WINAPI EditStreamCut(PAVISTREAM pStream, LONG *plStart, 02081 LONG *plLength, PAVISTREAM *ppResult) 02082 { 02083 PAVIEDITSTREAM pEdit = NULL; 02084 HRESULT hr; 02085 02086 TRACE("(%p,%p,%p,%p)\n", pStream, plStart, plLength, ppResult); 02087 02088 if (ppResult != NULL) 02089 *ppResult = NULL; 02090 if (pStream == NULL) 02091 return AVIERR_BADHANDLE; 02092 if (plStart == NULL || plLength == NULL) 02093 return AVIERR_BADPARAM; 02094 02095 hr = IAVIStream_QueryInterface(pStream, &IID_IAVIEditStream,(LPVOID*)&pEdit); 02096 if (SUCCEEDED(hr) && pEdit != NULL) { 02097 hr = IAVIEditStream_Cut(pEdit, plStart, plLength, ppResult); 02098 02099 IAVIEditStream_Release(pEdit); 02100 } else 02101 hr = AVIERR_UNSUPPORTED; 02102 02103 return hr; 02104 } 02105 02106 /*********************************************************************** 02107 * EditStreamPaste (AVIFIL32.@) 02108 */ 02109 HRESULT WINAPI EditStreamPaste(PAVISTREAM pDest, LONG *plStart, LONG *plLength, 02110 PAVISTREAM pSource, LONG lStart, LONG lEnd) 02111 { 02112 PAVIEDITSTREAM pEdit = NULL; 02113 HRESULT hr; 02114 02115 TRACE("(%p,%p,%p,%p,%d,%d)\n", pDest, plStart, plLength, 02116 pSource, lStart, lEnd); 02117 02118 if (pDest == NULL || pSource == NULL) 02119 return AVIERR_BADHANDLE; 02120 if (plStart == NULL || plLength == NULL || lStart < 0) 02121 return AVIERR_BADPARAM; 02122 02123 hr = IAVIStream_QueryInterface(pDest, &IID_IAVIEditStream,(LPVOID*)&pEdit); 02124 if (SUCCEEDED(hr) && pEdit != NULL) { 02125 hr = IAVIEditStream_Paste(pEdit, plStart, plLength, pSource, lStart, lEnd); 02126 02127 IAVIEditStream_Release(pEdit); 02128 } else 02129 hr = AVIERR_UNSUPPORTED; 02130 02131 return hr; 02132 } 02133 02134 /*********************************************************************** 02135 * EditStreamSetInfoA (AVIFIL32.@) 02136 */ 02137 HRESULT WINAPI EditStreamSetInfoA(PAVISTREAM pstream, LPAVISTREAMINFOA asi, 02138 LONG size) 02139 { 02140 AVISTREAMINFOW asiw; 02141 02142 TRACE("(%p,%p,%d)\n", pstream, asi, size); 02143 02144 if (size >= 0 && size < sizeof(AVISTREAMINFOA)) 02145 return AVIERR_BADSIZE; 02146 02147 memcpy(&asiw, asi, sizeof(asiw) - sizeof(asiw.szName)); 02148 MultiByteToWideChar(CP_ACP, 0, asi->szName, -1, 02149 asiw.szName, sizeof(asiw.szName)/sizeof(WCHAR)); 02150 02151 return EditStreamSetInfoW(pstream, &asiw, sizeof(asiw)); 02152 } 02153 02154 /*********************************************************************** 02155 * EditStreamSetInfoW (AVIFIL32.@) 02156 */ 02157 HRESULT WINAPI EditStreamSetInfoW(PAVISTREAM pstream, LPAVISTREAMINFOW asi, 02158 LONG size) 02159 { 02160 PAVIEDITSTREAM pEdit = NULL; 02161 HRESULT hr; 02162 02163 TRACE("(%p,%p,%d)\n", pstream, asi, size); 02164 02165 if (size >= 0 && size < sizeof(AVISTREAMINFOA)) 02166 return AVIERR_BADSIZE; 02167 02168 hr = IAVIStream_QueryInterface(pstream, &IID_IAVIEditStream,(LPVOID*)&pEdit); 02169 if (SUCCEEDED(hr) && pEdit != NULL) { 02170 hr = IAVIEditStream_SetInfo(pEdit, asi, size); 02171 02172 IAVIEditStream_Release(pEdit); 02173 } else 02174 hr = AVIERR_UNSUPPORTED; 02175 02176 return hr; 02177 } 02178 02179 /*********************************************************************** 02180 * EditStreamSetNameA (AVIFIL32.@) 02181 */ 02182 HRESULT WINAPI EditStreamSetNameA(PAVISTREAM pstream, LPCSTR szName) 02183 { 02184 AVISTREAMINFOA asia; 02185 HRESULT hres; 02186 02187 TRACE("(%p,%s)\n", pstream, debugstr_a(szName)); 02188 02189 if (pstream == NULL) 02190 return AVIERR_BADHANDLE; 02191 if (szName == NULL) 02192 return AVIERR_BADPARAM; 02193 02194 hres = AVIStreamInfoA(pstream, &asia, sizeof(asia)); 02195 if (FAILED(hres)) 02196 return hres; 02197 02198 memset(asia.szName, 0, sizeof(asia.szName)); 02199 lstrcpynA(asia.szName, szName, sizeof(asia.szName)/sizeof(asia.szName[0])); 02200 02201 return EditStreamSetInfoA(pstream, &asia, sizeof(asia)); 02202 } 02203 02204 /*********************************************************************** 02205 * EditStreamSetNameW (AVIFIL32.@) 02206 */ 02207 HRESULT WINAPI EditStreamSetNameW(PAVISTREAM pstream, LPCWSTR szName) 02208 { 02209 AVISTREAMINFOW asiw; 02210 HRESULT hres; 02211 02212 TRACE("(%p,%s)\n", pstream, debugstr_w(szName)); 02213 02214 if (pstream == NULL) 02215 return AVIERR_BADHANDLE; 02216 if (szName == NULL) 02217 return AVIERR_BADPARAM; 02218 02219 hres = IAVIStream_Info(pstream, &asiw, sizeof(asiw)); 02220 if (FAILED(hres)) 02221 return hres; 02222 02223 memset(asiw.szName, 0, sizeof(asiw.szName)); 02224 lstrcpynW(asiw.szName, szName, sizeof(asiw.szName)/sizeof(asiw.szName[0])); 02225 02226 return EditStreamSetInfoW(pstream, &asiw, sizeof(asiw)); 02227 } 02228 02229 /*********************************************************************** 02230 * AVIClearClipboard (AVIFIL32.@) 02231 */ 02232 HRESULT WINAPI AVIClearClipboard(void) 02233 { 02234 TRACE("()\n"); 02235 02236 return AVIERR_UNSUPPORTED; /* OleSetClipboard(NULL); */ 02237 } 02238 02239 /*********************************************************************** 02240 * AVIGetFromClipboard (AVIFIL32.@) 02241 */ 02242 HRESULT WINAPI AVIGetFromClipboard(PAVIFILE *ppfile) 02243 { 02244 FIXME("(%p), stub!\n", ppfile); 02245 02246 *ppfile = NULL; 02247 02248 return AVIERR_UNSUPPORTED; 02249 } 02250 02251 /*********************************************************************** 02252 * AVIMakeStreamFromClipboard (AVIFIL32.@) 02253 */ 02254 HRESULT WINAPI AVIMakeStreamFromClipboard(UINT cfFormat, HANDLE hGlobal, 02255 PAVISTREAM * ppstream) 02256 { 02257 FIXME("(0x%08x,%p,%p), stub!\n", cfFormat, hGlobal, ppstream); 02258 02259 if (ppstream == NULL) 02260 return AVIERR_BADHANDLE; 02261 02262 return AVIERR_UNSUPPORTED; 02263 } 02264 02265 /*********************************************************************** 02266 * AVIPutFileOnClipboard (AVIFIL32.@) 02267 */ 02268 HRESULT WINAPI AVIPutFileOnClipboard(PAVIFILE pfile) 02269 { 02270 FIXME("(%p), stub!\n", pfile); 02271 02272 if (pfile == NULL) 02273 return AVIERR_BADHANDLE; 02274 02275 return AVIERR_UNSUPPORTED; 02276 } 02277 02278 HRESULT WINAPIV AVISaveA(LPCSTR szFile, CLSID * pclsidHandler, AVISAVECALLBACK lpfnCallback, 02279 int nStreams, PAVISTREAM pavi, LPAVICOMPRESSOPTIONS lpOptions, ...) 02280 { 02281 FIXME("(%s,%p,%p,0x%08x,%p,%p), stub!\n", debugstr_a(szFile), pclsidHandler, lpfnCallback, 02282 nStreams, pavi, lpOptions); 02283 02284 return AVIERR_UNSUPPORTED; 02285 } 02286 02287 HRESULT WINAPIV AVISaveW(LPCWSTR szFile, CLSID * pclsidHandler, AVISAVECALLBACK lpfnCallback, 02288 int nStreams, PAVISTREAM pavi, LPAVICOMPRESSOPTIONS lpOptions, ...) 02289 { 02290 FIXME("(%s,%p,%p,0x%08x,%p,%p), stub!\n", debugstr_w(szFile), pclsidHandler, lpfnCallback, 02291 nStreams, pavi, lpOptions); 02292 02293 return AVIERR_UNSUPPORTED; 02294 } Generated on Sun May 27 2012 04:22:33 for ReactOS by
1.7.6.1
|