bool ofQtVideoSaver::setCodecPhotoJpeg() { initializeQuicktime(); OSStatus error = noErr; CodecNameSpecListPtr list; CodecNameSpec * codecNameSpecPtr; char typeName[32]; bool set = false; error = GetCodecNameList( &list, 0 ); if ( error ) return false; int numCodecs = list->count; codecNameSpecPtr = (CodecNameSpec *)((short *)list + 1); for (int i = 0; i < numCodecs; i++ ){ p2cstrcpy( typeName, codecNameSpecPtr->typeName ); //printf("codec (%i) = %s \n", i, typeName); codecNameSpecPtr++; //if(string(typeName) == "Photo - JPEG") //if(string(typeName) == "H.264") if(string(typeName) == "MPEG-4 Video") { codecType = codecNameSpecPtr->cType; set = true; printf("Setting Codec to %s\n", typeName); break; } } DisposeCodecNameList( list ); return set; }
//-------------------------------------------------------------------- ofQuickTimeGrabber::ofQuickTimeGrabber(){ //--------------------------------- #ifdef OF_VIDEO_CAPTURE_QUICKTIME //--------------------------------- initializeQuicktime(); bSgInited = false; gSeqGrabber = NULL; offscreenGWorldPixels = NULL; //--------------------------------- #endif //--------------------------------- // common bIsFrameNew = false; bVerbose = false; bGrabberInited = false; bChooseDevice = false; deviceID = 0; //width = 320; // default setting //height = 240; // default setting //pixels = NULL; attemptFramerate = -1; }
//-------------------------------------------------------------------- ofVideoGrabber::ofVideoGrabber(){ //--------------------------------- #ifdef OF_VIDEO_CAPTURE_QUICKTIME //--------------------------------- initializeQuicktime(); bSgInited = false; pixels = NULL; gSeqGrabber = NULL; offscreenGWorldPixels = NULL; //--------------------------------- #endif //--------------------------------- //--------------------------------- #ifdef OF_VIDEO_CAPTURE_DIRECTSHOW //--------------------------------- bVerbose = false; bDoWeNeedToResize = false; //--------------------------------- #endif //--------------------------------- //--------------------------------- #ifdef OF_VIDEO_CAPTURE_V4L // kept around if people have unicap issues... //-------------------------------- bV4LGrabberInited = false; //--------------------------------- #endif //--------------------------------- // common bIsFrameNew = false; bVerbose = false; bGrabberInited = false; bUseTexture = true; bChooseDevice = false; deviceID = 0; width = 320; // default setting height = 240; // default setting pixels = NULL; }
//-------------------------------------------------------------- void ofQtVideoSaver::listCodecs(){ initializeQuicktime(); OSStatus error = noErr; CodecNameSpecListPtr list; CodecNameSpec * codecNameSpecPtr; char typeName[32]; error = GetCodecNameList( &list, 0 ); if ( error ) return; int numCodecs = list->count; codecNameSpecPtr = (CodecNameSpec *)((short *)list + 1); for (int i = 0; i < numCodecs; i++ ){ p2cstrcpy( typeName, codecNameSpecPtr->typeName ); printf("codec (%i) = %s \n", i, typeName); codecNameSpecPtr++; } DisposeCodecNameList( list ); }
//-------------------------------------------------------------- void ofQtVideoSaver::setCodecType( int chosenCodec ){ initializeQuicktime(); OSStatus error = noErr; CodecNameSpecListPtr list; CodecNameSpec * codecNameSpecPtr; char typeName[32]; error = GetCodecNameList( &list, 0 ); if ( error ) return; int numCodecs = list->count; codecNameSpecPtr = (CodecNameSpec *)((short *)list + 1); for (int i = 0; i < numCodecs; i++ ){ if (i == chosenCodec){ p2cstrcpy( typeName, codecNameSpecPtr->typeName ); printf("trying to set codec type to (%s) \n", typeName); codecType = codecNameSpecPtr->cType; } codecNameSpecPtr++; } }
void ofQtVideoSaver::setup( int width , int height, string movieName){ w = width; h = height; fileName = (ofToDataPath(movieName)); //pszFlatFilename = flatFileName; initializeQuicktime(); /* Load the FSSpec structure to describe the receiving file. For a description of this and related calls see http://developer.apple.com/quicktime/icefloe/dispatch004.html. ================================================================ */ #ifdef TARGET_WIN32 //FILE * pFile = NULL; //pFile = fopen (fileName.c_str(),"w"); //fclose (pFile); char fileNameStr[255]; sprintf(fileNameStr, "%s", fileName.c_str()); osErr = NativePathNameToFSSpec (fileNameStr, &fsSpec, 0); #endif #ifdef TARGET_OSX /// kill a file and make a new one if needed: FILE * pFile; pFile = fopen (fileName.c_str(),"w"); fclose (pFile); Boolean isdir; osErr = FSPathMakeRef((const UInt8*)fileName.c_str(), &fsref, &isdir); osErr = FSGetCatalogInfo(&fsref, kFSCatInfoNone, NULL, NULL, &fsSpec, NULL); #endif if (osErr && (osErr != fnfErr)) /* File-not-found error is ok */ { printf ("getting FSS spec failed %d\n", osErr); goto bail; } /* Step 1: Create a new, empty movie file and a movie that references that file (CreateMovieFile). ======================================================================== */ osErr = CreateMovieFile ( &fsSpec, /* FSSpec specifier */ FOUR_CHAR_CODE('TVOD'), /* file creator type, TVOD = QT player*/ smCurrentScript, /* movie script system to use */ createMovieFileDeleteCurFile /* movie file creation flags */ | createMovieFileDontCreateResFile, &sResRefNum, /* returned file ref num to data fork */ &movie /* returned handle to open empty movie*/ /* that references the created file */ ); if (osErr) { printf ("CreateMovieFile failed %d\n", osErr); goto bail; } /* Step 2: Add a new track to that movie (NewMovieTrack). ======================================================= */ track = NewMovieTrack ( movie, /* the movie to add track to */ ((long) w << 16), /* width of track in pixels (Fixed) */ FixRatio (h, 1), /* height of track in pixels (Fixed) */ kNoVolume /* default volume level */ ); osErr = GetMoviesError (); if (osErr) { printf ("NewMovieTrack failed %d\n", osErr); goto bail; } /* Step 3: Add a new media to that track (NewTrackMedia). ======================================================= */ media = NewTrackMedia ( track, /* the track to add the media to */ VideoMediaType, /* media type, e.g. SoundMediaType */ 600, /* num media time units that elapse/sec*/ NULL, /* ptr to file that holds media sampls*/ 0 /* type of ptr to media samples */ ); osErr = GetMoviesError (); if (osErr) { printf ("NewTrackMedia failed %d\n", osErr); goto bail; } /* Step 4: Add media samples to the media. ======================================== */ BeginMediaEdits (media); /* Inform the Movie Toolbox that we */ /* want to change the media samples */ /* referenced by a track's media. */ /* This opens the media container */ /* and makes it ready to receive */ /* and/or remove sample data. */ // Step 5: setup graphics port for qt movie and compression type --- /* Create a new offscreen graphics world that will hold the movie's drawing surface. draw_image() copies the image of IceFlow to this surface with varying amounts of transparency. ================================================================= */ MacSetRect (&rect, 0, 0, w, h); osErr = NewGWorld ( &pMovieGWorld, /* receives the new GWorld. */ 24, /* pixel depth in bits/pixel */ &rect, /* desired size of the GWorld. */ NULL, NULL, (GWorldFlags) 0 ); if (osErr != noErr) { printf ("NewGWorld 1 failed %d\n", osErr); goto bail; } /* Retrieve the pixel map associated with that graphics world and lock the pixel map in memory. GetMaxCompressionSize() and CompressImage() only operate on pixel maps, not graphics worlds. ===================================================================== */ pixMapHandle = GetGWorldPixMap (pMovieGWorld); if (pixMapHandle == NULL) { printf ("GetGWorldPixMap failed\n"); goto bail; } LockPixels (pixMapHandle); /* Get the maximum number of bytes required to hold an image having the specified characteristics compressed using the specified compressor. ==================================================================== */ osErr = GetMaxCompressionSize ( pixMapHandle, /* the pixel map to compress from. */ &rect, /* the image rectangle. */ 0, /* let ICM choose image bit depth. */ codecHighQuality, /* compression quality specifier. */ kRawCodecType, /* desired compression type */ // < set to RAW in case we set to a new compression type... (CompressorComponent) anyCodec, /* codec specifier. */ &lMaxCompressionSize /* receives max bytes needed for cmp. */ ); if (osErr != noErr) { printf ("GetMaxCompressionSize failed %d\n", osErr); goto bail; } /* Allocate a buffer to hold the compressed image data by creating a new handle. ===================================================================== */ hCompressedData = NewHandle (lMaxCompressionSize); if (hCompressedData == NULL) { printf ("NewHandle(%ld) failed\n", lMaxCompressionSize); goto bail; } /* Lock the handle and then dereference it to obtain a pointer to the data buffer because CompressImage() wants us to pass it a pointer, not a handle. ======================================================================= */ HLockHi (hCompressedData); pCompressedData = *hCompressedData; /* Create an image description object in memory of minimum size to pass to CompressImage(). CompressImage() will resize the memory as necessary so create it small here. ==================================================================== */ hImageDescription = (ImageDescriptionHandle) NewHandle (4); if (hImageDescription == NULL) { printf ("NewHandle(4) failed\n"); goto bail; } bSetupForRecordingMovie = true; return; bail: printf("got to bail somehows \n"); if (sResRefNum != 0) CloseMovieFile (sResRefNum); if (movie != NULL) DisposeMovie (movie); //ExitMovies (); /* Finalize Quicktime */ return; }
//-------------------------------------------------------------- ofxThreadedVideo::ofxThreadedVideo(){ instanceID = ofxThreadedVideoGlobalInstanceID; ofxThreadedVideoGlobalInstanceID++; #ifdef OF_VIDEO_PLAYER_GSTREAMER setPlayer<ofGstVideoPlayer>(); #else initializeQuicktime(); setPlayer<ofQuickTimePlayer>(); #endif // setup video instances video[0].setUseTexture(false); video[1].setUseTexture(false); setPixelFormat(OF_PIXELS_RGB); drawTexture.allocate(1, 1, GL_RGB); ofPixels p; p.allocate(1, 1, OF_IMAGE_COLOR); p.set(0); drawTexture.loadData(p.getPixels(), 1, 1, GL_RGB); pixels = &video[0].getPixelsRef(); // set vars to default values currentVideoID = VIDEO_FLIP; bCriticalSection = false; bLoaded = false; bUseTexture = true; bIsFrameNew = false; bIsPlaying = false; bIsLoading = false; bIsMovieDone = false; width = 0.0f; height = 0.0f; speed = 0.0f; position = 0.0f; duration = 0.0f; volume = 0.0f; pan = 0.0f; loopState = OF_LOOP_NORMAL; frameCurrent = 0; frameTotal = 0; movieName = ""; moviePath = ""; fade = 1.0f; fades.clear(); prevMillis = ofGetElapsedTimeMillis(); lastFrameTime = timeNow = timeThen = fps = frameRate = 0; ofxThreadedVideoNullCommand.setCommand("NULL_COMMAND", -1); bVerbose = false; // let's go! startThread(); }
//--------------------------------------------------------------------------- bool ofQuickTimePlayer::loadMovie(string name){ //-------------------------------------- #ifdef OF_VIDEO_PLAYER_QUICKTIME //-------------------------------------- initializeQuicktime(); // init quicktime closeMovie(); // if we have a movie open, close it bLoaded = false; // try to load now if( name.substr(0, 7) == "http://" || name.substr(0,7) == "rtsp://" ){ if(! createMovieFromURL(name, moviePtr) ) return false; }else{ name = ofToDataPath(name); if( !createMovieFromPath((char *)name.c_str(), moviePtr) ) return false; } bool bDoWeAlreadyHaveAGworld = false; if (width != 0 && height != 0){ bDoWeAlreadyHaveAGworld = true; } Rect movieRect; GetMovieBox(moviePtr, &(movieRect)); if (bDoWeAlreadyHaveAGworld){ // is the gworld the same size, then lets *not* de-allocate and reallocate: if (width == movieRect.right && height == movieRect.bottom){ SetMovieGWorld (moviePtr, offscreenGWorld, nil); } else { width = movieRect.right; height = movieRect.bottom; pixels.clear(); delete(offscreenGWorldPixels); if ((offscreenGWorld)) DisposeGWorld((offscreenGWorld)); createImgMemAndGWorld(); } } else { width = movieRect.right; height = movieRect.bottom; createImgMemAndGWorld(); } if (moviePtr == NULL){ return false; } //----------------- callback method myDrawCompleteProc = NewMovieDrawingCompleteUPP (DrawCompleteProc); SetMovieDrawingCompleteProc (moviePtr, movieDrawingCallWhenChanged, myDrawCompleteProc, (long)this); // ------------- get the total # of frames: nFrames = 0; TimeValue curMovieTime; curMovieTime = 0; TimeValue duration; //OSType whichMediaType = VIDEO_TYPE; // mingw chokes on this OSType whichMediaType = FOUR_CHAR_CODE('vide'); short flags = nextTimeMediaSample + nextTimeEdgeOK; while( curMovieTime >= 0 ) { nFrames++; GetMovieNextInterestingTime(moviePtr,flags,1,&whichMediaType,curMovieTime,0,&curMovieTime,&duration); flags = nextTimeMediaSample; } nFrames--; // there's an extra time step at the end of themovie // ------------- get some pixels in there ------ GoToBeginningOfMovie(moviePtr); SetMovieActiveSegment(moviePtr, -1,-1); MoviesTask(moviePtr,0); #if defined(TARGET_OSX) && defined(__BIG_ENDIAN__) convertPixels(offscreenGWorldPixels, pixels.getPixels(), width, height); #endif bStarted = false; bLoaded = true; bPlaying = false; bHavePixelsChanged = false; speed = 1; return true; //-------------------------------------- #endif //-------------------------------------- }
//--------------------------------------------------------------------------- bool ofQuickTimePlayer::loadMovie(string name) { //-------------------------------------- #ifdef OF_VIDEO_PLAYER_QUICKTIME //-------------------------------------- initializeQuicktime(); // init quicktime closeMovie(); // if we have a movie open, close it bLoaded = false; // try to load now // from : https://github.com/openframeworks/openFrameworks/issues/244 // http://developer.apple.com/library/mac/#documentation/QuickTime/RM/QTforWindows/QTforWindows/C-Chapter/3BuildingQuickTimeCa.html // Apple's documentation *seems* to state that a Gworld should have been set prior to calling NewMovieFromFile // So I set a dummy Gworld (1x1 pixel) before calling createMovieFromPath // it avoids crash at the creation of objet ofVideoPlayer after a previous ofVideoPlayer have been deleted #ifdef TARGET_WIN32 if (width != 0 && height != 0) { pixels.clear(); delete [] offscreenGWorldPixels; } width = 1; height = 1; createImgMemAndGWorld(); #endif if( name.substr(0, 7) == "http://" || name.substr(0,7) == "rtsp://" ) { if(! createMovieFromURL(name, moviePtr) ) return false; } else { name = ofToDataPath(name); if( !createMovieFromPath((char *)name.c_str(), moviePtr) ) return false; } bool bDoWeAlreadyHaveAGworld = false; if (width != 0 && height != 0) { bDoWeAlreadyHaveAGworld = true; } Rect movieRect; GetMovieBox(moviePtr, &(movieRect)); if (bDoWeAlreadyHaveAGworld) { // is the gworld the same size, then lets *not* de-allocate and reallocate: if (width == movieRect.right && height == movieRect.bottom) { SetMovieGWorld (moviePtr, offscreenGWorld, nil); } else { width = movieRect.right; height = movieRect.bottom; pixels.clear(); delete [] offscreenGWorldPixels; if ((offscreenGWorld)) DisposeGWorld((offscreenGWorld)); createImgMemAndGWorld(); } } else { width = movieRect.right; height = movieRect.bottom; createImgMemAndGWorld(); } if (moviePtr == NULL) { return false; } //----------------- callback method myDrawCompleteProc = NewMovieDrawingCompleteUPP (DrawCompleteProc); SetMovieDrawingCompleteProc (moviePtr, movieDrawingCallWhenChanged, myDrawCompleteProc, (long)this); // ------------- get the total # of frames: nFrames = 0; TimeValue curMovieTime; curMovieTime = 0; TimeValue duration; //OSType whichMediaType = VIDEO_TYPE; // mingw chokes on this OSType whichMediaType = FOUR_CHAR_CODE('vide'); short flags = nextTimeMediaSample + nextTimeEdgeOK; while( curMovieTime >= 0 ) { nFrames++; GetMovieNextInterestingTime(moviePtr,flags,1,&whichMediaType,curMovieTime,0,&curMovieTime,&duration); flags = nextTimeMediaSample; } nFrames--; // there's an extra time step at the end of themovie // ------------- get some pixels in there ------ GoToBeginningOfMovie(moviePtr); SetMovieActiveSegment(moviePtr, -1,-1); MoviesTask(moviePtr,0); #if defined(TARGET_OSX) && defined(__BIG_ENDIAN__) convertPixels(offscreenGWorldPixels, pixels.getPixels(), width, height); #endif bStarted = false; bLoaded = true; bPlaying = false; bHavePixelsChanged = false; speed = 1; return true; //-------------------------------------- #endif //-------------------------------------- }
//--------------------------------------------------------------------------- bool ofVideoPlayer::loadMovie(string name){ //-------------------------------------- #ifdef OF_VIDEO_PLAYER_QUICKTIME //-------------------------------------- initializeQuicktime(); // init quicktime closeMovie(); // if we have a movie open, close it bLoaded = false; // try to load now if( name.substr(0, 7) == "http://"){ if(! createMovieFromURL(name, moviePtr) ) return false; }else{ name = ofToDataPath(name); if( !createMovieFromPath((char *)name.c_str(), moviePtr) ) return false; } bool bDoWeAlreadyHaveAGworld = false; if (width != 0 && height != 0){ bDoWeAlreadyHaveAGworld = true; } Rect movieRect; GetMovieBox(moviePtr, &(movieRect)); if (bDoWeAlreadyHaveAGworld){ // is the gworld the same size, then lets *not* de-allocate and reallocate: if (width == movieRect.right && height == movieRect.bottom){ SetMovieGWorld (moviePtr, offscreenGWorld, nil); } else { width = movieRect.right; height = movieRect.bottom; delete(pixels); delete(offscreenGWorldPixels); if ((offscreenGWorld)) DisposeGWorld((offscreenGWorld)); createImgMemAndGWorld(); } } else { width = movieRect.right; height = movieRect.bottom; createImgMemAndGWorld(); } if (moviePtr == NULL){ return false; } //----------------- callback method MovieDrawingCompleteUPP myDrawCompleteProc; myDrawCompleteProc = NewMovieDrawingCompleteUPP (DrawCompleteProc); SetMovieDrawingCompleteProc (moviePtr, movieDrawingCallWhenChanged, myDrawCompleteProc, (long)this); // ------------- get some pixels in there ------ GoToBeginningOfMovie(moviePtr); SetMovieActiveSegment(moviePtr, -1,-1); MoviesTask(moviePtr,0); convertPixels(offscreenGWorldPixels, pixels, width, height); if (bUseTexture == true){ tex.loadData(pixels, width, height, GL_RGB); } bStarted = false; bLoaded = true; bPlaying = false; bHavePixelsChanged = false; speed = 1; return true; //-------------------------------------- #else //-------------------------------------- bLoaded = false; bPaused = false; speed = 1.0f; bHavePixelsChanged = false; name = ofToDataPath(name); fobsDecoder = new omnividea::fobs::Decoder(name.c_str()); omnividea::fobs::ReturnCode error = fobsDecoder->open(); width = fobsDecoder->getWidth(); height = fobsDecoder->getHeight(); pixels = new unsigned char[width*height*3]; if (!fobsDecoder->isVideoPresent()){ return false; } bLoaded = true; 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); } error = fobsDecoder->setFrame(0); if(error == omnividea::fobs::NoFrameError) { error = omnividea::fobs::OkCode; printf("NoFrameError\n"); } if(omnividea::fobs::isOk(error)){ // get some pixels in: unsigned char *rgb = fobsDecoder->getRGB(); if(rgb == NULL) error = omnividea::fobs::GenericError; if(isOk(error)) { memcpy(pixels, rgb, width*height*3); tex.loadData(pixels, width, height, GL_RGB); } } iTotalFrames = (int)(fobsDecoder->getFrameRate()*fobsDecoder->getDurationSeconds()); positionPct = 0; timeLastIdle = ofGetElapsedTimef(); durationMillis = fobsDecoder->getDurationSeconds() * 1000.0f; return true; //-------------------------------------- #endif //-------------------------------------- }
ofxQtAudioRecorder::ofxQtAudioRecorder(){ initializeQuicktime(); }
//------------------------------------------------------------ void ofQuicktimeSoundPlayer::loadSound(string fileName, bool stream){ fileName = ofToDataPath(fileName); // TODO: hmm? bMultiPlay = false; // [1] init fmod, if necessary initializeQuicktime(); // [2] try to unload any previously loaded sounds // & prevent user-created memory leaks // if they call "loadSound" repeatedly, for example if (bLoadedOk == true){ unloadSound(); } // [3] load sound OSErr error; //CFBundleRef gameBundle = CFBundleGetMainBundle(); // Find the file in the application bundle. CFURLRef movieFileLocation; movieFileLocation = CFURLCreateFromFileSystemRepresentation(NULL, (UInt8*)fileName.c_str(), strlen(fileName.c_str()), false); //CFBundleCopyResourceURL(gameBundle, filename, fileExtension, subdirectory); if (movieFileLocation == NULL) return; Handle dataRef; OSType dataRefType; dataRef = NewHandle(sizeof(AliasHandle)); // Get the movie file set up so we can load it in memory. // The second parameter to QTNewDataReferenceFromCFURL is flags. // It should be set to 0. error = QTNewDataReferenceFromCFURL(movieFileLocation, 0, &dataRef, &dataRefType); if(error != noErr) { DisposeHandle(dataRef); CFRelease(movieFileLocation); return; } // Get the movie into memory short fileID = movieInDataForkResID; short flags = 0; error = NewMovieFromDataRef(&soundToPlay, flags, &fileID, dataRef, dataRefType); // Dispose of the memory we allocated. DisposeHandle(dataRef); CFRelease(movieFileLocation); // TODO: check here! bLoadedOk = true; }