/*
 * Very simple AVIPLAYER
 *
 * Copyright 1999 Marcus Meissner
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Status:
 * 	- plays .avi streams, video only
 *	- requires Microsoft avifil32.dll and builtin msvfw32.dll.
 *
 * Todo:
 *	- audio support (including synchronization etc)
 *	- replace DirectDraw by a 'normal' window, including dithering, controls
 *	  etc.
 *
 * Bugs:
 *	- no time scheduling, video plays too fast using DirectDraw/XF86DGA
 *	- requires DirectDraw with all disadvantages.
 */

#include <stdio.h>
#include <time.h>
#include <assert.h>
#include <string.h>

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windows.h"
#include "wingdi.h"
#include "mmsystem.h"
#include "ddraw.h"
#include "vfw.h"


int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show)
{
    int			bytesline,i,n,pos;
    time_t		tstart,tend;
    LONG		cnt;
    BITMAPINFOHEADER	*bmi;
    HRESULT		hres;
    PAVIFILE		avif;
    PAVISTREAM		vids=NULL,auds=NULL;
    AVIFILEINFO		afi;
    AVISTREAMINFO	asi;
    PGETFRAME		vidgetframe=NULL;
    LPDIRECTDRAW	ddraw;
    DDSURFACEDESC	dsdesc;
    LPDIRECTDRAWSURFACE dsurf;
    LPDIRECTDRAWPALETTE dpal;
    PALETTEENTRY	palent[256];

    AVIFileInit();
    if (GetFileAttributes(cmdline) == INVALID_FILE_ATTRIBUTES) {
    	fprintf(stderr,"Usage: aviplay <avifilename>\n");
	exit(1);
    }
    hres = AVIFileOpen(&avif,cmdline,OF_READ,NULL);
    if (hres) {
    	fprintf(stderr,"AVIFileOpen: 0x%08lx\n",hres);
	exit(1);
    }
    hres = AVIFileInfo(avif,&afi,sizeof(afi));
    if (hres) {
    	fprintf(stderr,"AVIFileInfo: 0x%08lx\n",hres);
	exit(1);
    }
    for (n=0;n<afi.dwStreams;n++) {
    	    char buf[5];
	    PAVISTREAM	ast;

	    hres = AVIFileGetStream(avif,&ast,0,n);
	    if (hres) {
		fprintf(stderr,"AVIFileGetStream %d: 0x%08lx\n",n,hres);
		exit(1);
	    }
	    hres = AVIStreamInfo(ast,&asi,sizeof(asi));
	    if (hres) {
		fprintf(stderr,"AVIStreamInfo %d: 0x%08lx\n",n,hres);
		exit(1);
	    }
	    fprintf(stderr,"[Stream %d: ",n);
	    buf[4]='\0';memcpy(buf,&(asi.fccType),4);
	    fprintf(stderr,"%s.",buf);
	    buf[4]='\0';memcpy(buf,&(asi.fccHandler),4);
	    fprintf(stderr,"%s, %s]\n",buf,asi.szName);
	    switch (asi.fccType) {
	    case streamtypeVIDEO:
	    	vids = ast;
		break;
	    case streamtypeAUDIO:
	    	auds = ast;
		break;
	    default:  {
	    	char type[5];
		type[4]='\0';memcpy(type,&(asi.fccType),4);

	    	fprintf(stderr,"Unhandled streamtype %s\n",type);
	    	AVIStreamRelease(ast);
		break;
	    }
	    }
    }
/********************* begin video setup ***********************************/
    if (!vids) {
    	fprintf(stderr,"No video stream found. Good Bye.\n");
	exit(0);
    }
    cnt = sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD);
    bmi = HeapAlloc(GetProcessHeap(),0,cnt);
    hres = AVIStreamReadFormat(vids,0,bmi,&cnt);
    if (hres) {
    	fprintf(stderr,"AVIStreamReadFormat vids: 0x%08lx\n",hres);
	exit(1);
    }
    vidgetframe = NULL;
    bmi->biCompression = 0; /* we want it in raw form, uncompressed */
    /* recalculate the image size */
    bmi->biSizeImage = ((bmi->biWidth*bmi->biBitCount+31)&~0x1f)*bmi->biPlanes*bmi->biHeight/8;
    bytesline = ((bmi->biWidth*bmi->biBitCount+31)&~0x1f)*bmi->biPlanes/8;
    vidgetframe = AVIStreamGetFrameOpen(vids,bmi);
    if (!vidgetframe) {
    	fprintf(stderr,"AVIStreamGetFrameOpen: failed\n");
	exit(1);
    }
/********************* end video setup ***********************************/

/********************* begin display setup *******************************/
    hres = DirectDrawCreate(NULL,&ddraw,NULL);
    if (hres) {
    	fprintf(stderr,"DirectDrawCreate: 0x%08lx\n",hres);
	exit(1);
    }
    hres = IDirectDraw_SetDisplayMode(ddraw,bmi->biWidth,bmi->biHeight,bmi->biBitCount);
    if (hres) {
    	fprintf(stderr,"ddraw.SetDisplayMode: 0x%08lx (change resolution!)\n",hres);
	exit(1);
    }
    dsdesc.dwSize=sizeof(dsdesc);
    dsdesc.dwFlags = DDSD_CAPS;
    dsdesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
    hres = IDirectDraw_CreateSurface(ddraw,&dsdesc,&dsurf,NULL);
    if (hres) {
    	fprintf(stderr,"ddraw.CreateSurface: 0x%08lx\n",hres);
	exit(1);
    }
    if (bmi->biBitCount==8) {
    	RGBQUAD		*rgb = (RGBQUAD*)(bmi+1);
	int		i;

	hres = IDirectDraw_CreatePalette(ddraw,DDPCAPS_8BIT,NULL,&dpal,NULL);
	if (hres) {
	    fprintf(stderr,"ddraw.CreateSurface: 0x%08lx\n",hres);
	    exit(1);
	}
	IDirectDrawSurface_SetPalette(dsurf,dpal);
	for (i=0;i<bmi->biClrUsed;i++) {
	    palent[i].peRed = rgb[i].rgbRed;
	    palent[i].peBlue = rgb[i].rgbBlue;
	    palent[i].peGreen = rgb[i].rgbGreen;
	}
	IDirectDrawPalette_SetEntries(dpal,0,0,bmi->biClrUsed,palent);
    } else
	dpal = NULL;
/********************* end display setup *******************************/

    tstart = time(NULL);
    pos = 0;
    while (1) {
    	LPVOID		decodedframe;
	LPBITMAPINFOHEADER lpbmi;
	LPVOID		decodedbits;

/* video stuff */
	if (!(decodedframe=AVIStreamGetFrame(vidgetframe,pos++)))
	    break;
	lpbmi = (LPBITMAPINFOHEADER)decodedframe;
	decodedbits = (LPVOID)(((DWORD)decodedframe)+lpbmi->biSize);
	if (lpbmi->biBitCount == 8) {
	/* can't detect palette change that way I think */
	    RGBQUAD	*rgb = (RGBQUAD*)(lpbmi+1);
	    int		i,palchanged;

	    /* skip used colorentries. */
	    decodedbits=(char*)decodedbits+bmi->biClrUsed*sizeof(RGBQUAD);
	    palchanged = 0;
	    for (i=0;i<bmi->biClrUsed;i++) {
	    	if (	(palent[i].peRed != rgb[i].rgbRed) ||
	    		(palent[i].peBlue != rgb[i].rgbBlue) ||
	    		(palent[i].peGreen != rgb[i].rgbGreen)
		) {
			palchanged = 1;
			break;
		}
	    }
	    if (palchanged) {
		for (i=0;i<bmi->biClrUsed;i++) {
		    palent[i].peRed = rgb[i].rgbRed;
		    palent[i].peBlue = rgb[i].rgbBlue;
		    palent[i].peGreen = rgb[i].rgbGreen;
		}
		IDirectDrawPalette_SetEntries(dpal,0,0,bmi->biClrUsed,palent);
	    }
	}
	dsdesc.dwSize = sizeof(dsdesc);
	hres = IDirectDrawSurface_Lock(dsurf,NULL,&dsdesc,DDLOCK_WRITEONLY,0);
	if (hres) {
	    fprintf(stderr,"dsurf.Lock: 0x%08lx\n",hres);
	    exit(1);
	}
	/* Argh. AVIs are upside down. */
	for (i=0;i<dsdesc.dwHeight;i++) {
	    memcpy( (char *)dsdesc.lpSurface+(i*dsdesc.u1.lPitch),
		    (char *)decodedbits+bytesline*(dsdesc.dwHeight-i-1),
		    bytesline
	    );
	}
	IDirectDrawSurface_Unlock(dsurf,dsdesc.lpSurface);
    }
    tend = time(NULL);
    AVIStreamGetFrameClose(vidgetframe);

    IDirectDrawSurface_Release(dsurf);
    IDirectDraw_RestoreDisplayMode(ddraw);
    IDirectDraw_Release(ddraw);
    if (vids) AVIStreamRelease(vids);
    if (auds) AVIStreamRelease(auds);
    fprintf(stderr,"%d frames at %g frames/s\n",pos,pos*1.0/(tend-tstart));
    AVIFileRelease(avif);
    AVIFileExit();
    return 0;
}
