static void exportCGImageToFileWithQT(CGImageRef image, CFURLRef url,
					    CFStringRef outputFormat,
					    float dpi)
{
	Handle						dataRef = NULL;
	OSType						dataRefType;
	GraphicsExportComponent		graphicsExporter;
	unsigned long				sizeWritten;
	ComponentResult				result;
	OSType						imageExportType;

	if(CFStringCompare(outputFormat, kUTTypeTIFF, kCFCompareCaseInsensitive) == kCFCompareEqualTo){
	    imageExportType = kQTFileTypeTIFF;
	}else if(CFStringCompare(outputFormat, kUTTypePNG, kCFCompareCaseInsensitive) == kCFCompareEqualTo){
	    imageExportType = kQTFileTypePNG;
	}else if(CFStringCompare(outputFormat, kUTTypeJPEG, kCFCompareCaseInsensitive) == kCFCompareEqualTo){
	    imageExportType = kQTFileTypeJPEG;
	}else{
	    fprintf(stderr, "Requested image export format %@s unsupported\n", outputFormat);
	    return;
	}
	
	result = QTNewDataReferenceFromCFURL(url, 0,  &dataRef, &dataRefType);
	if(!result){
		result = OpenADefaultComponent(GraphicsExporterComponentType,
				    imageExportType, &graphicsExporter);
		if(!result){
			result = GraphicsExportSetInputCGImage(graphicsExporter, 
						image);
			if(!result)
				result = GraphicsExportSetResolution(graphicsExporter, 
							FloatToFixed(dpi), FloatToFixed(dpi));
			if(!result)
				result = GraphicsExportSetOutputDataReference(
							graphicsExporter, dataRef, dataRefType);
			if(!result)
				result = GraphicsExportDoExport(
							graphicsExporter, &sizeWritten);
			CloseComponent(graphicsExporter);
		}
	}
	if(dataRef)
		DisposeHandle(dataRef);
	if(result)
		fprintf(stderr, "QT export got bad result = %d!\n", (int)result);
	return;
}
QuickTimeFileReader::QuickTimeFileReader(FileSource source,
                                         DecodeMode decodeMode,
                                         CacheMode mode,
                                         size_t targetRate,
                                         ProgressReporter *reporter) :
    CodedAudioFileReader(mode, targetRate),
    m_source(source),
    m_path(source.getLocalFilename()),
    m_d(new D),
    m_reporter(reporter),
    m_cancelled(false),
    m_completion(0),
    m_decodeThread(0)
{
    m_channelCount = 0;
    m_fileRate = 0;

    Profiler profiler("QuickTimeFileReader::QuickTimeFileReader", true);

SVDEBUG << "QuickTimeFileReader: path is \"" << m_path << "\"" << endl;

    long QTversion;

#ifdef WIN32
    InitializeQTML(0); // FIXME should check QT version
#else
    m_d->err = Gestalt(gestaltQuickTime,&QTversion);
    if ((m_d->err != noErr) || (QTversion < 0x07000000)) {
        m_error = QString("Failed to find compatible version of QuickTime (version 7 or above required)");
        return;
    }
#endif 

    EnterMovies();
	
    Handle dataRef; 
    OSType dataRefType;

//    CFStringRef URLString = CFStringCreateWithCString
 //       (0, m_path.toLocal8Bit().data(), 0);


    QByteArray ba = m_path.toLocal8Bit();

    CFURLRef url = CFURLCreateFromFileSystemRepresentation
        (kCFAllocatorDefault,
         (const UInt8 *)ba.data(),
         (CFIndex)ba.length(),
         false);


//    m_d->err = QTNewDataReferenceFromURLCFString
    m_d->err = QTNewDataReferenceFromCFURL
        (url, 0, &dataRef, &dataRefType);

    if (m_d->err) { 
        m_error = QString("Error creating data reference for QuickTime decoder: code %1").arg(m_d->err);
        return;
    }
    
    short fileID = movieInDataForkResID; 
    short flags = 0; 
    m_d->err = NewMovieFromDataRef
        (&m_d->movie, flags, &fileID, dataRef, dataRefType);

    DisposeHandle(dataRef);
    if (m_d->err) { 
        m_error = QString("Error creating new movie for QuickTime decoder: code %1").arg(m_d->err); 
        return;
    }

    Boolean isProtected = 0;
    Track aTrack = GetMovieIndTrackType
        (m_d->movie, 1, SoundMediaType,
         movieTrackMediaType | movieTrackEnabledOnly);

    if (aTrack) {
        Media aMedia = GetTrackMedia(aTrack);	// get the track media
        if (aMedia) {
            MediaHandler mh = GetMediaHandler(aMedia);	// get the media handler we can query
            if (mh) {
                m_d->err = QTGetComponentProperty(mh,
                                                  kQTPropertyClass_DRM,
                                                  kQTDRMPropertyID_IsProtected,
                                                  sizeof(Boolean), &isProtected,nil);
            } else {
                m_d->err = 1;
            }
        } else {
            m_d->err = 1;
        }
    } else {
        m_d->err = 1;
    }
	
    if (m_d->err && m_d->err != kQTPropertyNotSupportedErr) { 
        m_error = QString("Error checking for DRM in QuickTime decoder: code %1").arg(m_d->err);
        return;
    } else if (!m_d->err && isProtected) { 
        m_error = QString("File is protected with DRM");
        return;
    } else if (m_d->err == kQTPropertyNotSupportedErr && !isProtected) {
        std::cerr << "QuickTime: File is not protected with DRM" << std::endl;
    }

    if (m_d->movie) {
        SetMovieActive(m_d->movie, TRUE);
        m_d->err = GetMoviesError();
        if (m_d->err) {
            m_error = QString("Error in QuickTime decoder activation: code %1").arg(m_d->err);
            return;
        }
    } else {
	m_error = QString("Error in QuickTime decoder: Movie object not valid");
	return;
    }
    
    m_d->err = MovieAudioExtractionBegin
        (m_d->movie, 0, &m_d->extractionSessionRef);
    if (m_d->err) {
        m_error = QString("Error in QuickTime decoder extraction init: code %1").arg(m_d->err);
        return;
    }

    m_d->err = MovieAudioExtractionGetProperty
        (m_d->extractionSessionRef,
         kQTPropertyClass_MovieAudioExtraction_Audio, kQTMovieAudioExtractionAudioPropertyID_AudioStreamBasicDescription,
         sizeof(m_d->asbd),
         &m_d->asbd,
         nil);

    if (m_d->err) {
        m_error = QString("Error in QuickTime decoder property get: code %1").arg(m_d->err);
        return;
    }
	
    m_channelCount = m_d->asbd.mChannelsPerFrame;
    m_fileRate = m_d->asbd.mSampleRate;

    std::cerr << "QuickTime: " << m_channelCount << " channels, " << m_fileRate << " kHz" << std::endl;

    m_d->asbd.mFormatFlags =
        kAudioFormatFlagIsFloat |
        kAudioFormatFlagIsPacked |
        kAudioFormatFlagsNativeEndian;
    m_d->asbd.mBitsPerChannel = sizeof(float) * 8;
    m_d->asbd.mBytesPerFrame = sizeof(float) * m_d->asbd.mChannelsPerFrame;
    m_d->asbd.mBytesPerPacket = m_d->asbd.mBytesPerFrame;
	
    m_d->err = MovieAudioExtractionSetProperty
        (m_d->extractionSessionRef,
         kQTPropertyClass_MovieAudioExtraction_Audio,
         kQTMovieAudioExtractionAudioPropertyID_AudioStreamBasicDescription,
         sizeof(m_d->asbd),
         &m_d->asbd);

    if (m_d->err) {
        m_error = QString("Error in QuickTime decoder property set: code %1").arg(m_d->err);
        m_channelCount = 0;
        return;
    }
    m_d->buffer.mNumberBuffers = 1;
    m_d->buffer.mBuffers[0].mNumberChannels = m_channelCount;
    m_d->buffer.mBuffers[0].mDataByteSize =
        sizeof(float) * m_channelCount * m_d->blockSize;
    m_d->data = new float[m_channelCount * m_d->blockSize];
    m_d->buffer.mBuffers[0].mData = m_d->data;

    initialiseDecodeCache();

    if (decodeMode == DecodeAtOnce) {

        if (m_reporter) {
            connect(m_reporter, SIGNAL(cancelled()), this, SLOT(cancelled()));
            m_reporter->setMessage
                (tr("Decoding %1...").arg(QFileInfo(m_path).fileName()));
        }

        while (1) {
            
            UInt32 framesRead = m_d->blockSize;
            UInt32 extractionFlags = 0;
            m_d->err = MovieAudioExtractionFillBuffer
                (m_d->extractionSessionRef, &framesRead, &m_d->buffer,
                 &extractionFlags);
            if (m_d->err) {
                m_error = QString("Error in QuickTime decoding: code %1")
                    .arg(m_d->err);
                break;
            }

            //!!! progress?

//    std::cerr << "Read " << framesRead << " frames (block size " << m_d->blockSize << ")" << std::endl;

            // QuickTime buffers are interleaved unless specified otherwise
            addSamplesToDecodeCache(m_d->data, framesRead);

            if (framesRead < m_d->blockSize) break;
        }
        
        finishDecodeCache();
        endSerialised();

        m_d->err = MovieAudioExtractionEnd(m_d->extractionSessionRef);
        if (m_d->err) {
            m_error = QString("Error ending QuickTime extraction session: code %1").arg(m_d->err);
        }

        m_completion = 100;

    } else {
        if (m_reporter) m_reporter->setProgress(100);

        if (m_channelCount > 0) {
            m_decodeThread = new DecodeThread(this);
            m_decodeThread->start();
        }
    }

    std::cerr << "QuickTimeFileReader::QuickTimeFileReader: frame count is now " << getFrameCount() << ", error is \"\"" << m_error << "\"" << std::endl;
}
Beispiel #3
0
void MacQTStartRecording(char *path)
{
	OSStatus	err;
	CFStringRef str;
	CFURLRef	url;

	memset(&sqt, 0, sizeof(sqt));

	// storage

	str = CFStringCreateWithCString(kCFAllocatorDefault, path, MAC_PATH_ENCODING);
	url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, str, kCFURLPOSIXPathStyle, false);
	err = QTNewDataReferenceFromCFURL(url, 0, &(sqt.dataRef), &(sqt.dataRefType));
	CheckError(err, 21);
	CFRelease(url);
	CFRelease(str);
	
	err = CreateMovieStorage(sqt.dataRef, sqt.dataRefType, 'TVOD', smSystemScript, createMovieFileDeleteCurFile | newMovieActive, &(sqt.dataHandler), &(sqt.movie));
	CheckError(err, 22);
	
	// video

	MacQTOpenVideoComponent(&(sqt.vci));
	
	SCTemporalSettings	ts;

	err = SCGetInfo(sqt.vci, scTemporalSettingsType, &ts);
	ts.frameRate = FixRatio(Memory.ROMFramesPerSecond, 1);
	if (ts.keyFrameRate < 1)
		ts.keyFrameRate = Memory.ROMFramesPerSecond;
	sqt.keyFrame  = sqt.keyFrameCount  = ts.keyFrameRate;
	sqt.frameSkip = sqt.frameSkipCount = (macQTMovFlag & 0xFF00) >> 8;
	err = SCSetInfo(sqt.vci, scTemporalSettingsType, &ts);

	sqt.frame.top    = 0;
	sqt.frame.left   = 0;
	sqt.frame.right  = ((macQTMovFlag & kMovDoubleSize) ? 2 : 1) * SNES_WIDTH;
	sqt.frame.bottom = ((macQTMovFlag & kMovDoubleSize) ? 2 : 1) * ((macQTMovFlag & kMovExtendedHeight) ? SNES_HEIGHT_EXTENDED : SNES_HEIGHT);

	sqt.pw = sqt.ph = 0;
	sqt.firstFrame = true;
	
	Rect	rct;

	SetRect(&rct, 0, 0, SNES_WIDTH * 2, SNES_HEIGHT_EXTENDED * 2 + 4);
	InitGWorld(&(sqt.bw), &rct, 16);

	sqt.vTrack = NewMovieTrack(sqt.movie, FixRatio(sqt.frame.right, 1), FixRatio(sqt.frame.bottom, 1), kNoVolume);
	CheckError(GetMoviesError(), 23);
	
	sqt.vMedia = NewTrackMedia(sqt.vTrack, VideoMediaType, Memory.ROMFramesPerSecond, nil, 0);
	CheckError(GetMoviesError(), 24);
	
	err = BeginMediaEdits(sqt.vMedia);
	CheckError(err, 25);
	
	// sound
	
	sqt.soundDesc = (SoundDescriptionHandle) NewHandleClear(sizeof(SoundDescription));
	CheckError(MemError(), 26);

	(**sqt.soundDesc).descSize    = sizeof(SoundDescription);
#ifdef __BIG_ENDIAN__
	(**sqt.soundDesc).dataFormat  = Settings.SixteenBitSound ? k16BitBigEndianFormat    : k8BitOffsetBinaryFormat;
#else
	(**sqt.soundDesc).dataFormat  = Settings.SixteenBitSound ? k16BitLittleEndianFormat : k8BitOffsetBinaryFormat;
#endif
	(**sqt.soundDesc).numChannels = Settings.Stereo ? 2 : 1;
	(**sqt.soundDesc).sampleSize  = Settings.SixteenBitSound ? 16 : 8;
	(**sqt.soundDesc).sampleRate  = (UnsignedFixed) FixRatio(Settings.SoundPlaybackRate, 1);
	
	sqt.samplesPerSec = Settings.SoundPlaybackRate / Memory.ROMFramesPerSecond;
	
	sqt.soundBufferSize = sqt.samplesPerSec;
	if (Settings.SixteenBitSound)
		sqt.soundBufferSize <<= 1;
	if (Settings.Stereo)
		sqt.soundBufferSize <<= 1;

	sqt.soundBuffer = NewHandleClear(sqt.soundBufferSize);
	CheckError(MemError(), 27);
	HLock(sqt.soundBuffer);
	
	sqt.sTrack = NewMovieTrack(sqt.movie, 0, 0, kFullVolume);
	CheckError(GetMoviesError(), 28);

	sqt.sMedia = NewTrackMedia(sqt.sTrack, SoundMediaType, Settings.SoundPlaybackRate, nil, 0);
	CheckError(GetMoviesError(), 29);

	err = BeginMediaEdits(sqt.sMedia);
	CheckError(err, 30);
}
//------------------------------------------------------------
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;
	

}
Beispiel #5
0
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;
}