2 * Very simple AVIPLAYER
4 * Copyright 1999 Marcus Meissner
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * - plays .avi streams, video only
22 * - requires Microsoft avifil32.dll and builtin msvfw32.dll.
25 * - audio support (including synchronization etc)
26 * - replace DirectDraw by a 'normal' window, including dithering, controls
30 * - no time scheduling, video plays too fast using DirectDraw/XF86DGA
31 * - requires DirectDraw with all disadvantages.
39 #define NONAMELESSUNION
40 #define NONAMELESSSTRUCT
48 int PASCAL
WinMain(HINSTANCE hInstance
, HINSTANCE prev
, LPSTR cmdline
, int show
)
50 int bytesline
,i
,n
,pos
;
53 BITMAPINFOHEADER
*bmi
;
56 PAVISTREAM vids
=NULL
,auds
=NULL
;
59 PGETFRAME vidgetframe
=NULL
;
62 LPDIRECTDRAWSURFACE dsurf
;
63 LPDIRECTDRAWPALETTE dpal
;
64 PALETTEENTRY palent
[256];
67 if (GetFileAttributes(cmdline
) == INVALID_FILE_ATTRIBUTES
) {
68 fprintf(stderr
,"Usage: aviplay <avifilename>\n");
71 hres
= AVIFileOpen(&avif
,cmdline
,OF_READ
,NULL
);
73 fprintf(stderr
,"AVIFileOpen: 0x%08lx\n",hres
);
76 hres
= AVIFileInfo(avif
,&afi
,sizeof(afi
));
78 fprintf(stderr
,"AVIFileInfo: 0x%08lx\n",hres
);
81 for (n
=0;n
<afi
.dwStreams
;n
++) {
85 hres
= AVIFileGetStream(avif
,&ast
,0,n
);
87 fprintf(stderr
,"AVIFileGetStream %d: 0x%08lx\n",n
,hres
);
90 hres
= AVIStreamInfo(ast
,&asi
,sizeof(asi
));
92 fprintf(stderr
,"AVIStreamInfo %d: 0x%08lx\n",n
,hres
);
95 fprintf(stderr
,"[Stream %d: ",n
);
96 buf
[4]='\0';memcpy(buf
,&(asi
.fccType
),4);
97 fprintf(stderr
,"%s.",buf
);
98 buf
[4]='\0';memcpy(buf
,&(asi
.fccHandler
),4);
99 fprintf(stderr
,"%s, %s]\n",buf
,asi
.szName
);
100 switch (asi
.fccType
) {
101 case streamtypeVIDEO
:
104 case streamtypeAUDIO
:
109 type
[4]='\0';memcpy(type
,&(asi
.fccType
),4);
111 fprintf(stderr
,"Unhandled streamtype %s\n",type
);
112 AVIStreamRelease(ast
);
117 /********************* begin video setup ***********************************/
119 fprintf(stderr
,"No video stream found. Good Bye.\n");
122 cnt
= sizeof(BITMAPINFOHEADER
)+256*sizeof(RGBQUAD
);
123 bmi
= HeapAlloc(GetProcessHeap(),0,cnt
);
124 hres
= AVIStreamReadFormat(vids
,0,bmi
,&cnt
);
126 fprintf(stderr
,"AVIStreamReadFormat vids: 0x%08lx\n",hres
);
130 bmi
->biCompression
= 0; /* we want it in raw form, uncompressed */
131 /* recalculate the image size */
132 bmi
->biSizeImage
= ((bmi
->biWidth
*bmi
->biBitCount
+31)&~0x1f)*bmi
->biPlanes
*bmi
->biHeight
/8;
133 bytesline
= ((bmi
->biWidth
*bmi
->biBitCount
+31)&~0x1f)*bmi
->biPlanes
/8;
134 vidgetframe
= AVIStreamGetFrameOpen(vids
,bmi
);
136 fprintf(stderr
,"AVIStreamGetFrameOpen: failed\n");
139 /********************* end video setup ***********************************/
141 /********************* begin display setup *******************************/
142 hres
= DirectDrawCreate(NULL
,&ddraw
,NULL
);
144 fprintf(stderr
,"DirectDrawCreate: 0x%08lx\n",hres
);
147 hres
= IDirectDraw_SetDisplayMode(ddraw
,bmi
->biWidth
,bmi
->biHeight
,bmi
->biBitCount
);
149 fprintf(stderr
,"ddraw.SetDisplayMode: 0x%08lx (change resolution!)\n",hres
);
152 dsdesc
.dwSize
=sizeof(dsdesc
);
153 dsdesc
.dwFlags
= DDSD_CAPS
;
154 dsdesc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
155 hres
= IDirectDraw_CreateSurface(ddraw
,&dsdesc
,&dsurf
,NULL
);
157 fprintf(stderr
,"ddraw.CreateSurface: 0x%08lx\n",hres
);
160 if (bmi
->biBitCount
==8) {
161 RGBQUAD
*rgb
= (RGBQUAD
*)(bmi
+1);
164 hres
= IDirectDraw_CreatePalette(ddraw
,DDPCAPS_8BIT
,NULL
,&dpal
,NULL
);
166 fprintf(stderr
,"ddraw.CreateSurface: 0x%08lx\n",hres
);
169 IDirectDrawSurface_SetPalette(dsurf
,dpal
);
170 for (i
=0;i
<bmi
->biClrUsed
;i
++) {
171 palent
[i
].peRed
= rgb
[i
].rgbRed
;
172 palent
[i
].peBlue
= rgb
[i
].rgbBlue
;
173 palent
[i
].peGreen
= rgb
[i
].rgbGreen
;
175 IDirectDrawPalette_SetEntries(dpal
,0,0,bmi
->biClrUsed
,palent
);
178 /********************* end display setup *******************************/
184 LPBITMAPINFOHEADER lpbmi
;
188 if (!(decodedframe
=AVIStreamGetFrame(vidgetframe
,pos
++)))
190 lpbmi
= (LPBITMAPINFOHEADER
)decodedframe
;
191 decodedbits
= (LPVOID
)(((DWORD
)decodedframe
)+lpbmi
->biSize
);
192 if (lpbmi
->biBitCount
== 8) {
193 /* can't detect palette change that way I think */
194 RGBQUAD
*rgb
= (RGBQUAD
*)(lpbmi
+1);
197 /* skip used colorentries. */
198 decodedbits
=(char*)decodedbits
+bmi
->biClrUsed
*sizeof(RGBQUAD
);
200 for (i
=0;i
<bmi
->biClrUsed
;i
++) {
201 if ( (palent
[i
].peRed
!= rgb
[i
].rgbRed
) ||
202 (palent
[i
].peBlue
!= rgb
[i
].rgbBlue
) ||
203 (palent
[i
].peGreen
!= rgb
[i
].rgbGreen
)
210 for (i
=0;i
<bmi
->biClrUsed
;i
++) {
211 palent
[i
].peRed
= rgb
[i
].rgbRed
;
212 palent
[i
].peBlue
= rgb
[i
].rgbBlue
;
213 palent
[i
].peGreen
= rgb
[i
].rgbGreen
;
215 IDirectDrawPalette_SetEntries(dpal
,0,0,bmi
->biClrUsed
,palent
);
218 dsdesc
.dwSize
= sizeof(dsdesc
);
219 hres
= IDirectDrawSurface_Lock(dsurf
,NULL
,&dsdesc
,DDLOCK_WRITEONLY
,0);
221 fprintf(stderr
,"dsurf.Lock: 0x%08lx\n",hres
);
224 /* Argh. AVIs are upside down. */
225 for (i
=0;i
<dsdesc
.dwHeight
;i
++) {
226 memcpy( (char *)dsdesc
.lpSurface
+(i
*dsdesc
.u1
.lPitch
),
227 (char *)decodedbits
+bytesline
*(dsdesc
.dwHeight
-i
-1),
231 IDirectDrawSurface_Unlock(dsurf
,dsdesc
.lpSurface
);
234 AVIStreamGetFrameClose(vidgetframe
);
236 IDirectDrawSurface_Release(dsurf
);
237 IDirectDraw_RestoreDisplayMode(ddraw
);
238 IDirectDraw_Release(ddraw
);
239 if (vids
) AVIStreamRelease(vids
);
240 if (auds
) AVIStreamRelease(auds
);
241 fprintf(stderr
,"%d frames at %g frames/s\n",pos
,pos
*1.0/(tend
-tstart
));
242 AVIFileRelease(avif
);