// init driver static int init(sh_video_t *sh){ OSErr result = 1; int extradata_size = sh->bih ? sh->bih->biSize - sizeof(*sh->bih) : 0; void *extradata = sh->bih + 1; if (!sh->ImageDesc) mp_msg(MSGT_DECVIDEO,MSGL_ERR,"sh->ImageDesc not set, try -demuxer mov if this fails.\n"); #ifndef CONFIG_QUICKTIME #ifdef WIN32_LOADER Setup_LDT_Keeper(); #endif //preload quicktime.qts to avoid the problems caused by the hardcoded path inside the dll qtime_qts = LoadLibraryA("QuickTime.qts"); if(!qtime_qts){ mp_msg(MSGT_DECVIDEO,MSGL_ERR,"unable to load QuickTime.qts\n" ); return 0; } handler = LoadLibraryA("qtmlClient.dll"); if(!handler){ mp_msg(MSGT_DECVIDEO,MSGL_ERR,"unable to load qtmlClient.dll\n"); return 0; } InitializeQTML = (OSErr (*)(long))GetProcAddress(handler, "InitializeQTML"); EnterMovies = (OSErr (*)(void))GetProcAddress(handler, "EnterMovies"); ExitMovies = (void (*)(void))GetProcAddress(handler, "ExitMovies"); DecompressSequenceBegin = (OSErr (*)(ImageSequence*,ImageDescriptionHandle,CGrafPtr,void *,const Rect *,MatrixRecordPtr,short,RgnHandle,CodecFlags,CodecQ,DecompressorComponent))GetProcAddress(handler, "DecompressSequenceBegin"); DecompressSequenceFrameS = (OSErr (*)(ImageSequence,Ptr,long,CodecFlags,CodecFlags*,ICMCompletionProcRecordPtr))GetProcAddress(handler, "DecompressSequenceFrameS"); GetGWorldPixMap = (PixMapHandle (*)(GWorldPtr))GetProcAddress(handler, "GetGWorldPixMap"); QTNewGWorldFromPtr = (OSErr(*)(GWorldPtr *,OSType,const Rect *,CTabHandle,void*,GWorldFlags,void *,long))GetProcAddress(handler, "QTNewGWorldFromPtr"); NewHandleClear = (OSErr(*)(Size))GetProcAddress(handler, "NewHandleClear"); DisposeHandle = (void (*)(Handle))GetProcAddress(handler, "DisposeHandle"); DisposeGWorld = (void (*)(GWorldPtr))GetProcAddress(handler, "DisposeGWorld"); CDSequenceEnd = (OSErr (*)(ImageSequence))GetProcAddress(handler, "CDSequenceEnd"); if(!InitializeQTML || !EnterMovies || !DecompressSequenceBegin || !DecompressSequenceFrameS){ mp_msg(MSGT_DECVIDEO,MSGL_ERR,"invalid qtmlClient.dll!\n"); return 0; } result=InitializeQTML(kInitializeQTMLDisableDirectSound | kInitializeQTMLUseGDIFlag | kInitializeQTMLDisableDDClippers); mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"InitializeQTML returned %d\n",result); #endif /* CONFIG_QUICKTIME */ result=EnterMovies(); mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"EnterMovies returned %d\n",result); //make a yuy2 gworld OutBufferRect.top=0; OutBufferRect.left=0; OutBufferRect.right=sh->disp_w; OutBufferRect.bottom=sh->disp_h; //Fill the imagedescription for our SVQ3 frame //we can probably get this from Demuxer if (!sh->ImageDesc && extradata_size >= sizeof(ImageDescription) && ((ImageDescription *)extradata)->idSize <= extradata_size) sh->ImageDesc = extradata; if (sh->ImageDesc) { mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"ImageDescription size: %d\n",((ImageDescription*)(sh->ImageDesc))->idSize); framedescHandle=(ImageDescriptionHandle)NewHandleClear(((ImageDescription*)(sh->ImageDesc))->idSize); memcpy(*framedescHandle,sh->ImageDesc,((ImageDescription*)(sh->ImageDesc))->idSize); } else { // assume extradata consists only of the atoms, build the other parts ImageDescription *idesc; int size = sizeof(*idesc) + extradata_size; mp_msg(MSGT_DECVIDEO, MSGL_V, "Generating a ImageDescription\n"); framedescHandle=(ImageDescriptionHandle)NewHandleClear(size); idesc = *framedescHandle; memcpy(idesc + 1, extradata, extradata_size); idesc->idSize = size; idesc->width = sh->disp_w; idesc->height = sh->disp_h; } dump_ImageDescription(*framedescHandle); (**framedescHandle).cType = bswap_32(sh->format); sh->context = (void *)kYUVSPixelFormat; { int imgfmt = sh->codec->outfmt[sh->outfmtidx]; int qt_imgfmt; switch(imgfmt) { case IMGFMT_YUY2: qt_imgfmt = kYUVSPixelFormat; break; case IMGFMT_YVU9: qt_imgfmt = 0x73797639; //kYVU9PixelFormat; break; case IMGFMT_YV12: qt_imgfmt = 0x79343230; break; case IMGFMT_UYVY: qt_imgfmt = k2vuyPixelFormat; break; case IMGFMT_YVYU: qt_imgfmt = kYVYU422PixelFormat; imgfmt = IMGFMT_YUY2; break; case IMGFMT_RGB16: qt_imgfmt = k16LE555PixelFormat; break; case IMGFMT_BGR24: qt_imgfmt = k24BGRPixelFormat; break; case IMGFMT_BGR32: qt_imgfmt = k32BGRAPixelFormat; break; case IMGFMT_RGB32: qt_imgfmt = k32RGBAPixelFormat; break; default: mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Unknown requested csp\n"); return 0; } mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"imgfmt: %s qt_imgfmt: %.4s\n", vo_format_name(imgfmt), (char *)&qt_imgfmt); sh->context = (void *)qt_imgfmt; if(!mpcodecs_config_vo(sh,sh->disp_w,sh->disp_h,imgfmt)) return 0; } mpi=mpcodecs_get_image(sh, MP_IMGTYPE_STATIC, MP_IMGFLAG_PRESERVE, sh->disp_w, sh->disp_h); if(!mpi) return 0; result = QTNewGWorldFromPtr( &OutBufferGWorld, (OSType)sh->context, &OutBufferRect, //we should benchmark if yvu9 is faster for svq3, too 0, 0, 0, mpi->planes[0], mpi->stride[0]); if (result) { mp_msg(MSGT_DECVIDEO,MSGL_ERR,"QTNewGWorldFromPtr result=%d\n",result); return 0; } result = DecompressSequenceBegin(&imageSeq, framedescHandle, (CGrafPtr)OutBufferGWorld, NULL, NULL, NULL, srcCopy, NULL, 0, codecNormalQuality, 0); if(result) { mp_msg(MSGT_DECVIDEO,MSGL_ERR,"DecompressSequenceBegin result=%d\n",result); return 0; } return 1; }
// decode a frame static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){ long result = 1; int i; mp_image_t* mpi; ComponentResult cres; if(len<=0) return NULL; // skipped frame mpi=mpcodecs_get_image(sh, MP_IMGTYPE_STATIC, MP_IMGFLAG_PRESERVE, sh->disp_w, sh->disp_h); if(!mpi) return NULL; decpar.data = (char*)data; decpar.bufferSize = len; (**framedescHandle).dataSize=len; if(!codec_inited){ result = QTNewGWorldFromPtr( &OutBufferGWorld, // kYUVSPixelFormat, //pixel format of new GWorld == YUY2 (OSType)sh->context, &OutBufferRect, //we should benchmark if yvu9 is faster for svq3, too 0, 0, 0, mpi->planes[0], mpi->stride[0]); mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"NewGWorldFromPtr returned:%ld\n",65536-(result&0xffff)); // if (65536-(result&0xFFFF) != 10000) // return NULL; // printf("IDesc=%d\n",sizeof(ImageDescription)); decpar.imageDescription = framedescHandle; decpar.startLine=0; decpar.stopLine=(**framedescHandle).height; decpar.frameNumber = 1; //1 // decpar.conditionFlags=0xFFD; // first // decpar.callerFlags=0x2001; // first decpar.matrixFlags = 0; decpar.matrixType = 0; decpar.matrix = 0; decpar.capabilities=&codeccap; // decpar.accuracy = 0x1680000; //codecNormalQuality; decpar.accuracy = codecNormalQuality; // decpar.port = OutBufferGWorld; // decpar.preferredOffscreenPixelSize=17207; // decpar.sequenceID=malloc(1000); // memset(decpar.sequenceID,0,1000); // SrcRect.top=17207; // SrcRect.left=0; // SrcRect.right=0;//image_width; // SrcRect.bottom=0;//image_height; // decpar.srcRect = SrcRect; decpar.srcRect = OutBufferRect; decpar.transferMode = srcCopy; decpar.dstPixMap = **GetGWorldPixMap( OutBufferGWorld);//destPixmap; cres=ImageCodecPreDecompress(ci,&decpar); mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"ImageCodecPreDecompress cres=0x%X\n",cres); if(decpar.wantedDestinationPixelTypes) { OSType *p=*(decpar.wantedDestinationPixelTypes); if(p) while(*p){ mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"supported csp: 0x%08X %.4s\n",*p,(char *)p); ++p; } } // decpar.conditionFlags=0x10FFF; // first // decpar.preferredOffscreenPixelSize=17207; // decpar.conditionFlags=0x10FFD; // first // cres=ImageCodecPreDecompress(ci,&decpar); // printf("ImageCodecPreDecompress cres=0x%X\n",cres); codec_inited=1; } #if 0 if(decpar.frameNumber==124){ decpar.frameNumber=1; cres=ImageCodecPreDecompress(ci,&decpar); mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"ImageCodecPreDecompress cres=0x%lX\n",cres); } #endif cres=ImageCodecBandDecompress(ci,&decpar); ++decpar.frameNumber; if(cres&0xFFFF){ mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"ImageCodecBandDecompress cres=0x%X (-0x%X) %d\n",cres,-cres,cres); return NULL; } // for(i=0;i<8;i++) // printf("img_base[%d]=%p\n",i,((int*)decpar.dstPixMap.baseAddr)[i]); if((int)sh->context==0x73797639){ // Sorenson 16-bit YUV -> std YVU9 short *src0=(short *)((char*)decpar.dstPixMap.baseAddr+0x20); for(i=0;i<mpi->h;i++){ int x; unsigned char* dst=mpi->planes[0]+i*mpi->stride[0]; unsigned short* src=src0+i*((mpi->w+15)&(~15)); for(x=0;x<mpi->w;x++) dst[x]=src[x]; } src0+=((mpi->w+15)&(~15))*((mpi->h+15)&(~15)); for(i=0;i<mpi->h/4;i++){ int x; unsigned char* dst=mpi->planes[1]+i*mpi->stride[1]; unsigned short* src=src0+i*(((mpi->w+63)&(~63))/4); for(x=0;x<mpi->w/4;x++) dst[x]=src[x]; src+=((mpi->w+63)&(~63))/4; } src0+=(((mpi->w+63)&(~63))/4)*(((mpi->h+63)&(~63))/4); for(i=0;i<mpi->h/4;i++){ int x; unsigned char* dst=mpi->planes[2]+i*mpi->stride[2]; unsigned short* src=src0+i*(((mpi->w+63)&(~63))/4); for(x=0;x<mpi->w/4;x++) dst[x]=src[x]; src+=((mpi->w+63)&(~63))/4; } } return mpi; }
//-------------------------------------------------------------------- bool ofQuickTimeGrabber::setup(int w, int h){ //--------------------------------- #ifdef OF_VIDEO_CAPTURE_QUICKTIME //--------------------------------- //---------------------------------- 1 - open the sequence grabber if( !qtInitSeqGrabber() ){ ofLogError("ofQuickTimeGrabber") << "initGrabber(): unable to initialize the seq grabber"; return false; } //---------------------------------- 2 - set the dimensions //width = w; //height = h; MacSetRect(&videoRect, 0, 0, w, h); //---------------------------------- 3 - buffer allocation // Create a buffer big enough to hold the video data, // make sure the pointer is 32-byte aligned. // also the rgb image that people will grab offscreenGWorldPixels = (unsigned char*)malloc(4 * w * h + 32); pixels.allocate(w, h, OF_IMAGE_COLOR); #if defined(TARGET_OSX) && defined(__BIG_ENDIAN__) QTNewGWorldFromPtr (&(videogworld), k32ARGBPixelFormat, &(videoRect), NULL, NULL, 0, (offscreenGWorldPixels), 4 * w); #else QTNewGWorldFromPtr (&(videogworld), k24RGBPixelFormat, &(videoRect), NULL, NULL, 0, (pixels.getPixels()), 3 * w); #endif LockPixels(GetGWorldPixMap(videogworld)); SetGWorld (videogworld, NULL); SGSetGWorld(gSeqGrabber, videogworld, nil); //---------------------------------- 4 - device selection bool didWeChooseADevice = bChooseDevice; bool deviceIsSelected = false; //if we have a device selected then try first to setup //that device if(didWeChooseADevice){ deviceIsSelected = qtSelectDevice(deviceID, true); if(!deviceIsSelected && bVerbose) ofLogError("ofQuickTimeGrabber") << "initGrabber(): unable to open device[" << deviceID << "], will attempt other devices"; } //if we couldn't select our required device //or we aren't specifiying a device to setup //then lets try to setup ANY device! if(deviceIsSelected == false){ //lets list available devices listDevices(); setDeviceID(0); deviceIsSelected = qtSelectDevice(deviceID, false); } //if we still haven't been able to setup a device //we should error and stop! if( deviceIsSelected == false){ goto bail; } //---------------------------------- 5 - final initialization steps OSStatus err; err = SGSetChannelUsage(gVideoChannel,seqGrabPreview); if ( err != noErr ) goto bail; //----------------- callback method for notifying new frame err = SGSetChannelRefCon(gVideoChannel, (long)&bHavePixelsChanged ); if(!err) { VideoBottles vb; /* get the current bottlenecks */ vb.procCount = 9; err = SGGetVideoBottlenecks(gVideoChannel, &vb); if (!err) { myGrabCompleteProc = NewSGGrabCompleteBottleUPP(frameIsGrabbedProc); vb.grabCompleteProc = myGrabCompleteProc; /* add our GrabFrameComplete function */ err = SGSetVideoBottlenecks(gVideoChannel, &vb); } } err = SGSetChannelBounds(gVideoChannel, &videoRect); if ( err != noErr ) goto bail; err = SGPrepare(gSeqGrabber, true, false); //theo swapped so preview is true and capture is false if ( err != noErr ) goto bail; err = SGStartPreview(gSeqGrabber); if ( err != noErr ) goto bail; bGrabberInited = true; loadSettings(); if( attemptFramerate >= 0 ){ err = SGSetFrameRate(gVideoChannel, IntToFixed(attemptFramerate) ); if ( err != noErr ){ ofLogError("ofQuickTimeGrabber") << "initGrabber: couldn't setting framerate to " << attemptFramerate << ": OSStatus " << err; } } ofLogNotice("ofQuickTimeGrabber") << " inited grabbed "; ofLogNotice("ofQuickTimeGrabber") << "-------------------------------------"; // we are done return true; //--------------------- (bail) something's wrong ----- bail: ofLogError("ofQuickTimeGrabber") << "***** ofQuickTimeGrabber error *****"; ofLogError("ofQuickTimeGrabber") << "------------------------------------"; //if we don't close this - it messes up the next device! if(bSgInited) qtCloseSeqGrabber(); bGrabberInited = false; return false; //--------------------------------- #else //--------------------------------- return false; //--------------------------------- #endif //--------------------------------- }
void TLevelReader3gp::load(const TRasterP &rasP, int frameIndex, const TPoint &pos, int shrinkX, int shrinkY) { TRaster32P ras = rasP; { QMutexLocker sl(&m_mutex); ras->lock(); if (m_IOError != QTNoError) goto error; Rect rect; rect.right = pos.x + ras->getLx(); rect.left = pos.x; rect.bottom = pos.y + ras->getLy(); rect.top = pos.y; GWorldPtr offscreenGWorld; OSErr err; #if defined TNZ_MACHINE_CHANNEL_ORDER_BGRM OSType pixelFormat = k32BGRAPixelFormat; #elif defined TNZ_MACHINE_CHANNEL_ORDER_MRGB OSType pixelFormat = k32ARGBPixelFormat; #endif err = QTNewGWorldFromPtr( &offscreenGWorld, pixelFormat, &rect, 0, 0, 0, ras->getRawData(), ras->getWrap() * 4); if (err != noErr) { m_IOError = QTUnableToCreateResource; goto error; } SetMovieBox(m_movie, &rect); err = GetMoviesError(); if (err != noErr) { m_IOError = QTUnableToSetMovieBox; #if 0 DisposeGWorld(offscreenGWorld); #endif goto error; } #if 0 SetMovieGWorld(m_movie, offscreenGWorld, GetGWorldDevice(offscreenGWorld)); #endif err = GetMoviesError(); if (err != noErr) { m_IOError = QTUnableToSetMovieGWorld; #if 0 DisposeGWorld(offscreenGWorld); #endif goto error; } TimeValue currentTime = currentTimes[frameIndex]; SetMovieTimeValue(m_movie, currentTime); err = GetMoviesError(); if (err != noErr) { m_IOError = QTUnableToSetTimeValue; #if 0 DisposeGWorld(offscreenGWorld); #endif goto error; } err = UpdateMovie(m_movie); if (err != noErr) { m_IOError = QTUnableToUpdateMovie; #if 0 DisposeGWorld(offscreenGWorld); #endif goto error; } MoviesTask(m_movie, 0); err = GetMoviesError(); if (err != noErr) { m_IOError = QTUnableToDoMovieTask; #if 0 DisposeGWorld(offscreenGWorld); #endif goto error; } SetMovieGWorld(m_movie, 0, 0); #if 0 DisposeGWorld(offscreenGWorld); #endif ras->unlock(); } if (m_depth != 32) { setMatteAndYMirror(rasP); } else { rasP->yMirror(); } return; error: ras->unlock(); throw TImageException(m_path, buildQTErrorString(m_IOError)); }
static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ OSErr cres; long framesizemax; UInt8 similarity=0; long compressedsize; OSType in_format=kYUVSPixelFormat; int width = mpi->width; int height = mpi->height; int stride = width*2; if(!codec_inited){ FrameRect.top=0; FrameRect.left=0; FrameRect.right=width; FrameRect.bottom=height; cres = QTNewGWorldFromPtr( &frame_GWorld_in, in_format, &FrameRect, 0, 0, 0, mpi->planes[0], stride); mp_msg(MSGT_MENCODER,MSGL_DBG2,"NewGWorldFromPtr returned:%i\n",cres&0xFFFF); //dunno what todo about this frame_prev = malloc(stride * height); cres = QTNewGWorldFromPtr( &frame_GWorld_prev, in_format, &FrameRect, 0, 0, 0, frame_prev, stride); mp_msg(MSGT_MENCODER,MSGL_DBG2,"height:%i width:%i stride:%i\n",height,width,stride); mp_msg(MSGT_MENCODER,MSGL_DBG2,"NewGWorldFromPtr returned:%i\n",cres&0xFFFF); cres= GetMaxCompressionSize ( GetGWorldPixMap(frame_GWorld_in), &FrameRect, 24, codecNormalQuality, bswap_32(format), compressor, &framesizemax ); mp_msg(MSGT_MENCODER,MSGL_DBG2,"GetMaxCompressionSize returned:%i : MaxSize:%li\n",cres&0xFFFF,framesizemax); frame_comp=malloc(framesizemax); desc = (ImageDescriptionHandle)NewHandleClear(MAX_IDSIZE); //memory where the desc will be stored (*desc)->idSize=MAX_IDSIZE; cres= CompressSequenceBegin ( &seq, GetGWorldPixMap( frame_GWorld_in), GetGWorldPixMap( frame_GWorld_prev), &FrameRect, &FrameRect, 24, // color depth bswap_32(format), // fourcc compressor, // codec component codecNormalQuality, //codecNormalQuality, codecMaxQuality, //codecNormalQuality, 10*30, // keyframe rate 0, 0, desc); mp_msg(MSGT_MENCODER,MSGL_DBG2,"CompressSequenceBegin returned:%i\n",cres&0xFFFF); mp_msg(MSGT_MENCODER,MSGL_DBG2,"Sequence ID:%i\n",seq); dump_ImageDescription(*desc); codec_inited++; } cres = CompressSequenceFrame ( seq, GetGWorldPixMap(frame_GWorld_in), &FrameRect, 0, (char*)mux_v->buffer, &compressedsize, &similarity, 0); if(cres&0xFFFF)mp_msg(MSGT_MENCODER,MSGL_DBG2,"CompressSequenceFrame returned:%i\n",cres&0xFFFF); #if 0 printf("Size %i->%i \n",stride*height,compressedsize); printf("Ratio: %i:1\n",(stride*height)/compressedsize); #endif muxer_write_chunk(mux_v, compressedsize , similarity?0:0x10, MP_NOPTS_VALUE, MP_NOPTS_VALUE); if(((*desc)->idSize)>MAX_IDSIZE){ mp_msg(MSGT_MENCODER,MSGL_ERR,"FATAL! idSize=%d too big, increase MAX_IDSIZE in ve_qtvideo.c!\n",((*desc)->idSize)); } else { // according to QT docs, imagedescription may be changed while encoding // a frame (even its size may (and does!) change!) memcpy(mux_v->bih+1,*desc,(*desc)->idSize); } return 1; }
/********************> LoadTGA() <*****/ bool upload_image(const unsigned char* filePath, bool hasalpha) { if(visibleloading){ loadscreencolor=1; pgame->LoadingScreen(); } #if 1 // for Windows, just use TGA loader for now char fileName[ 256]; CopyPascalStringToC( filePath, fileName); /* // change extension to .TGA int len = strlen( fileName); if (len > 3) { fileName[ len - 3] = 't'; fileName[ len - 2] = 'g'; fileName[ len - 1] = 'a'; } */ // return (LoadTGA( fileName) != NULL); return (LoadImage(fileName, texture)); #else OSStatus err; ComponentResult cr; /*FSRef fsref; Boolean isdir; err = FSPathMakeRef((const UInt8*)filePath, &fsref, &isdir); if(err)return; FSSpec fsspec; err = FSGetCatalogInfo(&fsref, kFSCatInfoNone, NULL, NULL, &fsspec, NULL); if(err)return; */ //Boolean isdir; FSSpec fsspec; //err = FSMakeFSSpec (0, 0, (const unsigned char*)filePath, &fsspec); err = FSMakeFSSpec (0, 0, filePath, &fsspec); //err=FSPathMakeFSSpec((const UInt8*)filePath,&fsspec,&isdir);*/ if(err)return; GraphicsImportComponent gi; err = GetGraphicsImporterForFile(&fsspec, &gi); if(err)return; Rect natbounds; cr = GraphicsImportGetNaturalBounds(gi, &natbounds); size_t buffersize = 4 * natbounds.bottom * natbounds.right; //void* buf = malloc(buffersize); texture.sizeX=natbounds.right; texture.sizeY=natbounds.bottom; /*if(hasalpha)*/texture.bpp = 32; //if(!hasalpha)texture.bpp = 24; GWorldPtr gw; err = QTNewGWorldFromPtr(&gw, k32ARGBPixelFormat, &natbounds, NULL, NULL, 0, texture.data, 4 * natbounds.right); if(err)return; cr = GraphicsImportSetGWorld(gi, gw, NULL); natbounds.top = natbounds.bottom; natbounds.bottom = 0; cr = GraphicsImportSetBoundsRect(gi, &natbounds); cr = GraphicsImportDraw(gi); err = CloseComponent(gi); if(err)return; /*glTexImage2D(textureTarget, 0, GL_RGBA, natbounds.right, natbounds.top, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buf); */ //free(buf); DisposeGWorld(gw); // Loop Through The Image Data GLuint imageSize; // Used To Store The Image Size When Setting Aside Ram GLuint temp; // Temporary Variable GLuint bytesPerPixel; // Temporary Variable bytesPerPixel=texture.bpp/8; imageSize = texture.sizeX * texture.sizeY * bytesPerPixel; int alltrans=10; for( GLuint i = 0; i < int( imageSize ); i += 4 ) { // Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue) temp = texture.data[i]; // Temporarily Store The Value At Image Data 'i' texture.data[i] = texture.data[i + 1]; // Set The 1st Byte To The Value Of The 3rd Byte texture.data[i + 1] = texture.data[i + 2]; // Set The 3rd Byte To The Value In 'temp' (1st Byte Value) texture.data[i + 2] = texture.data[i + 3]; texture.data[i + 3] = temp; } int tempplace; tempplace=0; if(!hasalpha){ for( GLuint i = 0; i < int( imageSize ); i += 4 ) { texture.data[i + 3] = 255; /*texture.data[tempplace] = texture.data[i]; // Set The 1st Byte To The Value Of The 3rd Byte texture.data[tempplace + 1] = texture.data[i + 1]; // Set The 3rd Byte To The Value In 'temp' (1st Byte Value) texture.data[tempplace + 2] = texture.data[i + 2]; tempplace+=3;*/ } } if(texdetail>1){ int which=0; float temp; float howmany; for( GLuint k = 0; k < int( imageSize); k += bytesPerPixel*texture.sizeX*texdetail ) { for( GLuint i = 0; i < int( imageSize/texture.sizeY ); i += bytesPerPixel*texdetail ) { for( GLuint b = 0; b < bytesPerPixel ; b ++ ){ temp=0; howmany=0; for( GLuint l = 0; l < texdetail*texture.sizeX ; l +=texture.sizeX ){ for( GLuint j = 0; j < texdetail ; j ++ ) { temp += (int)texture.data[k+i+j*bytesPerPixel+l*bytesPerPixel+b]; // Set The 1st Byte To The Value Of The 3rd Byte howmany++; } } texture.data[which+b]=GLubyte(temp/howmany); } which+=bytesPerPixel; } } texture.sizeX/=texdetail; texture.sizeY/=texdetail; } return true; #endif }
bool macsgCamera::initCamera(int width, int height, bool colour) { if (cameraID < 0) return false; this->width = width; this->height = height; this->colour = colour; this->fps = 30; bytes = (colour?3:1); int rowlength= width*bytes; switch (colour) { case false: { pixelFormat = k8IndexedGrayPixelFormat; //pixelFormat = kYVYU422PixelFormat; break; } case true: { pixelFormat = k24RGBPixelFormat; break; } } OSErr result; Rect srcRect = {0,0, height, width}; sg = OpenDefaultComponent(SeqGrabComponentType, 0); if(sg==NULL){ fprintf(stderr, "could not open default component\n"); } result = SGInitialize(sg); if(result!=noErr){ fprintf(stdout, "could not initialize SG\n"); } result = SGSetDataRef(sg, 0, 0, seqGrabDontMakeMovie); if (result != noErr){ fprintf(stdout, "dataref failed\n"); } result = SGNewChannel(sg, VideoMediaType, &vc); if(result!=noErr){ //fprintf(stdout, "could not make new SG channnel\n"); return false; } result = SGSettingsDialog ( sg, vc ,0 ,NULL ,seqGrabSettingsPreviewOnly,NULL,0); if(result!=noErr){ fprintf(stdout, "could not get settings from dialog\n"); } result = SGSetChannelBounds(vc, &srcRect); if(result!=noErr){ fprintf(stdout, "could not set SG ChannelBounds\n"); } /*result = SGSetFrameRate (vc, fps); if(result!=noErr){ fprintf(stdout, "could not set SG FrameRate\n"); }*/ result = SGSetChannelUsage(vc, seqGrabPreview); if(result!=noErr){ fprintf(stdout, "could not set SG ChannelUsage\n"); } result = SGSetChannelPlayFlags(vc, channelPlayAllData); if(result!=noErr){ fprintf(stdout, "could not set SG AllData\n"); }; buffer = new unsigned char[width*height*bytes]; result = QTNewGWorldFromPtr (&srcGWorld, pixelFormat, &srcRect, NULL, NULL, 0, buffer, rowlength); if (result!= noErr) { fprintf(stdout, "%d error at QTNewGWorldFromPtr\n", result); delete []buffer; buffer = NULL; return false; } if (srcGWorld == NULL) { fprintf(stdout, "Could not allocate off screen\n"); delete []buffer; buffer = NULL; return false; } result = SGSetGWorld(sg,(CGrafPtr)srcGWorld, NULL); if (result != noErr) { fprintf(stdout, "Could not set SGSetGWorld\n"); delete []buffer; buffer = NULL; return false; } result = SGPrepare(sg, TRUE, FALSE); if (result != noErr) { fprintf(stderr, "SGPrepare Preview failed\n"); } pbuffer = new unsigned char[width*height*bytes]; return true; }
//-------------------------------------------------------------------- bool ofVideoGrabber::initGrabber(int w, int h, bool setUseTexture){ bUseTexture = setUseTexture; //--------------------------------- #ifdef OF_VIDEO_CAPTURE_QUICKTIME //--------------------------------- //---------------------------------- 1 - open the sequence grabber if( !qtInitSeqGrabber() ){ ofLog(OF_LOG_ERROR, "error: unable to initialize the seq grabber"); return false; } //---------------------------------- 2 - set the dimensions width = w; height = h; MacSetRect(&videoRect, 0, 0, width, height); //---------------------------------- 3 - buffer allocation // Create a buffer big enough to hold the video data, // make sure the pointer is 32-byte aligned. // also the rgb image that people will grab offscreenGWorldPixels = (unsigned char*)malloc(4 * width * height + 32); pixels = new unsigned char[width*height*3]; QTNewGWorldFromPtr (&videogworld, k32ARGBPixelFormat, &videoRect, NULL, NULL, 0, offscreenGWorldPixels, 4 * width); LockPixels(GetGWorldPixMap(videogworld)); SetGWorld (videogworld, NULL); SGSetGWorld(gSeqGrabber, videogworld, nil); //---------------------------------- 4 - device selection bool didWeChooseADevice = bChooseDevice; bool deviceIsSelected = false; //if we have a device selected then try first to setup //that device if(didWeChooseADevice){ deviceIsSelected = qtSelectDevice(deviceID, true); if(!deviceIsSelected && bVerbose) ofLog(OF_LOG_WARNING, "unable to open device[%i] - will attempt other devices", deviceID); } //if we couldn't select our required device //or we aren't specifiying a device to setup //then lets try to setup ANY device! if(deviceIsSelected == false){ //lets list available devices listDevices(); setDeviceID(0); deviceIsSelected = qtSelectDevice(deviceID, false); } //if we still haven't been able to setup a device //we should error and stop! if( deviceIsSelected == false){ goto bail; } //---------------------------------- 5 - final initialization steps OSStatus err; err = SGSetChannelUsage(gVideoChannel,seqGrabPreview); if ( err != noErr ) goto bail; err = SGSetChannelBounds(gVideoChannel, &videoRect); if ( err != noErr ) goto bail; err = SGPrepare(gSeqGrabber, true, false); //theo swapped so preview is true and capture is false if ( err != noErr ) goto bail; err = SGStartPreview(gSeqGrabber); if ( err != noErr ) goto bail; bGrabberInited = true; loadSettings(); ofLog(OF_LOG_NOTICE,"end setup ofVideoGrabber"); ofLog(OF_LOG_NOTICE,"-------------------------------------\n"); //---------------------------------- 6 - setup texture if needed if (bUseTexture){ // create the texture, set the pixels to black and // upload them to the texture (so at least we see nothing black the callback) tex.allocate(width,height,GL_RGB); memset(pixels, 0, width*height*3); tex.loadData(pixels, width, height, GL_RGB); } // we are done return true; //--------------------- (bail) something's wrong ----- bail: ofLog(OF_LOG_ERROR, "***** ofVideoGrabber error *****"); ofLog(OF_LOG_ERROR, "-------------------------------------\n"); //if we don't close this - it messes up the next device! if(bSgInited) qtCloseSeqGrabber(); bGrabberInited = false; return false; //--------------------------------- #endif //--------------------------------- //--------------------------------- #ifdef OF_VIDEO_CAPTURE_DIRECTSHOW //--------------------------------- //printf("ofVideoGrabber.bChooseDevice: %s",bChooseDevice ? "true" : "false"); if (bChooseDevice){ device = deviceID; ofLog(OF_LOG_NOTICE, "choosing %i", deviceID); } else { device = 0; } width = w; height = h; bGrabberInited = false; bool bOk = VI.setupDevice(device, width, height); int ourRequestedWidth = width; int ourRequestedHeight = height; std::cout << "ourRequestedWidth :"<< width<<std::endl; std::cout << "bOk :"<< bOk<<std::endl; if (bOk == true){ bGrabberInited = true; width = VI.getWidth(device); height = VI.getHeight(device); if (width == ourRequestedWidth && height == ourRequestedHeight){ bDoWeNeedToResize = false; } else { bDoWeNeedToResize = true; width = ourRequestedWidth; height = ourRequestedHeight; } std::cout << "ourRequestedWidth :"<< width<<std::endl; pixels = new unsigned char[width * height * 3]; if (bUseTexture){ // create the texture, set the pixels to black and // upload them to the texture (so at least we see nothing black the callback) tex.allocate(width,height,GL_RGB); memset(pixels, 0, width*height*3); tex.loadData(pixels, width, height, GL_RGB); } return true; } else { ofLog(OF_LOG_ERROR, "error allocating a video device"); ofLog(OF_LOG_ERROR, "please check your camera with AMCAP or other software"); bGrabberInited = false; return false; } //--------------------------------- #endif //--------------------------------- //--------------------------------- #ifdef OF_VIDEO_CAPTURE_UNICAP //-------------------------------- if( !bGrabberInited ){ if ( !bChooseDevice ){ deviceID = 0; } width = w; height = h; pixels = new unsigned char[width * height * 3]; if (bUseTexture){ // create the texture, set the pixels to black and // upload them to the texture (so at least we see nothing black the callback) tex.allocate(width,height,GL_RGB); memset(pixels, 0, width*height*3); tex.loadData(pixels, width, height, GL_RGB); } bGrabberInited = ucGrabber.open_device (deviceID); if( bGrabberInited ){ ofLog(OF_LOG_NOTICE, "choosing device %i: %s", deviceID,ucGrabber.device_identifier()); ucGrabber.set_format(w,h); ucGrabber.start_capture(); } } return bGrabberInited; //--------------------------------- #endif //--------------------------------- //--------------------------------- #ifdef OF_VIDEO_CAPTURE_V4L //-------------------------------- if (bChooseDevice){ device = deviceID; } else { device = 0; } sprintf(dev_name, "/dev/video%i", device); ofLog(OF_LOG_NOTICE, "choosing device "+dev_name+""); bool bOk = initV4L(w, h, dev_name); if (bOk == true){ bV4LGrabberInited = true; width = getV4L_Width(); height = getV4L_Height(); pixels = new unsigned char[width * height * 3]; if (bUseTexture){ // create the texture, set the pixels to black and // upload them to the texture (so at least we see nothing black the callback) tex.allocate(width,height,GL_RGB); //memset(pixels, 0, width*height*3); //tex.loadData(pixels, width, height, GL_RGB); } ofLog(OF_LOG_NOTICE, "success allocating a video device "); return true; } else { ofLog(OF_LOG_ERROR, "error allocating a video device"); ofLog(OF_LOG_ERROR, "please check your camera and verify that your driver is correctly installed."); return false; } //--------------------------------- //--------------------------------- #endif //--------------------------------- }
GWorldPtr OpenImage (void) { unsigned long rowStride; GraphicsImportComponent giComp; NavReplyRecord replyNav; NavTypeListHandle hTypeList = (NavTypeListHandle) NewHandleClear (sizeof (NavTypeList) + sizeof (OSType) * 13); FSSpec fsspecImage; AEKeyword theKeyword; DescType actualType; Size actualSize; OSStatus err = noErr; Rect rectImage; GDHandle origDevice; CGrafPtr origPort; PixMapHandle hPixMap; ImageDescriptionHandle hImageDesc; MatrixRecord matrix; GWorldPtr pGWorld; unsigned char * pImageBuffer; long imageWidth; long imageHeight; float imageAspect; long imageDepth; long textureWidth; long textureHeight; GetGWorld (&origPort, &origDevice); // save onscreen graphics port HLock ((Handle) hTypeList); (**hTypeList).osTypeCount = 14; (**hTypeList).osType[0] = 'qtif'; (**hTypeList).osType[1] = 'SGI '; (**hTypeList).osType[2] = '8BPS'; (**hTypeList).osType[3] = 'GIF '; (**hTypeList).osType[4] = 'GIFf'; (**hTypeList).osType[5] = 'JPEG'; (**hTypeList).osType[6] = 'JPG '; (**hTypeList).osType[7] = 'PICT'; (**hTypeList).osType[8] = 'PNTG'; (**hTypeList).osType[9] = 'grip'; (**hTypeList).osType[10] = 'BMPp'; (**hTypeList).osType[11] = 'TIFF'; (**hTypeList).osType[12] = 'TEXT'; (**hTypeList).osType[13] = '????'; err = NavChooseFile (NULL, &replyNav, NULL, NULL, NULL, NULL, hTypeList, NULL); if ((err == noErr) && (replyNav.validRecord)) err = AEGetNthPtr (&(replyNav.selection), 1, typeFSS, &theKeyword, &actualType, &fsspecImage, sizeof (fsspecImage), &actualSize); NavDisposeReply (&replyNav); if (err != noErr) return NULL; GetGraphicsImporterForFile (&fsspecImage, &giComp); if (err != noErr) return NULL; // create GWorld err = GraphicsImportGetNaturalBounds (giComp, &rectImage); if (err != noErr) return NULL; hImageDesc = (ImageDescriptionHandle) NewHandle (sizeof (ImageDescriptionHandle)); HLock ((Handle) hImageDesc); err = GraphicsImportGetImageDescription (giComp, &hImageDesc); if (err != noErr) return NULL; imageWidth = rectImage.right - rectImage.left; imageHeight = rectImage.bottom - rectImage.top; imageAspect = ((float) imageWidth) / ((float) imageHeight); imageDepth = (**hImageDesc).depth; // bits if (imageDepth <= 16) imageDepth = 16; else imageDepth = 32; #if 1 textureWidth = imageWidth;//40;//imageWidth;//256; textureHeight = imageHeight;//40 * imageHeight / imageWidth;//imageHeight;//256; #else textureWidth = imageWidth;//256; textureHeight = imageHeight;//256; #endif SetRect (&rectImage, 0, 0, textureWidth, textureHeight); // l, t, r. b reset to texture rectangle rowStride = textureWidth * imageDepth / 8; pImageBuffer = (unsigned char *) NewPtrClear (rowStride * (textureHeight)); if (imageDepth == 32) QTNewGWorldFromPtr (&(pGWorld), k32ARGBPixelFormat, &rectImage, NULL, NULL, 0, pImageBuffer, rowStride); else QTNewGWorldFromPtr (&(pGWorld), k16BE555PixelFormat, &rectImage, NULL, NULL, 0, pImageBuffer, rowStride); if (NULL == pGWorld) return NULL; // decompress to gworld SetIdentityMatrix (&matrix); ScaleMatrix (&matrix, X2Fix ((float) textureWidth / (float) imageWidth), X2Fix ((float) textureHeight / (float) imageHeight), X2Fix (0.0), X2Fix (0.0)); err = GraphicsImportSetMatrix(giComp, &matrix); if (err != noErr) return NULL; err = GraphicsImportSetGWorld (giComp, pGWorld, NULL); if (err != noErr) return NULL; err = GraphicsImportSetQuality(giComp, codecLosslessQuality); if (err != noErr) return NULL; hPixMap = GetGWorldPixMap (pGWorld); if ((hPixMap) && (LockPixels (hPixMap))) // lock offscreen pixel map GraphicsImportDraw (giComp); else return NULL; // modify alpha if ( imageDepth == 32 ) { unsigned long i; unsigned long * pixel = (unsigned long *)GetPixBaseAddr( hPixMap ); for (i = 0; i < textureWidth * textureHeight; i++) { if ((*pixel & 0x00FFFFFF) == 0x00FF00) // mask only color bits and look for green *pixel = 0x00000000;//0x00303040; // replace green with dark gray transparent (to help filtering) else *pixel |= 0xFF000000; // ensure alpha is set for opaque pixels pixel++; } } else { unsigned short i; unsigned short * pixel = (unsigned short *)GetPixBaseAddr( hPixMap ); for (i = 0; i < textureWidth * textureHeight; i++) { if ((*pixel & 0x7FFF) == 0x03E0) // mask only color bits and look for green *pixel = 0x0000;//0x0363; // replace green with dark gray transparent (to help filtering) else *pixel |= 0x8000; // ensure alpha is set for opaque pixels pixel++; } } return pGWorld; }
void pix_videoDarwin :: InitSeqGrabber() { OSErr anErr; Rect m_srcRect = {0,0, m_vidYSize, m_vidXSize}; SGDeviceList devices; short deviceIndex,inputIndex; short deviceCount = 0; SGDeviceInputList theSGInputList = NULL; bool showInputsAsDevices; // UserData *uD; /* int num_components = 0; Component c = 0; ComponentDescription cd; cd.componentType = SeqGrabComponentType; cd.componentSubType = 0; cd.componentManufacturer = 0; cd.componentFlags = 0; cd.componentFlagsMask = 0; while((c = FindNextComponent(c, &cd)) != 0) { num_components++; } // add component c to the list. // post("number of SGcomponents: %d",num_components); */ m_sg = OpenDefaultComponent(SeqGrabComponentType, 0); if(m_sg==NULL){ error("could not open default component"); return; } anErr = SGInitialize(m_sg); if(anErr!=noErr){ error("could not initialize SG error %d",anErr); return; } anErr = SGSetDataRef(m_sg, 0, 0, seqGrabDontMakeMovie); if (anErr != noErr){ error("dataref failed with error %d",anErr); } anErr = SGNewChannel(m_sg, VideoMediaType, &m_vc); if(anErr!=noErr){ error("could not make new SG channnel error %d",anErr); return; } anErr = SGGetChannelDeviceList(m_vc, sgDeviceListIncludeInputs, &devices); if(anErr!=noErr){ error("could not get SG channnel Device List"); }else{ deviceCount = (*devices)->count; deviceIndex = (*devices)->selectedIndex; logpost(NULL, 3, "SG channnel Device List count %d index %d",deviceCount,deviceIndex); int i; for (i = 0; i < deviceCount; i++){ logpost(NULL, 3, "SG channnel Device List %.*s", (*devices)->entry[i].name[0], (*devices)->entry[i].name+1); } SGGetChannelDeviceAndInputNames(m_vc, NULL, NULL, &inputIndex); showInputsAsDevices = ((*devices)->entry[deviceIndex].flags) & sgDeviceNameFlagShowInputsAsDevices; theSGInputList = ((SGDeviceName *)(&((*devices)->entry[deviceIndex])))->inputs; //fugly //we should have device names in big ass undocumented structs //walk through the list //for (i = 0; i < deviceCount; i++){ for (i = 0; i < inputIndex; i++){ logpost(NULL, 3, "SG channnel Input Device List %d %.*s", i, (*theSGInputList)->entry[i].name[0], (*theSGInputList)->entry[i].name+1); } } //this call sets the input device if (m_inputDevice > 0 && m_inputDevice < deviceCount) //check that the device is not out of bounds //anErr = SGSetChannelDeviceInput(m_vc,m_inputDevice); logpost(NULL, 3, "SGSetChannelDevice trying %s", (*devices)->entry[m_inputDevice].name[0], (*devices)->entry[m_inputDevice].name+1); anErr = SGSetChannelDevice(m_vc, (*devices)->entry[m_inputDevice].name); if(anErr!=noErr) error("SGSetChannelDevice returned error %d",anErr); anErr = SGSetChannelDeviceInput(m_vc,m_inputDeviceChannel); if(anErr!=noErr) error("SGSetChannelDeviceInput returned error %d",anErr); /* //attempt to save SG settings to disk NewUserData(uD); SGGetSettings(m_sg,uD,0); short uDCount; uDCount = CountUserDataType(*uD,sgClipType); post("UserDataType count %d",uDCount); Handle myHandle; PutUserDataIntoHandle(*uD,myHandle); int myFile; myFile = open("/Users/lincoln/Documents/temp",O_CREAT | O_RDWR, 0600); write(myFile,myHandle,4096); close(myFile); */ //grab the VDIG info from the SGChannel m_vdig = SGGetVideoDigitizerComponent(m_vc); vdigErr = VDGetDigitizerInfo(m_vdig,&m_vdigInfo); //not sure if this is useful Str255 vdigName; memset(vdigName,0,255); vdigErr = VDGetInputName(m_vdig,m_inputDevice,vdigName); logpost(NULL, 3, "vdigName is %s",vdigName); // pascal string? Rect vdRect; vdigErr = VDGetDigitizerRect(m_vdig,&vdRect); logpost(NULL, 3, "digitizer rect is top %d bottom %d left %d right %d",vdRect.top,vdRect.bottom,vdRect.left,vdRect.right); vdigErr = VDGetActiveSrcRect(m_vdig,0,&vdRect); logpost(NULL, 3, "active src rect is top %d bottom %d left %d right %d",vdRect.top,vdRect.bottom,vdRect.left,vdRect.right); anErr = SGSetChannelBounds(m_vc, &m_srcRect); if(anErr!=noErr){ error("could not set SG ChannelBounds "); } anErr = SGSetVideoRect(m_vc, &m_srcRect); if(anErr!=noErr){ error("could not set SG Rect "); } anErr = SGSetChannelUsage(m_vc, seqGrabPreview); if(anErr!=noErr){ error("could not set SG ChannelUsage "); } switch (m_quality){ case 0: anErr = SGSetChannelPlayFlags(m_vc, channelPlayNormal); post("set SG NormalQuality"); break; case 1: anErr = SGSetChannelPlayFlags(m_vc, channelPlayHighQuality); post("set SG HighQuality"); break; case 2: anErr = SGSetChannelPlayFlags(m_vc, channelPlayFast); post("set SG FastQuality"); break; case 3: anErr = SGSetChannelPlayFlags(m_vc, channelPlayAllData); post("set SG PlayAlldata"); break; } if (m_colorspace==GL_BGRA_EXT){ m_pixBlock.image.xsize = m_vidXSize; m_pixBlock.image.ysize = m_vidYSize; m_pixBlock.image.setCsizeByFormat(GL_RGBA_GEM); m_pixBlock.image.reallocate(); m_rowBytes = m_vidXSize*4; anErr = QTNewGWorldFromPtr (&m_srcGWorld, k32ARGBPixelFormat, &m_srcRect, NULL, NULL, 0, m_pixBlock.image.data, m_rowBytes); post ("using RGB"); }else{ m_pixBlock.image.xsize = m_vidXSize; m_pixBlock.image.ysize = m_vidYSize; m_pixBlock.image.csize = 2; m_pixBlock.image.format = GL_YCBCR_422_APPLE; #ifdef __VEC__ m_pixBlock.image.type = GL_UNSIGNED_SHORT_8_8_REV_APPLE; #else m_pixBlock.image.type = GL_UNSIGNED_SHORT_8_8_APPLE; #endif m_pixBlock.image.reallocate(); m_rowBytes = m_vidXSize*2; anErr = QTNewGWorldFromPtr (&m_srcGWorld, // k422YpCbCr8CodecType, k422YpCbCr8PixelFormat, // '2vuy', // kComponentVideoUnsigned, &m_srcRect, NULL, NULL, 0, m_pixBlock.image.data, m_rowBytes); post ("using YUV"); } if (anErr!= noErr) { error("%d error at QTNewGWorldFromPtr", anErr); return; } if (NULL == m_srcGWorld) { error("could not allocate off screen"); return; } SGSetGWorld(m_sg,(CGrafPtr)m_srcGWorld, NULL); SGStartPreview(m_sg); //moved to starttransfer? m_haveVideo = 1; }
quicktime_recorder* quicktime_recorder::create( const char *path2, int width, int height, float fps ) { OSErr err; OSType dataRefType; Handle dataRef = NULL; impl *m = new impl(width, height); std::string pathStd = path2; #ifdef WIN32 for (std::string::iterator p = pathStd.begin(); p != pathStd.end(); ++p) if (*p == '/') *p = '\\'; #endif CFStringRef cfPath = CFStringCreateWithCString(NULL, pathStd.c_str(), kCFStringEncodingISOLatin1); err = QTNewDataReferenceFromFullPathCFString(cfPath, kQTNativeDefaultPathStyle, 0, &dataRef, &dataRefType); CFRelease(cfPath); if (err != noErr) { delete m; return NULL; } err = CreateMovieStorage(dataRef, dataRefType, FOUR_CHAR_CODE('TVOD'), smSystemScript, createMovieFileDeleteCurFile | createMovieFileDontCreateResFile, &m->data_handler, &m->movie); DisposeHandle(dataRef); if (err != noErr) { delete m; return NULL; } m->track = NewMovieTrack(m->movie, FixRatio(m->width, 1), FixRatio(m->height, 1), kNoVolume); err &= GetMoviesError(); TimeScale timeScale = (TimeScale)(fps * 100.0f); m->media = NewTrackMedia(m->track, VideoMediaType, timeScale, nil, 0 ); err &= GetMoviesError(); if (err != noErr) { delete m; return NULL; } SetMovieTimeScale(m->movie, timeScale); m->buffer = new unsigned char[4 * m->width * m->height]; Rect rect; rect.left = rect.top = 0; rect.right = m->width; rect.bottom = m->height; err = QTNewGWorldFromPtr(&m->gworld, k32BGRAPixelFormat, &rect, NULL, NULL, 0, m->buffer, 4 * m->width); if (err != noErr) { delete m; return NULL; } m->pixmap = GetGWorldPixMap(m->gworld); if (!m->pixmap) { delete m; return NULL; } LockPixels(m->pixmap); long maxSize = 0; err = GetMaxCompressionSize(m->pixmap, &rect, 0, codecNormalQuality, kPNGCodecType, anyCodec, &maxSize); if (err != noErr) { delete m; return NULL; } m->handle = NewHandle(maxSize); if (!m->handle) { delete m; return NULL; } HLockHi(m->handle); m->ptr = *m->handle; m->image_desc = (ImageDescriptionHandle)NewHandle(4); if (!m->image_desc) { delete m; return NULL; } err = BeginMediaEdits( m->media ); if (err != noErr) { delete m; return NULL; } return new quicktime_recorder(m); }
void MacQTRecordFrame(int width, int height) { OSStatus err; // video Rect rct; SetRect(&rct, 0, 0, width, height); if (((sqt.pw != width) || (sqt.ph != height)) || (((drawingMethod == kDrawingDirect) || (drawingMethod == kDrawingBlitGL)) && multiprocessor)) { if (sqt.gw) { DisposeGWorld(sqt.gw); sqt.gw = nil; } int pitch = Settings.OpenGLEnable ? (width << 1) : (SNES_WIDTH << 2); #ifdef __BIG_ENDIAN__ err = QTNewGWorldFromPtr(&(sqt.gw), k16BE555PixelFormat, &rct, nil, nil, 0, GFX.Screen, pitch); #else err = QTNewGWorldFromPtr(&(sqt.gw), k16LE555PixelFormat, &rct, nil, nil, 0, GFX.Screen, pitch); #endif CheckError(err, 41); sqt.pw = width; sqt.ph = height; } if (sqt.frameSkipCount == sqt.frameSkip) { Rect src, dst; src = rct; if ((!(height % SNES_HEIGHT_EXTENDED)) && (!(macQTMovFlag & kMovExtendedHeight))) src.bottom = SNES_HEIGHT << ((height > 256) ? 1 : 0); if ((sqt.frame.bottom << 1) % src.bottom) { Rect b1, b2; b1.left = b2.left = dst.left = 0; b1.right = b2.right = dst.right = sqt.frame.right; int x = (macQTMovFlag & kMovDoubleSize) ? 1 : 0; if (drawoverscan) { b1.top = 0; b1.bottom = 0; b2.top = SNES_HEIGHT << x; b2.bottom = SNES_HEIGHT_EXTENDED << x; } else { b1.top = 0; b1.bottom = (SNES_HEIGHT_EXTENDED - SNES_HEIGHT) >> (1 - x); b2.top = b1.bottom + (SNES_HEIGHT << x); b2.bottom = SNES_HEIGHT_EXTENDED << x; } dst.top = b1.bottom; dst.bottom = b2.top; PrepareForGDrawing(sqt.bw); PaintRect(&b1); PaintRect(&b2); FinishGDrawing(sqt.bw); }
bool LoadTexture(IplTexture *tex, const char *filename, const char *subdir) { ComponentInstance fileImporter; OSErr error; ImageDescriptionHandle imageInfo; ComponentResult err; CFStringRef name = CFStringCreateWithCStringNoCopy(NULL, filename, kCFStringEncodingASCII, NULL); CFStringRef _subdir = CFStringCreateWithCStringNoCopy(NULL, subdir, kCFStringEncodingASCII, NULL); CFURLRef texture_url = CFBundleCopyResourceURL( CFBundleGetMainBundle(), name, NULL, _subdir); // Create the data reference so we can get the file's graphics importer. Handle dataRef; OSType dataRefType; dataRef = NewHandle(sizeof(AliasHandle)); // The second parameter to QTNewDataReferenceFromCFURL is flags. // It should be set to 0. error = QTNewDataReferenceFromCFURL(texture_url, 0, &dataRef, &dataRefType); if(error != noErr) { //DisposeHandle(dataRef); //CFRelease(texture_url); return false; } // Get the importer for the file so we can read the information. error = GetGraphicsImporterForDataRef(dataRef, dataRefType, &fileImporter); // Retrieve information about the image imageInfo = (ImageDescriptionHandle)NewHandle(sizeof(ImageDescription)); err = GraphicsImportGetImageDescription(fileImporter, &imageInfo); unsigned width = ((**imageInfo).width); unsigned height = ((**imageInfo).height); IplImage *im = tex->getIm(); if (im && (im->width != width || im->height!=height)) cvReleaseImage(&im); if (im==0) { im = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U, 4); //memset(im->imageData, 0x8f, 30*im->widthStep ); //memset(im->imageData+ 50*im->widthStep, 0xff, 30*im->widthStep); tex->setImage(im); //return true; } tex->update(); void *imageData = im->imageData; // Get the boundary rectangle of the image Rect imageRect; err = GraphicsImportGetNaturalBounds(fileImporter, &imageRect); // Create an offscreen buffer to hold the image. // Apparently QuickTime requires a GWorld to // decompress a texture file. long bytesPerRow = im->widthStep; //static GWorldPtr offscreenBuffer=0; if (offscreenBuffer==0) { error = QTNewGWorldFromPtr(&offscreenBuffer, k32RGBAPixelFormat, &imageRect, NULL, NULL, kNativeEndianPixMap, imageData, bytesPerRow); assert(error == noErr); } // Draw the image into the offscreen buffer err = GraphicsImportSetGWorld(fileImporter, offscreenBuffer, NULL); assert(err == noErr); err = GraphicsImportDraw(fileImporter); assert(err == noErr); // Cleanup error = CloseComponent(fileImporter); DisposeHandle((Handle)imageInfo); DisposeHandle(dataRef); DisposeGWorld(offscreenBuffer); return true; }