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 + -
显示快捷键?