2 * Copyright 1999 Marcus Meissner
3 * Copyright 2002-2003 Michael Günnewig
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #define WIN32_NO_STATUS
22 #define COM_NO_WINDOWS_H
32 //#include "winuser.h"
34 //#include "winerror.h"
37 //#include "shellapi.h"
42 #include "avifile_private.h"
44 #include <wine/debug.h>
45 #include <wine/unicode.h>
47 WINE_DEFAULT_DEBUG_CHANNEL(avifile
);
50 /***********************************************************************
51 * for AVIBuildFilterW -- uses fixed size table
53 #define MAX_FILTERS 30 /* 30 => 7kB */
55 typedef struct _AVIFilter
{
57 WCHAR szExtensions
[MAX_FILTERS
* 7];
60 /***********************************************************************
67 LPAVICOMPRESSOPTIONS
*ppOptions
;
71 /***********************************************************************
72 * copied from dlls/ole32/compobj.c
74 static HRESULT
AVIFILE_CLSIDFromString(LPCSTR idstr
, LPCLSID id
)
82 memset(id
, 0, sizeof(CLSID
));
86 /* validate the CLSID string */
87 if (lstrlenA(idstr
) != 38)
88 return CO_E_CLASSSTRING
;
90 s
= (BYTE
const*)idstr
;
91 if ((s
[0]!='{') || (s
[9]!='-') || (s
[14]!='-') || (s
[19]!='-') ||
92 (s
[24]!='-') || (s
[37]!='}'))
93 return CO_E_CLASSSTRING
;
95 for (i
= 1; i
< 37; i
++) {
96 if ((i
== 9) || (i
== 14) || (i
== 19) || (i
== 24))
98 if (!(((s
[i
] >= '0') && (s
[i
] <= '9')) ||
99 ((s
[i
] >= 'a') && (s
[i
] <= 'f')) ||
100 ((s
[i
] >= 'A') && (s
[i
] <= 'F')))
102 return CO_E_CLASSSTRING
;
105 TRACE("%s -> %p\n", s
, id
);
107 /* quick lookup table */
108 memset(table
, 0, 256);
110 for (i
= 0; i
< 10; i
++)
113 for (i
= 0; i
< 6; i
++) {
114 table
['A' + i
] = i
+10;
115 table
['a' + i
] = i
+10;
118 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
121 s
++; /* skip leading brace */
122 for (i
= 0; i
< 4; i
++) {
123 p
[3 - i
] = table
[*s
]<<4 | table
[*(s
+1)];
129 for (i
= 0; i
< 2; i
++) {
130 p
[1-i
] = table
[*s
]<<4 | table
[*(s
+1)];
136 for (i
= 0; i
< 2; i
++) {
137 p
[1-i
] = table
[*s
]<<4 | table
[*(s
+1)];
143 /* these are just sequential bytes */
144 for (i
= 0; i
< 2; i
++) {
145 *p
++ = table
[*s
]<<4 | table
[*(s
+1)];
150 for (i
= 0; i
< 6; i
++) {
151 *p
++ = table
[*s
]<<4 | table
[*(s
+1)];
158 static BOOL
AVIFILE_GetFileHandlerByExtension(LPCWSTR szFile
, LPCLSID lpclsid
)
162 LPWSTR szExt
= strrchrW(szFile
, '.');
163 LONG len
= sizeof(szValue
) / sizeof(szValue
[0]);
170 wsprintfA(szRegKey
, "AVIFile\\Extensions\\%.3ls", szExt
);
171 if (RegQueryValueA(HKEY_CLASSES_ROOT
, szRegKey
, szValue
, &len
) != ERROR_SUCCESS
)
174 return (AVIFILE_CLSIDFromString(szValue
, lpclsid
) == S_OK
);
177 /***********************************************************************
178 * AVIFileInit (AVIFIL32.@)
180 void WINAPI
AVIFileInit(void) {
184 /***********************************************************************
185 * AVIFileExit (AVIFIL32.@)
187 void WINAPI
AVIFileExit(void) {
188 /* need to free ole32.dll if we are the last exit call */
189 /* OleUninitialize() */
190 FIXME("(): stub!\n");
193 /***********************************************************************
194 * AVIFileOpen (AVIFIL32.@)
195 * AVIFileOpenA (AVIFIL32.@)
197 HRESULT WINAPI
AVIFileOpenA(PAVIFILE
*ppfile
, LPCSTR szFile
, UINT uMode
,
200 LPWSTR wszFile
= NULL
;
204 TRACE("(%p,%s,0x%08X,%s)\n", ppfile
, debugstr_a(szFile
), uMode
,
205 debugstr_guid(lpHandler
));
207 /* check parameters */
208 if (ppfile
== NULL
|| szFile
== NULL
)
209 return AVIERR_BADPARAM
;
211 /* convert ASCII string to Unicode and call unicode function */
212 len
= MultiByteToWideChar(CP_ACP
, 0, szFile
, -1, NULL
, 0);
214 return AVIERR_BADPARAM
;
216 wszFile
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
218 return AVIERR_MEMORY
;
220 MultiByteToWideChar(CP_ACP
, 0, szFile
, -1, wszFile
, len
);
222 hr
= AVIFileOpenW(ppfile
, wszFile
, uMode
, lpHandler
);
224 HeapFree(GetProcessHeap(), 0, wszFile
);
229 /***********************************************************************
230 * AVIFileOpenW (AVIFIL32.@)
232 HRESULT WINAPI
AVIFileOpenW(PAVIFILE
*ppfile
, LPCWSTR szFile
, UINT uMode
,
235 IPersistFile
*ppersist
= NULL
;
239 TRACE("(%p,%s,0x%X,%s)\n", ppfile
, debugstr_w(szFile
), uMode
,
240 debugstr_guid(lpHandler
));
242 /* check parameters */
243 if (ppfile
== NULL
|| szFile
== NULL
)
244 return AVIERR_BADPARAM
;
248 /* if no handler then try guessing it by extension */
249 if (lpHandler
== NULL
) {
250 if (! AVIFILE_GetFileHandlerByExtension(szFile
, &clsidHandler
))
251 clsidHandler
= CLSID_AVIFile
;
253 clsidHandler
= *lpHandler
;
255 /* create instance of handler */
256 hr
= CoCreateInstance(&clsidHandler
, NULL
, CLSCTX_INPROC
, &IID_IAVIFile
, (LPVOID
*)ppfile
);
257 if (FAILED(hr
) || *ppfile
== NULL
)
260 /* ask for IPersistFile interface for loading/creating the file */
261 hr
= IAVIFile_QueryInterface(*ppfile
, &IID_IPersistFile
, (LPVOID
*)&ppersist
);
262 if (FAILED(hr
) || ppersist
== NULL
) {
263 IAVIFile_Release(*ppfile
);
268 hr
= IPersistFile_Load(ppersist
, szFile
, uMode
);
269 IPersistFile_Release(ppersist
);
271 IAVIFile_Release(*ppfile
);
278 /***********************************************************************
279 * AVIFileAddRef (AVIFIL32.@)
281 ULONG WINAPI
AVIFileAddRef(PAVIFILE pfile
)
283 TRACE("(%p)\n", pfile
);
286 ERR(": bad handle passed!\n");
290 return IAVIFile_AddRef(pfile
);
293 /***********************************************************************
294 * AVIFileRelease (AVIFIL32.@)
296 ULONG WINAPI
AVIFileRelease(PAVIFILE pfile
)
298 TRACE("(%p)\n", pfile
);
301 ERR(": bad handle passed!\n");
305 return IAVIFile_Release(pfile
);
308 /***********************************************************************
309 * AVIFileInfo (AVIFIL32.@)
310 * AVIFileInfoA (AVIFIL32.@)
312 HRESULT WINAPI
AVIFileInfoA(PAVIFILE pfile
, LPAVIFILEINFOA afi
, LONG size
)
317 TRACE("(%p,%p,%d)\n", pfile
, afi
, size
);
320 return AVIERR_BADHANDLE
;
321 if ((DWORD
)size
< sizeof(AVIFILEINFOA
))
322 return AVIERR_BADSIZE
;
324 hres
= IAVIFile_Info(pfile
, &afiw
, sizeof(afiw
));
326 memcpy(afi
, &afiw
, sizeof(*afi
) - sizeof(afi
->szFileType
));
327 WideCharToMultiByte(CP_ACP
, 0, afiw
.szFileType
, -1, afi
->szFileType
,
328 sizeof(afi
->szFileType
), NULL
, NULL
);
329 afi
->szFileType
[sizeof(afi
->szFileType
) - 1] = 0;
334 /***********************************************************************
335 * AVIFileInfoW (AVIFIL32.@)
337 HRESULT WINAPI
AVIFileInfoW(PAVIFILE pfile
, LPAVIFILEINFOW afiw
, LONG size
)
339 TRACE("(%p,%p,%d)\n", pfile
, afiw
, size
);
342 return AVIERR_BADHANDLE
;
344 return IAVIFile_Info(pfile
, afiw
, size
);
347 /***********************************************************************
348 * AVIFileGetStream (AVIFIL32.@)
350 HRESULT WINAPI
AVIFileGetStream(PAVIFILE pfile
, PAVISTREAM
*avis
,
351 DWORD fccType
, LONG lParam
)
353 TRACE("(%p,%p,'%4.4s',%d)\n", pfile
, avis
, (char*)&fccType
, lParam
);
356 return AVIERR_BADHANDLE
;
358 return IAVIFile_GetStream(pfile
, avis
, fccType
, lParam
);
361 /***********************************************************************
362 * AVIFileCreateStream (AVIFIL32.@)
363 * AVIFileCreateStreamA (AVIFIL32.@)
365 HRESULT WINAPI
AVIFileCreateStreamA(PAVIFILE pfile
, PAVISTREAM
*ppavi
,
366 LPAVISTREAMINFOA psi
)
370 TRACE("(%p,%p,%p)\n", pfile
, ppavi
, psi
);
373 return AVIERR_BADHANDLE
;
375 /* Only the szName at the end is different */
376 memcpy(&psiw
, psi
, sizeof(*psi
) - sizeof(psi
->szName
));
377 MultiByteToWideChar(CP_ACP
, 0, psi
->szName
, -1, psiw
.szName
,
378 sizeof(psiw
.szName
) / sizeof(psiw
.szName
[0]));
380 return IAVIFile_CreateStream(pfile
, ppavi
, &psiw
);
383 /***********************************************************************
384 * AVIFileCreateStreamW (AVIFIL32.@)
386 HRESULT WINAPI
AVIFileCreateStreamW(PAVIFILE pfile
, PAVISTREAM
*avis
,
387 LPAVISTREAMINFOW asi
)
389 TRACE("(%p,%p,%p)\n", pfile
, avis
, asi
);
392 return AVIERR_BADHANDLE
;
394 return IAVIFile_CreateStream(pfile
, avis
, asi
);
397 /***********************************************************************
398 * AVIFileWriteData (AVIFIL32.@)
400 HRESULT WINAPI
AVIFileWriteData(PAVIFILE pfile
,DWORD fcc
,LPVOID lp
,LONG size
)
402 TRACE("(%p,'%4.4s',%p,%d)\n", pfile
, (char*)&fcc
, lp
, size
);
405 return AVIERR_BADHANDLE
;
407 return IAVIFile_WriteData(pfile
, fcc
, lp
, size
);
410 /***********************************************************************
411 * AVIFileReadData (AVIFIL32.@)
413 HRESULT WINAPI
AVIFileReadData(PAVIFILE pfile
,DWORD fcc
,LPVOID lp
,LPLONG size
)
415 TRACE("(%p,'%4.4s',%p,%p)\n", pfile
, (char*)&fcc
, lp
, size
);
418 return AVIERR_BADHANDLE
;
420 return IAVIFile_ReadData(pfile
, fcc
, lp
, size
);
423 /***********************************************************************
424 * AVIFileEndRecord (AVIFIL32.@)
426 HRESULT WINAPI
AVIFileEndRecord(PAVIFILE pfile
)
428 TRACE("(%p)\n", pfile
);
431 return AVIERR_BADHANDLE
;
433 return IAVIFile_EndRecord(pfile
);
436 /***********************************************************************
437 * AVIStreamAddRef (AVIFIL32.@)
439 ULONG WINAPI
AVIStreamAddRef(PAVISTREAM pstream
)
441 TRACE("(%p)\n", pstream
);
443 if (pstream
== NULL
) {
444 ERR(": bad handle passed!\n");
448 return IAVIStream_AddRef(pstream
);
451 /***********************************************************************
452 * AVIStreamRelease (AVIFIL32.@)
454 ULONG WINAPI
AVIStreamRelease(PAVISTREAM pstream
)
456 TRACE("(%p)\n", pstream
);
458 if (pstream
== NULL
) {
459 ERR(": bad handle passed!\n");
463 return IAVIStream_Release(pstream
);
466 /***********************************************************************
467 * AVIStreamCreate (AVIFIL32.@)
469 HRESULT WINAPI
AVIStreamCreate(PAVISTREAM
*ppavi
, LONG lParam1
, LONG lParam2
,
470 LPCLSID pclsidHandler
)
474 TRACE("(%p,0x%08X,0x%08X,%s)\n", ppavi
, lParam1
, lParam2
,
475 debugstr_guid(pclsidHandler
));
478 return AVIERR_BADPARAM
;
481 if (pclsidHandler
== NULL
)
482 return AVIERR_UNSUPPORTED
;
484 hr
= CoCreateInstance(pclsidHandler
, NULL
, CLSCTX_INPROC
, &IID_IAVIStream
, (LPVOID
*)ppavi
);
485 if (FAILED(hr
) || *ppavi
== NULL
)
488 hr
= IAVIStream_Create(*ppavi
, lParam1
, lParam2
);
490 IAVIStream_Release(*ppavi
);
497 /***********************************************************************
498 * AVIStreamInfo (AVIFIL32.@)
499 * AVIStreamInfoA (AVIFIL32.@)
501 HRESULT WINAPI
AVIStreamInfoA(PAVISTREAM pstream
, LPAVISTREAMINFOA asi
,
507 TRACE("(%p,%p,%d)\n", pstream
, asi
, size
);
510 return AVIERR_BADHANDLE
;
511 if ((DWORD
)size
< sizeof(AVISTREAMINFOA
))
512 return AVIERR_BADSIZE
;
514 hres
= IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
));
516 memcpy(asi
, &asiw
, sizeof(asiw
) - sizeof(asiw
.szName
));
517 WideCharToMultiByte(CP_ACP
, 0, asiw
.szName
, -1, asi
->szName
,
518 sizeof(asi
->szName
), NULL
, NULL
);
519 asi
->szName
[sizeof(asi
->szName
) - 1] = 0;
524 /***********************************************************************
525 * AVIStreamInfoW (AVIFIL32.@)
527 HRESULT WINAPI
AVIStreamInfoW(PAVISTREAM pstream
, LPAVISTREAMINFOW asi
,
530 TRACE("(%p,%p,%d)\n", pstream
, asi
, size
);
533 return AVIERR_BADHANDLE
;
535 return IAVIStream_Info(pstream
, asi
, size
);
538 /***********************************************************************
539 * AVIStreamFindSample (AVIFIL32.@)
541 LONG WINAPI
AVIStreamFindSample(PAVISTREAM pstream
, LONG pos
, LONG flags
)
543 TRACE("(%p,%d,0x%X)\n", pstream
, pos
, flags
);
548 return IAVIStream_FindSample(pstream
, pos
, flags
);
551 /***********************************************************************
552 * AVIStreamReadFormat (AVIFIL32.@)
554 HRESULT WINAPI
AVIStreamReadFormat(PAVISTREAM pstream
, LONG pos
,
555 LPVOID format
, LPLONG formatsize
)
557 TRACE("(%p,%d,%p,%p)\n", pstream
, pos
, format
, formatsize
);
560 return AVIERR_BADHANDLE
;
562 return IAVIStream_ReadFormat(pstream
, pos
, format
, formatsize
);
565 /***********************************************************************
566 * AVIStreamSetFormat (AVIFIL32.@)
568 HRESULT WINAPI
AVIStreamSetFormat(PAVISTREAM pstream
, LONG pos
,
569 LPVOID format
, LONG formatsize
)
571 TRACE("(%p,%d,%p,%d)\n", pstream
, pos
, format
, formatsize
);
574 return AVIERR_BADHANDLE
;
576 return IAVIStream_SetFormat(pstream
, pos
, format
, formatsize
);
579 /***********************************************************************
580 * AVIStreamRead (AVIFIL32.@)
582 HRESULT WINAPI
AVIStreamRead(PAVISTREAM pstream
, LONG start
, LONG samples
,
583 LPVOID buffer
, LONG buffersize
,
584 LPLONG bytesread
, LPLONG samplesread
)
586 TRACE("(%p,%d,%d,%p,%d,%p,%p)\n", pstream
, start
, samples
, buffer
,
587 buffersize
, bytesread
, samplesread
);
590 return AVIERR_BADHANDLE
;
592 return IAVIStream_Read(pstream
, start
, samples
, buffer
, buffersize
,
593 bytesread
, samplesread
);
596 /***********************************************************************
597 * AVIStreamWrite (AVIFIL32.@)
599 HRESULT WINAPI
AVIStreamWrite(PAVISTREAM pstream
, LONG start
, LONG samples
,
600 LPVOID buffer
, LONG buffersize
, DWORD flags
,
601 LPLONG sampwritten
, LPLONG byteswritten
)
603 TRACE("(%p,%d,%d,%p,%d,0x%X,%p,%p)\n", pstream
, start
, samples
, buffer
,
604 buffersize
, flags
, sampwritten
, byteswritten
);
607 return AVIERR_BADHANDLE
;
609 return IAVIStream_Write(pstream
, start
, samples
, buffer
, buffersize
,
610 flags
, sampwritten
, byteswritten
);
613 /***********************************************************************
614 * AVIStreamReadData (AVIFIL32.@)
616 HRESULT WINAPI
AVIStreamReadData(PAVISTREAM pstream
, DWORD fcc
, LPVOID lp
,
619 TRACE("(%p,'%4.4s',%p,%p)\n", pstream
, (char*)&fcc
, lp
, lpread
);
622 return AVIERR_BADHANDLE
;
624 return IAVIStream_ReadData(pstream
, fcc
, lp
, lpread
);
627 /***********************************************************************
628 * AVIStreamWriteData (AVIFIL32.@)
630 HRESULT WINAPI
AVIStreamWriteData(PAVISTREAM pstream
, DWORD fcc
, LPVOID lp
,
633 TRACE("(%p,'%4.4s',%p,%d)\n", pstream
, (char*)&fcc
, lp
, size
);
636 return AVIERR_BADHANDLE
;
638 return IAVIStream_WriteData(pstream
, fcc
, lp
, size
);
641 /***********************************************************************
642 * AVIStreamGetFrameOpen (AVIFIL32.@)
644 PGETFRAME WINAPI
AVIStreamGetFrameOpen(PAVISTREAM pstream
,
645 LPBITMAPINFOHEADER lpbiWanted
)
649 TRACE("(%p,%p)\n", pstream
, lpbiWanted
);
651 if (FAILED(IAVIStream_QueryInterface(pstream
, &IID_IGetFrame
, (LPVOID
*)&pg
)) ||
653 pg
= AVIFILE_CreateGetFrame(pstream
);
658 if (FAILED(IGetFrame_SetFormat(pg
, lpbiWanted
, NULL
, 0, 0, -1, -1))) {
659 IGetFrame_Release(pg
);
666 /***********************************************************************
667 * AVIStreamGetFrame (AVIFIL32.@)
669 LPVOID WINAPI
AVIStreamGetFrame(PGETFRAME pg
, LONG pos
)
671 TRACE("(%p,%d)\n", pg
, pos
);
676 return IGetFrame_GetFrame(pg
, pos
);
679 /***********************************************************************
680 * AVIStreamGetFrameClose (AVIFIL32.@)
682 HRESULT WINAPI
AVIStreamGetFrameClose(PGETFRAME pg
)
687 return IGetFrame_Release(pg
);
691 /***********************************************************************
692 * AVIMakeCompressedStream (AVIFIL32.@)
694 HRESULT WINAPI
AVIMakeCompressedStream(PAVISTREAM
*ppsCompressed
,
696 LPAVICOMPRESSOPTIONS aco
,
697 LPCLSID pclsidHandler
)
704 LONG size
= sizeof(szValue
);
706 TRACE("(%p,%p,%p,%s)\n", ppsCompressed
, psSource
, aco
,
707 debugstr_guid(pclsidHandler
));
709 if (ppsCompressed
== NULL
)
710 return AVIERR_BADPARAM
;
711 if (psSource
== NULL
)
712 return AVIERR_BADHANDLE
;
714 *ppsCompressed
= NULL
;
716 /* if no handler given get default ones based on streamtype */
717 if (pclsidHandler
== NULL
) {
718 hr
= IAVIStream_Info(psSource
, &asiw
, sizeof(asiw
));
722 wsprintfA(szRegKey
, "AVIFile\\Compressors\\%4.4s", (char*)&asiw
.fccType
);
723 if (RegQueryValueA(HKEY_CLASSES_ROOT
, szRegKey
, szValue
, &size
) != ERROR_SUCCESS
)
724 return AVIERR_UNSUPPORTED
;
725 if (AVIFILE_CLSIDFromString(szValue
, &clsidHandler
) != S_OK
)
726 return AVIERR_UNSUPPORTED
;
728 clsidHandler
= *pclsidHandler
;
730 hr
= CoCreateInstance(&clsidHandler
, NULL
, CLSCTX_INPROC
, &IID_IAVIStream
, (LPVOID
*)ppsCompressed
);
731 if (FAILED(hr
) || *ppsCompressed
== NULL
)
734 hr
= IAVIStream_Create(*ppsCompressed
, (LPARAM
)psSource
, (LPARAM
)aco
);
736 IAVIStream_Release(*ppsCompressed
);
737 *ppsCompressed
= NULL
;
743 /***********************************************************************
744 * AVIMakeFileFromStreams (AVIFIL32.@)
746 HRESULT WINAPI
AVIMakeFileFromStreams(PAVIFILE
*ppfile
, int nStreams
,
747 PAVISTREAM
*ppStreams
)
749 TRACE("(%p,%d,%p)\n", ppfile
, nStreams
, ppStreams
);
751 if (nStreams
< 0 || ppfile
== NULL
|| ppStreams
== NULL
)
752 return AVIERR_BADPARAM
;
754 *ppfile
= AVIFILE_CreateAVITempFile(nStreams
, ppStreams
);
756 return AVIERR_MEMORY
;
761 /***********************************************************************
762 * AVIStreamOpenFromFile (AVIFIL32.@)
763 * AVIStreamOpenFromFileA (AVIFIL32.@)
765 HRESULT WINAPI
AVIStreamOpenFromFileA(PAVISTREAM
*ppavi
, LPCSTR szFile
,
766 DWORD fccType
, LONG lParam
,
767 UINT mode
, LPCLSID pclsidHandler
)
769 PAVIFILE pfile
= NULL
;
772 TRACE("(%p,%s,'%4.4s',%d,0x%X,%s)\n", ppavi
, debugstr_a(szFile
),
773 (char*)&fccType
, lParam
, mode
, debugstr_guid(pclsidHandler
));
775 if (ppavi
== NULL
|| szFile
== NULL
)
776 return AVIERR_BADPARAM
;
780 hr
= AVIFileOpenA(&pfile
, szFile
, mode
, pclsidHandler
);
781 if (FAILED(hr
) || pfile
== NULL
)
784 hr
= IAVIFile_GetStream(pfile
, ppavi
, fccType
, lParam
);
785 IAVIFile_Release(pfile
);
790 /***********************************************************************
791 * AVIStreamOpenFromFileW (AVIFIL32.@)
793 HRESULT WINAPI
AVIStreamOpenFromFileW(PAVISTREAM
*ppavi
, LPCWSTR szFile
,
794 DWORD fccType
, LONG lParam
,
795 UINT mode
, LPCLSID pclsidHandler
)
797 PAVIFILE pfile
= NULL
;
800 TRACE("(%p,%s,'%4.4s',%d,0x%X,%s)\n", ppavi
, debugstr_w(szFile
),
801 (char*)&fccType
, lParam
, mode
, debugstr_guid(pclsidHandler
));
803 if (ppavi
== NULL
|| szFile
== NULL
)
804 return AVIERR_BADPARAM
;
808 hr
= AVIFileOpenW(&pfile
, szFile
, mode
, pclsidHandler
);
809 if (FAILED(hr
) || pfile
== NULL
)
812 hr
= IAVIFile_GetStream(pfile
, ppavi
, fccType
, lParam
);
813 IAVIFile_Release(pfile
);
818 /***********************************************************************
819 * AVIStreamBeginStreaming (AVIFIL32.@)
821 LONG WINAPI
AVIStreamBeginStreaming(PAVISTREAM pavi
, LONG lStart
, LONG lEnd
, LONG lRate
)
823 IAVIStreaming
* pstream
= NULL
;
826 TRACE("(%p,%d,%d,%d)\n", pavi
, lStart
, lEnd
, lRate
);
829 return AVIERR_BADHANDLE
;
831 hr
= IAVIStream_QueryInterface(pavi
, &IID_IAVIStreaming
, (LPVOID
*)&pstream
);
832 if (SUCCEEDED(hr
) && pstream
!= NULL
) {
833 hr
= IAVIStreaming_Begin(pstream
, lStart
, lEnd
, lRate
);
834 IAVIStreaming_Release(pstream
);
841 /***********************************************************************
842 * AVIStreamEndStreaming (AVIFIL32.@)
844 LONG WINAPI
AVIStreamEndStreaming(PAVISTREAM pavi
)
846 IAVIStreaming
* pstream
= NULL
;
849 TRACE("(%p)\n", pavi
);
851 hr
= IAVIStream_QueryInterface(pavi
, &IID_IAVIStreaming
, (LPVOID
*)&pstream
);
852 if (SUCCEEDED(hr
) && pstream
!= NULL
) {
853 IAVIStreaming_End(pstream
);
854 IAVIStreaming_Release(pstream
);
860 /***********************************************************************
861 * AVIStreamStart (AVIFIL32.@)
863 LONG WINAPI
AVIStreamStart(PAVISTREAM pstream
)
867 TRACE("(%p)\n", pstream
);
872 if (FAILED(IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
))))
878 /***********************************************************************
879 * AVIStreamLength (AVIFIL32.@)
881 LONG WINAPI
AVIStreamLength(PAVISTREAM pstream
)
885 TRACE("(%p)\n", pstream
);
890 if (FAILED(IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
))))
893 return asiw
.dwLength
;
896 /***********************************************************************
897 * AVIStreamSampleToTime (AVIFIL32.@)
899 LONG WINAPI
AVIStreamSampleToTime(PAVISTREAM pstream
, LONG lSample
)
904 TRACE("(%p,%d)\n", pstream
, lSample
);
909 if (FAILED(IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
))))
911 if (asiw
.dwRate
== 0)
914 /* limit to stream bounds */
915 if (lSample
< asiw
.dwStart
)
916 lSample
= asiw
.dwStart
;
917 if (lSample
> asiw
.dwStart
+ asiw
.dwLength
)
918 lSample
= asiw
.dwStart
+ asiw
.dwLength
;
920 if (asiw
.dwRate
/ asiw
.dwScale
< 1000)
921 time
= (LONG
)(((float)lSample
* asiw
.dwScale
* 1000) / asiw
.dwRate
);
923 time
= (LONG
)(((float)lSample
* asiw
.dwScale
* 1000 + (asiw
.dwRate
- 1)) / asiw
.dwRate
);
925 TRACE(" -> %d\n",time
);
929 /***********************************************************************
930 * AVIStreamTimeToSample (AVIFIL32.@)
932 LONG WINAPI
AVIStreamTimeToSample(PAVISTREAM pstream
, LONG lTime
)
937 TRACE("(%p,%d)\n", pstream
, lTime
);
939 if (pstream
== NULL
|| lTime
< 0)
942 if (FAILED(IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
))))
944 if (asiw
.dwScale
== 0)
947 if (asiw
.dwRate
/ asiw
.dwScale
< 1000)
948 sample
= (LONG
)((((float)asiw
.dwRate
* lTime
) / (asiw
.dwScale
* 1000)));
950 sample
= (LONG
)(((float)asiw
.dwRate
* lTime
+ (asiw
.dwScale
* 1000 - 1)) / (asiw
.dwScale
* 1000));
952 /* limit to stream bounds */
953 if (sample
< asiw
.dwStart
)
954 sample
= asiw
.dwStart
;
955 if (sample
> asiw
.dwStart
+ asiw
.dwLength
)
956 sample
= asiw
.dwStart
+ asiw
.dwLength
;
958 TRACE(" -> %d\n", sample
);
962 /***********************************************************************
963 * AVIBuildFilter (AVIFIL32.@)
964 * AVIBuildFilterA (AVIFIL32.@)
966 HRESULT WINAPI
AVIBuildFilterA(LPSTR szFilter
, LONG cbFilter
, BOOL fSaving
)
971 TRACE("(%p,%d,%d)\n", szFilter
, cbFilter
, fSaving
);
973 /* check parameters */
974 if (szFilter
== NULL
)
975 return AVIERR_BADPARAM
;
977 return AVIERR_BADSIZE
;
982 wszFilter
= HeapAlloc(GetProcessHeap(), 0, cbFilter
* sizeof(WCHAR
));
983 if (wszFilter
== NULL
)
984 return AVIERR_MEMORY
;
986 hr
= AVIBuildFilterW(wszFilter
, cbFilter
, fSaving
);
988 WideCharToMultiByte(CP_ACP
, 0, wszFilter
, cbFilter
,
989 szFilter
, cbFilter
, NULL
, NULL
);
992 HeapFree(GetProcessHeap(), 0, wszFilter
);
997 /***********************************************************************
998 * AVIBuildFilterW (AVIFIL32.@)
1000 HRESULT WINAPI
AVIBuildFilterW(LPWSTR szFilter
, LONG cbFilter
, BOOL fSaving
)
1002 static const WCHAR all_files
[] = { '*','.','*',0,0 };
1003 static const WCHAR szClsid
[] = {'C','L','S','I','D',0};
1004 static const WCHAR szExtensionFmt
[] = {';','*','.','%','s',0};
1005 static const WCHAR szAVIFileExtensions
[] =
1006 {'A','V','I','F','i','l','e','\\','E','x','t','e','n','s','i','o','n','s',0};
1009 WCHAR szAllFiles
[40];
1010 WCHAR szFileExt
[10];
1017 TRACE("(%p,%d,%d)\n", szFilter
, cbFilter
, fSaving
);
1019 /* check parameters */
1020 if (szFilter
== NULL
)
1021 return AVIERR_BADPARAM
;
1023 return AVIERR_BADSIZE
;
1025 lp
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, MAX_FILTERS
* sizeof(AVIFilter
));
1027 return AVIERR_MEMORY
;
1030 * 1. iterate over HKEY_CLASSES_ROOT\\AVIFile\\Extensions and collect
1031 * extensions and CLSIDs
1032 * 2. iterate over collected CLSIDs and copy its description and its
1033 * extensions to szFilter if it fits
1035 * First filter is named "All multimedia files" and its filter is a
1036 * collection of all possible extensions except "*.*".
1038 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, szAVIFileExtensions
, &hKey
) != ERROR_SUCCESS
) {
1039 HeapFree(GetProcessHeap(), 0, lp
);
1040 return AVIERR_ERROR
;
1042 for (n
= 0;RegEnumKeyW(hKey
, n
, szFileExt
, sizeof(szFileExt
)/sizeof(szFileExt
[0])) == ERROR_SUCCESS
;n
++) {
1043 /* get CLSID to extension */
1044 size
= sizeof(szValue
);
1045 if (RegQueryValueW(hKey
, szFileExt
, szValue
, &size
) != ERROR_SUCCESS
)
1048 /* search if the CLSID is already known */
1049 for (i
= 1; i
<= count
; i
++) {
1050 if (lstrcmpW(lp
[i
].szClsid
, szValue
) == 0)
1051 break; /* a new one */
1054 if (i
== count
+ 1) {
1055 /* it's a new CLSID */
1057 /* FIXME: How do we get info's about read/write capabilities? */
1059 if (count
>= MAX_FILTERS
) {
1060 /* try to inform user of our full fixed size table */
1061 ERR(": More than %d filters found! Adjust MAX_FILTERS in dlls/avifil32/api.c\n", MAX_FILTERS
);
1065 lstrcpyW(lp
[i
].szClsid
, szValue
);
1070 /* append extension to the filter */
1071 wsprintfW(szValue
, szExtensionFmt
, szFileExt
);
1072 if (lp
[i
].szExtensions
[0] == 0)
1073 lstrcatW(lp
[i
].szExtensions
, szValue
+ 1);
1075 lstrcatW(lp
[i
].szExtensions
, szValue
);
1077 /* also append to the "all multimedia"-filter */
1078 if (lp
[0].szExtensions
[0] == 0)
1079 lstrcatW(lp
[0].szExtensions
, szValue
+ 1);
1081 lstrcatW(lp
[0].szExtensions
, szValue
);
1085 /* 2. get descriptions for the CLSIDs and fill out szFilter */
1086 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, szClsid
, &hKey
) != ERROR_SUCCESS
) {
1087 HeapFree(GetProcessHeap(), 0, lp
);
1088 return AVIERR_ERROR
;
1090 for (n
= 0; n
<= count
; n
++) {
1091 /* first the description */
1093 size
= sizeof(szValue
);
1094 if (RegQueryValueW(hKey
, lp
[n
].szClsid
, szValue
, &size
) == ERROR_SUCCESS
) {
1095 size
= lstrlenW(szValue
);
1096 lstrcpynW(szFilter
, szValue
, cbFilter
);
1099 size
= LoadStringW(AVIFILE_hModule
,IDS_ALLMULTIMEDIA
,szFilter
,cbFilter
);
1101 /* check for enough space */
1103 if (cbFilter
< size
+ lstrlenW(lp
[n
].szExtensions
) + 2) {
1106 HeapFree(GetProcessHeap(), 0, lp
);
1108 return AVIERR_BUFFERTOOSMALL
;
1113 /* and then the filter */
1114 lstrcpynW(szFilter
, lp
[n
].szExtensions
, cbFilter
);
1115 size
= lstrlenW(lp
[n
].szExtensions
) + 1;
1121 HeapFree(GetProcessHeap(), 0, lp
);
1123 /* add "All files" "*.*" filter if enough space left */
1124 size
= LoadStringW(AVIFILE_hModule
, IDS_ALLFILES
,
1125 szAllFiles
, (sizeof(szAllFiles
) - sizeof(all_files
))/sizeof(WCHAR
)) + 1;
1126 memcpy( szAllFiles
+ size
, all_files
, sizeof(all_files
) );
1127 size
+= sizeof(all_files
) / sizeof(WCHAR
);
1129 if (cbFilter
> size
) {
1130 memcpy(szFilter
, szAllFiles
, size
* sizeof(szAllFiles
[0]));
1134 return AVIERR_BUFFERTOOSMALL
;
1138 static BOOL
AVISaveOptionsFmtChoose(HWND hWnd
)
1140 LPAVICOMPRESSOPTIONS pOptions
= SaveOpts
.ppOptions
[SaveOpts
.nCurrent
];
1141 AVISTREAMINFOW sInfo
;
1143 TRACE("(%p)\n", hWnd
);
1145 if (pOptions
== NULL
|| SaveOpts
.ppavis
[SaveOpts
.nCurrent
] == NULL
) {
1146 ERR(": bad state!\n");
1150 if (FAILED(AVIStreamInfoW(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],
1151 &sInfo
, sizeof(sInfo
)))) {
1152 ERR(": AVIStreamInfoW failed!\n");
1156 if (sInfo
.fccType
== streamtypeVIDEO
) {
1160 memset(&cv
, 0, sizeof(cv
));
1162 if ((pOptions
->dwFlags
& AVICOMPRESSF_VALID
) == 0) {
1163 memset(pOptions
, 0, sizeof(AVICOMPRESSOPTIONS
));
1164 pOptions
->fccType
= streamtypeVIDEO
;
1165 pOptions
->fccHandler
= comptypeDIB
;
1166 pOptions
->dwQuality
= (DWORD
)ICQUALITY_DEFAULT
;
1169 cv
.cbSize
= sizeof(cv
);
1170 cv
.dwFlags
= ICMF_COMPVARS_VALID
;
1171 /*cv.fccType = pOptions->fccType; */
1172 cv
.fccHandler
= pOptions
->fccHandler
;
1173 cv
.lQ
= pOptions
->dwQuality
;
1174 cv
.lpState
= pOptions
->lpParms
;
1175 cv
.cbState
= pOptions
->cbParms
;
1176 if (pOptions
->dwFlags
& AVICOMPRESSF_KEYFRAMES
)
1177 cv
.lKey
= pOptions
->dwKeyFrameEvery
;
1180 if (pOptions
->dwFlags
& AVICOMPRESSF_DATARATE
)
1181 cv
.lDataRate
= pOptions
->dwBytesPerSecond
/ 1024; /* need kBytes */
1185 ret
= ICCompressorChoose(hWnd
, SaveOpts
.uFlags
, NULL
,
1186 SaveOpts
.ppavis
[SaveOpts
.nCurrent
], &cv
, NULL
);
1189 pOptions
->fccHandler
= cv
.fccHandler
;
1190 pOptions
->lpParms
= cv
.lpState
;
1191 pOptions
->cbParms
= cv
.cbState
;
1192 pOptions
->dwQuality
= cv
.lQ
;
1194 pOptions
->dwKeyFrameEvery
= cv
.lKey
;
1195 pOptions
->dwFlags
|= AVICOMPRESSF_KEYFRAMES
;
1197 pOptions
->dwFlags
&= ~AVICOMPRESSF_KEYFRAMES
;
1198 if (cv
.lDataRate
!= 0) {
1199 pOptions
->dwBytesPerSecond
= cv
.lDataRate
* 1024; /* need bytes */
1200 pOptions
->dwFlags
|= AVICOMPRESSF_DATARATE
;
1202 pOptions
->dwFlags
&= ~AVICOMPRESSF_DATARATE
;
1203 pOptions
->dwFlags
|= AVICOMPRESSF_VALID
;
1205 ICCompressorFree(&cv
);
1208 } else if (sInfo
.fccType
== streamtypeAUDIO
) {
1209 ACMFORMATCHOOSEW afmtc
;
1213 /* FIXME: check ACM version -- Which version is needed? */
1215 memset(&afmtc
, 0, sizeof(afmtc
));
1216 afmtc
.cbStruct
= sizeof(afmtc
);
1218 afmtc
.hwndOwner
= hWnd
;
1220 acmMetrics(NULL
, ACM_METRIC_MAX_SIZE_FORMAT
, &size
);
1221 if ((pOptions
->cbFormat
== 0 || pOptions
->lpFormat
== NULL
) && size
!= 0) {
1222 pOptions
->lpFormat
= HeapAlloc(GetProcessHeap(), 0, size
);
1223 if (!pOptions
->lpFormat
) return FALSE
;
1224 pOptions
->cbFormat
= size
;
1225 } else if (pOptions
->cbFormat
< (DWORD
)size
) {
1226 void *new_buffer
= HeapReAlloc(GetProcessHeap(), 0, pOptions
->lpFormat
, size
);
1227 if (!new_buffer
) return FALSE
;
1228 pOptions
->lpFormat
= new_buffer
;
1229 pOptions
->cbFormat
= size
;
1231 afmtc
.pwfx
= pOptions
->lpFormat
;
1232 afmtc
.cbwfx
= pOptions
->cbFormat
;
1235 AVIStreamFormatSize(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],
1236 sInfo
.dwStart
, &size
);
1237 if (size
< (LONG
)sizeof(PCMWAVEFORMAT
))
1238 size
= sizeof(PCMWAVEFORMAT
);
1239 afmtc
.pwfxEnum
= HeapAlloc(GetProcessHeap(), 0, size
);
1240 if (afmtc
.pwfxEnum
!= NULL
) {
1241 AVIStreamReadFormat(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],
1242 sInfo
.dwStart
, afmtc
.pwfxEnum
, &size
);
1243 afmtc
.fdwEnum
= ACM_FORMATENUMF_CONVERT
;
1246 ret
= acmFormatChooseW(&afmtc
);
1248 pOptions
->dwFlags
|= AVICOMPRESSF_VALID
;
1250 HeapFree(GetProcessHeap(), 0, afmtc
.pwfxEnum
);
1253 ERR(": unknown streamtype 0x%08X\n", sInfo
.fccType
);
1258 static void AVISaveOptionsUpdate(HWND hWnd
)
1260 static const WCHAR szVideoFmt
[]={'%','l','d','x','%','l','d','x','%','d',0};
1261 static const WCHAR szAudioFmt
[]={'%','s',' ','%','s',0};
1263 WCHAR szFormat
[128];
1264 AVISTREAMINFOW sInfo
;
1268 TRACE("(%p)\n", hWnd
);
1270 SaveOpts
.nCurrent
= SendDlgItemMessageW(hWnd
,IDC_STREAM
,CB_GETCURSEL
,0,0);
1271 if (SaveOpts
.nCurrent
< 0)
1274 if (FAILED(AVIStreamInfoW(SaveOpts
.ppavis
[SaveOpts
.nCurrent
], &sInfo
, sizeof(sInfo
))))
1277 AVIStreamFormatSize(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],sInfo
.dwStart
,&size
);
1281 /* read format to build format description string */
1282 lpFormat
= HeapAlloc(GetProcessHeap(), 0, size
);
1283 if (lpFormat
!= NULL
) {
1284 if (SUCCEEDED(AVIStreamReadFormat(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],sInfo
.dwStart
,lpFormat
, &size
))) {
1285 if (sInfo
.fccType
== streamtypeVIDEO
) {
1286 LPBITMAPINFOHEADER lpbi
= lpFormat
;
1289 wsprintfW(szFormat
, szVideoFmt
, lpbi
->biWidth
,
1290 lpbi
->biHeight
, lpbi
->biBitCount
);
1292 if (lpbi
->biCompression
!= BI_RGB
) {
1295 hic
= ICLocate(ICTYPE_VIDEO
, sInfo
.fccHandler
, lpFormat
,
1296 NULL
, ICMODE_DECOMPRESS
);
1298 if (ICGetInfo(hic
, &icinfo
, sizeof(icinfo
)) == S_OK
)
1299 lstrcatW(szFormat
, icinfo
.szDescription
);
1303 LoadStringW(AVIFILE_hModule
, IDS_UNCOMPRESSED
,
1304 icinfo
.szDescription
,
1305 sizeof(icinfo
.szDescription
)/sizeof(icinfo
.szDescription
[0]));
1306 lstrcatW(szFormat
, icinfo
.szDescription
);
1308 } else if (sInfo
.fccType
== streamtypeAUDIO
) {
1309 ACMFORMATTAGDETAILSW aftd
;
1310 ACMFORMATDETAILSW afd
;
1312 memset(&aftd
, 0, sizeof(aftd
));
1313 memset(&afd
, 0, sizeof(afd
));
1315 aftd
.cbStruct
= sizeof(aftd
);
1316 aftd
.dwFormatTag
= afd
.dwFormatTag
=
1317 ((PWAVEFORMATEX
)lpFormat
)->wFormatTag
;
1318 aftd
.cbFormatSize
= afd
.cbwfx
= size
;
1320 afd
.cbStruct
= sizeof(afd
);
1321 afd
.pwfx
= lpFormat
;
1323 if (acmFormatTagDetailsW(NULL
, &aftd
,
1324 ACM_FORMATTAGDETAILSF_FORMATTAG
) == S_OK
) {
1325 if (acmFormatDetailsW(NULL
,&afd
,ACM_FORMATDETAILSF_FORMAT
) == S_OK
)
1326 wsprintfW(szFormat
, szAudioFmt
, afd
.szFormat
, aftd
.szFormatTag
);
1330 HeapFree(GetProcessHeap(), 0, lpFormat
);
1333 /* set text for format description */
1334 SetDlgItemTextW(hWnd
, IDC_FORMATTEXT
, szFormat
);
1336 /* Disable option button for unsupported streamtypes */
1337 if (sInfo
.fccType
== streamtypeVIDEO
||
1338 sInfo
.fccType
== streamtypeAUDIO
)
1339 EnableWindow(GetDlgItem(hWnd
, IDC_OPTIONS
), TRUE
);
1341 EnableWindow(GetDlgItem(hWnd
, IDC_OPTIONS
), FALSE
);
1346 static INT_PTR CALLBACK
AVISaveOptionsDlgProc(HWND hWnd
, UINT uMsg
,
1347 WPARAM wParam
, LPARAM lParam
)
1350 BOOL bIsInterleaved
;
1353 /*TRACE("(%p,%u,0x%04X,0x%08lX)\n", hWnd, uMsg, wParam, lParam);*/
1357 SaveOpts
.nCurrent
= 0;
1358 if (SaveOpts
.nStreams
== 1) {
1359 EndDialog(hWnd
, AVISaveOptionsFmtChoose(hWnd
));
1364 for (n
= 0; n
< SaveOpts
.nStreams
; n
++) {
1365 AVISTREAMINFOW sInfo
;
1367 AVIStreamInfoW(SaveOpts
.ppavis
[n
], &sInfo
, sizeof(sInfo
));
1368 SendDlgItemMessageW(hWnd
, IDC_STREAM
, CB_ADDSTRING
,
1369 0L, (LPARAM
)sInfo
.szName
);
1372 /* select first stream */
1373 SendDlgItemMessageW(hWnd
, IDC_STREAM
, CB_SETCURSEL
, 0, 0);
1374 SendMessageW(hWnd
, WM_COMMAND
, MAKELONG(IDC_STREAM
, CBN_SELCHANGE
), (LPARAM
)hWnd
);
1376 /* initialize interleave */
1377 if (SaveOpts
.ppOptions
[0] != NULL
&&
1378 (SaveOpts
.ppOptions
[0]->dwFlags
& AVICOMPRESSF_VALID
)) {
1379 bIsInterleaved
= (SaveOpts
.ppOptions
[0]->dwFlags
& AVICOMPRESSF_INTERLEAVE
);
1380 dwInterleave
= SaveOpts
.ppOptions
[0]->dwInterleaveEvery
;
1382 bIsInterleaved
= TRUE
;
1385 CheckDlgButton(hWnd
, IDC_INTERLEAVE
, bIsInterleaved
);
1386 SetDlgItemInt(hWnd
, IDC_INTERLEAVEEVERY
, dwInterleave
, FALSE
);
1387 EnableWindow(GetDlgItem(hWnd
, IDC_INTERLEAVEEVERY
), bIsInterleaved
);
1390 switch (LOWORD(wParam
)) {
1392 /* get data from controls and save them */
1393 dwInterleave
= GetDlgItemInt(hWnd
, IDC_INTERLEAVEEVERY
, NULL
, 0);
1394 bIsInterleaved
= IsDlgButtonChecked(hWnd
, IDC_INTERLEAVE
);
1395 for (n
= 0; n
< SaveOpts
.nStreams
; n
++) {
1396 if (SaveOpts
.ppOptions
[n
] != NULL
) {
1397 if (bIsInterleaved
) {
1398 SaveOpts
.ppOptions
[n
]->dwFlags
|= AVICOMPRESSF_INTERLEAVE
;
1399 SaveOpts
.ppOptions
[n
]->dwInterleaveEvery
= dwInterleave
;
1401 SaveOpts
.ppOptions
[n
]->dwFlags
&= ~AVICOMPRESSF_INTERLEAVE
;
1406 EndDialog(hWnd
, LOWORD(wParam
) == IDOK
);
1408 case IDC_INTERLEAVE
:
1409 EnableWindow(GetDlgItem(hWnd
, IDC_INTERLEAVEEVERY
),
1410 IsDlgButtonChecked(hWnd
, IDC_INTERLEAVE
));
1413 if (HIWORD(wParam
) == CBN_SELCHANGE
) {
1414 /* update control elements */
1415 AVISaveOptionsUpdate(hWnd
);
1419 AVISaveOptionsFmtChoose(hWnd
);
1428 /***********************************************************************
1429 * AVISaveOptions (AVIFIL32.@)
1431 BOOL WINAPI
AVISaveOptions(HWND hWnd
, UINT uFlags
, INT nStreams
,
1432 PAVISTREAM
*ppavi
, LPAVICOMPRESSOPTIONS
*ppOptions
)
1434 LPAVICOMPRESSOPTIONS pSavedOptions
= NULL
;
1437 TRACE("(%p,0x%X,%d,%p,%p)\n", hWnd
, uFlags
, nStreams
,
1440 /* check parameters */
1441 if (nStreams
<= 0 || ppavi
== NULL
|| ppOptions
== NULL
)
1442 return AVIERR_BADPARAM
;
1444 /* save options in case the user presses cancel */
1446 pSavedOptions
= HeapAlloc(GetProcessHeap(), 0, nStreams
* sizeof(AVICOMPRESSOPTIONS
));
1447 if (pSavedOptions
== NULL
)
1450 for (n
= 0; n
< nStreams
; n
++) {
1451 if (ppOptions
[n
] != NULL
)
1452 memcpy(pSavedOptions
+ n
, ppOptions
[n
], sizeof(AVICOMPRESSOPTIONS
));
1456 SaveOpts
.uFlags
= uFlags
;
1457 SaveOpts
.nStreams
= nStreams
;
1458 SaveOpts
.ppavis
= ppavi
;
1459 SaveOpts
.ppOptions
= ppOptions
;
1461 ret
= DialogBoxW(AVIFILE_hModule
, MAKEINTRESOURCEW(IDD_SAVEOPTIONS
),
1462 hWnd
, AVISaveOptionsDlgProc
);
1467 /* restore options when user pressed cancel */
1468 if (pSavedOptions
!= NULL
) {
1470 for (n
= 0; n
< nStreams
; n
++) {
1471 if (ppOptions
[n
] != NULL
)
1472 memcpy(ppOptions
[n
], pSavedOptions
+ n
, sizeof(AVICOMPRESSOPTIONS
));
1475 HeapFree(GetProcessHeap(), 0, pSavedOptions
);
1481 /***********************************************************************
1482 * AVISaveOptionsFree (AVIFIL32.@)
1484 HRESULT WINAPI
AVISaveOptionsFree(INT nStreams
,LPAVICOMPRESSOPTIONS
*ppOptions
)
1486 TRACE("(%d,%p)\n", nStreams
, ppOptions
);
1488 if (nStreams
< 0 || ppOptions
== NULL
)
1489 return AVIERR_BADPARAM
;
1491 for (nStreams
--; nStreams
>= 0; nStreams
--) {
1492 if (ppOptions
[nStreams
] != NULL
) {
1493 ppOptions
[nStreams
]->dwFlags
&= ~AVICOMPRESSF_VALID
;
1495 if (ppOptions
[nStreams
]->lpParms
!= NULL
) {
1496 HeapFree(GetProcessHeap(), 0, ppOptions
[nStreams
]->lpParms
);
1497 ppOptions
[nStreams
]->lpParms
= NULL
;
1498 ppOptions
[nStreams
]->cbParms
= 0;
1500 if (ppOptions
[nStreams
]->lpFormat
!= NULL
) {
1501 HeapFree(GetProcessHeap(), 0, ppOptions
[nStreams
]->lpFormat
);
1502 ppOptions
[nStreams
]->lpFormat
= NULL
;
1503 ppOptions
[nStreams
]->cbFormat
= 0;
1511 /***********************************************************************
1512 * AVISaveVA (AVIFIL32.@)
1514 HRESULT WINAPI
AVISaveVA(LPCSTR szFile
, CLSID
*pclsidHandler
,
1515 AVISAVECALLBACK lpfnCallback
, int nStream
,
1516 PAVISTREAM
*ppavi
, LPAVICOMPRESSOPTIONS
*plpOptions
)
1518 LPWSTR wszFile
= NULL
;
1522 TRACE("%s,%p,%p,%d,%p,%p)\n", debugstr_a(szFile
), pclsidHandler
,
1523 lpfnCallback
, nStream
, ppavi
, plpOptions
);
1525 if (szFile
== NULL
|| ppavi
== NULL
|| plpOptions
== NULL
)
1526 return AVIERR_BADPARAM
;
1528 /* convert ASCII string to Unicode and call Unicode function */
1529 len
= MultiByteToWideChar(CP_ACP
, 0, szFile
, -1, NULL
, 0);
1531 return AVIERR_BADPARAM
;
1533 wszFile
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
1534 if (wszFile
== NULL
)
1535 return AVIERR_MEMORY
;
1537 MultiByteToWideChar(CP_ACP
, 0, szFile
, -1, wszFile
, len
);
1539 hr
= AVISaveVW(wszFile
, pclsidHandler
, lpfnCallback
,
1540 nStream
, ppavi
, plpOptions
);
1542 HeapFree(GetProcessHeap(), 0, wszFile
);
1547 /***********************************************************************
1548 * AVIFILE_AVISaveDefaultCallback (internal)
1550 static BOOL WINAPI
AVIFILE_AVISaveDefaultCallback(INT progress
)
1552 TRACE("(%d)\n", progress
);
1557 /***********************************************************************
1558 * AVISaveVW (AVIFIL32.@)
1560 HRESULT WINAPI
AVISaveVW(LPCWSTR szFile
, CLSID
*pclsidHandler
,
1561 AVISAVECALLBACK lpfnCallback
, int nStreams
,
1562 PAVISTREAM
*ppavi
, LPAVICOMPRESSOPTIONS
*plpOptions
)
1564 LONG lStart
[MAX_AVISTREAMS
];
1565 PAVISTREAM pOutStreams
[MAX_AVISTREAMS
];
1566 PAVISTREAM pInStreams
[MAX_AVISTREAMS
];
1568 AVISTREAMINFOW sInfo
;
1570 PAVIFILE pfile
= NULL
; /* the output AVI file */
1571 LONG lFirstVideo
= -1;
1574 /* for interleaving ... */
1575 DWORD dwInterleave
= 0; /* interleave rate */
1576 DWORD dwFileInitialFrames
;
1580 /* for reading/writing the data ... */
1581 LPVOID lpBuffer
= NULL
;
1582 LONG cbBuffer
; /* real size of lpBuffer */
1583 LONG lBufferSize
; /* needed bytes for format(s), etc. */
1588 TRACE("(%s,%p,%p,%d,%p,%p)\n", debugstr_w(szFile
), pclsidHandler
,
1589 lpfnCallback
, nStreams
, ppavi
, plpOptions
);
1591 if (szFile
== NULL
|| ppavi
== NULL
|| plpOptions
== NULL
)
1592 return AVIERR_BADPARAM
;
1593 if (nStreams
>= MAX_AVISTREAMS
) {
1594 WARN("Can't write AVI with %d streams only supports %d -- change MAX_AVISTREAMS!\n", nStreams
, MAX_AVISTREAMS
);
1595 return AVIERR_INTERNAL
;
1598 if (lpfnCallback
== NULL
)
1599 lpfnCallback
= AVIFILE_AVISaveDefaultCallback
;
1601 /* clear local variable(s) */
1602 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1603 pInStreams
[curStream
] = NULL
;
1604 pOutStreams
[curStream
] = NULL
;
1607 /* open output AVI file (create it if it doesn't exist) */
1608 hres
= AVIFileOpenW(&pfile
, szFile
, OF_CREATE
|OF_SHARE_EXCLUSIVE
|OF_WRITE
,
1612 AVIFileInfoW(pfile
, &fInfo
, sizeof(fInfo
)); /* for dwCaps */
1614 /* initialize our data structures part 1 */
1615 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1616 PAVISTREAM pCurStream
= ppavi
[curStream
];
1618 hres
= AVIStreamInfoW(pCurStream
, &sInfo
, sizeof(sInfo
));
1622 /* search first video stream and check for interleaving */
1623 if (sInfo
.fccType
== streamtypeVIDEO
) {
1624 /* remember first video stream -- needed for interleaving */
1625 if (lFirstVideo
< 0)
1626 lFirstVideo
= curStream
;
1627 } else if (!dwInterleave
) {
1628 /* check if any non-video stream wants to be interleaved */
1629 WARN("options.flags=0x%X options.dwInterleave=%u\n",plpOptions
[curStream
]->dwFlags
,plpOptions
[curStream
]->dwInterleaveEvery
);
1630 if (plpOptions
[curStream
] != NULL
&&
1631 plpOptions
[curStream
]->dwFlags
& AVICOMPRESSF_INTERLEAVE
)
1632 dwInterleave
= plpOptions
[curStream
]->dwInterleaveEvery
;
1635 /* create de-/compressed stream interface if needed */
1636 pInStreams
[curStream
] = NULL
;
1637 if (plpOptions
[curStream
] != NULL
) {
1638 if (plpOptions
[curStream
]->fccHandler
||
1639 plpOptions
[curStream
]->lpFormat
!= NULL
) {
1640 DWORD dwKeySave
= plpOptions
[curStream
]->dwKeyFrameEvery
;
1642 if (fInfo
.dwCaps
& AVIFILECAPS_ALLKEYFRAMES
)
1643 plpOptions
[curStream
]->dwKeyFrameEvery
= 1;
1645 hres
= AVIMakeCompressedStream(&pInStreams
[curStream
], pCurStream
,
1646 plpOptions
[curStream
], NULL
);
1647 plpOptions
[curStream
]->dwKeyFrameEvery
= dwKeySave
;
1648 if (FAILED(hres
) || pInStreams
[curStream
] == NULL
) {
1649 pInStreams
[curStream
] = NULL
;
1653 /* test stream interface and update stream-info */
1654 hres
= AVIStreamInfoW(pInStreams
[curStream
], &sInfo
, sizeof(sInfo
));
1660 /* now handle streams which will only be copied */
1661 if (pInStreams
[curStream
] == NULL
) {
1662 pCurStream
= pInStreams
[curStream
] = ppavi
[curStream
];
1663 AVIStreamAddRef(pCurStream
);
1665 pCurStream
= pInStreams
[curStream
];
1667 lStart
[curStream
] = sInfo
.dwStart
;
1668 } /* for all streams */
1670 /* check that first video stream is the first stream */
1671 if (lFirstVideo
> 0) {
1672 PAVISTREAM pTmp
= pInStreams
[lFirstVideo
];
1673 LONG lTmp
= lStart
[lFirstVideo
];
1675 pInStreams
[lFirstVideo
] = pInStreams
[0];
1676 pInStreams
[0] = pTmp
;
1677 lStart
[lFirstVideo
] = lStart
[0];
1682 /* allocate buffer for formats, data, etc. of an initial size of 64 kBytes*/
1683 cbBuffer
= 0x00010000;
1684 lpBuffer
= HeapAlloc(GetProcessHeap(), 0, cbBuffer
);
1685 if (lpBuffer
== NULL
) {
1686 hres
= AVIERR_MEMORY
;
1690 AVIStreamInfoW(pInStreams
[0], &sInfo
, sizeof(sInfo
));
1691 lFileLength
= sInfo
.dwLength
;
1692 dwFileInitialFrames
= 0;
1693 if (lFirstVideo
>= 0) {
1694 /* check for correct version of the format
1695 * -- need at least BITMAPINFOHEADER or newer
1698 lBufferSize
= cbBuffer
;
1699 hres
= AVIStreamReadFormat(pInStreams
[lFirstVideo
], AVIStreamStart(pInStreams
[lFirstVideo
]), lpBuffer
, &lBufferSize
);
1700 if (lBufferSize
< (LONG
)sizeof(BITMAPINFOHEADER
))
1701 hres
= AVIERR_INTERNAL
;
1704 } else /* use one second blocks for interleaving if no video present */
1705 lSampleInc
= AVIStreamTimeToSample(pInStreams
[0], 1000000);
1707 /* create output streams */
1708 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1709 AVIStreamInfoW(pInStreams
[curStream
], &sInfo
, sizeof(sInfo
));
1711 sInfo
.dwInitialFrames
= 0;
1712 if (dwInterleave
!= 0 && curStream
> 0 && sInfo
.fccType
!= streamtypeVIDEO
) {
1713 /* 750 ms initial frames for non-video streams */
1714 sInfo
.dwInitialFrames
= AVIStreamTimeToSample(pInStreams
[0], 750);
1717 hres
= AVIFileCreateStreamW(pfile
, &pOutStreams
[curStream
], &sInfo
);
1718 if (pOutStreams
[curStream
] != NULL
&& SUCCEEDED(hres
)) {
1719 /* copy initial format for this stream */
1720 lBufferSize
= cbBuffer
;
1721 hres
= AVIStreamReadFormat(pInStreams
[curStream
], sInfo
.dwStart
,
1722 lpBuffer
, &lBufferSize
);
1725 hres
= AVIStreamSetFormat(pOutStreams
[curStream
], 0, lpBuffer
, lBufferSize
);
1729 /* try to copy stream handler data */
1730 lBufferSize
= cbBuffer
;
1731 hres
= AVIStreamReadData(pInStreams
[curStream
], ckidSTREAMHANDLERDATA
,
1732 lpBuffer
, &lBufferSize
);
1733 if (SUCCEEDED(hres
) && lBufferSize
> 0) {
1734 hres
= AVIStreamWriteData(pOutStreams
[curStream
],ckidSTREAMHANDLERDATA
,
1735 lpBuffer
, lBufferSize
);
1740 if (dwFileInitialFrames
< sInfo
.dwInitialFrames
)
1741 dwFileInitialFrames
= sInfo
.dwInitialFrames
;
1743 AVIStreamSampleToSample(pOutStreams
[0], pInStreams
[curStream
],
1745 if (lFileLength
< lReadBytes
)
1746 lFileLength
= lReadBytes
;
1748 /* creation of de-/compression stream interface failed */
1749 WARN("creation of (de-)compression stream failed for stream %d\n",curStream
);
1750 AVIStreamRelease(pInStreams
[curStream
]);
1751 if (curStream
+ 1 >= nStreams
) {
1752 /* move the others one up */
1753 PAVISTREAM
*ppas
= &pInStreams
[curStream
];
1754 int n
= nStreams
- (curStream
+ 1);
1757 *ppas
= pInStreams
[curStream
+ 1];
1763 } /* create output streams for all input streams */
1765 /* have we still something to write, or lost everything? */
1770 LONG lCurFrame
= -dwFileInitialFrames
;
1772 /* interleaved file */
1773 if (dwInterleave
== 1)
1774 AVIFileEndRecord(pfile
);
1776 for (; lCurFrame
< lFileLength
; lCurFrame
+= lSampleInc
) {
1777 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1780 hres
= AVIStreamInfoW(pOutStreams
[curStream
], &sInfo
, sizeof(sInfo
));
1784 /* initial frames phase at the end for this stream? */
1785 if (-(LONG
)sInfo
.dwInitialFrames
> lCurFrame
)
1788 if ((lFileLength
- lSampleInc
) <= lCurFrame
) {
1789 lLastSample
= AVIStreamLength(pInStreams
[curStream
]);
1790 lFirstVideo
= lLastSample
+ AVIStreamStart(pInStreams
[curStream
]);
1792 if (curStream
!= 0) {
1794 AVIStreamSampleToSample(pInStreams
[curStream
], pInStreams
[0],
1795 (sInfo
.fccType
== streamtypeVIDEO
?
1796 (LONG
)dwInterleave
: lSampleInc
) +
1797 sInfo
.dwInitialFrames
+ lCurFrame
);
1799 lFirstVideo
= lSampleInc
+ (sInfo
.dwInitialFrames
+ lCurFrame
);
1801 lLastSample
= AVIStreamEnd(pInStreams
[curStream
]);
1802 if (lLastSample
<= lFirstVideo
)
1803 lFirstVideo
= lLastSample
;
1806 /* copy needed samples now */
1807 WARN("copy from stream %d samples %d to %d...\n",curStream
,
1808 lStart
[curStream
],lFirstVideo
);
1809 while (lFirstVideo
> lStart
[curStream
]) {
1812 /* copy format in case it can change */
1813 lBufferSize
= cbBuffer
;
1814 hres
= AVIStreamReadFormat(pInStreams
[curStream
], lStart
[curStream
],
1815 lpBuffer
, &lBufferSize
);
1818 AVIStreamSetFormat(pOutStreams
[curStream
], lStart
[curStream
],
1819 lpBuffer
, lBufferSize
);
1821 /* try to read data until we got it, or error */
1823 hres
= AVIStreamRead(pInStreams
[curStream
], lStart
[curStream
],
1824 lFirstVideo
- lStart
[curStream
], lpBuffer
,
1825 cbBuffer
, &lReadBytes
, &lReadSamples
);
1826 } while ((hres
== AVIERR_BUFFERTOOSMALL
) &&
1827 (lpBuffer
= HeapReAlloc(GetProcessHeap(), 0, lpBuffer
, cbBuffer
*= 2)) != NULL
);
1828 if (lpBuffer
== NULL
)
1829 hres
= AVIERR_MEMORY
;
1833 if (AVIStreamIsKeyFrame(pInStreams
[curStream
], (LONG
)sInfo
.dwStart
))
1834 flags
= AVIIF_KEYFRAME
;
1835 hres
= AVIStreamWrite(pOutStreams
[curStream
], -1, lReadSamples
,
1836 lpBuffer
, lReadBytes
, flags
, NULL
, NULL
);
1840 lStart
[curStream
] += lReadSamples
;
1842 lStart
[curStream
] = lFirstVideo
;
1843 } /* stream by stream */
1845 /* need to close this block? */
1846 if (dwInterleave
== 1) {
1847 hres
= AVIFileEndRecord(pfile
);
1853 if (lpfnCallback(MulDiv(dwFileInitialFrames
+ lCurFrame
, 100,
1854 dwFileInitialFrames
+ lFileLength
))) {
1855 hres
= AVIERR_USERABORT
;
1858 } /* copy frame by frame */
1860 /* non-interleaved file */
1862 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1864 if (lpfnCallback(MulDiv(curStream
, 100, nStreams
))) {
1865 hres
= AVIERR_USERABORT
;
1869 AVIStreamInfoW(pInStreams
[curStream
], &sInfo
, sizeof(sInfo
));
1871 if (sInfo
.dwSampleSize
!= 0) {
1872 /* sample-based data like audio */
1873 while (sInfo
.dwStart
< sInfo
.dwLength
) {
1874 LONG lSamples
= cbBuffer
/ sInfo
.dwSampleSize
;
1876 /* copy format in case it can change */
1877 lBufferSize
= cbBuffer
;
1878 hres
= AVIStreamReadFormat(pInStreams
[curStream
], sInfo
.dwStart
,
1879 lpBuffer
, &lBufferSize
);
1882 AVIStreamSetFormat(pOutStreams
[curStream
], sInfo
.dwStart
,
1883 lpBuffer
, lBufferSize
);
1885 /* limit to stream boundaries */
1886 if (lSamples
!= (LONG
)(sInfo
.dwLength
- sInfo
.dwStart
))
1887 lSamples
= sInfo
.dwLength
- sInfo
.dwStart
;
1889 /* now try to read until we get it, or an error occurs */
1891 lReadBytes
= cbBuffer
;
1893 hres
= AVIStreamRead(pInStreams
[curStream
],sInfo
.dwStart
,lSamples
,
1894 lpBuffer
,cbBuffer
,&lReadBytes
,&lReadSamples
);
1895 } while ((hres
== AVIERR_BUFFERTOOSMALL
) &&
1896 (lpBuffer
= HeapReAlloc(GetProcessHeap(), 0, lpBuffer
, cbBuffer
*= 2)) != NULL
);
1897 if (lpBuffer
== NULL
)
1898 hres
= AVIERR_MEMORY
;
1901 if (lReadSamples
!= 0) {
1902 sInfo
.dwStart
+= lReadSamples
;
1903 hres
= AVIStreamWrite(pOutStreams
[curStream
], -1, lReadSamples
,
1904 lpBuffer
, lReadBytes
, 0, NULL
, NULL
);
1909 if (lpfnCallback(MulDiv(sInfo
.dwStart
,100,nStreams
*sInfo
.dwLength
)+
1910 MulDiv(curStream
, 100, nStreams
))) {
1911 hres
= AVIERR_USERABORT
;
1915 if ((sInfo
.dwLength
- sInfo
.dwStart
) != 1) {
1916 hres
= AVIERR_FILEREAD
;
1922 /* block-based data like video */
1923 for (; sInfo
.dwStart
< sInfo
.dwLength
; sInfo
.dwStart
++) {
1926 /* copy format in case it can change */
1927 lBufferSize
= cbBuffer
;
1928 hres
= AVIStreamReadFormat(pInStreams
[curStream
], sInfo
.dwStart
,
1929 lpBuffer
, &lBufferSize
);
1932 AVIStreamSetFormat(pOutStreams
[curStream
], sInfo
.dwStart
,
1933 lpBuffer
, lBufferSize
);
1935 /* try to read block and resize buffer if necessary */
1938 lReadBytes
= cbBuffer
;
1939 hres
= AVIStreamRead(pInStreams
[curStream
], sInfo
.dwStart
, 1,
1940 lpBuffer
, cbBuffer
,&lReadBytes
,&lReadSamples
);
1941 } while ((hres
== AVIERR_BUFFERTOOSMALL
) &&
1942 (lpBuffer
= HeapReAlloc(GetProcessHeap(), 0, lpBuffer
, cbBuffer
*= 2)) != NULL
);
1943 if (lpBuffer
== NULL
)
1944 hres
= AVIERR_MEMORY
;
1947 if (lReadSamples
!= 1) {
1948 hres
= AVIERR_FILEREAD
;
1952 if (AVIStreamIsKeyFrame(pInStreams
[curStream
], (LONG
)sInfo
.dwStart
))
1953 flags
= AVIIF_KEYFRAME
;
1954 hres
= AVIStreamWrite(pOutStreams
[curStream
], -1, lReadSamples
,
1955 lpBuffer
, lReadBytes
, flags
, NULL
, NULL
);
1960 if (lpfnCallback(MulDiv(sInfo
.dwStart
,100,nStreams
*sInfo
.dwLength
)+
1961 MulDiv(curStream
, 100, nStreams
))) {
1962 hres
= AVIERR_USERABORT
;
1965 } /* copy all blocks */
1967 } /* copy data stream by stream */
1971 HeapFree(GetProcessHeap(), 0, lpBuffer
);
1972 if (pfile
!= NULL
) {
1973 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1974 if (pOutStreams
[curStream
] != NULL
)
1975 AVIStreamRelease(pOutStreams
[curStream
]);
1976 if (pInStreams
[curStream
] != NULL
)
1977 AVIStreamRelease(pInStreams
[curStream
]);
1980 AVIFileRelease(pfile
);
1986 /***********************************************************************
1987 * CreateEditableStream (AVIFIL32.@)
1989 HRESULT WINAPI
CreateEditableStream(PAVISTREAM
*ppEditable
, PAVISTREAM pSource
)
1991 IAVIEditStream
*pEdit
= NULL
;
1994 TRACE("(%p,%p)\n", ppEditable
, pSource
);
1996 if (ppEditable
== NULL
)
1997 return AVIERR_BADPARAM
;
2001 if (pSource
!= NULL
) {
2002 hr
= IAVIStream_QueryInterface(pSource
, &IID_IAVIEditStream
,
2004 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
2005 hr
= IAVIEditStream_Clone(pEdit
, ppEditable
);
2006 IAVIEditStream_Release(pEdit
);
2012 /* need own implementation of IAVIEditStream */
2013 pEdit
= AVIFILE_CreateEditStream(pSource
);
2015 return AVIERR_MEMORY
;
2017 hr
= IAVIEditStream_QueryInterface(pEdit
, &IID_IAVIStream
,
2018 (LPVOID
*)ppEditable
);
2019 IAVIEditStream_Release(pEdit
);
2024 /***********************************************************************
2025 * EditStreamClone (AVIFIL32.@)
2027 HRESULT WINAPI
EditStreamClone(PAVISTREAM pStream
, PAVISTREAM
*ppResult
)
2029 PAVIEDITSTREAM pEdit
= NULL
;
2032 TRACE("(%p,%p)\n", pStream
, ppResult
);
2034 if (pStream
== NULL
)
2035 return AVIERR_BADHANDLE
;
2036 if (ppResult
== NULL
)
2037 return AVIERR_BADPARAM
;
2041 hr
= IAVIStream_QueryInterface(pStream
, &IID_IAVIEditStream
,(LPVOID
*)&pEdit
);
2042 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
2043 hr
= IAVIEditStream_Clone(pEdit
, ppResult
);
2045 IAVIEditStream_Release(pEdit
);
2047 hr
= AVIERR_UNSUPPORTED
;
2052 /***********************************************************************
2053 * EditStreamCopy (AVIFIL32.@)
2055 HRESULT WINAPI
EditStreamCopy(PAVISTREAM pStream
, LONG
*plStart
,
2056 LONG
*plLength
, PAVISTREAM
*ppResult
)
2058 PAVIEDITSTREAM pEdit
= NULL
;
2061 TRACE("(%p,%p,%p,%p)\n", pStream
, plStart
, plLength
, ppResult
);
2063 if (pStream
== NULL
)
2064 return AVIERR_BADHANDLE
;
2065 if (plStart
== NULL
|| plLength
== NULL
|| ppResult
== NULL
)
2066 return AVIERR_BADPARAM
;
2070 hr
= IAVIStream_QueryInterface(pStream
, &IID_IAVIEditStream
,(LPVOID
*)&pEdit
);
2071 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
2072 hr
= IAVIEditStream_Copy(pEdit
, plStart
, plLength
, ppResult
);
2074 IAVIEditStream_Release(pEdit
);
2076 hr
= AVIERR_UNSUPPORTED
;
2081 /***********************************************************************
2082 * EditStreamCut (AVIFIL32.@)
2084 HRESULT WINAPI
EditStreamCut(PAVISTREAM pStream
, LONG
*plStart
,
2085 LONG
*plLength
, PAVISTREAM
*ppResult
)
2087 PAVIEDITSTREAM pEdit
= NULL
;
2090 TRACE("(%p,%p,%p,%p)\n", pStream
, plStart
, plLength
, ppResult
);
2092 if (ppResult
!= NULL
)
2094 if (pStream
== NULL
)
2095 return AVIERR_BADHANDLE
;
2096 if (plStart
== NULL
|| plLength
== NULL
)
2097 return AVIERR_BADPARAM
;
2099 hr
= IAVIStream_QueryInterface(pStream
, &IID_IAVIEditStream
,(LPVOID
*)&pEdit
);
2100 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
2101 hr
= IAVIEditStream_Cut(pEdit
, plStart
, plLength
, ppResult
);
2103 IAVIEditStream_Release(pEdit
);
2105 hr
= AVIERR_UNSUPPORTED
;
2110 /***********************************************************************
2111 * EditStreamPaste (AVIFIL32.@)
2113 HRESULT WINAPI
EditStreamPaste(PAVISTREAM pDest
, LONG
*plStart
, LONG
*plLength
,
2114 PAVISTREAM pSource
, LONG lStart
, LONG lEnd
)
2116 PAVIEDITSTREAM pEdit
= NULL
;
2119 TRACE("(%p,%p,%p,%p,%d,%d)\n", pDest
, plStart
, plLength
,
2120 pSource
, lStart
, lEnd
);
2122 if (pDest
== NULL
|| pSource
== NULL
)
2123 return AVIERR_BADHANDLE
;
2124 if (plStart
== NULL
|| plLength
== NULL
|| lStart
< 0)
2125 return AVIERR_BADPARAM
;
2127 hr
= IAVIStream_QueryInterface(pDest
, &IID_IAVIEditStream
,(LPVOID
*)&pEdit
);
2128 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
2129 hr
= IAVIEditStream_Paste(pEdit
, plStart
, plLength
, pSource
, lStart
, lEnd
);
2131 IAVIEditStream_Release(pEdit
);
2133 hr
= AVIERR_UNSUPPORTED
;
2138 /***********************************************************************
2139 * EditStreamSetInfoA (AVIFIL32.@)
2141 HRESULT WINAPI
EditStreamSetInfoA(PAVISTREAM pstream
, LPAVISTREAMINFOA asi
,
2144 AVISTREAMINFOW asiw
;
2146 TRACE("(%p,%p,%d)\n", pstream
, asi
, size
);
2148 if (size
>= 0 && size
< sizeof(AVISTREAMINFOA
))
2149 return AVIERR_BADSIZE
;
2151 memcpy(&asiw
, asi
, sizeof(asiw
) - sizeof(asiw
.szName
));
2152 MultiByteToWideChar(CP_ACP
, 0, asi
->szName
, -1,
2153 asiw
.szName
, sizeof(asiw
.szName
)/sizeof(WCHAR
));
2155 return EditStreamSetInfoW(pstream
, &asiw
, sizeof(asiw
));
2158 /***********************************************************************
2159 * EditStreamSetInfoW (AVIFIL32.@)
2161 HRESULT WINAPI
EditStreamSetInfoW(PAVISTREAM pstream
, LPAVISTREAMINFOW asi
,
2164 PAVIEDITSTREAM pEdit
= NULL
;
2167 TRACE("(%p,%p,%d)\n", pstream
, asi
, size
);
2169 if (size
>= 0 && size
< sizeof(AVISTREAMINFOA
))
2170 return AVIERR_BADSIZE
;
2172 hr
= IAVIStream_QueryInterface(pstream
, &IID_IAVIEditStream
,(LPVOID
*)&pEdit
);
2173 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
2174 hr
= IAVIEditStream_SetInfo(pEdit
, asi
, size
);
2176 IAVIEditStream_Release(pEdit
);
2178 hr
= AVIERR_UNSUPPORTED
;
2183 /***********************************************************************
2184 * EditStreamSetNameA (AVIFIL32.@)
2186 HRESULT WINAPI
EditStreamSetNameA(PAVISTREAM pstream
, LPCSTR szName
)
2188 AVISTREAMINFOA asia
;
2191 TRACE("(%p,%s)\n", pstream
, debugstr_a(szName
));
2193 if (pstream
== NULL
)
2194 return AVIERR_BADHANDLE
;
2196 return AVIERR_BADPARAM
;
2198 hres
= AVIStreamInfoA(pstream
, &asia
, sizeof(asia
));
2202 memset(asia
.szName
, 0, sizeof(asia
.szName
));
2203 lstrcpynA(asia
.szName
, szName
, sizeof(asia
.szName
)/sizeof(asia
.szName
[0]));
2205 return EditStreamSetInfoA(pstream
, &asia
, sizeof(asia
));
2208 /***********************************************************************
2209 * EditStreamSetNameW (AVIFIL32.@)
2211 HRESULT WINAPI
EditStreamSetNameW(PAVISTREAM pstream
, LPCWSTR szName
)
2213 AVISTREAMINFOW asiw
;
2216 TRACE("(%p,%s)\n", pstream
, debugstr_w(szName
));
2218 if (pstream
== NULL
)
2219 return AVIERR_BADHANDLE
;
2221 return AVIERR_BADPARAM
;
2223 hres
= IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
));
2227 memset(asiw
.szName
, 0, sizeof(asiw
.szName
));
2228 lstrcpynW(asiw
.szName
, szName
, sizeof(asiw
.szName
)/sizeof(asiw
.szName
[0]));
2230 return EditStreamSetInfoW(pstream
, &asiw
, sizeof(asiw
));
2233 /***********************************************************************
2234 * AVIClearClipboard (AVIFIL32.@)
2236 HRESULT WINAPI
AVIClearClipboard(void)
2240 return AVIERR_UNSUPPORTED
; /* OleSetClipboard(NULL); */
2243 /***********************************************************************
2244 * AVIGetFromClipboard (AVIFIL32.@)
2246 HRESULT WINAPI
AVIGetFromClipboard(PAVIFILE
*ppfile
)
2248 FIXME("(%p), stub!\n", ppfile
);
2252 return AVIERR_UNSUPPORTED
;
2255 /***********************************************************************
2256 * AVIMakeStreamFromClipboard (AVIFIL32.@)
2258 HRESULT WINAPI
AVIMakeStreamFromClipboard(UINT cfFormat
, HANDLE hGlobal
,
2259 PAVISTREAM
* ppstream
)
2261 FIXME("(0x%08x,%p,%p), stub!\n", cfFormat
, hGlobal
, ppstream
);
2263 if (ppstream
== NULL
)
2264 return AVIERR_BADHANDLE
;
2266 return AVIERR_UNSUPPORTED
;
2269 /***********************************************************************
2270 * AVIPutFileOnClipboard (AVIFIL32.@)
2272 HRESULT WINAPI
AVIPutFileOnClipboard(PAVIFILE pfile
)
2274 FIXME("(%p), stub!\n", pfile
);
2277 return AVIERR_BADHANDLE
;
2279 return AVIERR_UNSUPPORTED
;
2282 HRESULT WINAPIV
AVISaveA(LPCSTR szFile
, CLSID
* pclsidHandler
, AVISAVECALLBACK lpfnCallback
,
2283 int nStreams
, PAVISTREAM pavi
, LPAVICOMPRESSOPTIONS lpOptions
, ...)
2285 FIXME("(%s,%p,%p,0x%08x,%p,%p), stub!\n", debugstr_a(szFile
), pclsidHandler
, lpfnCallback
,
2286 nStreams
, pavi
, lpOptions
);
2288 return AVIERR_UNSUPPORTED
;
2291 HRESULT WINAPIV
AVISaveW(LPCWSTR szFile
, CLSID
* pclsidHandler
, AVISAVECALLBACK lpfnCallback
,
2292 int nStreams
, PAVISTREAM pavi
, LPAVICOMPRESSOPTIONS lpOptions
, ...)
2294 FIXME("(%s,%p,%p,0x%08x,%p,%p), stub!\n", debugstr_w(szFile
), pclsidHandler
, lpfnCallback
,
2295 nStreams
, pavi
, lpOptions
);
2297 return AVIERR_UNSUPPORTED
;