ReactOS 0.4.17-dev-806-gffa4164
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 145 of file mmoutput.c.

147{
148 const BYTE *p;
149 DWORD stream_n;
150 DWORD twocc;
151
152 if (mmck->ckid == ckidAVIPADDING) return TRUE;
153
154 p = (const BYTE *)&mmck->ckid;
155
156 if (!isxdigit(p[0]) || !isxdigit(p[1]))
157 {
158 WARN("wrongly encoded stream #\n");
159 return FALSE;
160 }
161
162 stream_n = (p[0] <= '9') ? (p[0] - '0') : (tolower(p[0]) - 'a' + 10);
163 stream_n <<= 4;
164 stream_n |= (p[1] <= '9') ? (p[1] - '0') : (tolower(p[1]) - 'a' + 10);
165
166 TRACE("ckid %4.4s (stream #%ld)\n", (LPSTR)&mmck->ckid, stream_n);
167
168 /* Some (rare?) AVI files have video streams name XXYY where XX = stream number and YY = TWOCC
169 * of the last 2 characters of the biCompression member of the BITMAPINFOHEADER structure.
170 * Ex: fccHandler = IV32 & biCompression = IV32 => stream name = XX32
171 * fccHandler = MSVC & biCompression = CRAM => stream name = XXAM
172 * Another possibility is that these TWOCC are simply ignored.
173 * Default to cktypeDIBcompressed when this case happens.
174 */
175 twocc = TWOCCFromFOURCC(mmck->ckid);
176 if (twocc == TWOCCFromFOURCC(wma->inbih->biCompression))
177 twocc = cktypeDIBcompressed;
178 /* Also detect some chunks that seem to be used by Indeo videos where the chunk is named
179 * after the codec. */
180 else if (twocc == LOWORD(wma->ash_video.fccHandler))
181 twocc = cktypeDIBcompressed;
182 switch (twocc) {
183 case cktypeDIBbits:
185 case cktypePALchange:
186 if (stream_n != wma->video_stream_n)
187 {
188 TRACE("data belongs to another video stream #%ld\n", stream_n);
189 return FALSE;
190 }
191
192 TRACE("Adding video frame[%ld]: %ld bytes\n",
193 alb->numVideoFrames, mmck->cksize);
194
195 if (alb->numVideoFrames < wma->dwPlayableVideoFrames) {
196 wma->lpVideoIndex[alb->numVideoFrames].dwOffset = mmck->dwDataOffset;
197 wma->lpVideoIndex[alb->numVideoFrames].dwSize = mmck->cksize;
198 if (alb->inVideoSize < mmck->cksize)
199 alb->inVideoSize = mmck->cksize;
200 alb->numVideoFrames++;
201 } else {
202 WARN("Too many video frames\n");
203 }
204 break;
205 case cktypeWAVEbytes:
206 if (stream_n != wma->audio_stream_n)
207 {
208 TRACE("data belongs to another audio stream #%ld\n", stream_n);
209 return FALSE;
210 }
211
212 TRACE("Adding audio frame[%ld]: %ld bytes\n",
213 alb->numAudioBlocks, mmck->cksize);
214 if (wma->lpWaveFormat) {
215 if (alb->numAudioBlocks >= alb->numAudioAllocated) {
216 DWORD newsize = alb->numAudioAllocated + 32;
217 struct MMIOPos* newindex;
218
219 newindex = realloc(wma->lpAudioIndex, newsize * sizeof(struct MMIOPos));
220 if (!newindex) return FALSE;
221 alb->numAudioAllocated = newsize;
222 wma->lpAudioIndex = newindex;
223 }
224 wma->lpAudioIndex[alb->numAudioBlocks].dwOffset = mmck->dwDataOffset;
225 wma->lpAudioIndex[alb->numAudioBlocks].dwSize = mmck->cksize;
226 if (alb->inAudioSize < mmck->cksize)
227 alb->inAudioSize = mmck->cksize;
228 alb->numAudioBlocks++;
229 } else {
230 WARN("Wave chunk without wave format... discarding\n");
231 }
232 break;
233 default:
234 WARN("Unknown frame type %4.4s\n", (LPSTR)&mmck->ckid);
235 break;
236 }
237 return TRUE;
238}
#define isxdigit(c)
Definition: acclib.h:70
#define TWOCCFromFOURCC(fcc)
Definition: avisplit.c:49
#define WARN(fmt,...)
Definition: precomp.h:61
#define realloc
Definition: debug_ros.c:6
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
int CDECL tolower(int c)
Definition: ctype.c:572
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:140
DWORD inVideoSize
Definition: mmoutput.c:141
DWORD inAudioSize
Definition: mmoutput.c:142
DWORD numAudioAllocated
Definition: mmoutput.c:139
DWORD numVideoFrames
Definition: mmoutput.c:138
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:1509
DWORD cksize
Definition: mmsystem.h:1510
DWORD dwDataOffset
Definition: mmsystem.h:1512
char * LPSTR
Definition: typedefs.h:51
#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
unsigned char BYTE
Definition: xxhash.c:193

Referenced by MCIAVI_GetInfo().

◆ MCIAVI_GetInfo()

BOOL MCIAVI_GetInfo ( WINE_MCIAVI wma)

Definition at line 240 of file mmoutput.c.

241{
242 MMCKINFO ckMainRIFF;
243 MMCKINFO mmckHead;
244 MMCKINFO mmckList;
245 MMCKINFO mmckInfo;
246 AVIStreamHeader strh;
247 struct AviListBuild alb;
248 DWORD stream_n;
249
250 if (mmioDescend(wma->hFile, &ckMainRIFF, NULL, 0) != 0) {
251 WARN("Can't find 'RIFF' chunk\n");
252 return FALSE;
253 }
254
255 if ((ckMainRIFF.ckid != FOURCC_RIFF) || (ckMainRIFF.fccType != formtypeAVI)) {
256 WARN("Can't find 'AVI ' chunk\n");
257 return FALSE;
258 }
259
260 mmckHead.fccType = listtypeAVIHEADER;
261 if (mmioDescend(wma->hFile, &mmckHead, &ckMainRIFF, MMIO_FINDLIST) != 0) {
262 WARN("Can't find 'hdrl' list\n");
263 return FALSE;
264 }
265
266 mmckInfo.ckid = ckidAVIMAINHDR;
267 if (mmioDescend(wma->hFile, &mmckInfo, &mmckHead, MMIO_FINDCHUNK) != 0) {
268 WARN("Can't find 'avih' chunk\n");
269 return FALSE;
270 }
271
272 mmioRead(wma->hFile, (LPSTR)&wma->mah, sizeof(wma->mah));
273
274 TRACE("mah.dwMicroSecPerFrame=%ld\n", wma->mah.dwMicroSecPerFrame);
275 TRACE("mah.dwMaxBytesPerSec=%ld\n", wma->mah.dwMaxBytesPerSec);
276 TRACE("mah.dwPaddingGranularity=%ld\n", wma->mah.dwPaddingGranularity);
277 TRACE("mah.dwFlags=%ld\n", wma->mah.dwFlags);
278 TRACE("mah.dwTotalFrames=%ld\n", wma->mah.dwTotalFrames);
279 TRACE("mah.dwInitialFrames=%ld\n", wma->mah.dwInitialFrames);
280 TRACE("mah.dwStreams=%ld\n", wma->mah.dwStreams);
281 TRACE("mah.dwSuggestedBufferSize=%ld\n", wma->mah.dwSuggestedBufferSize);
282 TRACE("mah.dwWidth=%ld\n", wma->mah.dwWidth);
283 TRACE("mah.dwHeight=%ld\n", wma->mah.dwHeight);
284
285 mmioAscend(wma->hFile, &mmckInfo, 0);
286
287 TRACE("Start of streams\n");
288 wma->video_stream_n = 0;
289 wma->audio_stream_n = 0;
290
291 for (stream_n = 0; stream_n < wma->mah.dwStreams; stream_n++)
292 {
293 MMCKINFO mmckStream;
294
295 mmckList.fccType = listtypeSTREAMHEADER;
296 if (mmioDescend(wma->hFile, &mmckList, &mmckHead, MMIO_FINDLIST) != 0)
297 break;
298
299 mmckStream.ckid = ckidSTREAMHEADER;
300 if (mmioDescend(wma->hFile, &mmckStream, &mmckList, MMIO_FINDCHUNK) != 0)
301 {
302 WARN("Can't find 'strh' chunk\n");
303 continue;
304 }
305
306 mmioRead(wma->hFile, (LPSTR)&strh, sizeof(strh));
307
308 TRACE("Stream #%ld fccType %4.4s\n", stream_n, (LPSTR)&strh.fccType);
309
310 if (strh.fccType == streamtypeVIDEO)
311 {
312 TRACE("found video stream\n");
313 if (wma->inbih)
314 WARN("ignoring another video stream\n");
315 else
316 {
317 wma->ash_video = strh;
318
319 if (!MCIAVI_GetInfoVideo(wma, &mmckList, &mmckStream))
320 return FALSE;
321 wma->video_stream_n = stream_n;
322 wma->dwSet |= 4;
323 }
324 }
325 else if (strh.fccType == streamtypeAUDIO)
326 {
327 TRACE("found audio stream\n");
328 if (wma->lpWaveFormat)
329 WARN("ignoring another audio stream\n");
330 else
331 {
332 wma->ash_audio = strh;
333
334 if (!MCIAVI_GetInfoAudio(wma, &mmckList, &mmckStream))
335 return FALSE;
336 wma->audio_stream_n = stream_n;
337 wma->dwSet |= 3;
338 }
339 }
340 else
341 TRACE("Unsupported stream type %4.4s\n", (LPSTR)&strh.fccType);
342
343 mmioAscend(wma->hFile, &mmckList, 0);
344 }
345
346 TRACE("End of streams\n");
347
348 mmioAscend(wma->hFile, &mmckHead, 0);
349
350 /* no need to read optional JUNK chunk */
351
352 mmckList.fccType = listtypeAVIMOVIE;
353 if (mmioDescend(wma->hFile, &mmckList, &ckMainRIFF, MMIO_FINDLIST) != 0) {
354 WARN("Can't find 'movi' list\n");
355 return FALSE;
356 }
357
359 wma->lpVideoIndex = calloc(wma->dwPlayableVideoFrames, sizeof(struct MMIOPos));
360 if (!wma->lpVideoIndex) {
361 WARN("Can't alloc video index array\n");
362 return FALSE;
363 }
364 wma->dwPlayableAudioBlocks = 0;
365 wma->lpAudioIndex = NULL;
366
367 alb.numAudioBlocks = alb.numVideoFrames = 0;
368 alb.inVideoSize = alb.inAudioSize = 0;
369 alb.numAudioAllocated = 0;
370
371 while (mmioDescend(wma->hFile, &mmckInfo, &mmckList, 0) == 0) {
372 if (mmckInfo.fccType == listtypeAVIRECORD) {
373 MMCKINFO tmp;
374
375 while (mmioDescend(wma->hFile, &tmp, &mmckInfo, 0) == 0) {
376 MCIAVI_AddFrame(wma, &tmp, &alb);
377 mmioAscend(wma->hFile, &tmp, 0);
378 }
379 } else {
380 MCIAVI_AddFrame(wma, &mmckInfo, &alb);
381 }
382
383 mmioAscend(wma->hFile, &mmckInfo, 0);
384 }
385
386#ifdef __REACTOS__
387 /* Empty file */
388 if (alb.numVideoFrames == 0) {
389 WARN("NumVideoFrames: %u, Empty or possibly corrupt video file");
390 return FALSE;
391 }
392#endif
393
394 if (alb.numVideoFrames != wma->dwPlayableVideoFrames) {
395 WARN("AVI header says %ld frames, we found %ld video frames, reducing playable frames\n",
396 wma->dwPlayableVideoFrames, alb.numVideoFrames);
397 wma->dwPlayableVideoFrames = alb.numVideoFrames;
398 }
399 wma->dwPlayableAudioBlocks = alb.numAudioBlocks;
400
401 if (alb.inVideoSize > wma->ash_video.dwSuggestedBufferSize) {
402 WARN("inVideoSize=%ld suggestedSize=%ld\n", alb.inVideoSize, wma->ash_video.dwSuggestedBufferSize);
403 wma->ash_video.dwSuggestedBufferSize = alb.inVideoSize;
404 }
405 if (alb.inAudioSize > wma->ash_audio.dwSuggestedBufferSize) {
406 WARN("inAudioSize=%ld suggestedSize=%ld\n", alb.inAudioSize, wma->ash_audio.dwSuggestedBufferSize);
407 wma->ash_audio.dwSuggestedBufferSize = alb.inAudioSize;
408 }
409
411 if (!wma->indata) {
412 WARN("Can't alloc input buffer\n");
413 return FALSE;
414 }
415
416 return TRUE;
417}
#define streamtypeAUDIO
Definition: aviriff.h:93
#define streamtypeVIDEO
Definition: aviriff.h:92
#define ckidSTREAMHEADER
Definition: aviriff.h:88
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
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:145
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:82
#define FOURCC_RIFF
Definition: mmsystem.h:564
#define MMIO_FINDCHUNK
Definition: mmsystem.h:551
#define MMIO_FINDLIST
Definition: mmsystem.h:553
#define calloc
Definition: rosglue.h:14
FOURCC fccType
Definition: vfw.h:959
DWORD dwSuggestedBufferSize
Definition: vfw.h:969
AVIStreamHeader ash_audio
DWORD dwPlayableAudioBlocks
MainAVIHeader mah
FOURCC fccType
Definition: mmsystem.h:1511
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=%s\n", debugstr_fourcc(wma->ash_audio.fccType));
32 if (wma->ash_audio.fccHandler) /* not all streams specify a handler */
33 TRACE("ash.fccHandler=%s\n", debugstr_fourcc(wma->ash_audio.fccHandler));
34 else
35 TRACE("ash.fccHandler=0, no handler specified\n");
36 TRACE("ash.dwFlags=%ld\n", wma->ash_audio.dwFlags);
37 TRACE("ash.wPriority=%d\n", wma->ash_audio.wPriority);
38 TRACE("ash.wLanguage=%d\n", wma->ash_audio.wLanguage);
39 TRACE("ash.dwInitialFrames=%ld\n", wma->ash_audio.dwInitialFrames);
40 TRACE("ash.dwScale=%ld\n", wma->ash_audio.dwScale);
41 TRACE("ash.dwRate=%ld\n", wma->ash_audio.dwRate);
42 TRACE("ash.dwStart=%ld\n", wma->ash_audio.dwStart);
43 TRACE("ash.dwLength=%ld\n", wma->ash_audio.dwLength);
44 TRACE("ash.dwSuggestedBufferSize=%ld\n", wma->ash_audio.dwSuggestedBufferSize);
45 TRACE("ash.dwQuality=%ld\n", wma->ash_audio.dwQuality);
46 TRACE("ash.dwSampleSize=%ld\n", wma->ash_audio.dwSampleSize);
47 TRACE("ash.rcFrame=(%d,%d,%d,%d)\n", wma->ash_audio.rcFrame.top, wma->ash_audio.rcFrame.left,
48 wma->ash_audio.rcFrame.bottom, wma->ash_audio.rcFrame.right);
49
50 /* rewind to the start of the stream */
51 mmioAscend(wma->hFile, mmckStream, 0);
52
53 mmckInfo.ckid = ckidSTREAMFORMAT;
54 if (mmioDescend(wma->hFile, &mmckInfo, mmckList, MMIO_FINDCHUNK) != 0) {
55 WARN("Can't find 'strf' chunk\n");
56 return FALSE;
57 }
58 if (mmckInfo.cksize < sizeof(WAVEFORMAT)) {
59 WARN("Size of strf chunk (%ld) < audio format struct\n", mmckInfo.cksize);
60 return FALSE;
61 }
62 wma->lpWaveFormat = malloc(mmckInfo.cksize);
63 if (!wma->lpWaveFormat) {
64 WARN("Can't alloc WaveFormat\n");
65 return FALSE;
66 }
67
68 mmioRead(wma->hFile, (LPSTR)wma->lpWaveFormat, mmckInfo.cksize);
69
70 TRACE("waveFormat.wFormatTag=%d\n", wma->lpWaveFormat->wFormatTag);
71 TRACE("waveFormat.nChannels=%d\n", wma->lpWaveFormat->nChannels);
72 TRACE("waveFormat.nSamplesPerSec=%ld\n", wma->lpWaveFormat->nSamplesPerSec);
73 TRACE("waveFormat.nAvgBytesPerSec=%ld\n", wma->lpWaveFormat->nAvgBytesPerSec);
74 TRACE("waveFormat.nBlockAlign=%d\n", wma->lpWaveFormat->nBlockAlign);
75 TRACE("waveFormat.wBitsPerSample=%d\n", wma->lpWaveFormat->wBitsPerSample);
76 if (mmckInfo.cksize >= sizeof(WAVEFORMATEX))
77 TRACE("waveFormat.cbSize=%d\n", wma->lpWaveFormat->cbSize);
78
79 return TRUE;
80}
#define ckidSTREAMFORMAT
Definition: aviriff.h:125
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
struct AVIStreamHeader::@3683 rcFrame
DWORD dwLength
Definition: vfw.h:968
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

Referenced by MCIAVI_GetInfo().

◆ MCIAVI_GetInfoVideo()

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

Definition at line 82 of file mmoutput.c.

83{
84 MMCKINFO mmckInfo;
85
86 TRACE("ash.fccType=%s\n", debugstr_fourcc(wma->ash_video.fccType));
87 TRACE("ash.fccHandler=%s\n", debugstr_fourcc(wma->ash_video.fccHandler));
88 TRACE("ash.dwFlags=%ld\n", wma->ash_video.dwFlags);
89 TRACE("ash.wPriority=%d\n", wma->ash_video.wPriority);
90 TRACE("ash.wLanguage=%d\n", wma->ash_video.wLanguage);
91 TRACE("ash.dwInitialFrames=%ld\n", wma->ash_video.dwInitialFrames);
92 TRACE("ash.dwScale=%ld\n", wma->ash_video.dwScale);
93 TRACE("ash.dwRate=%ld\n", wma->ash_video.dwRate);
94 TRACE("ash.dwStart=%ld\n", wma->ash_video.dwStart);
95 TRACE("ash.dwLength=%ld\n", wma->ash_video.dwLength);
96 TRACE("ash.dwSuggestedBufferSize=%ld\n", wma->ash_video.dwSuggestedBufferSize);
97 TRACE("ash.dwQuality=%ld\n", wma->ash_video.dwQuality);
98 TRACE("ash.dwSampleSize=%ld\n", wma->ash_video.dwSampleSize);
99 TRACE("ash.rcFrame=(%d,%d,%d,%d)\n", wma->ash_video.rcFrame.top, wma->ash_video.rcFrame.left,
100 wma->ash_video.rcFrame.bottom, wma->ash_video.rcFrame.right);
101
102 /* rewind to the start of the stream */
103 mmioAscend(wma->hFile, mmckStream, 0);
104
105 mmckInfo.ckid = ckidSTREAMFORMAT;
106 if (mmioDescend(wma->hFile, &mmckInfo, mmckList, MMIO_FINDCHUNK) != 0) {
107 WARN("Can't find 'strf' chunk\n");
108 return FALSE;
109 }
110
111 wma->inbih = malloc(mmckInfo.cksize);
112 if (!wma->inbih) {
113 WARN("Can't alloc input BIH\n");
114 return FALSE;
115 }
116
117 mmioRead(wma->hFile, (LPSTR)wma->inbih, mmckInfo.cksize);
118
119 TRACE("bih.biSize=%ld\n", wma->inbih->biSize);
120 TRACE("bih.biWidth=%ld\n", wma->inbih->biWidth);
121 TRACE("bih.biHeight=%ld\n", wma->inbih->biHeight);
122 TRACE("bih.biPlanes=%d\n", wma->inbih->biPlanes);
123 TRACE("bih.biBitCount=%d\n", wma->inbih->biBitCount);
124 TRACE("bih.biCompression=%lx\n", wma->inbih->biCompression);
125 TRACE("bih.biSizeImage=%ld\n", wma->inbih->biSizeImage);
126 TRACE("bih.biXPelsPerMeter=%ld\n", wma->inbih->biXPelsPerMeter);
127 TRACE("bih.biYPelsPerMeter=%ld\n", wma->inbih->biYPelsPerMeter);
128 TRACE("bih.biClrUsed=%ld\n", wma->inbih->biClrUsed);
129 TRACE("bih.biClrImportant=%ld\n", wma->inbih->biClrImportant);
130
131 SetRect(&wma->source, 0, 0, wma->inbih->biWidth, wma->inbih->biHeight);
132 wma->dest = wma->source;
133
134 return TRUE;
135}
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 526 of file mmoutput.c.

527{
528 DWORD dwRet;
529 LPWAVEHDR waveHdr;
530 unsigned i;
531
532 dwRet = waveOutOpen((HWAVEOUT *)&wma->hWave, WAVE_MAPPER, wma->lpWaveFormat,
534 if (dwRet != 0) {
535 TRACE("Can't open low level audio device %ld\n", dwRet);
536 dwRet = MCIERR_DEVICE_OPEN;
537 wma->hWave = 0;
538 goto cleanUp;
539 }
540
541 /* FIXME: should set up a heuristic to compute the number of wave headers
542 * to be used...
543 */
544 *nHdr = 7;
545 waveHdr = calloc(*nHdr, sizeof(WAVEHDR) + wma->ash_audio.dwSuggestedBufferSize);
546 if (!waveHdr) {
547 TRACE("Can't alloc wave headers\n");
548 dwRet = MCIERR_DEVICE_OPEN;
549 goto cleanUp;
550 }
551
552 for (i = 0; i < *nHdr; i++) {
553 /* other fields are zero:ed on allocation */
554 waveHdr[i].lpData = (char*)waveHdr +
555 *nHdr * sizeof(WAVEHDR) + i * wma->ash_audio.dwSuggestedBufferSize;
557 if (waveOutPrepareHeader(wma->hWave, &waveHdr[i], sizeof(WAVEHDR))) {
558 dwRet = MCIERR_INTERNAL;
559 goto cleanUp;
560 }
561 }
562
563 if (wma->dwCurrVideoFrame != 0 && wma->lpWaveFormat) {
564 FIXME("Should recompute dwCurrAudioBlock, except unsynchronized sound & video\n");
565 }
566 wma->dwCurrAudioBlock = 0;
567
569 wma->dwEventCount = *nHdr - 1;
570 *pWaveHdr = waveHdr;
571 cleanUp:
572 return dwRet;
573}
#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:501
#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:1017
LPSTR lpData
Definition: mmsystem.h:1016
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:587
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 419 of file mmoutput.c.

420{
421 HDC hDC;
422 DWORD outSize;
423 FOURCC fcc = wma->ash_video.fccHandler;
424
425 TRACE("fcc %4.4s\n", (LPSTR)&fcc);
426
427 wma->dwCachedFrame = -1;
428
429 /* get the right handle */
430 if (fcc == mmioFOURCC('C','R','A','M')) fcc = mmioFOURCC('M','S','V','C');
431
432 /* try to get a decompressor for that type */
434 if (!wma->hic) {
435 /* check for builtin DIB compressions */
436 fcc = wma->inbih->biCompression;
437 if ((fcc == mmioFOURCC('D','I','B',' ')) ||
438 (fcc == mmioFOURCC('R','L','E',' ')) ||
439 (fcc == BI_RGB) || (fcc == BI_RLE8) ||
440 (fcc == BI_RLE4) || (fcc == BI_BITFIELDS))
441 goto paint_frame;
442
443 WARN("Can't locate codec for the file\n");
444 return FALSE;
445 }
446
447 outSize = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD);
448
449 wma->outbih = malloc(outSize);
450 if (!wma->outbih) {
451 WARN("Can't alloc output BIH\n");
452 return FALSE;
453 }
454 if (!ICGetDisplayFormat(wma->hic, wma->inbih, wma->outbih, 0, 0, 0)) {
455 WARN("Can't open decompressor\n");
456 return FALSE;
457 }
458
459 TRACE("bih.biSize=%ld\n", wma->outbih->biSize);
460 TRACE("bih.biWidth=%ld\n", wma->outbih->biWidth);
461 TRACE("bih.biHeight=%ld\n", wma->outbih->biHeight);
462 TRACE("bih.biPlanes=%d\n", wma->outbih->biPlanes);
463 TRACE("bih.biBitCount=%d\n", wma->outbih->biBitCount);
464 TRACE("bih.biCompression=%lx\n", wma->outbih->biCompression);
465 TRACE("bih.biSizeImage=%ld\n", wma->outbih->biSizeImage);
466 TRACE("bih.biXPelsPerMeter=%ld\n", wma->outbih->biXPelsPerMeter);
467 TRACE("bih.biYPelsPerMeter=%ld\n", wma->outbih->biYPelsPerMeter);
468 TRACE("bih.biClrUsed=%ld\n", wma->outbih->biClrUsed);
469 TRACE("bih.biClrImportant=%ld\n", wma->outbih->biClrImportant);
470
471 wma->outdata = malloc(wma->outbih->biSizeImage);
472 if (!wma->outdata) {
473 WARN("Can't alloc output buffer\n");
474 return FALSE;
475 }
476
478 (DWORD_PTR)wma->inbih, (DWORD_PTR)wma->outbih) != ICERR_OK) {
479 WARN("Can't begin decompression\n");
480 return FALSE;
481 }
482
483paint_frame:
484 if (!(wma->hdd = DrawDibOpen()))
485 {
486 ERR("DrawDibOpen() failed.\n");
487 free(wma->outdata);
488 wma->outdata = NULL;
489 return FALSE;
490 }
491
492 hDC = wma->hWndPaint ? GetDC(wma->hWndPaint) : 0;
493 if (hDC)
494 {
496 ReleaseDC(wma->hWndPaint, hDC);
497 }
498 return TRUE;
499}
static HDC hDC
Definition: 3dtext.c:33
#define ERR(fmt,...)
Definition: precomp.h:57
#define free
Definition: debug_ros.c:5
HDRAWDIB VFWAPI DrawDibOpen(void)
Definition: drawdib.c:80
DWORD FOURCC
Definition: dmdls.h:25
#define BI_RLE4
Definition: precomp.h:45
ULONG RGBQUAD
Definition: precomp.h:47
double MCIAVI_PaintFrame(WINE_MCIAVI *wma, HDC hDC)
Definition: mmoutput.c:604
#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
HDRAWDIB hdd
#define BI_RGB
Definition: uefivid.c:46
#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 604 of file mmoutput.c.

605{
606 void* pBitmapData;
607 LPBITMAPINFO pBitmapInfo;
608 DWORD frame;
609
610 if (!hDC || !wma->inbih)
611 return 0;
612
614 frame = wma->dwPlayableVideoFrames - 1;
615 else
616 frame = wma->dwCurrVideoFrame;
617
618 TRACE("Painting frame %lu (cached %lu)\n", frame, wma->dwCachedFrame);
619
620 if (frame != wma->dwCachedFrame)
621 {
622#ifdef __REACTOS__
623 if (wma->dwCurrVideoFrame >= wma->dwPlayableVideoFrames) {
624 ERR("Invalid frame requested. Current : %u Total Playable %u\n", wma->dwCurrVideoFrame, wma->dwPlayableVideoFrames);
625 return 0;
626 }
627#endif
628 if (!wma->lpVideoIndex[frame].dwOffset)
629 return 0;
630
631 if (wma->lpVideoIndex[frame].dwSize)
632 {
633 mmioSeek(wma->hFile, wma->lpVideoIndex[frame].dwOffset, SEEK_SET);
634 mmioRead(wma->hFile, wma->indata, wma->lpVideoIndex[frame].dwSize);
635
636 wma->inbih->biSizeImage = wma->lpVideoIndex[frame].dwSize;
637
638 if (wma->hic && ICDecompress(wma->hic, 0, wma->inbih, wma->indata,
639 wma->outbih, wma->outdata) != ICERR_OK)
640 {
641 WARN("Decompression error\n");
642 return 0;
643 }
644 }
645
646 wma->dwCachedFrame = frame;
647 }
648
649 if (wma->hic) {
650 pBitmapData = wma->outdata;
651 pBitmapInfo = (LPBITMAPINFO)wma->outbih;
652 } else {
653 pBitmapData = wma->indata;
654 pBitmapInfo = (LPBITMAPINFO)wma->inbih;
655 }
656
657 DrawDibDraw(wma->hdd, hDC, wma->dest.left, wma->dest.top, wma->dest.right - wma->dest.left, wma->dest.bottom - wma->dest.top,
658 &pBitmapInfo->bmiHeader, pBitmapData,
659 wma->source.left, wma->source.top, wma->source.right - wma->source.left, wma->source.bottom - wma->source.top, 0);
660
661 return (wma->ash_video.dwScale / (double)wma->ash_video.dwRate) * 1000000;
662}
BOOL VFWAPI DrawDibDraw(HDRAWDIB hdd, HDC hdc, INT xDst, INT yDst, INT dxDst, INT dyDst, LPBITMAPINFOHEADER lpbi, LPVOID lpBits, INT xSrc, INT ySrc, INT dxSrc, INT dySrc, UINT wFlags)
Definition: drawdib.c:308
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
BITMAPINFOHEADER bmiHeader
Definition: wingdi.h:1922
LONG right
Definition: windef.h:108
LONG bottom
Definition: windef.h:109
LONG top
Definition: windef.h:107
LONG left
Definition: windef.h:106
struct tagBITMAPINFO * LPBITMAPINFO

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 575 of file mmoutput.c.

576{
577 if (!wma->lpAudioIndex)
578 return;
579 TRACE("%ld (ec=%lu)\n", wma->lpAudioIndex[wma->dwCurrAudioBlock].dwOffset, wma->dwEventCount);
580
581 /* push as many blocks as possible => audio gets priority */
582 while (wma->dwStatus != MCI_MODE_STOP && wma->dwStatus != MCI_MODE_NOT_READY &&
584 unsigned whidx = wma->dwCurrAudioBlock % nHdr;
585
586 ResetEvent(wma->hEvent);
587 if (InterlockedDecrement(&wma->dwEventCount) < 0 ||
588 !wma->lpAudioIndex[wma->dwCurrAudioBlock].dwOffset)
589 {
591 break;
592 }
593
594 mmioSeek(wma->hFile, wma->lpAudioIndex[wma->dwCurrAudioBlock].dwOffset, SEEK_SET);
595 mmioRead(wma->hFile, waveHdr[whidx].lpData, wma->lpAudioIndex[wma->dwCurrAudioBlock].dwSize);
596
597 waveHdr[whidx].dwFlags &= ~WHDR_DONE;
598 waveHdr[whidx].dwBufferLength = wma->lpAudioIndex[wma->dwCurrAudioBlock].dwSize;
599 waveOutWrite(wma->hWave, &waveHdr[whidx], sizeof(WAVEHDR));
600 wma->dwCurrAudioBlock++;
601 }
602}
#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:1020
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:650
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 501 of file mmoutput.c.

503{
504 WINE_MCIAVI *wma = MCIAVI_mciGetOpenDev(dwInstance);
505
506 if (!wma) return;
507
509
510 switch (uMsg) {
511 case WOM_OPEN:
512 case WOM_CLOSE:
513 break;
514 case WOM_DONE:
516 TRACE("Returning waveHdr=%Ix\n", dwParam1);
517 SetEvent(wma->hEvent);
518 break;
519 default:
520 ERR("Unknown uMsg=%d\n", uMsg);
521 }
522
524}
WINE_MCIAVI * MCIAVI_mciGetOpenDev(UINT wDevID)
Definition: mciavi.c:156
#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:669
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)

Referenced by MCIAVI_OpenAudio().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( mciavi  )