vdiggrab.c

来自「来自网络的iaxclient的协议栈源码」· C语言 代码 · 共 859 行 · 第 1/2 页

C
859
字号
/* * iaxclient: a cross-platform IAX softphone library * * Copyrights: * Copyright (c) 2004, Daniel Heckenberg. All rights reserved. * Copyright (c) 2005, Tipic, Inc. All rights reserved. * Copyright (C) 2006, Horizon Wimba, Inc. * Copyright (C) 2007, Wimba, Inc. * * Contributors: * Daniel Heckenberg <danielh.seeSaw<at>cse<dot>unsw<dot>edu<dot>au> * Francesco Delfino <pluto@tipic.com> * Mihai Balea <mihai AT hates DOT ms> * Peter Grayson <jpgrayson@gmail.com> * * This program is free software, distributed under the terms of * the GNU Lesser (Library) General Public License. *//* *  vdigGrab.c *  seeSaw * *  Created by Daniel Heckenberg. *  Copyright (c) 2004 Daniel Heckenberg. All rights reserved. *  (danielh.seeSaw<at>cse<dot>unsw<dot>edu<dot>au) * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the right to use, copy, modify, merge, publish, communicate, sublicence, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */#include "vdigGrab.h"struct tagVdigGrab{	// State	int isPreflighted;	int isGrabbing;	int isRecording;	// QT Components	SeqGrabComponent seqGrab;	SGChannel sgchanVideo;	ComponentInstance vdCompInst;	// Device settings	ImageDescriptionHandle vdImageDesc;	Rect vdDigitizerRect;	// Destination Settings	CGrafPtr dstPort;	ImageSequence dstImageSeq;	// Compression settings	short cpDepth;	CompressorComponent cpCompressor;	CodecQ cpSpatialQuality;	CodecQ cpTemporalQuality;	long cpKeyFrameRate;	Fixed cpFrameRate;};Boolean MySGModalFilterProc (		DialogPtr            theDialog,		const EventRecord    *theEvent,		short                *itemHit,		long                 refCon );SeqGrabComponentMakeSequenceGrabber(WindowRef pWindow);OSErrMakeSequenceGrabChannel(SeqGrabComponent seqGrab, SGChannel *sgchanVideo);OSErrvdgGetSettings(VdigGrab* pVdg);VdigGrab*vdgNew(){	return malloc(sizeof(VdigGrab));}OSErrvdgInit(VdigGrab* pVdg){	OSErr err;	memset(pVdg, 0, sizeof(VdigGrab));	if ((err = EnterMovies()))	{		fprintf(stderr, "EnterMovies err=%d\n", err);		return err;	}	if (!(pVdg->seqGrab = MakeSequenceGrabber(NULL)))	{		fprintf(stderr, "MakeSequenceGrabber error\n");		return -1;	}	if ((err = MakeSequenceGrabChannel(pVdg->seqGrab, &pVdg->sgchanVideo)))	{		if ( err != couldntGetRequiredComponent )			fprintf(stderr, "MakeSequenceGrabChannel err=%d\n", err);		return err;	}	return 0;}OSErrvdgRequestSettings(VdigGrab* pVdg){	OSErr err;	if ((err = vdgGetSettings(pVdg)))		fprintf(stderr, "vdgGetSettings err=%d\n", err);	return err;}OSErrvdgGetDeviceNameAndFlags(VdigGrab* pVdg, char* szName, long* pBuffSize, UInt32* pVdFlags){	OSErr err;	Str255 vdName;	UInt32 vdFlags;	if (!pBuffSize)	{		fprintf(stderr, "vdgGetDeviceName: NULL pointer error\n");		err = qtParamErr;		goto endFunc;	}	if ((err = VDGetDeviceNameAndFlags(pVdg->vdCompInst, vdName, &vdFlags)))	{		fprintf(stderr, "VDGetDeviceNameAndFlags err=%d\n", err);		*pBuffSize = 0;		goto endFunc;	}	if (szName)	{		int copyLen = *pBuffSize-1 < vdName[0] ?			*pBuffSize - 1 : vdName[0];		strncpy(szName, (char *)vdName+1, copyLen);		szName[copyLen] = '\0';		*pBuffSize = copyLen + 1;	} else	{		*pBuffSize = vdName[0] + 1;	}	if (pVdFlags)		*pVdFlags = vdFlags;endFunc:	return err;}OSErrvdgSetDestination(VdigGrab* pVdg, CGrafPtr dstPort){	pVdg->dstPort = dstPort;	return noErr;}OSErrvdgPreflightGrabbing(VdigGrab* pVdg, int w, int h){/* from Steve Sisak (on quicktime-api list):A much more optimal case, if you're doing it yourself is:  VDGetDigitizerInfo() // make sure this is a compressed source only  VDGetCompressTypes() // tells you the supported types  VDGetMaxSourceRect() // returns full-size rectangle (sensor size)  VDSetDigitizerRect() // determines cropping  VDSetCompressionOnOff(true)    VDSetFrameRate()         // set to 0 for default    VDSetCompression()       // compresstype=0 means default    VDGetImageDescription()  // find out image format    VDGetDigitizerRect()     // find out if vdig is cropping for you    VDResetCompressSequence()    (grab frames here)  VDSetCompressionOnOff(false)*/	OSErr err;	Rect maxRect;	DigitizerInfo info;	// make sure this is a compressed source only	if ((err = VDGetDigitizerInfo(pVdg->vdCompInst, &info)))	{		if (!(info.outputCapabilityFlags & digiOutDoesCompress))		{			fprintf(stderr, "VDGetDigitizerInfo: not a compressed source device.\n");			goto endFunc;		}	}	/* VDGetCompressTypes() // tells you the supported types */#if 0	// Apple's SoftVDig doesn't seem to like these calls	if (err = VDCaptureStateChanging(pVdg->vdCompInst,			vdFlagCaptureLowLatency | vdFlagCaptureSetSettingsBegin))	{		fprintf(stderr, "VDCaptureStateChanging err=%d\n", err);		//goto endFunc;	}#endif	if ((err = VDGetMaxSrcRect(  pVdg->vdCompInst, currentIn, &maxRect)))	{		fprintf(stderr, "VDGetMaxSrcRect err=%d\n", err);		//goto endFunc;	}	// Try to set maximum capture size ... is this necessary as we're setting the	// rectangle in the VDSetCompression call later?  I suppose that it is, as	// we're setting digitization size rather than compression size here...	// Apple vdigs don't like this call	//maxRect.top = 0; maxRect.bottom = h;	//maxRect.left = 0; maxRect.right = w;	if ((err = VDSetDigitizerRect( pVdg->vdCompInst, &maxRect)))	{		fprintf(stderr, "VDSetDigitizerRect err=%d\n", err);	}	if ((err = VDSetCompressionOnOff( pVdg->vdCompInst, 1)))	{		fprintf(stderr, "VDSetCompressionOnOff err=%d\n", err);	}	// We could try to force the frame rate here... necessary for ASC softvdig	if ((err = VDSetFrameRate( pVdg->vdCompInst, 0)))	{		fprintf(stderr, "VDSetFrameRate err=%d\n", err);	}	// try to set a format that matches our target	// necessary for ASC softvdig (even if it doesn't support	// the requested codec)	// note that for the Apple IIDC vdig in 10.3 if we request yuv2 explicitly	// we'll get 320x240 frames returned but if we leave codecType as 0	// we'll get 640x480 frames returned instead (which use 4:1:1 encoding on	// the wire rather than 4:2:2)	maxRect.top = 0; maxRect.bottom = h;	maxRect.left = 0; maxRect.right = w;	if ((err = VDSetCompression(pVdg->vdCompInst,					0, //'yuv2'					0,					&maxRect,					0, //codecNormalQuality,					0, //codecNormalQuality,					0)))	{		fprintf(stderr, "VDSetCompression err=%d\n", err);	}#if 0	if (err = VDCaptureStateChanging(pVdg->vdCompInst,				vdFlagCaptureLowLatency | vdFlagCaptureSetSettingsEnd))	{		fprintf(stderr, "VDCaptureStateChanging err=%d\n", err);		//goto endFunc;	}#endif	if ((err = VDResetCompressSequence( pVdg->vdCompInst )))	{		fprintf(stderr, "VDResetCompressSequence err=%d\n", err);	}	pVdg->vdImageDesc = (ImageDescriptionHandle)NewHandle(0);	if ((err = VDGetImageDescription( pVdg->vdCompInst, pVdg->vdImageDesc)))	{		fprintf(stderr, "VDResetCompressSequence err=%d\n", err);	}	// From Steve Sisak: find out if Digitizer is cropping for you.	if ((err = VDGetDigitizerRect( pVdg->vdCompInst, &pVdg->vdDigitizerRect)))	{		fprintf(stderr, "VDGetDigitizerRect err=%d\n", err);	}	pVdg->isPreflighted = 1;endFunc:	return err;}OSErrvdgStartGrabbing(VdigGrab* pVdg){	OSErr err;	if (!pVdg->isPreflighted)	{		fprintf(stderr, "vdgStartGrabbing called without previous successful vdgPreflightGrabbing()\n");		err = badCallOrderErr;		goto endFunc;	}	if ((err = VDCompressOneFrameAsync( pVdg->vdCompInst )))	{		fprintf(stderr, "VDCompressOneFrameAsync err=%d\n", err);		goto endFunc;	}	if ((err = vdgDecompressionSequenceBegin( pVdg, pVdg->dstPort, NULL, NULL )))	{		fprintf(stderr, "vdgDecompressionSequenceBegin err=%d\n", err);		goto endFunc;	}	pVdg->isGrabbing = 1;endFunc:	return err;}OSErrvdgGetDataRate( VdigGrab*   pVdg,		long*		pMilliSecPerFrame,		Fixed*      pFramesPerSecond,		long*       pBytesPerSecond){	OSErr err;	if ((err = VDGetDataRate( pVdg->vdCompInst,					pMilliSecPerFrame,					pFramesPerSecond,					pBytesPerSecond)))		fprintf(stderr, "VDGetDataRate err=%d\n", err);	return err;}OSErrvdgGetImageDescription( VdigGrab* pVdg,		ImageDescriptionHandle vdImageDesc ){	OSErr err;	if ((err = VDGetImageDescription( pVdg->vdCompInst, vdImageDesc)))		fprintf(stderr, "VDGetImageDescription err=%d\n", err);	return err;}OSErrvdgDecompressionSequenceBegin(VdigGrab* pVdg,		CGrafPtr dstPort,		Rect* pDstRect,		MatrixRecord* pDstScaleMatrix){	OSErr err;	//Rect sourceRect = pMungData->bounds;	//MatrixRecord scaleMatrix;  	// !HACK! Different conversions are used for these two equivalent types	// so we force the cType so that the more efficient path is used	if ((*pVdg->vdImageDesc)->cType == FOUR_CHAR_CODE('yuv2'))		(*pVdg->vdImageDesc)->cType = FOUR_CHAR_CODE('yuvu'); // kYUVUPixelFormat	// make a scaling matrix for the sequence	//sourceRect.right = (*pVdg->vdImageDesc)->width;	//sourceRect.bottom = (*pVdg->vdImageDesc)->height;	//RectMatrix(&scaleMatrix, &sourceRect, &pMungData->bounds);	// begin the process of decompressing a sequence of frames	// this is a set-up call and is only called once for the sequence	// - the ICM will interrogate different codecs and construct a	// suitable decompression chain, as this is a time consuming	// process we don't want to do this once per frame (eg. by using	// DecompressImage) for more information see Ice Floe #8	// http://developer.apple.com/quicktime/icefloe/dispatch008.html	// the destination is specified as the GWorld	if ((err = DecompressSequenceBeginS(					// pointer to field to receive unique					// ID for sequence					&pVdg->dstImageSeq,					// handle to image description structure					pVdg->vdImageDesc,					0,					0,					// port for the DESTINATION image					//GetWindowPort(pMungData->pWindow),					dstPort,					// graphics device handle, if port is					// set, set to NULL					NULL,					// source rectangle defining the					// portion of the image to decompress					//&sourceRect,					NULL,					// transformation matrix					//&scaleMatrix,					NULL,					// transfer mode specifier					srcCopy,					// clipping region in dest. coordinate

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?