/*
    Bt8xx QuickTime driver component
    Copyright (C) 2002 Andreas Thiede ( a.thiede@berlin.de )

    Based on : 
    macam - webcam app and QuickTime driver component
    Copyright (C) 2002 Matthias Krauss (macam@matthias-krauss.de)

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#ifndef	_QT_VIDEO_DIGITIZER_
#define	_QT_VIDEO_DIGITIZER_

#include <Carbon/Carbon.h>
#include <QuickTime/QuickTime.h>
#include <QuickTime/QuickTimeComponents.h>
#include <QuickTime/QuickTimeComponents.k.h>
//#include "GlobalDefs.h"
//#import "MyBridge.h"

//Video digitizer states - the component is considered a finite state machine

typedef enum VDState {
    vdsIdle,		   //Uncompressed mode, no async grab running.
                           //-> vdsAsyncGrab by vdigGrabOneFrameAsync()
                           //-> vdsCompressedIdle by vdigSetCompressionOnOff()
                           //-> vdsPlayThru by vdigSetPlayThruOnOff()

    vdsAsyncGrab,	   //Uncompressed mode async grab running.
                           //-> vdsAsyncGrab by vdigGrabOneFrameAsync()
                           //-> vdsIdle by vdigDone()

    vdsPlayThru,	   //Uncompressed mode, playing thru.
                           //-> vdsIdle by vdigSetPlayThruOnOff()

    vdsCompressedIdle,	   //Compressed mode, no async grab running.
                           //-> vdsCompressedAsyncGrab by vdigCompressOneFrameAsync()
                           //-> vdsIdle by vdigSetCompressionOnOff()

    vdsCompressedAsyncGrab //Compressed mode, async grab running.
                           //-> vdsCompressedIdle by vdigCompressDone()
} VDState;

//Our Globals struct

typedef struct VDGlobals {
    ComponentInstance self;			//Our instance - just to know (no cases we need it yet)

//Our bridge to the digitizer object
    //MyBridge* 	bridge;				//The bridge object to the driver

//General grab settings
    Rect 	maxRect;			//In our case, activeSrcRect and maxSrcRect. They are the same since we don't have blanking lines
    Rect 	digitizerRect;			//the part of our image we are grabbing - VDGetDigitizerRect and VDSetDigitizerRect
    Fixed 	fps;				//the fps we should use - VDSetFrameRate
    TimeBase	timeBase;			//Our time base - set and get - VDSetTimeBase
    VDState 	vdState;			//Our current state
    MatrixRecord playThruMatrix;		//The transformation matrix - we'll force this to be id
    short 	fieldPreference;		//The fieldPreference (we ignore it since we don't have interlaced video)
    short 	inputStandard;			//The selected (and ignored) input standard: PAL, SECAM or NTSC
    
//This buffer fills up - for all grabbing modes
    Ptr		fillingBuffer;			//The current destination buffer

//Settings for sync frame grab (the default method)
    CGrafPtr 	destinationPort;		//The port we are drawing to in synchronous mode
    PixMapHandle playThruDest;			//The PixMap (we rather use destinationPort) 
    Rect 	playThruDestRect;		//The destination rectangle (PixMap-relative - we move internally to Port-rel.)

//Data for compressed image transfers
    OSType	compressedType;			//The requested compressor type - we just use the Raw codec
    short	compressedDepth;		//The requested bit depth - setup by VDSetCompression
    Rect 	compressedBounds;		//The requested destination rect - setup by VDSetCompression
    CodecQ	compressedSpatialQuality;	//The requested spatial quality - setup by VDSetCompression - ignore (Raw codec)
    CodecQ	compressedTemporalQuality;	//The requested spatial quality - setup by VDSetCompression - ignore (Raw codec)
    long	compressedKeyFrameRate;		//Key requested key frame rate - setup by VDSetCompression - ignore (Raw codec)

//A cached image description so we can use DecompressImage, FDecompressImage and just copy it if we should return compressed data
    ImageDescriptionHandle imgDesc;
    
    unsigned   mVideoBufferSize;
    char     * mVideoBuffer;
    GWorldPtr  mGWorld;
    
} VDGlobals;

typedef VDGlobals** vdigGlobals;

//Main Entry

pascal ComponentResult vdigMainEntry (ComponentParameters *params, Handle storage);

//Function Dispatcher

bool vdigLookupSelector(short what,ProcPtr* ptr,ProcInfoType* info);

//Required Generic Component Functions

pascal ComponentResult vdigOpen(vdigGlobals storage, ComponentInstance self);
pascal ComponentResult vdigClose(vdigGlobals storage, ComponentInstance self);
pascal ComponentResult vdigCanDo(vdigGlobals storage, short ftnNumber);
pascal ComponentResult vdigVersion(vdigGlobals storage);

//Required Video Digitizer Functions

pascal VideoDigitizerError vdigGetDigitizerInfo(vdigGlobals storage, DigitizerInfo *info);
pascal VideoDigitizerError vdigGetCurrentFlags(vdigGlobals storage, long *inputCurrentFlag, long *outputCurrentFlag);
pascal VideoDigitizerError vdigGetMaxSrcRect(vdigGlobals storage, short inputStd, Rect *maxSrcRect);
pascal VideoDigitizerError vdigGetActiveSrcRect(vdigGlobals storage, short inputStd, Rect *activeSrcRect);
pascal VideoDigitizerError vdigGetDigitizerRect(vdigGlobals storage, Rect *digiRect);
pascal VideoDigitizerError vdigSetDigitizerRect(vdigGlobals storage, Rect *digiRect);
pascal VideoDigitizerError vdigGetNumberOfInputs(vdigGlobals storage, short *inputs);
pascal VideoDigitizerError vdigGetInputFormat(vdigGlobals storage, short input, short *format);
pascal VideoDigitizerError vdigGetInput(vdigGlobals storage, short *input);
pascal VideoDigitizerError vdigSetInput(vdigGlobals storage, short input);
pascal VideoDigitizerError vdigSetInputStandard(vdigGlobals storage, short inputStandard);
pascal VideoDigitizerError vdigGetPlayThruDestination(vdigGlobals storage,PixMapHandle* dest, Rect* destRect,
                                    MatrixRecord* m, RgnHandle* mask);
pascal VideoDigitizerError vdigSetPlayThruDestination(vdigGlobals storage, PixMapHandle dest, Rect *destRect,
                                    MatrixRecord *m, RgnHandle mask);
pascal VideoDigitizerError vdigPreflightDestination(vdigGlobals storage, Rect *digitizerRect, PixMap **dest,
                                    Rect *destRect, MatrixRecord *m);
pascal VideoDigitizerError vdigGrabOneFrame(vdigGlobals storage);
pascal VideoDigitizerError vdigGetFieldPreference(vdigGlobals storage, short* fieldFlag);
pascal VideoDigitizerError vdigSetFieldPreference(vdigGlobals storage, short fieldFlag);
pascal VideoDigitizerError vdigGetVBlankRect(vdigGlobals storage, short inputStd, Rect* vBlankRect);
pascal VideoDigitizerError vdigGetVideoDefaults(vdigGlobals storage,
                                    unsigned short *blackLevel, unsigned short *whiteLevel,
                                    unsigned short *brightness, unsigned short *hue, unsigned short *saturation,
                                    unsigned short *contrast, unsigned short *sharpness);

//Optional Video Digitizer functions for continuous grabbing (play-thru)

pascal VideoDigitizerError vdigSetPlayThruOnOff(vdigGlobals storage, short state);

//Optional Video Digitizer Functions

pascal VideoDigitizerError vdigSetDestinationPort(vdigGlobals storage, CGrafPtr port);
pascal VideoDigitizerError vdigGetBrightness(vdigGlobals storage,unsigned short* val);
pascal VideoDigitizerError vdigSetBrightness(vdigGlobals storage,unsigned short* val);
pascal VideoDigitizerError vdigGetContrast(vdigGlobals storage,unsigned short* val);
pascal VideoDigitizerError vdigSetContrast(vdigGlobals storage,unsigned short* val);
pascal VideoDigitizerError vdigGetSaturation(vdigGlobals storage,unsigned short* val);
pascal VideoDigitizerError vdigSetSaturation(vdigGlobals storage,unsigned short* val);
pascal VideoDigitizerError vdigGetSharpness(vdigGlobals storage,unsigned short* val);
pascal VideoDigitizerError vdigSetSharpness(vdigGlobals storage,unsigned short* val);
pascal VideoDigitizerError vdigGetPreferredTimeScale(vdigGlobals storage,TimeScale* ts);
pascal VideoDigitizerError vdigSetHue( VideoDigitizerComponent ci, unsigned short *hue );
pascal VideoDigitizerError vdigGetHue( VideoDigitizerComponent ci, unsigned short *hue );

pascal VideoDigitizerError vdigSetBlackLevelValue( VideoDigitizerComponent ci, unsigned short * blackLevel );
pascal VideoDigitizerError vdigGetBlackLevelValue( VideoDigitizerComponent ci, unsigned short * blackLevel );
pascal VideoDigitizerError vdigSetWhiteLevelValue( VideoDigitizerComponent ci, unsigned short * whiteLevel );
pascal VideoDigitizerError vdigGetWhiteLevelValue( VideoDigitizerComponent ci, unsigned short * whiteLevel );

// The compressed source devices function suite - e.g. needed for BTV and Oculus

pascal VideoDigitizerError vdigGetCompressionTypes(vdigGlobals storage, VDCompressionListHandle h);
pascal VideoDigitizerError vdigSetCompression(vdigGlobals storage,OSType compressType, short depth, Rect* bounds,
                                            CodecQ spatialQuality, CodecQ temporalQuality, long keyFrameRate);
pascal VideoDigitizerError vdigSetFrameRate(vdigGlobals storage,Fixed fps);
pascal VideoDigitizerError vdigSetTimeBase(vdigGlobals storage,TimeBase t);
pascal VideoDigitizerError vdigCompressOneFrameAsync(vdigGlobals storage);
pascal VideoDigitizerError vdigCompressDone(vdigGlobals storage,Boolean* done,Ptr* theData,long* dataSize,
                                            UInt8* similarity,TimeRecord* t);
pascal VideoDigitizerError vdigResetCompressSequence(vdigGlobals storage);
pascal VideoDigitizerError vdigGetImageDescription(vdigGlobals storage, ImageDescriptionHandle iDesc);
pascal VideoDigitizerError vdigGetDataRate(vdigGlobals storage, long* mspf,Fixed* fps, long* bps);
pascal VideoDigitizerError vdigSetCompressionOnOff(vdigGlobals storage, Boolean state);
pascal VideoDigitizerError vdigReleaseCompressBuffer(vdigGlobals storage,Ptr bufferAddr);
pascal VideoDigitizerError vdigGetDataRate(vdigGlobals storage, long* msPerFrame, Fixed* fps, long* bps);

//Input names

pascal VideoDigitizerError vdigGetInputName(vdigGlobals storage, long videoInput, Str255 name);

//Tool functions

Ptr GetRawBuffer(vdigGlobals storage);			//tries to get a buffer from our raw buffer temp pool or allocs a new one
bool PutRawBufferToPool(vdigGlobals storage, Ptr buffer);	//tries to put a buffer to our raw buffer temp pool
void CleanupRawBufferPool(vdigGlobals storage);		//Cleans up our array of moved-aside async grab buffers
void CheckCachedStuff(vdigGlobals globals);		//Reflect environment changes in cached stuff (e.g. resolution change -> clear raw buffer pool)

// 
pascal VideoDigitizerError vdigGetMaxAuxBuffer( vdigGlobals storage, PixMapHandle * pm, Rect * r );
pascal VideoDigitizerError vdigReleaseAsyncBuffers( VideoDigitizerComponent ci );
pascal VideoDigitizerError vdigGetSoundInputDriver( VideoDigitizerComponent ci, Str255 soundDriverName );
pascal VideoDigitizerError vdigSetPreferredPacketSize( VideoDigitizerComponent ci, long preferredPacketSizeInBytes ); 

#endif
