Started implementation of the functions GetDefaultCommConfigA/W.
[wine.git] / programs / avitools / aviplay.c
blob0e7011eae1e43e9992df4e50243b8c3af22064d2
1 /*
2 * Very simple AVIPLAYER
3 *
4 * Copyright 1999 Marcus Meissner
5 *
6 * Status:
7 * - plays .avi streams, video only
8 * - requires MicroSoft avifil32.dll and builtin msvfw32.dll.
10 * Todo:
11 * - audio support (including synchronization etc)
12 * - replace DirectDraw by a 'normal' window, including dithering, controls
13 * etc.
15 * Bugs:
16 * - no time scheduling, video plays too fast using DirectDraw/XF86DGA
17 * - requires DirectDraw with all disadvantages.
20 #include <stdio.h>
21 #include <time.h>
22 #include <assert.h>
23 #include <string.h>
24 #include "windows.h"
25 #include "wingdi.h"
26 #include "mmsystem.h"
27 #include "ddraw.h"
28 #include "vfw.h"
31 int PASCAL WinMain (HANDLE hInstance, HANDLE prev, LPSTR cmdline, int show)
33 int bytesline,i,n,pos;
34 time_t tstart,tend;
35 LONG cnt;
36 BITMAPINFOHEADER *bmi;
37 HRESULT hres;
38 HMODULE avifil32 = LoadLibrary("avifil32.dll");
39 PAVIFILE avif;
40 PAVISTREAM vids=NULL,auds=NULL;
41 AVIFILEINFO afi;
42 AVISTREAMINFO asi;
43 PGETFRAME vidgetframe=NULL;
44 LPDIRECTDRAW ddraw;
45 DDSURFACEDESC dsdesc;
46 LPDIRECTDRAWSURFACE dsurf;
47 LPDIRECTDRAWPALETTE dpal;
48 PALETTEENTRY palent[256];
51 void (WINAPI *fnAVIFileInit)(void);
52 void (WINAPI *fnAVIFileExit)(void);
53 ULONG (WINAPI *fnAVIFileRelease)(PAVIFILE);
54 ULONG (WINAPI *fnAVIStreamRelease)(PAVISTREAM);
55 HRESULT (WINAPI *fnAVIFileOpen)(PAVIFILE * ppfile,LPCTSTR szFile,UINT uMode,LPCLSID lpHandler);
56 HRESULT (WINAPI *fnAVIFileInfo)(PAVIFILE ppfile,AVIFILEINFO *afi,LONG size);
57 HRESULT (WINAPI *fnAVIFileGetStream)(PAVIFILE ppfile,PAVISTREAM *afi,DWORD fccType,LONG lParam);
58 HRESULT (WINAPI *fnAVIStreamInfo)(PAVISTREAM iface,AVISTREAMINFO *afi,LONG size);
59 HRESULT (WINAPI *fnAVIStreamReadFormat)(PAVISTREAM iface,LONG pos,LPVOID format,LPLONG size);
60 PGETFRAME (WINAPI *fnAVIStreamGetFrameOpen)(PAVISTREAM iface,LPBITMAPINFOHEADER wanted);
61 LPVOID (WINAPI *fnAVIStreamGetFrame)(PGETFRAME pg,LONG pos);
62 HRESULT (WINAPI *fnAVIStreamGetFrameClose)(PGETFRAME pg);
64 #define XX(x) fn##x = (void*)GetProcAddress(avifil32,#x);assert(fn##x);
65 #ifdef UNICODE
66 # define XXT(x) fn##x = (void*)GetProcAddress(avifil32,#x##"W");assert(fn##x);
67 #else
68 # define XXT(x) fn##x = (void*)GetProcAddress(avifil32,#x##"A");assert(fn##x);
69 #endif
70 /* non character dependend routines: */
71 XX (AVIFileInit);
72 XX (AVIFileExit);
73 XX (AVIFileRelease);
74 XX (AVIFileGetStream);
75 XX (AVIStreamRelease);
76 XX (AVIStreamReadFormat);
77 XX (AVIStreamGetFrameOpen);
78 XX (AVIStreamGetFrame);
79 XX (AVIStreamGetFrameClose);
80 /* A/W routines: */
81 XXT(AVIFileOpen);
82 XXT(AVIFileInfo);
83 XXT(AVIStreamInfo);
84 #undef XX
85 #undef XXT
88 fnAVIFileInit();
89 if (-1==GetFileAttributes(cmdline)) {
90 fprintf(stderr,"Usage: aviplay <avifilename>\n");
91 exit(1);
93 hres = fnAVIFileOpen(&avif,cmdline,OF_READ,NULL);
94 if (hres) {
95 fprintf(stderr,"AVIFileOpen: 0x%08lx\n",hres);
96 exit(1);
98 hres = fnAVIFileInfo(avif,&afi,sizeof(afi));
99 if (hres) {
100 fprintf(stderr,"AVIFileInfo: 0x%08lx\n",hres);
101 exit(1);
103 for (n=0;n<afi.dwStreams;n++) {
104 char buf[5];
105 PAVISTREAM ast;
107 hres = fnAVIFileGetStream(avif,&ast,0,n);
108 if (hres) {
109 fprintf(stderr,"AVIFileGetStream %d: 0x%08lx\n",n,hres);
110 exit(1);
112 hres = fnAVIStreamInfo(ast,&asi,sizeof(asi));
113 if (hres) {
114 fprintf(stderr,"AVIStreamInfo %d: 0x%08lx\n",n,hres);
115 exit(1);
117 fprintf(stderr,"[Stream %d: ",n);
118 buf[4]='\0';memcpy(buf,&(asi.fccType),4);
119 fprintf(stderr,"%s.",buf);
120 buf[4]='\0';memcpy(buf,&(asi.fccHandler),4);
121 fprintf(stderr,"%s, %s]\n",buf,asi.szName);
122 switch (asi.fccType) {
123 case streamtypeVIDEO:
124 vids = ast;
125 break;
126 case streamtypeAUDIO:
127 auds = ast;
128 break;
129 default: {
130 char type[5];
131 type[4]='\0';memcpy(type,&(asi.fccType),4);
133 fprintf(stderr,"Unhandled streamtype %s\n",type);
134 fnAVIStreamRelease(ast);
135 break;
139 /********************* begin video setup ***********************************/
140 if (!vids) {
141 fprintf(stderr,"No video stream found. Good Bye.\n");
142 exit(0);
144 cnt = sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD);
145 bmi = HeapAlloc(GetProcessHeap(),0,cnt);
146 hres = fnAVIStreamReadFormat(vids,0,bmi,&cnt);
147 if (hres) {
148 fprintf(stderr,"AVIStreamReadFormat vids: 0x%08lx\n",hres);
149 exit(1);
151 vidgetframe = NULL;
152 bmi->biCompression = 0; /* we want it in raw form, uncompressed */
153 /* recalculate the image size */
154 bmi->biSizeImage = ((bmi->biWidth*bmi->biBitCount+31)&~0x1f)*bmi->biPlanes*bmi->biHeight/8;
155 bytesline = ((bmi->biWidth*bmi->biBitCount+31)&~0x1f)*bmi->biPlanes/8;
156 vidgetframe = fnAVIStreamGetFrameOpen(vids,bmi);
157 if (!vidgetframe) {
158 fprintf(stderr,"AVIStreamGetFrameOpen: failed\n");
159 exit(1);
161 /********************* end video setup ***********************************/
163 /********************* begin display setup *******************************/
164 hres = DirectDrawCreate(NULL,&ddraw,NULL);
165 if (hres) {
166 fprintf(stderr,"DirectDrawCreate: 0x%08lx\n",hres);
167 exit(1);
169 hres = IDirectDraw_SetDisplayMode(ddraw,bmi->biWidth,bmi->biHeight,bmi->biBitCount);
170 if (hres) {
171 fprintf(stderr,"ddraw.SetDisplayMode: 0x%08lx (change resolution!)\n",hres);
172 exit(1);
174 dsdesc.dwSize=sizeof(dsdesc);
175 dsdesc.dwFlags = DDSD_CAPS;
176 dsdesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
177 hres = IDirectDraw_CreateSurface(ddraw,&dsdesc,&dsurf,NULL);
178 if (hres) {
179 fprintf(stderr,"ddraw.CreateSurface: 0x%08lx\n",hres);
180 exit(1);
182 if (bmi->biBitCount==8) {
183 RGBQUAD *rgb = (RGBQUAD*)(bmi+1);
184 int i;
186 hres = IDirectDraw_CreatePalette(ddraw,DDPCAPS_8BIT,NULL,&dpal,NULL);
187 if (hres) {
188 fprintf(stderr,"ddraw.CreateSurface: 0x%08lx\n",hres);
189 exit(1);
191 IDirectDrawSurface_SetPalette(dsurf,dpal);
192 for (i=0;i<bmi->biClrUsed;i++) {
193 palent[i].peRed = rgb[i].rgbRed;
194 palent[i].peBlue = rgb[i].rgbBlue;
195 palent[i].peGreen = rgb[i].rgbGreen;
197 IDirectDrawPalette_SetEntries(dpal,0,0,bmi->biClrUsed,palent);
198 } else
199 dpal = NULL;
200 /********************* end display setup *******************************/
202 tstart = time(NULL);
203 pos = 0;
204 while (1) {
205 LPVOID decodedframe;
206 LPBITMAPINFOHEADER lpbmi;
207 LPVOID decodedbits;
209 /* video stuff */
210 if (!(decodedframe=fnAVIStreamGetFrame(vidgetframe,pos++)))
211 break;
212 lpbmi = (LPBITMAPINFOHEADER)decodedframe;
213 decodedbits = (LPVOID)(((DWORD)decodedframe)+lpbmi->biSize);
214 if (lpbmi->biBitCount == 8) {
215 /* cant detect palette change that way I think */
216 RGBQUAD *rgb = (RGBQUAD*)(lpbmi+1);
217 int i,palchanged;
219 /* skip used colorentries. */
220 decodedbits=(char*)decodedbits+bmi->biClrUsed*sizeof(RGBQUAD);
221 palchanged = 0;
222 for (i=0;i<bmi->biClrUsed;i++) {
223 if ( (palent[i].peRed != rgb[i].rgbRed) ||
224 (palent[i].peBlue != rgb[i].rgbBlue) ||
225 (palent[i].peGreen != rgb[i].rgbGreen)
227 palchanged = 1;
228 break;
231 if (palchanged) {
232 for (i=0;i<bmi->biClrUsed;i++) {
233 palent[i].peRed = rgb[i].rgbRed;
234 palent[i].peBlue = rgb[i].rgbBlue;
235 palent[i].peGreen = rgb[i].rgbGreen;
237 IDirectDrawPalette_SetEntries(dpal,0,0,bmi->biClrUsed,palent);
240 dsdesc.dwSize = sizeof(dsdesc);
241 hres = IDirectDrawSurface_Lock(dsurf,NULL,&dsdesc,DDLOCK_WRITEONLY,0);
242 if (hres) {
243 fprintf(stderr,"dsurf.Lock: 0x%08lx\n",hres);
244 exit(1);
246 /* Argh. AVIs are upside down. */
247 for (i=0;i<dsdesc.dwHeight;i++) {
248 memcpy( (char *)dsdesc.u1.lpSurface+(i*dsdesc.lPitch),
249 (char *)decodedbits+bytesline*(dsdesc.dwHeight-i-1),
250 bytesline
253 IDirectDrawSurface_Unlock(dsurf,dsdesc.u1.lpSurface);
255 tend = time(NULL);
256 fnAVIStreamGetFrameClose(vidgetframe);
258 IDirectDrawSurface_Release(dsurf);
259 IDirectDraw_RestoreDisplayMode(ddraw);
260 IDirectDraw_Release(ddraw);
261 if (vids) fnAVIStreamRelease(vids);
262 if (auds) fnAVIStreamRelease(auds);
263 fprintf(stderr,"%d frames at %g frames/s\n",pos,pos*1.0/(tend-tstart));
264 fnAVIFileRelease(avif);
265 fnAVIFileExit();
266 return 0;