Mercurial > mplayer.hg
annotate loader/afl.c @ 33259:04dc3e55cd90
Increase the maximum value of the DVB timeout to 240 seconds.
Some devices may need more time for the initial tune (e.g. firmware loading).
Let the user specify higher timeout value if there is need to.
The default remains 30 seconds.
author | iive |
---|---|
date | Sun, 01 May 2011 18:07:59 +0000 |
parents | 8fa2f43cb760 |
children |
rev | line source |
---|---|
1 | 1 /************************************************************************** |
2 | |
3 | |
4 This file will contain an interface to ACM drivers. | |
5 Its content will be based mainly on wine/dlls/msacm32 | |
6 actually, for audio decompression only the following functions | |
7 are needed: | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
8 |
1 | 9 acmStreamOpen ( takes formats of src and dest, returns stream handle ) |
10 acmStreamPrepareHeader ( takes stream handler and info on data ) | |
11 acmStreamConvert ( the same as PrepareHeader ) | |
12 acmStreamUnprepareHeader | |
13 acmStreamClose | |
14 acmStreamSize | |
15 maybe acmStreamReset | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
16 |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
17 In future I'll also add functions for format enumeration, |
1 | 18 but not right now. |
19 | |
18783 | 20 Modified for use with MPlayer, detailed changelog at |
21 http://svn.mplayerhq.hu/mplayer/trunk/ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
22 |
1 | 23 ***************************************************************************/ |
2069 | 24 #include "config.h" |
21261
a2e02e6b6379
Rename config.h --> debug.h and include config.h explicitly.
diego
parents:
18878
diff
changeset
|
25 #include "debug.h" |
1 | 26 |
2069 | 27 #include "wine/winbase.h" |
28 #include "wine/windef.h" | |
29 #include "wine/winuser.h" | |
30 #include "wine/vfw.h" | |
31 #include "wine/winestring.h" | |
32 #include "wine/driver.h" | |
33 #include "wine/winerror.h" | |
34 #include "wine/msacm.h" | |
35 #include "wine/msacmdrv.h" | |
1 | 36 #include "wineacm.h" |
9978 | 37 #ifndef __MINGW32__ |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
1
diff
changeset
|
38 #include "ext.h" |
9978 | 39 #endif |
26999
0b21ffa03b9c
Rename loader/driver.[ch] to loader/drv.[ch], otherwise loader/driver.h can
diego
parents:
25849
diff
changeset
|
40 #include "drv.h" |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
1
diff
changeset
|
41 |
7386 | 42 #include <stdio.h> |
43 #include <stdlib.h> | |
44 #include <string.h> | |
45 #pragma pack(1) | |
1 | 46 #define OpenDriverA DrvOpen |
47 #define CloseDriver DrvClose | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
1
diff
changeset
|
48 |
7386 | 49 static inline PWINE_ACMSTREAM ACM_GetStream(HACMSTREAM has) |
1 | 50 { |
51 return (PWINE_ACMSTREAM)has; | |
52 } | |
53 | |
54 /*********************************************************************** | |
55 * acmDriverAddA (MSACM32.2) | |
56 */ | |
57 MMRESULT WINAPI acmDriverAddA(PHACMDRIVERID phadid, HINSTANCE hinstModule, | |
58 LPARAM lParam, DWORD dwPriority, DWORD fdwAdd) | |
59 { | |
60 if (!phadid) | |
61 return MMSYSERR_INVALPARAM; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
62 |
1 | 63 /* Check if any unknown flags */ |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
64 if (fdwAdd & |
1 | 65 ~(ACM_DRIVERADDF_FUNCTION|ACM_DRIVERADDF_NOTIFYHWND| |
66 ACM_DRIVERADDF_GLOBAL)) | |
67 return MMSYSERR_INVALFLAG; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
68 |
1 | 69 /* Check if any incompatible flags */ |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
70 if ((fdwAdd & ACM_DRIVERADDF_FUNCTION) && |
1 | 71 (fdwAdd & ACM_DRIVERADDF_NOTIFYHWND)) |
72 return MMSYSERR_INVALFLAG; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
73 |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
74 /* FIXME: in fact, should GetModuleFileName(hinstModule) and do a |
1 | 75 * LoadDriver on it, to be sure we can call SendDriverMessage on the |
76 * hDrvr handle. | |
77 */ | |
7386 | 78 *phadid = (HACMDRIVERID) MSACM_RegisterDriver(NULL, 0, hinstModule); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
79 |
1 | 80 /* FIXME: lParam, dwPriority and fdwAdd ignored */ |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
81 |
1 | 82 return MMSYSERR_NOERROR; |
83 } | |
84 | |
85 /*********************************************************************** | |
86 * acmDriverClose (MSACM32.4) | |
87 */ | |
88 MMRESULT WINAPI acmDriverClose(HACMDRIVER had, DWORD fdwClose) | |
89 { | |
90 PWINE_ACMDRIVER p; | |
91 PWINE_ACMDRIVER* tp; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
92 |
1 | 93 if (fdwClose) |
94 return MMSYSERR_INVALFLAG; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
95 |
1 | 96 p = MSACM_GetDriver(had); |
97 if (!p) | |
98 return MMSYSERR_INVALHANDLE; | |
99 | |
100 for (tp = &(p->obj.pACMDriverID->pACMDriverList); *tp; *tp = (*tp)->pNextACMDriver) { | |
101 if (*tp == p) { | |
102 *tp = (*tp)->pNextACMDriver; | |
103 break; | |
104 } | |
105 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
106 |
1 | 107 if (p->hDrvr && !p->obj.pACMDriverID->pACMDriverList) |
108 CloseDriver(p->hDrvr); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
109 |
1 | 110 HeapFree(MSACM_hHeap, 0, p); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
111 |
1 | 112 return MMSYSERR_NOERROR; |
113 } | |
114 | |
115 /*********************************************************************** | |
116 * acmDriverEnum (MSACM32.7) | |
117 */ | |
118 MMRESULT WINAPI acmDriverEnum(ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum) | |
119 { | |
120 PWINE_ACMDRIVERID p; | |
121 DWORD fdwSupport; | |
122 | |
123 if (!fnCallback) { | |
124 return MMSYSERR_INVALPARAM; | |
125 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
126 |
1 | 127 if (fdwEnum && ~(ACM_DRIVERENUMF_NOLOCAL|ACM_DRIVERENUMF_DISABLED)) { |
128 return MMSYSERR_INVALFLAG; | |
129 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
130 |
1 | 131 for (p = MSACM_pFirstACMDriverID; p; p = p->pNextACMDriverID) { |
132 fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC; | |
133 if (!p->bEnabled) { | |
134 if (fdwEnum & ACM_DRIVERENUMF_DISABLED) | |
135 fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED; | |
136 else | |
137 continue; | |
138 } | |
139 (*fnCallback)((HACMDRIVERID) p, dwInstance, fdwSupport); | |
140 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
141 |
1 | 142 return MMSYSERR_NOERROR; |
143 } | |
144 | |
145 /*********************************************************************** | |
146 * acmDriverID (MSACM32.8) | |
147 */ | |
148 MMRESULT WINAPI acmDriverID(HACMOBJ hao, PHACMDRIVERID phadid, DWORD fdwDriverID) | |
149 { | |
150 PWINE_ACMOBJ pao; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
151 |
1 | 152 pao = MSACM_GetObj(hao); |
153 if (!pao) | |
154 return MMSYSERR_INVALHANDLE; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
155 |
1 | 156 if (!phadid) |
157 return MMSYSERR_INVALPARAM; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
158 |
1 | 159 if (fdwDriverID) |
160 return MMSYSERR_INVALFLAG; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
161 |
1 | 162 *phadid = (HACMDRIVERID) pao->pACMDriverID; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
163 |
1 | 164 return MMSYSERR_NOERROR; |
165 } | |
166 | |
167 /*********************************************************************** | |
168 * acmDriverMessage (MSACM32.9) | |
169 * FIXME | |
170 * Not implemented | |
171 */ | |
172 LRESULT WINAPI acmDriverMessage(HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2) | |
173 { | |
174 PWINE_ACMDRIVER pad = MSACM_GetDriver(had); | |
175 if (!pad) | |
176 return MMSYSERR_INVALPARAM; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
177 |
1 | 178 /* FIXME: Check if uMsg legal */ |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
179 |
1 | 180 if (!SendDriverMessage(pad->hDrvr, uMsg, lParam1, lParam2)) |
181 return MMSYSERR_NOTSUPPORTED; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
182 |
1 | 183 return MMSYSERR_NOERROR; |
184 } | |
185 | |
186 | |
187 /*********************************************************************** | |
188 * acmDriverOpen (MSACM32.10) | |
189 */ | |
190 MMRESULT WINAPI acmDriverOpen(PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen) | |
191 { | |
192 PWINE_ACMDRIVERID padid; | |
193 PWINE_ACMDRIVER pad; | |
194 ICOPEN icopen; | |
195 | |
196 | |
197 TRACE("(%p, %x, %08lu)\n", phad, hadid, fdwOpen); | |
198 | |
199 if (!phad) | |
200 return MMSYSERR_INVALPARAM; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
201 |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
202 padid = MSACM_GetDriverID(hadid); |
1 | 203 if (!padid) |
204 return MMSYSERR_INVALHANDLE; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
205 |
1 | 206 if (fdwOpen) |
207 return MMSYSERR_INVALFLAG; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
208 |
7386 | 209 pad = (PWINE_ACMDRIVER) HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVER)); |
210 if (!pad) | |
211 return MMSYSERR_NOMEM; | |
1 | 212 |
213 pad->obj.pACMDriverID = padid; | |
214 icopen.fccType = mmioFOURCC('a', 'u', 'd', 'c'); | |
215 icopen.fccHandler = (long)padid->pszFileName; | |
216 icopen.dwSize = sizeof(ICOPEN); | |
217 icopen.dwFlags = 0; | |
218 | |
7386 | 219 icopen.pV1Reserved = padid->pszFileName; |
220 if (!padid->hInstModule) | |
1 | 221 pad->hDrvr = OpenDriverA((long)&icopen); |
222 else | |
223 pad->hDrvr = padid->hInstModule; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
224 |
1 | 225 if (!pad->hDrvr) { |
226 HeapFree(MSACM_hHeap, 0, pad); | |
227 return MMSYSERR_ERROR; | |
228 } | |
7386 | 229 |
1 | 230 pad->pfnDriverProc = GetProcAddress(pad->hDrvr, "DriverProc"); |
231 | |
232 /* insert new pad at beg of list */ | |
233 pad->pNextACMDriver = padid->pACMDriverList; | |
234 padid->pACMDriverList = pad; | |
235 | |
236 /* FIXME: Create a WINE_ACMDRIVER32 */ | |
237 *phad = (HACMDRIVER)pad; | |
7386 | 238 |
1 | 239 return MMSYSERR_NOERROR; |
240 } | |
241 | |
242 /*********************************************************************** | |
243 * acmDriverRemove (MSACM32.12) | |
244 */ | |
245 MMRESULT WINAPI acmDriverRemove(HACMDRIVERID hadid, DWORD fdwRemove) | |
246 { | |
247 PWINE_ACMDRIVERID padid; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
248 |
1 | 249 padid = MSACM_GetDriverID(hadid); |
250 if (!padid) | |
251 return MMSYSERR_INVALHANDLE; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
252 |
1 | 253 if (fdwRemove) |
254 return MMSYSERR_INVALFLAG; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
255 |
1 | 256 MSACM_UnregisterDriver(padid); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
257 |
1 | 258 return MMSYSERR_NOERROR; |
259 } | |
260 | |
261 | |
262 | |
263 /**********************************************************************/ | |
264 | |
265 HANDLE MSACM_hHeap = (HANDLE) NULL; | |
266 PWINE_ACMDRIVERID MSACM_pFirstACMDriverID = NULL; | |
267 PWINE_ACMDRIVERID MSACM_pLastACMDriverID = NULL; | |
268 | |
269 /*********************************************************************** | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
270 * MSACM_RegisterDriver32() |
1 | 271 */ |
7386 | 272 PWINE_ACMDRIVERID MSACM_RegisterDriver(const char* pszFileName, |
273 WORD wFormatTag, | |
1 | 274 HINSTANCE hinstModule) |
7386 | 275 { |
1 | 276 PWINE_ACMDRIVERID padid; |
277 | |
7386 | 278 TRACE("('%s', '%x', 0x%08x)\n", pszFileName, wFormatTag, hinstModule); |
1 | 279 |
9961 | 280 #ifndef WIN32_LOADER |
281 MSACM_hHeap = GetProcessHeap(); | |
282 #endif | |
1 | 283 padid = (PWINE_ACMDRIVERID) HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVERID)); |
18878 | 284 padid->pszFileName = malloc(strlen(pszFileName)+1); |
7386 | 285 strcpy(padid->pszFileName, pszFileName); |
1 | 286 // 1~strdup(pszDriverAlias); |
7386 | 287 padid->wFormatTag = wFormatTag; |
1 | 288 padid->hInstModule = hinstModule; |
289 padid->bEnabled = TRUE; | |
290 padid->pACMDriverList = NULL; | |
291 padid->pNextACMDriverID = NULL; | |
292 padid->pPrevACMDriverID = MSACM_pLastACMDriverID; | |
293 if (MSACM_pLastACMDriverID) | |
294 MSACM_pLastACMDriverID->pNextACMDriverID = padid; | |
295 MSACM_pLastACMDriverID = padid; | |
296 if (!MSACM_pFirstACMDriverID) | |
297 MSACM_pFirstACMDriverID = padid; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
298 |
1 | 299 return padid; |
300 } | |
301 | |
302 | |
303 /*********************************************************************** | |
304 * MSACM_UnregisterDriver32() | |
305 */ | |
306 PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p) | |
307 { | |
308 PWINE_ACMDRIVERID pNextACMDriverID; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
309 |
1 | 310 while (p->pACMDriverList) |
311 acmDriverClose((HACMDRIVER) p->pACMDriverList, 0); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
312 |
32537
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
32116
diff
changeset
|
313 free(p->pszFileName); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
314 |
1 | 315 if (p == MSACM_pFirstACMDriverID) |
316 MSACM_pFirstACMDriverID = p->pNextACMDriverID; | |
317 if (p == MSACM_pLastACMDriverID) | |
318 MSACM_pLastACMDriverID = p->pPrevACMDriverID; | |
319 | |
320 if (p->pPrevACMDriverID) | |
321 p->pPrevACMDriverID->pNextACMDriverID = p->pNextACMDriverID; | |
322 if (p->pNextACMDriverID) | |
323 p->pNextACMDriverID->pPrevACMDriverID = p->pPrevACMDriverID; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
324 |
1 | 325 pNextACMDriverID = p->pNextACMDriverID; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
326 |
1 | 327 HeapFree(MSACM_hHeap, 0, p); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
328 |
1 | 329 return pNextACMDriverID; |
330 } | |
331 | |
332 /*********************************************************************** | |
333 * MSACM_UnregisterAllDrivers32() | |
334 * FIXME | |
335 * Where should this function be called? | |
336 */ | |
337 void MSACM_UnregisterAllDrivers(void) | |
338 { | |
339 PWINE_ACMDRIVERID p; | |
340 | |
341 for (p = MSACM_pFirstACMDriverID; p; p = MSACM_UnregisterDriver(p)); | |
342 } | |
343 | |
344 /*********************************************************************** | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
345 * MSACM_GetDriverID32() |
1 | 346 */ |
347 PWINE_ACMDRIVERID MSACM_GetDriverID(HACMDRIVERID hDriverID) | |
348 { | |
349 return (PWINE_ACMDRIVERID)hDriverID; | |
350 } | |
351 | |
352 /*********************************************************************** | |
353 * MSACM_GetDriver32() | |
354 */ | |
355 PWINE_ACMDRIVER MSACM_GetDriver(HACMDRIVER hDriver) | |
356 { | |
357 return (PWINE_ACMDRIVER)hDriver; | |
358 } | |
359 | |
360 /*********************************************************************** | |
361 * MSACM_GetObj32() | |
362 */ | |
363 PWINE_ACMOBJ MSACM_GetObj(HACMOBJ hObj) | |
364 { | |
365 return (PWINE_ACMOBJ)hObj; | |
366 } | |
367 | |
368 | |
369 | |
370 /*********************************************************************** | |
371 * acmStreamOpen (MSACM32.40) | |
372 */ | |
373 MMRESULT WINAPI acmStreamOpen(PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pwfxSrc, | |
374 PWAVEFORMATEX pwfxDst, PWAVEFILTER pwfltr, DWORD dwCallback, | |
375 DWORD dwInstance, DWORD fdwOpen) | |
376 { | |
377 PWINE_ACMSTREAM was; | |
378 PWINE_ACMDRIVER wad; | |
379 MMRESULT ret; | |
380 int wfxSrcSize; | |
381 int wfxDstSize; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
382 |
1 | 383 TRACE("(%p, 0x%08x, %p, %p, %p, %ld, %ld, %ld)\n", |
384 phas, had, pwfxSrc, pwfxDst, pwfltr, dwCallback, dwInstance, fdwOpen); | |
385 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
386 TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n", |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
387 pwfxSrc->wFormatTag, pwfxSrc->nChannels, pwfxSrc->nSamplesPerSec, pwfxSrc->nAvgBytesPerSec, |
1 | 388 pwfxSrc->nBlockAlign, pwfxSrc->wBitsPerSample, pwfxSrc->cbSize); |
389 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
390 TRACE("dst [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n", |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
391 pwfxDst->wFormatTag, pwfxDst->nChannels, pwfxDst->nSamplesPerSec, pwfxDst->nAvgBytesPerSec, |
1 | 392 pwfxDst->nBlockAlign, pwfxDst->wBitsPerSample, pwfxDst->cbSize); |
393 | |
394 #define SIZEOF_WFX(wfx) (sizeof(WAVEFORMATEX) + ((wfx->wFormatTag == WAVE_FORMAT_PCM) ? 0 : wfx->cbSize)) | |
395 wfxSrcSize = SIZEOF_WFX(pwfxSrc); | |
396 wfxDstSize = SIZEOF_WFX(pwfxDst); | |
397 #undef SIZEOF_WFX | |
398 | |
7386 | 399 was = (PWINE_ACMSTREAM) HeapAlloc(MSACM_hHeap, 0, sizeof(*was) + wfxSrcSize + wfxDstSize + ((pwfltr) ? sizeof(WAVEFILTER) : 0)); |
1 | 400 if (was == NULL) |
401 return MMSYSERR_NOMEM; | |
402 was->drvInst.cbStruct = sizeof(was->drvInst); | |
32116
601319a3523e
Avoid some pointless uses of sizeof() and one related cast.
reimar
parents:
29263
diff
changeset
|
403 was->drvInst.pwfxSrc = (PWAVEFORMATEX)(was + 1); |
1 | 404 memcpy(was->drvInst.pwfxSrc, pwfxSrc, wfxSrcSize); |
7386 | 405 // LHACM is checking for 0x1 |
406 // but if this will not help | |
407 // was->drvInst.pwfxSrc->wFormatTag = 1; | |
32116
601319a3523e
Avoid some pointless uses of sizeof() and one related cast.
reimar
parents:
29263
diff
changeset
|
408 was->drvInst.pwfxDst = (PWAVEFORMATEX)((LPSTR)(was + 1) + wfxSrcSize); |
1 | 409 memcpy(was->drvInst.pwfxDst, pwfxDst, wfxDstSize); |
410 if (pwfltr) { | |
32116
601319a3523e
Avoid some pointless uses of sizeof() and one related cast.
reimar
parents:
29263
diff
changeset
|
411 was->drvInst.pwfltr = (PWAVEFILTER)((LPSTR)(was + 1) + wfxSrcSize + wfxDstSize); |
1 | 412 memcpy(was->drvInst.pwfltr, pwfltr, sizeof(WAVEFILTER)); |
413 } else { | |
414 was->drvInst.pwfltr = NULL; | |
415 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
416 was->drvInst.dwCallback = dwCallback; |
1 | 417 was->drvInst.dwInstance = dwInstance; |
418 was->drvInst.fdwOpen = fdwOpen; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
419 was->drvInst.fdwDriver = 0L; |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
420 was->drvInst.dwDriver = 0L; |
1 | 421 was->drvInst.has = (HACMSTREAM)was; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
422 |
1 | 423 if (had) { |
424 if (!(wad = MSACM_GetDriver(had))) { | |
425 ret = MMSYSERR_INVALPARAM; | |
426 goto errCleanUp; | |
427 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
428 |
1 | 429 was->obj.pACMDriverID = wad->obj.pACMDriverID; |
430 was->pDrv = wad; | |
431 was->hAcmDriver = 0; /* not to close it in acmStreamClose */ | |
432 | |
433 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L); | |
434 if (ret != MMSYSERR_NOERROR) | |
435 goto errCleanUp; | |
436 } else { | |
437 PWINE_ACMDRIVERID wadi; | |
24380 | 438 //short drv_tag; |
1 | 439 ret = ACMERR_NOTPOSSIBLE; |
440 /* if(pwfxSrc->wFormatTag==1)//compression | |
441 drv_tag=pwfxDst->wFormatTag; | |
442 else | |
443 if(pwfxDst->wFormatTag==1)//decompression | |
444 drv_tag=pwfxSrc->wFormatTag; | |
445 else | |
446 goto errCleanUp; | |
447 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
448 ret=acmDriverOpen2(drv_tag); |
1 | 449 if (ret == MMSYSERR_NOERROR) { |
450 if ((wad = MSACM_GetDriver(had)) != 0) { | |
451 was->obj.pACMDriverID = wad->obj.pACMDriverID; | |
452 was->pDrv = wad; | |
453 was->hAcmDriver = had; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
454 |
1 | 455 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L); |
456 if (ret == MMSYSERR_NOERROR) { | |
457 if (fdwOpen & ACM_STREAMOPENF_QUERY) { | |
458 acmDriverClose(had, 0L); | |
459 } | |
460 break; | |
461 } | |
462 } | |
463 acmDriverClose(had, 0L);*/ | |
7386 | 464 //if(MSACM_pFirstACMDriverID==NULL) |
465 // MSACM_RegisterAllDrivers(); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
466 |
7386 | 467 for (wadi = MSACM_pFirstACMDriverID; wadi; wadi = wadi->pNextACMDriverID) |
468 { | |
469 /* Check Format */ | |
470 if ((int)wadi->wFormatTag != (int)pwfxSrc->wFormatTag) continue; | |
471 | |
1 | 472 ret = acmDriverOpen(&had, (HACMDRIVERID)wadi, 0L); |
473 if (ret == MMSYSERR_NOERROR) { | |
474 if ((wad = MSACM_GetDriver(had)) != 0) { | |
475 was->obj.pACMDriverID = wad->obj.pACMDriverID; | |
476 was->pDrv = wad; | |
477 was->hAcmDriver = had; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
478 |
1 | 479 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L); |
7386 | 480 //lhacm - crash printf("RETOPEN %d\n", ret); |
481 //ret = 0; | |
1 | 482 if (ret == MMSYSERR_NOERROR) { |
483 if (fdwOpen & ACM_STREAMOPENF_QUERY) { | |
484 acmDriverClose(had, 0L); | |
485 } | |
486 break; | |
487 } | |
488 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
489 // no match, close this acm driver and try next one |
1 | 490 acmDriverClose(had, 0L); |
491 } | |
492 } | |
493 if (ret != MMSYSERR_NOERROR) { | |
494 ret = ACMERR_NOTPOSSIBLE; | |
495 goto errCleanUp; | |
496 } | |
497 } | |
498 ret = MMSYSERR_NOERROR; | |
499 if (!(fdwOpen & ACM_STREAMOPENF_QUERY)) { | |
500 if (phas) | |
501 *phas = (HACMSTREAM)was; | |
502 TRACE("=> (%d)\n", ret); | |
9961 | 503 #ifdef WIN32_LOADER |
7386 | 504 CodecAlloc(); |
9961 | 505 #endif |
1 | 506 return ret; |
507 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
508 errCleanUp: |
1 | 509 if (phas) |
510 *phas = (HACMSTREAM)0; | |
511 HeapFree(MSACM_hHeap, 0, was); | |
512 TRACE("=> (%d)\n", ret); | |
513 return ret; | |
514 } | |
515 | |
516 | |
517 MMRESULT WINAPI acmStreamClose(HACMSTREAM has, DWORD fdwClose) | |
518 { | |
519 PWINE_ACMSTREAM was; | |
520 MMRESULT ret; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
521 |
1 | 522 TRACE("(0x%08x, %ld)\n", has, fdwClose); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
523 |
1 | 524 if ((was = ACM_GetStream(has)) == NULL) { |
525 return MMSYSERR_INVALHANDLE; | |
526 } | |
527 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CLOSE, (DWORD)&was->drvInst, 0); | |
528 if (ret == MMSYSERR_NOERROR) { | |
529 if (was->hAcmDriver) | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
530 acmDriverClose(was->hAcmDriver, 0L); |
1 | 531 HeapFree(MSACM_hHeap, 0, was); |
9961 | 532 #ifdef WIN32_LOADER |
7386 | 533 CodecRelease(); |
9961 | 534 #endif |
1 | 535 } |
536 TRACE("=> (%d)\n", ret); | |
537 return ret; | |
538 } | |
539 | |
540 /*********************************************************************** | |
541 * acmStreamConvert (MSACM32.38) | |
542 */ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
543 MMRESULT WINAPI acmStreamConvert(HACMSTREAM has, PACMSTREAMHEADER pash, |
1 | 544 DWORD fdwConvert) |
545 { | |
546 PWINE_ACMSTREAM was; | |
547 MMRESULT ret = MMSYSERR_NOERROR; | |
548 PACMDRVSTREAMHEADER padsh; | |
549 | |
550 TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwConvert); | |
7386 | 551 |
1 | 552 if ((was = ACM_GetStream(has)) == NULL) |
553 return MMSYSERR_INVALHANDLE; | |
554 if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER)) | |
555 return MMSYSERR_INVALPARAM; | |
556 | |
557 if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED)) | |
558 return ACMERR_UNPREPARED; | |
559 | |
560 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same | |
561 * size. some fields are private to msacm internals, and are exposed | |
562 * in ACMSTREAMHEADER in the dwReservedDriver array | |
563 */ | |
564 padsh = (PACMDRVSTREAMHEADER)pash; | |
565 | |
566 /* check that pointers have not been modified */ | |
567 if (padsh->pbPreparedSrc != padsh->pbSrc || | |
568 padsh->cbPreparedSrcLength < padsh->cbSrcLength || | |
569 padsh->pbPreparedDst != padsh->pbDst || | |
570 padsh->cbPreparedDstLength < padsh->cbDstLength) { | |
571 return MMSYSERR_INVALPARAM; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
572 } |
1 | 573 |
574 padsh->fdwConvert = fdwConvert; | |
575 | |
576 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CONVERT, (DWORD)&was->drvInst, (DWORD)padsh); | |
577 if (ret == MMSYSERR_NOERROR) { | |
578 padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_DONE; | |
579 } | |
580 TRACE("=> (%d)\n", ret); | |
581 return ret; | |
582 } | |
583 | |
584 | |
585 /*********************************************************************** | |
586 * acmStreamPrepareHeader (MSACM32.41) | |
587 */ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
588 MMRESULT WINAPI acmStreamPrepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash, |
1 | 589 DWORD fdwPrepare) |
590 { | |
591 PWINE_ACMSTREAM was; | |
592 MMRESULT ret = MMSYSERR_NOERROR; | |
593 PACMDRVSTREAMHEADER padsh; | |
594 | |
595 TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwPrepare); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
596 |
1 | 597 if ((was = ACM_GetStream(has)) == NULL) |
598 return MMSYSERR_INVALHANDLE; | |
599 if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER)) | |
600 return MMSYSERR_INVALPARAM; | |
601 if (fdwPrepare) | |
602 ret = MMSYSERR_INVALFLAG; | |
603 | |
604 if (pash->fdwStatus & ACMSTREAMHEADER_STATUSF_DONE) | |
605 return MMSYSERR_NOERROR; | |
606 | |
607 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same | |
608 * size. some fields are private to msacm internals, and are exposed | |
609 * in ACMSTREAMHEADER in the dwReservedDriver array | |
610 */ | |
611 padsh = (PACMDRVSTREAMHEADER)pash; | |
612 | |
613 padsh->fdwConvert = fdwPrepare; | |
614 padsh->padshNext = NULL; | |
615 padsh->fdwDriver = padsh->dwDriver = 0L; | |
616 | |
617 padsh->fdwPrepared = 0; | |
618 padsh->dwPrepared = 0; | |
619 padsh->pbPreparedSrc = 0; | |
620 padsh->cbPreparedSrcLength = 0; | |
621 padsh->pbPreparedDst = 0; | |
622 padsh->cbPreparedDstLength = 0; | |
623 | |
624 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_PREPARE, (DWORD)&was->drvInst, (DWORD)padsh); | |
625 if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) { | |
626 ret = MMSYSERR_NOERROR; | |
627 padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE); | |
628 padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_PREPARED; | |
629 padsh->fdwPrepared = padsh->fdwStatus; | |
630 padsh->dwPrepared = 0; | |
631 padsh->pbPreparedSrc = padsh->pbSrc; | |
632 padsh->cbPreparedSrcLength = padsh->cbSrcLength; | |
633 padsh->pbPreparedDst = padsh->pbDst; | |
634 padsh->cbPreparedDstLength = padsh->cbDstLength; | |
635 } else { | |
636 padsh->fdwPrepared = 0; | |
637 padsh->dwPrepared = 0; | |
638 padsh->pbPreparedSrc = 0; | |
639 padsh->cbPreparedSrcLength = 0; | |
640 padsh->pbPreparedDst = 0; | |
641 padsh->cbPreparedDstLength = 0; | |
642 } | |
643 TRACE("=> (%d)\n", ret); | |
644 return ret; | |
645 } | |
646 | |
647 /*********************************************************************** | |
648 * acmStreamReset (MSACM32.42) | |
649 */ | |
650 MMRESULT WINAPI acmStreamReset(HACMSTREAM has, DWORD fdwReset) | |
651 { | |
652 PWINE_ACMSTREAM was; | |
653 MMRESULT ret = MMSYSERR_NOERROR; | |
654 | |
655 TRACE("(0x%08x, %ld)\n", has, fdwReset); | |
656 | |
657 if (fdwReset) { | |
658 ret = MMSYSERR_INVALFLAG; | |
659 } else if ((was = ACM_GetStream(has)) == NULL) { | |
660 return MMSYSERR_INVALHANDLE; | |
661 } else if (was->drvInst.fdwOpen & ACM_STREAMOPENF_ASYNC) { | |
662 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_RESET, (DWORD)&was->drvInst, 0); | |
663 } | |
664 TRACE("=> (%d)\n", ret); | |
665 return ret; | |
666 } | |
667 | |
668 /*********************************************************************** | |
669 * acmStreamSize (MSACM32.43) | |
670 */ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
671 MMRESULT WINAPI acmStreamSize(HACMSTREAM has, DWORD cbInput, |
1 | 672 LPDWORD pdwOutputBytes, DWORD fdwSize) |
673 { | |
674 PWINE_ACMSTREAM was; | |
675 ACMDRVSTREAMSIZE adss; | |
676 MMRESULT ret; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
677 |
1 | 678 TRACE("(0x%08x, %ld, %p, %ld)\n", has, cbInput, pdwOutputBytes, fdwSize); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
679 |
1 | 680 if ((was = ACM_GetStream(has)) == NULL) { |
681 return MMSYSERR_INVALHANDLE; | |
682 } | |
683 if ((fdwSize & ~ACM_STREAMSIZEF_QUERYMASK) != 0) { | |
684 return MMSYSERR_INVALFLAG; | |
685 } | |
686 | |
687 *pdwOutputBytes = 0L; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
688 |
1 | 689 switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) { |
690 case ACM_STREAMSIZEF_DESTINATION: | |
691 adss.cbDstLength = cbInput; | |
692 adss.cbSrcLength = 0; | |
693 break; | |
694 case ACM_STREAMSIZEF_SOURCE: | |
695 adss.cbSrcLength = cbInput; | |
696 adss.cbDstLength = 0; | |
697 break; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
698 default: |
1 | 699 return MMSYSERR_INVALFLAG; |
700 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
701 |
1 | 702 adss.cbStruct = sizeof(adss); |
703 adss.fdwSize = fdwSize; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
704 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_SIZE, |
1 | 705 (DWORD)&was->drvInst, (DWORD)&adss); |
706 if (ret == MMSYSERR_NOERROR) { | |
707 switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) { | |
708 case ACM_STREAMSIZEF_DESTINATION: | |
709 *pdwOutputBytes = adss.cbSrcLength; | |
710 break; | |
711 case ACM_STREAMSIZEF_SOURCE: | |
712 *pdwOutputBytes = adss.cbDstLength; | |
713 break; | |
714 } | |
715 } | |
716 TRACE("=> (%d) [%lu]\n", ret, *pdwOutputBytes); | |
717 return ret; | |
718 } | |
719 | |
720 /*********************************************************************** | |
721 * acmStreamUnprepareHeader (MSACM32.44) | |
722 */ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
723 MMRESULT WINAPI acmStreamUnprepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash, |
1 | 724 DWORD fdwUnprepare) |
725 { | |
726 PWINE_ACMSTREAM was; | |
727 MMRESULT ret = MMSYSERR_NOERROR; | |
728 PACMDRVSTREAMHEADER padsh; | |
729 | |
730 TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwUnprepare); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
731 |
1 | 732 if ((was = ACM_GetStream(has)) == NULL) |
733 return MMSYSERR_INVALHANDLE; | |
734 if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER)) | |
735 return MMSYSERR_INVALPARAM; | |
736 | |
737 if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED)) | |
738 return ACMERR_UNPREPARED; | |
739 | |
740 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same | |
741 * size. some fields are private to msacm internals, and are exposed | |
742 * in ACMSTREAMHEADER in the dwReservedDriver array | |
743 */ | |
744 padsh = (PACMDRVSTREAMHEADER)pash; | |
745 | |
746 /* check that pointers have not been modified */ | |
747 if (padsh->pbPreparedSrc != padsh->pbSrc || | |
748 padsh->cbPreparedSrcLength < padsh->cbSrcLength || | |
749 padsh->pbPreparedDst != padsh->pbDst || | |
750 padsh->cbPreparedDstLength < padsh->cbDstLength) { | |
751 return MMSYSERR_INVALPARAM; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26999
diff
changeset
|
752 } |
1 | 753 |
754 padsh->fdwConvert = fdwUnprepare; | |
755 | |
756 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_UNPREPARE, (DWORD)&was->drvInst, (DWORD)padsh); | |
757 if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) { | |
758 ret = MMSYSERR_NOERROR; | |
759 padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE|ACMSTREAMHEADER_STATUSF_PREPARED); | |
760 } | |
761 TRACE("=> (%d)\n", ret); | |
762 return ret; | |
763 } |