ReactOS 0.4.16-dev-340-g0540c21
mmoutput.c File Reference
#include "private_mciavi.h"
#include "wine/debug.h"
Include dependency graph for mmoutput.c:

Go to the source code of this file.

Classes

struct  AviListBuild
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (mciavi)
 
static BOOL MCIAVI_GetInfoAudio (WINE_MCIAVI *wma, const MMCKINFO *mmckList, MMCKINFO *mmckStream)
 
static BOOL MCIAVI_GetInfoVideo (WINE_MCIAVI *wma, const MMCKINFO *mmckList, MMCKINFO *mmckStream)
 
static BOOL MCIAVI_AddFrame (WINE_MCIAVI *wma, LPMMCKINFO mmck, struct AviListBuild *alb)
 
BOOL MCIAVI_GetInfo (WINE_MCIAVI *wma)
 
BOOL MCIAVI_OpenVideo (WINE_MCIAVI *wma)
 
static void CALLBACK MCIAVI_waveCallback (HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
 
DWORD MCIAVI_OpenAudio (WINE_MCIAVI *wma, unsigned *nHdr, LPWAVEHDR *pWaveHdr)
 
void MCIAVI_PlayAudioBlocks (WINE_MCIAVI *wma, unsigned nHdr, LPWAVEHDR waveHdr)
 
double MCIAVI_PaintFrame (WINE_MCIAVI *wma, HDC hDC)
 

Function Documentation

◆ MCIAVI_AddFrame()

static BOOL MCIAVI_AddFrame ( WINE_MCIAVI wma,
LPMMCKINFO  mmck,
struct AviListBuild alb 
)
static

Definition at line 157 of file mmoutput.c.

159{
160 const BYTE *p;
161 DWORD stream_n;
162 DWORD twocc;
163
164 if (mmck->ckid == ckidAVIPADDING) return TRUE;
165
166 p = (const BYTE *)&mmck->ckid;
167
168 if (!isxdigit(p[0]) || !isxdigit(p[1]))
169 {
170 WARN("wrongly encoded stream #\n");
171 return FALSE;
172 }
173
174 stream_n = (p[0] <= '9') ? (p[0] - '0') : (tolower(p[0]) - 'a' + 10);
175 stream_n <<= 4;
176 stream_n |= (p[1] <= '9') ? (p[1] - '0') : (tolower(p[1]) - 'a' + 10);
177
178 TRACE("ckid %4.4s (stream #%d)\n", (LPSTR)&mmck->ckid, stream_n);
179
180 /* Some (rare?) AVI files have video streams name XXYY where XX = stream number and YY = TWOCC
181 * of the last 2 characters of the biCompression member of the BITMAPINFOHEADER structure.
182 * Ex: fccHandler = IV32 & biCompression = IV32 => stream name = XX32
183 * fccHandler = MSVC & biCompression = CRAM => stream name = XXAM
184 * Another possibility is that these TWOCC are simply ignored.
185 * Default to cktypeDIBcompressed when this case happens.
186 */
187 twocc = TWOCCFromFOURCC(mmck->ckid);
188 if (twocc == TWOCCFromFOURCC(wma->inbih->biCompression))
189 twocc = cktypeDIBcompressed;
190 /* Also detect some chunks that seem to be used by Indeo videos where the chunk is named
191 * after the codec. */
192 else if (twocc == LOWORD(wma->ash_video.fccHandler))
193 twocc = cktypeDIBcompressed;
194 switch (twocc) {
195 case cktypeDIBbits:
197 case cktypePALchange:
198 if (stream_n != wma->video_stream_n)
199 {
200 TRACE("data belongs to another video stream #%d\n", stream_n);
201 return FALSE;
202 }
203
204 TRACE("Adding video frame[%d]: %d bytes\n",
205 alb->numVideoFrames, mmck->cksize);
206
207 if (alb->numVideoFrames < wma->dwPlayableVideoFrames) {
208 wma->lpVideoIndex[alb->numVideoFrames].dwOffset = mmck->dwDataOffset;
209 wma->lpVideoIndex[alb->numVideoFrames].dwSize = mmck->cksize;
210 if (alb->inVideoSize < mmck->cksize)
211 alb->inVideoSize = mmck->cksize;
212 alb->numVideoFrames++;
213 } else {
214 WARN("Too many video frames\n");
215 }
216 break;
217 case cktypeWAVEbytes:
218 if (stream_n != wma->audio_stream_n)
219 {
220 TRACE("data belongs to another audio stream #%d\n", stream_n);
221 return FALSE;
222 }
223
224 TRACE("Adding audio frame[%d]: %d bytes\n",
225 alb->numAudioBlocks, mmck->cksize);
226 if (wma->lpWaveFormat) {
227 if (alb->numAudioBlocks >= alb->numAudioAllocated) {
228 DWORD newsize = alb->numAudioAllocated + 32;
229 struct MMIOPos* newindex;
230
231 if (!wma->lpAudioIndex)
232 newindex = HeapAlloc(GetProcessHeap(), 0, newsize * sizeof(struct MMIOPos));
233 else
234 newindex = HeapReAlloc(GetProcessHeap(), 0, wma->lpAudioIndex, newsize * sizeof(struct MMIOPos));
235 if (!newindex) return FALSE;
236 alb->numAudioAllocated = newsize;
237 wma->lpAudioIndex = newindex;
238 }
239 wma->lpAudioIndex[alb->numAudioBlocks].dwOffset = mmck->dwDataOffset;
240 wma->lpAudioIndex[alb->numAudioBlocks].dwSize = mmck->cksize;
241 if (alb->inAudioSize < mmck->cksize)
242 alb->inAudioSize = mmck->cksize;
243 alb->numAudioBlocks++;
244 } else {
245 WARN("Wave chunk without wave format... discarding\n");
246 }
247 break;
248 default:
249 WARN("Unknown frame type %4.4s\n", (LPSTR)&mmck->ckid);
250 break;
251 }
252 return TRUE;
253}
#define isxdigit(c)
Definition: acclib.h:70
int tolower(int c)
Definition: utclib.c:902
#define TWOCCFromFOURCC(fcc)
Definition: avisplit.c:49
#define WARN(fmt,...)
Definition: precomp.h:61
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
unsigned long DWORD
Definition: ntddk_ex.h:95
GLfloat GLfloat p
Definition: glext.h:8902
if(dx< 0)
Definition: linetemp.h:194
#define LOWORD(l)
Definition: pedump.c:82
#define TRACE(s)
Definition: solgame.cpp:4
FOURCC fccHandler
Definition: vfw.h:960
DWORD numAudioBlocks
Definition: mmoutput.c:152
DWORD inVideoSize
Definition: mmoutput.c:153
DWORD inAudioSize
Definition: mmoutput.c:154
DWORD numAudioAllocated
Definition: mmoutput.c:151
DWORD numVideoFrames
Definition: mmoutput.c:150
DWORD biCompression
Definition: amvideo.idl:35
LPWAVEFORMATEX lpWaveFormat
DWORD audio_stream_n
LPBITMAPINFOHEADER inbih
DWORD video_stream_n
struct MMIOPos * lpVideoIndex
DWORD dwPlayableVideoFrames
struct MMIOPos * lpAudioIndex
AVIStreamHeader ash_video
FOURCC ckid
Definition: mmsystem.h:1507
DWORD cksize
Definition: mmsystem.h:1508
DWORD dwDataOffset
Definition: mmsystem.h:1510
#define cktypePALchange
Definition: vfw.h:912
#define cktypeDIBcompressed
Definition: vfw.h:911
#define ckidAVIPADDING
Definition: vfw.h:916
#define cktypeWAVEbytes
Definition: vfw.h:913
#define cktypeDIBbits
Definition: vfw.h:910
char * LPSTR
Definition: xmlstorage.h:182
unsigned char BYTE
Definition: xxhash.c:193

Referenced by MCIAVI_GetInfo().

◆ MCIAVI_GetInfo()

BOOL MCIAVI_GetInfo ( WINE_MCIAVI wma)

Definition at line 255 of file mmoutput.c.

256{
257 MMCKINFO ckMainRIFF;
258 MMCKINFO mmckHead;
259 MMCKINFO mmckList;
260 MMCKINFO mmckInfo;
261 AVIStreamHeader strh;
262 struct AviListBuild alb;
263 DWORD stream_n;
264
265 if (mmioDescend(wma->hFile, &ckMainRIFF, NULL, 0) != 0) {
266 WARN("Can't find 'RIFF' chunk\n");
267 return FALSE;
268 }
269
270 if ((ckMainRIFF.ckid != FOURCC_RIFF) || (ckMainRIFF.fccType != formtypeAVI)) {
271 WARN("Can't find 'AVI ' chunk\n");
272 return FALSE;
273 }
274
275 mmckHead.fccType = listtypeAVIHEADER;
276 if (mmioDescend(wma->hFile, &mmckHead, &ckMainRIFF, MMIO_FINDLIST) != 0) {
277 WARN("Can't find 'hdrl' list\n");
278 return FALSE;
279 }
280
281 mmckInfo.ckid = ckidAVIMAINHDR;
282 if (mmioDescend(wma->hFile, &mmckInfo, &mmckHead, MMIO_FINDCHUNK) != 0) {
283 WARN("Can't find 'avih' chunk\n");
284 return FALSE;
285 }
286
287 mmioRead(wma->hFile, (LPSTR)&wma->mah, sizeof(wma->mah));
288
289 TRACE("mah.dwMicroSecPerFrame=%d\n", wma->mah.dwMicroSecPerFrame);
290 TRACE("mah.dwMaxBytesPerSec=%d\n", wma->mah.dwMaxBytesPerSec);
291 TRACE("mah.dwPaddingGranularity=%d\n", wma->mah.dwPaddingGranularity);
292 TRACE("mah.dwFlags=%d\n", wma->mah.dwFlags);
293 TRACE("mah.dwTotalFrames=%d\n", wma->mah.dwTotalFrames);
294 TRACE("mah.dwInitialFrames=%d\n", wma->mah.dwInitialFrames);
295 TRACE("mah.dwStreams=%d\n", wma->mah.dwStreams);
296 TRACE("mah.dwSuggestedBufferSize=%d\n", wma->mah.dwSuggestedBufferSize);
297 TRACE("mah.dwWidth=%d\n", wma->mah.dwWidth);
298 TRACE("mah.dwHeight=%d\n", wma->mah.dwHeight);
299
300 mmioAscend(wma->hFile, &mmckInfo, 0);
301
302 TRACE("Start of streams\n");
303 wma->video_stream_n = 0;
304 wma->audio_stream_n = 0;
305
306 for (stream_n = 0; stream_n < wma->mah.dwStreams; stream_n++)
307 {
308 MMCKINFO mmckStream;
309
310 mmckList.fccType = listtypeSTREAMHEADER;
311 if (mmioDescend(wma->hFile, &mmckList, &mmckHead, MMIO_FINDLIST) != 0)
312 break;
313
314 mmckStream.ckid = ckidSTREAMHEADER;
315 if (mmioDescend(wma->hFile, &mmckStream, &mmckList, MMIO_FINDCHUNK) != 0)
316 {
317 WARN("Can't find 'strh' chunk\n");
318 continue;
319 }
320
321 mmioRead(wma->hFile, (LPSTR)&strh, sizeof(strh));
322
323 TRACE("Stream #%d fccType %4.4s\n", stream_n, (LPSTR)&strh.fccType);
324
325 if (strh.fccType == streamtypeVIDEO)
326 {
327 TRACE("found video stream\n");
328 if (wma->inbih)
329 WARN("ignoring another video stream\n");
330 else
331 {
332 wma->ash_video = strh;
333
334 if (!MCIAVI_GetInfoVideo(wma, &mmckList, &mmckStream))
335 return FALSE;
336 wma->video_stream_n = stream_n;
337 wma->dwSet |= 4;
338 }
339 }
340 else if (strh.fccType == streamtypeAUDIO)
341 {
342 TRACE("found audio stream\n");
343 if (wma->lpWaveFormat)
344 WARN("ignoring another audio stream\n");
345 else
346 {
347 wma->ash_audio = strh;
348
349 if (!MCIAVI_GetInfoAudio(wma, &mmckList, &mmckStream))
350 return FALSE;
351 wma->audio_stream_n = stream_n;
352 wma->dwSet |= 3;
353 }
354 }
355 else
356 TRACE("Unsupported stream type %4.4s\n", (LPSTR)&strh.fccType);
357
358 mmioAscend(wma->hFile, &mmckList, 0);
359 }
360
361 TRACE("End of streams\n");
362
363 mmioAscend(wma->hFile, &mmckHead, 0);
364
365 /* no need to read optional JUNK chunk */
366
367 mmckList.fccType = listtypeAVIMOVIE;
368 if (mmioDescend(wma->hFile, &mmckList, &ckMainRIFF, MMIO_FINDLIST) != 0) {
369 WARN("Can't find 'movi' list\n");
370 return FALSE;
371 }
372
375 wma->dwPlayableVideoFrames * sizeof(struct MMIOPos));
376 if (!wma->lpVideoIndex) {
377 WARN("Can't alloc video index array\n");
378 return FALSE;
379 }
380 wma->dwPlayableAudioBlocks = 0;
381 wma->lpAudioIndex = NULL;
382
383 alb.numAudioBlocks = alb.numVideoFrames = 0;
384 alb.inVideoSize = alb.inAudioSize = 0;
385 alb.numAudioAllocated = 0;
386
387 while (mmioDescend(wma->hFile, &mmckInfo, &mmckList, 0) == 0) {
388 if (mmckInfo.fccType == listtypeAVIRECORD) {
389 MMCKINFO tmp;
390
391 while (mmioDescend(wma->hFile, &tmp, &mmckInfo, 0) == 0) {
392 MCIAVI_AddFrame(wma, &tmp, &alb);
393 mmioAscend(wma->hFile, &tmp, 0);
394 }
395 } else {
396 MCIAVI_AddFrame(wma, &mmckInfo, &alb);
397 }
398
399 mmioAscend(wma->hFile, &mmckInfo, 0);
400 }
401
402#ifdef __REACTOS__
403 /* Empty file */
404 if (alb.numVideoFrames == 0) {
405 WARN("NumVideoFrames: %u, Empty or possibly corrupt video file");
406 return FALSE;
407 }
408#endif
409
410 if (alb.numVideoFrames != wma->dwPlayableVideoFrames) {
411 WARN("AVI header says %d frames, we found %d video frames, reducing playable frames\n",
412 wma->dwPlayableVideoFrames, alb.numVideoFrames);
413 wma->dwPlayableVideoFrames = alb.numVideoFrames;
414 }
415 wma->dwPlayableAudioBlocks = alb.numAudioBlocks;
416
417 if (alb.inVideoSize > wma->ash_video.dwSuggestedBufferSize) {
418 WARN("inVideoSize=%d suggestedSize=%d\n", alb.inVideoSize, wma->ash_video.dwSuggestedBufferSize);
419 wma->ash_video.dwSuggestedBufferSize = alb.inVideoSize;
420 }
421 if (alb.inAudioSize > wma->ash_audio.dwSuggestedBufferSize) {
422 WARN("inAudioSize=%d suggestedSize=%d\n", alb.inAudioSize, wma->ash_audio.dwSuggestedBufferSize);
423 wma->ash_audio.dwSuggestedBufferSize = alb.inAudioSize;
424 }
425
427 if (!wma->indata) {
428 WARN("Can't alloc input buffer\n");
429 return FALSE;
430 }
431
432 return TRUE;
433}
#define streamtypeAUDIO
Definition: aviriff.h:93
#define streamtypeVIDEO
Definition: aviriff.h:92
#define ckidSTREAMHEADER
Definition: aviriff.h:88
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
MMRESULT WINAPI mmioAscend(HMMIO hmmio, LPMMCKINFO lpck, UINT uFlags)
Definition: mmio.c:1205
MMRESULT WINAPI mmioDescend(HMMIO hmmio, LPMMCKINFO lpck, const MMCKINFO *lpckParent, UINT uFlags)
Definition: mmio.c:1107
LONG WINAPI mmioRead(HMMIO hmmio, HPSTR pch, LONG cch)
Definition: mmio.c:733
static BOOL MCIAVI_AddFrame(WINE_MCIAVI *wma, LPMMCKINFO mmck, struct AviListBuild *alb)
Definition: mmoutput.c:157
static BOOL MCIAVI_GetInfoAudio(WINE_MCIAVI *wma, const MMCKINFO *mmckList, MMCKINFO *mmckStream)
Definition: mmoutput.c:27
static BOOL MCIAVI_GetInfoVideo(WINE_MCIAVI *wma, const MMCKINFO *mmckList, MMCKINFO *mmckStream)
Definition: mmoutput.c:88
#define FOURCC_RIFF
Definition: mmsystem.h:564
#define MMIO_FINDCHUNK
Definition: mmsystem.h:551
#define MMIO_FINDLIST
Definition: mmsystem.h:553
FOURCC fccType
Definition: vfw.h:959
DWORD dwSuggestedBufferSize
Definition: vfw.h:969
AVIStreamHeader ash_audio
DWORD dwPlayableAudioBlocks
MainAVIHeader mah
FOURCC fccType
Definition: mmsystem.h:1509
DWORD dwWidth
Definition: vfw.h:949
DWORD dwSuggestedBufferSize
Definition: vfw.h:948
DWORD dwHeight
Definition: vfw.h:950
DWORD dwPaddingGranularity
Definition: vfw.h:943
DWORD dwStreams
Definition: vfw.h:947
DWORD dwMaxBytesPerSec
Definition: vfw.h:942
DWORD dwInitialFrames
Definition: vfw.h:946
DWORD dwFlags
Definition: vfw.h:944
DWORD dwMicroSecPerFrame
Definition: vfw.h:941
DWORD dwTotalFrames
Definition: vfw.h:945
#define listtypeAVIMOVIE
Definition: vfw.h:898
#define listtypeSTREAMHEADER
Definition: vfw.h:892
#define listtypeAVIRECORD
Definition: vfw.h:899
#define listtypeAVIHEADER
Definition: vfw.h:890
#define ckidAVIMAINHDR
Definition: vfw.h:891
#define formtypeAVI
Definition: vfw.h:889

Referenced by MCIAVI_mciOpen().

◆ MCIAVI_GetInfoAudio()

static BOOL MCIAVI_GetInfoAudio ( WINE_MCIAVI wma,
const MMCKINFO mmckList,
MMCKINFO mmckStream 
)
static

Definition at line 27 of file mmoutput.c.

28{
29 MMCKINFO mmckInfo;
30
31 TRACE("ash.fccType='%c%c%c%c'\n", LOBYTE(LOWORD(wma->ash_audio.fccType)),
35 if (wma->ash_audio.fccHandler) /* not all streams specify a handler */
36 TRACE("ash.fccHandler='%c%c%c%c'\n", LOBYTE(LOWORD(wma->ash_audio.fccHandler)),
40 else
41 TRACE("ash.fccHandler=0, no handler specified\n");
42 TRACE("ash.dwFlags=%d\n", wma->ash_audio.dwFlags);
43 TRACE("ash.wPriority=%d\n", wma->ash_audio.wPriority);
44 TRACE("ash.wLanguage=%d\n", wma->ash_audio.wLanguage);
45 TRACE("ash.dwInitialFrames=%d\n", wma->ash_audio.dwInitialFrames);
46 TRACE("ash.dwScale=%d\n", wma->ash_audio.dwScale);
47 TRACE("ash.dwRate=%d\n", wma->ash_audio.dwRate);
48 TRACE("ash.dwStart=%d\n", wma->ash_audio.dwStart);
49 TRACE("ash.dwLength=%d\n", wma->ash_audio.dwLength);
50 TRACE("ash.dwSuggestedBufferSize=%d\n", wma->ash_audio.dwSuggestedBufferSize);
51 TRACE("ash.dwQuality=%d\n", wma->ash_audio.dwQuality);
52 TRACE("ash.dwSampleSize=%d\n", wma->ash_audio.dwSampleSize);
53 TRACE("ash.rcFrame=(%d,%d,%d,%d)\n", wma->ash_audio.rcFrame.top, wma->ash_audio.rcFrame.left,
54 wma->ash_audio.rcFrame.bottom, wma->ash_audio.rcFrame.right);
55
56 /* rewind to the start of the stream */
57 mmioAscend(wma->hFile, mmckStream, 0);
58
59 mmckInfo.ckid = ckidSTREAMFORMAT;
60 if (mmioDescend(wma->hFile, &mmckInfo, mmckList, MMIO_FINDCHUNK) != 0) {
61 WARN("Can't find 'strf' chunk\n");
62 return FALSE;
63 }
64 if (mmckInfo.cksize < sizeof(WAVEFORMAT)) {
65 WARN("Size of strf chunk (%d) < audio format struct\n", mmckInfo.cksize);
66 return FALSE;
67 }
68 wma->lpWaveFormat = HeapAlloc(GetProcessHeap(), 0, mmckInfo.cksize);
69 if (!wma->lpWaveFormat) {
70 WARN("Can't alloc WaveFormat\n");
71 return FALSE;
72 }
73
74 mmioRead(wma->hFile, (LPSTR)wma->lpWaveFormat, mmckInfo.cksize);
75
76 TRACE("waveFormat.wFormatTag=%d\n", wma->lpWaveFormat->wFormatTag);
77 TRACE("waveFormat.nChannels=%d\n", wma->lpWaveFormat->nChannels);
78 TRACE("waveFormat.nSamplesPerSec=%d\n", wma->lpWaveFormat->nSamplesPerSec);
79 TRACE("waveFormat.nAvgBytesPerSec=%d\n", wma->lpWaveFormat->nAvgBytesPerSec);
80 TRACE("waveFormat.nBlockAlign=%d\n", wma->lpWaveFormat->nBlockAlign);
81 TRACE("waveFormat.wBitsPerSample=%d\n", wma->lpWaveFormat->wBitsPerSample);
82 if (mmckInfo.cksize >= sizeof(WAVEFORMATEX))
83 TRACE("waveFormat.cbSize=%d\n", wma->lpWaveFormat->cbSize);
84
85 return TRUE;
86}
#define ckidSTREAMFORMAT
Definition: aviriff.h:125
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
DWORD dwInitialFrames
Definition: vfw.h:964
DWORD dwStart
Definition: vfw.h:967
DWORD dwQuality
Definition: vfw.h:970
WORD wLanguage
Definition: vfw.h:963
DWORD dwSampleSize
Definition: vfw.h:971
DWORD dwScale
Definition: vfw.h:965
DWORD dwFlags
Definition: vfw.h:961
DWORD dwLength
Definition: vfw.h:968
struct AVIStreamHeader::@3270 rcFrame
DWORD dwRate
Definition: vfw.h:966
WORD wPriority
Definition: vfw.h:962
WORD nBlockAlign
Definition: mmreg.h:82
WORD cbSize
Definition: mmreg.h:84
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
DWORD nSamplesPerSec
Definition: mmreg.h:80
WORD nChannels
Definition: mmreg.h:79
WORD wFormatTag
Definition: mmreg.h:78
WORD wBitsPerSample
Definition: mmreg.h:83
#define HIWORD(l)
Definition: typedefs.h:247

Referenced by MCIAVI_GetInfo().

◆ MCIAVI_GetInfoVideo()

static BOOL MCIAVI_GetInfoVideo ( WINE_MCIAVI wma,
const MMCKINFO mmckList,
MMCKINFO mmckStream 
)
static

Definition at line 88 of file mmoutput.c.

89{
90 MMCKINFO mmckInfo;
91
92 TRACE("ash.fccType='%c%c%c%c'\n", LOBYTE(LOWORD(wma->ash_video.fccType)),
96 TRACE("ash.fccHandler='%c%c%c%c'\n", LOBYTE(LOWORD(wma->ash_video.fccHandler)),
100 TRACE("ash.dwFlags=%d\n", wma->ash_video.dwFlags);
101 TRACE("ash.wPriority=%d\n", wma->ash_video.wPriority);
102 TRACE("ash.wLanguage=%d\n", wma->ash_video.wLanguage);
103 TRACE("ash.dwInitialFrames=%d\n", wma->ash_video.dwInitialFrames);
104 TRACE("ash.dwScale=%d\n", wma->ash_video.dwScale);
105 TRACE("ash.dwRate=%d\n", wma->ash_video.dwRate);
106 TRACE("ash.dwStart=%d\n", wma->ash_video.dwStart);
107 TRACE("ash.dwLength=%d\n", wma->ash_video.dwLength);
108 TRACE("ash.dwSuggestedBufferSize=%d\n", wma->ash_video.dwSuggestedBufferSize);
109 TRACE("ash.dwQuality=%d\n", wma->ash_video.dwQuality);
110 TRACE("ash.dwSampleSize=%d\n", wma->ash_video.dwSampleSize);
111 TRACE("ash.rcFrame=(%d,%d,%d,%d)\n", wma->ash_video.rcFrame.top, wma->ash_video.rcFrame.left,
112 wma->ash_video.rcFrame.bottom, wma->ash_video.rcFrame.right);
113
114 /* rewind to the start of the stream */
115 mmioAscend(wma->hFile, mmckStream, 0);
116
117 mmckInfo.ckid = ckidSTREAMFORMAT;
118 if (mmioDescend(wma->hFile, &mmckInfo, mmckList, MMIO_FINDCHUNK) != 0) {
119 WARN("Can't find 'strf' chunk\n");
120 return FALSE;
121 }
122
123 wma->inbih = HeapAlloc(GetProcessHeap(), 0, mmckInfo.cksize);
124 if (!wma->inbih) {
125 WARN("Can't alloc input BIH\n");
126 return FALSE;
127 }
128
129 mmioRead(wma->hFile, (LPSTR)wma->inbih, mmckInfo.cksize);
130
131 TRACE("bih.biSize=%d\n", wma->inbih->biSize);
132 TRACE("bih.biWidth=%d\n", wma->inbih->biWidth);
133 TRACE("bih.biHeight=%d\n", wma->inbih->biHeight);
134 TRACE("bih.biPlanes=%d\n", wma->inbih->biPlanes);
135 TRACE("bih.biBitCount=%d\n", wma->inbih->biBitCount);
136 TRACE("bih.biCompression=%x\n", wma->inbih->biCompression);
137 TRACE("bih.biSizeImage=%d\n", wma->inbih->biSizeImage);
138 TRACE("bih.biXPelsPerMeter=%d\n", wma->inbih->biXPelsPerMeter);
139 TRACE("bih.biYPelsPerMeter=%d\n", wma->inbih->biYPelsPerMeter);
140 TRACE("bih.biClrUsed=%d\n", wma->inbih->biClrUsed);
141 TRACE("bih.biClrImportant=%d\n", wma->inbih->biClrImportant);
142
143 SetRect(&wma->source, 0, 0, wma->inbih->biWidth, wma->inbih->biHeight);
144 wma->dest = wma->source;
145
146 return TRUE;
147}
LONG biYPelsPerMeter
Definition: amvideo.idl:38
DWORD biClrImportant
Definition: amvideo.idl:40
LONG biXPelsPerMeter
Definition: amvideo.idl:37
DWORD biSizeImage
Definition: amvideo.idl:36
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)

Referenced by MCIAVI_GetInfo().

◆ MCIAVI_OpenAudio()

DWORD MCIAVI_OpenAudio ( WINE_MCIAVI wma,
unsigned nHdr,
LPWAVEHDR pWaveHdr 
)

Definition at line 534 of file mmoutput.c.

535{
536 DWORD dwRet;
537 LPWAVEHDR waveHdr;
538 unsigned i;
539
540 dwRet = waveOutOpen((HWAVEOUT *)&wma->hWave, WAVE_MAPPER, wma->lpWaveFormat,
542 if (dwRet != 0) {
543 TRACE("Can't open low level audio device %d\n", dwRet);
544 dwRet = MCIERR_DEVICE_OPEN;
545 wma->hWave = 0;
546 goto cleanUp;
547 }
548
549 /* FIXME: should set up a heuristic to compute the number of wave headers
550 * to be used...
551 */
552 *nHdr = 7;
554 *nHdr * (sizeof(WAVEHDR) + wma->ash_audio.dwSuggestedBufferSize));
555 if (!waveHdr) {
556 TRACE("Can't alloc wave headers\n");
557 dwRet = MCIERR_DEVICE_OPEN;
558 goto cleanUp;
559 }
560
561 for (i = 0; i < *nHdr; i++) {
562 /* other fields are zero:ed on allocation */
563 waveHdr[i].lpData = (char*)waveHdr +
564 *nHdr * sizeof(WAVEHDR) + i * wma->ash_audio.dwSuggestedBufferSize;
566 if (waveOutPrepareHeader(wma->hWave, &waveHdr[i], sizeof(WAVEHDR))) {
567 dwRet = MCIERR_INTERNAL;
568 goto cleanUp;
569 }
570 }
571
572 if (wma->dwCurrVideoFrame != 0 && wma->lpWaveFormat) {
573 FIXME("Should recompute dwCurrAudioBlock, except unsynchronized sound & video\n");
574 }
575 wma->dwCurrAudioBlock = 0;
576
578 wma->dwEventCount = *nHdr - 1;
579 *pWaveHdr = waveHdr;
580 cleanUp:
581 return dwRet;
582}
#define FIXME(fmt,...)
Definition: precomp.h:53
void cleanUp()
Definition: main.cpp:469
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static void CALLBACK MCIAVI_waveCallback(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: mmoutput.c:509
#define WAVE_MAPPER
Definition: mmsystem.h:187
#define MCIERR_DEVICE_OPEN
Definition: mmsystem.h:575
#define MCIERR_INTERNAL
Definition: mmsystem.h:587
#define CALLBACK_FUNCTION
Definition: mmsystem.h:150
MCIDEVICEID wDevID
DWORD dwCurrAudioBlock
DWORD dwCurrVideoFrame
DWORD dwBufferLength
Definition: mmsystem.h:1015
LPSTR lpData
Definition: mmsystem.h:1014
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
uint32_t DWORD_PTR
Definition: typedefs.h:65
MMRESULT WINAPI waveOutOpen(LPHWAVEOUT lphWaveOut, UINT uDeviceID, LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:2246
UINT WINAPI waveOutPrepareHeader(HWAVEOUT hWaveOut, WAVEHDR *lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2277

Referenced by MCIAVI_player().

◆ MCIAVI_OpenVideo()

BOOL MCIAVI_OpenVideo ( WINE_MCIAVI wma)

Definition at line 435 of file mmoutput.c.

436{
437 HDC hDC;
438 DWORD outSize;
439 FOURCC fcc = wma->ash_video.fccHandler;
440
441 TRACE("fcc %4.4s\n", (LPSTR)&fcc);
442
443 wma->dwCachedFrame = -1;
444
445 /* get the right handle */
446 if (fcc == mmioFOURCC('C','R','A','M')) fcc = mmioFOURCC('M','S','V','C');
447
448 /* try to get a decompressor for that type */
450 if (!wma->hic) {
451 /* check for builtin DIB compressions */
452 fcc = wma->inbih->biCompression;
453 if ((fcc == mmioFOURCC('D','I','B',' ')) ||
454 (fcc == mmioFOURCC('R','L','E',' ')) ||
455 (fcc == BI_RGB) || (fcc == BI_RLE8) ||
456 (fcc == BI_RLE4) || (fcc == BI_BITFIELDS))
457 goto paint_frame;
458
459 WARN("Can't locate codec for the file\n");
460 return FALSE;
461 }
462
463 outSize = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD);
464
465 wma->outbih = HeapAlloc(GetProcessHeap(), 0, outSize);
466 if (!wma->outbih) {
467 WARN("Can't alloc output BIH\n");
468 return FALSE;
469 }
470 if (!ICGetDisplayFormat(wma->hic, wma->inbih, wma->outbih, 0, 0, 0)) {
471 WARN("Can't open decompressor\n");
472 return FALSE;
473 }
474
475 TRACE("bih.biSize=%d\n", wma->outbih->biSize);
476 TRACE("bih.biWidth=%d\n", wma->outbih->biWidth);
477 TRACE("bih.biHeight=%d\n", wma->outbih->biHeight);
478 TRACE("bih.biPlanes=%d\n", wma->outbih->biPlanes);
479 TRACE("bih.biBitCount=%d\n", wma->outbih->biBitCount);
480 TRACE("bih.biCompression=%x\n", wma->outbih->biCompression);
481 TRACE("bih.biSizeImage=%d\n", wma->outbih->biSizeImage);
482 TRACE("bih.biXPelsPerMeter=%d\n", wma->outbih->biXPelsPerMeter);
483 TRACE("bih.biYPelsPerMeter=%d\n", wma->outbih->biYPelsPerMeter);
484 TRACE("bih.biClrUsed=%d\n", wma->outbih->biClrUsed);
485 TRACE("bih.biClrImportant=%d\n", wma->outbih->biClrImportant);
486
488 if (!wma->outdata) {
489 WARN("Can't alloc output buffer\n");
490 return FALSE;
491 }
492
494 (DWORD_PTR)wma->inbih, (DWORD_PTR)wma->outbih) != ICERR_OK) {
495 WARN("Can't begin decompression\n");
496 return FALSE;
497 }
498
499paint_frame:
500 hDC = wma->hWndPaint ? GetDC(wma->hWndPaint) : 0;
501 if (hDC)
502 {
504 ReleaseDC(wma->hWndPaint, hDC);
505 }
506 return TRUE;
507}
static HDC hDC
Definition: 3dtext.c:33
DWORD FOURCC
Definition: dmdls.h:25
#define BI_RLE4
Definition: precomp.h:57
#define BI_RGB
Definition: precomp.h:56
ULONG RGBQUAD
Definition: precomp.h:59
double MCIAVI_PaintFrame(WINE_MCIAVI *wma, HDC hDC)
Definition: mmoutput.c:613
#define BI_BITFIELDS
Definition: mmreg.h:507
#define ICTYPE_VIDEO
Definition: mmreg.h:531
#define mmioFOURCC(c0, c1, c2, c3)
Definition: mmsystem.h:38
static HDC
Definition: imagelist.c:88
LRESULT VFWAPI ICSendMessage(HIC hic, UINT msg, DWORD_PTR lParam1, DWORD_PTR lParam2)
HIC VFWAPI ICLocate(DWORD type, DWORD handler, BITMAPINFOHEADER *in, BITMAPINFOHEADER *out, WORD mode)
Definition: msvideo_main.c:633
HIC VFWAPI ICGetDisplayFormat(HIC hic, BITMAPINFOHEADER *in, BITMAPINFOHEADER *out, int depth, int width, int height)
Definition: msvideo_main.c:699
DWORD dwCachedFrame
LPVOID outdata
LPBITMAPINFOHEADER outbih
#define ICMODE_DECOMPRESS
Definition: vfw.h:269
#define ICERR_OK
Definition: vfw.h:50
#define ICM_DECOMPRESS_BEGIN
Definition: vfw.h:108
#define BI_RLE8
Definition: wingdi.h:35
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
HDC WINAPI GetDC(_In_opt_ HWND)

Referenced by MCIAVI_mciOpen().

◆ MCIAVI_PaintFrame()

double MCIAVI_PaintFrame ( WINE_MCIAVI wma,
HDC  hDC 
)

Definition at line 613 of file mmoutput.c.

614{
615 void* pBitmapData;
616 LPBITMAPINFO pBitmapInfo;
617
618 if (!hDC || !wma->inbih)
619 return 0;
620
621 TRACE("Painting frame %u (cached %u)\n", wma->dwCurrVideoFrame, wma->dwCachedFrame);
622
623 if (wma->dwCurrVideoFrame != wma->dwCachedFrame)
624 {
625#ifdef __REACTOS__
626 if (wma->dwCurrVideoFrame >= wma->dwPlayableVideoFrames) {
627 ERR("Invalid frame requested. Current : %u Total Playable %u\n", wma->dwCurrVideoFrame, wma->dwPlayableVideoFrames);
628 return 0;
629 }
630#endif
631
632 if (!wma->lpVideoIndex[wma->dwCurrVideoFrame].dwOffset)
633 return 0;
634
635 if (wma->lpVideoIndex[wma->dwCurrVideoFrame].dwSize)
636 {
637 mmioSeek(wma->hFile, wma->lpVideoIndex[wma->dwCurrVideoFrame].dwOffset, SEEK_SET);
638 mmioRead(wma->hFile, wma->indata, wma->lpVideoIndex[wma->dwCurrVideoFrame].dwSize);
639
640 wma->inbih->biSizeImage = wma->lpVideoIndex[wma->dwCurrVideoFrame].dwSize;
641
642 if (wma->hic && ICDecompress(wma->hic, 0, wma->inbih, wma->indata,
643 wma->outbih, wma->outdata) != ICERR_OK)
644 {
645 WARN("Decompression error\n");
646 return 0;
647 }
648 }
649
651 }
652
653 if (wma->hic) {
654 pBitmapData = wma->outdata;
655 pBitmapInfo = (LPBITMAPINFO)wma->outbih;
656 } else {
657 pBitmapData = wma->indata;
658 pBitmapInfo = (LPBITMAPINFO)wma->inbih;
659 }
660
662 wma->dest.left, wma->dest.top,
663 wma->dest.right - wma->dest.left, wma->dest.bottom - wma->dest.top,
664 wma->source.left, wma->source.top,
665 wma->source.right - wma->source.left, wma->source.bottom - wma->source.top,
666 pBitmapData, pBitmapInfo, DIB_RGB_COLORS, SRCCOPY);
667
668 return (wma->ash_video.dwScale / (double)wma->ash_video.dwRate) * 1000000;
669}
#define ERR(fmt,...)
Definition: precomp.h:57
LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, INT iOrigin)
Definition: mmio.c:836
#define SEEK_SET
Definition: jmemansi.c:26
DWORD VFWAPIV ICDecompress(HIC hic, DWORD dwFlags, LPBITMAPINFOHEADER lpbiFormat, LPVOID lpData, LPBITMAPINFOHEADER lpbi, LPVOID lpBits)
Definition: msvideo_main.c:827
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
#define DIB_RGB_COLORS
Definition: wingdi.h:367
struct tagBITMAPINFO * LPBITMAPINFO
#define SRCCOPY
Definition: wingdi.h:333
int WINAPI StretchDIBits(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_opt_ const VOID *, _In_ const BITMAPINFO *, _In_ UINT, _In_ DWORD)

Referenced by MCIAVI_mciUpdate(), MCIAVI_OpenVideo(), MCIAVI_player(), and MCIAVI_WindowProc().

◆ MCIAVI_PlayAudioBlocks()

void MCIAVI_PlayAudioBlocks ( WINE_MCIAVI wma,
unsigned  nHdr,
LPWAVEHDR  waveHdr 
)

Definition at line 584 of file mmoutput.c.

585{
586 if (!wma->lpAudioIndex)
587 return;
588 TRACE("%d (ec=%u)\n", wma->lpAudioIndex[wma->dwCurrAudioBlock].dwOffset, wma->dwEventCount);
589
590 /* push as many blocks as possible => audio gets priority */
591 while (wma->dwStatus != MCI_MODE_STOP && wma->dwStatus != MCI_MODE_NOT_READY &&
593 unsigned whidx = wma->dwCurrAudioBlock % nHdr;
594
595 ResetEvent(wma->hEvent);
596 if (InterlockedDecrement(&wma->dwEventCount) < 0 ||
597 !wma->lpAudioIndex[wma->dwCurrAudioBlock].dwOffset)
598 {
600 break;
601 }
602
603 mmioSeek(wma->hFile, wma->lpAudioIndex[wma->dwCurrAudioBlock].dwOffset, SEEK_SET);
604 mmioRead(wma->hFile, waveHdr[whidx].lpData, wma->lpAudioIndex[wma->dwCurrAudioBlock].dwSize);
605
606 waveHdr[whidx].dwFlags &= ~WHDR_DONE;
607 waveHdr[whidx].dwBufferLength = wma->lpAudioIndex[wma->dwCurrAudioBlock].dwSize;
608 waveOutWrite(wma->hWave, &waveHdr[whidx], sizeof(WAVEHDR));
609 wma->dwCurrAudioBlock++;
610 }
611}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define MCI_MODE_STOP
Definition: mmsystem.h:695
#define MCI_MODE_NOT_READY
Definition: mmsystem.h:694
DWORD dwFlags
Definition: mmsystem.h:1018
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:714
UINT WINAPI waveOutWrite(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2341

Referenced by MCIAVI_player().

◆ MCIAVI_waveCallback()

static void CALLBACK MCIAVI_waveCallback ( HWAVEOUT  hwo,
UINT  uMsg,
DWORD_PTR  dwInstance,
DWORD_PTR  dwParam1,
DWORD_PTR  dwParam2 
)
static

Definition at line 509 of file mmoutput.c.

511{
512 WINE_MCIAVI *wma = MCIAVI_mciGetOpenDev(dwInstance);
513
514 if (!wma) return;
515
517
518 switch (uMsg) {
519 case WOM_OPEN:
520 case WOM_CLOSE:
521 break;
522 case WOM_DONE:
524 TRACE("Returning waveHdr=%lx\n", dwParam1);
525 SetEvent(wma->hEvent);
526 break;
527 default:
528 ERR("Unknown uMsg=%d\n", uMsg);
529 }
530
532}
WINE_MCIAVI * MCIAVI_mciGetOpenDev(UINT wDevID)
Definition: mciavi.c:157
#define WOM_DONE
Definition: mmsystem.h:183
#define WOM_OPEN
Definition: mmsystem.h:181
#define WOM_CLOSE
Definition: mmsystem.h:182
CRITICAL_SECTION cs
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)

Referenced by MCIAVI_OpenAudio().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( mciavi  )