bool qtCanvas::Impl::setupTrack() { mTrack = NewMovieTrack(mMovie, FixRatio(mWidth,1), FixRatio(mHeight,1), (short)kNoVolume); if (!CheckMoviesError("NewMovieTrack")) return false; SCTemporalSettings temporal; SCGetInfo(mSCComponent, scTemporalSettingsType, &temporal); mMedia = NewTrackMedia(mTrack, VideoMediaType, (TimeScale)temporal.frameRate, nil, 0); if (!CheckMoviesError("NewTrackMedia" )) return false; MediaHandler mh = GetMediaHandler(mMedia); if (!CheckMoviesError("GetMediaHandler")) return false; ComponentResult err; err = MediaSetGraphicsMode(mh, graphicsModePreMulColorAlpha, NULL); if (!CheckError(err, "MediaSetGraphicsMode")) return false; BeginMediaEdits(mMedia); if (!CheckMoviesError("BeginMediaEdits" )) return false; return true; }
/* Get the media identifier for the media that contains the first video track's sample data, and also get the media handler for this media. */ void MovieGetVideoMediaAndMediaHandler(Movie inMovie, Media *outMedia, MediaHandler *outMediaHandler) { *outMedia = NULL; *outMediaHandler = NULL; /* get first video track */ Track videoTrack = GetMovieIndTrackType(inMovie, 1, kCharacteristicHasVideoFrameRate, movieTrackCharacteristic | movieTrackEnabledOnly); if (videoTrack != NULL) { /* get media ref. for track's sample data */ *outMedia = GetTrackMedia(videoTrack); if (*outMedia) { /* get a reference to the media handler component */ *outMediaHandler = GetMediaHandler(*outMedia); } } }
OSErr QTTarg_AddTextToggleButtonTrack (Movie theMovie) { Track myTrack = NULL; Media myMedia = NULL; MatrixRecord myMatrix; RGBColor myKeyColor; Fixed myWidth, myHeight; TimeValue myDuration = 0L; TimeValue myTimeScale = 0L; OSErr myErr = noErr; ////////// // // get some information about the target movie // ////////// if (theMovie == NULL) { myErr = paramErr; goto bail; } myWidth = Long2Fix(2 * kButtonWidth); myHeight = Long2Fix(2 * kButtonHeight); myDuration = GetMovieDuration(theMovie); myTimeScale = GetMovieTimeScale(theMovie); ////////// // // create a new sprite track in the target movie // ////////// myTrack = NewMovieTrack(theMovie, myWidth, myHeight, kNoVolume); myMedia = NewTrackMedia(myTrack, SpriteMediaType, myTimeScale, NULL, 0); // set the track matrix to compensate for any existing movie matrix GetMovieMatrix(theMovie, &myMatrix); if (InverseMatrix(&myMatrix, &myMatrix)) SetTrackMatrix(myTrack, &myMatrix); myErr = BeginMediaEdits(myMedia); if (myErr != noErr) goto bail; ////////// // // add sprite images and sprites to the sprite track; add actions to the sprites // ////////// QTTarg_AddTextButtonSamplesToMedia(myMedia, 2 * kButtonWidth, 2 * kButtonHeight, myDuration); ////////// // // insert media into track // ////////// myErr = EndMediaEdits(myMedia); if (myErr != noErr) goto bail; // add the media to the track InsertMediaIntoTrack(myTrack, 0, 0, GetMediaDuration(myMedia), fixed1); ////////// // // set the sprite track properties // ////////// QTTarg_SetTrackProperties(myMedia, kNoQTIdleEvents); // no idle events myKeyColor.red = myKeyColor.green = myKeyColor.blue = 0xffff; // white MediaSetGraphicsMode(GetMediaHandler(myMedia), transparent, &myKeyColor); // make sure that the sprite track is in the frontmost layer SetTrackLayer(myTrack, kMaxLayerNumber); SetTrackLayer(myTrack, QTTarg_GetLowestLayerInMovie(theMovie) - 1); bail: return(myErr); }
OSErr QTTarg_MakeDualVRControllerMovie (void) { Movie myMovie = NULL; Track myTrack = NULL; Media myMedia = NULL; RGBColor myKeyColor; Fixed myWidth, myHeight; FSSpec myFile; Boolean myIsSelected = false; Boolean myIsReplacing = false; StringPtr myPrompt = QTUtils_ConvertCToPascalString(kSpriteSavePrompt); StringPtr myFileName = QTUtils_ConvertCToPascalString(kSpriteSaveMovieFileName); long myFlags = createMovieFileDeleteCurFile | createMovieFileDontCreateResFile; short myResRefNum = 0; short myResID = movieInDataForkResID; OSType myType = FOUR_CHAR_CODE('none'); OSErr myErr = noErr; ////////// // // create a new movie file // ////////// // prompt the user for the destination file name QTFrame_PutFile(myPrompt, myFileName, &myFile, &myIsSelected, &myIsReplacing); myErr = myIsSelected ? noErr : userCanceledErr; if (!myIsSelected) goto bail; // create a movie file for the destination movie myErr = CreateMovieFile(&myFile, FOUR_CHAR_CODE('TVOD'), smSystemScript, myFlags, &myResRefNum, &myMovie); if (myErr != noErr) goto bail; // select the "no-interface" movie controller myType = EndianU32_NtoB(myType); SetUserDataItem(GetMovieUserData(myMovie), &myType, sizeof(myType), kUserDataMovieControllerType, 1); ////////// // // get some information about the target movie // ////////// myWidth = Long2Fix(kVRControlMovieWidth); myHeight = Long2Fix(kVRControlMovieHeight); ////////// // // create a new sprite track in the target movie // ////////// myTrack = NewMovieTrack(myMovie, myWidth, myHeight, kNoVolume); myMedia = NewTrackMedia(myTrack, SpriteMediaType, kVRControlMovieDuration, NULL, 0); myErr = BeginMediaEdits(myMedia); if (myErr != noErr) goto bail; ////////// // // add sprite images and sprites to the sprite track; add actions to the sprites // ////////// QTTarg_AddVRControllerButtonSamplesToMedia(myMedia, kVRControlMovieWidth, kVRControlMovieHeight, kVRControlMovieDuration); ////////// // // insert media into track // ////////// myErr = EndMediaEdits(myMedia); if (myErr != noErr) goto bail; // add the media to the track InsertMediaIntoTrack(myTrack, 0, 0, GetMediaDuration(myMedia), fixed1); ////////// // // set the sprite track properties // ////////// QTTarg_SetTrackProperties(myMedia, 0); // idle as fast as possible myKeyColor.red = myKeyColor.green = myKeyColor.blue = 0xffff; // white MediaSetGraphicsMode(GetMediaHandler(myMedia), transparent, &myKeyColor); ////////// // // add the movie resource to the movie file // ////////// myErr = AddMovieResource(myMovie, myResRefNum, &myResID, myFile.name); bail: if (myResRefNum != 0) CloseMovieFile(myResRefNum); if (myMovie != NULL) DisposeMovie(myMovie); free(myPrompt); free(myFileName); return(myErr); }
/* call-seq: enable_alpha() Enable the straight alpha graphic mode for this track. This is best used on an overlayed video track which includes some alpha transparency (such as in a PNG image). */ static VALUE track_enable_alpha(VALUE obj) { MediaSetGraphicsMode(GetMediaHandler(TRACK_MEDIA(obj)), graphicsModeStraightAlpha, 0); return obj; }
Boolean QTApp_HandleMenu (UInt16 theMenuItem) { WindowObject myWindowObject = NULL; ApplicationDataHdl myAppData = NULL; MovieController myMC = NULL; Movie myMovie = NULL; Boolean myIsHandled = false; // false => allow caller to process the menu item OSErr myErr = noErr; myWindowObject = QTFrame_GetWindowObjectFromFrontWindow(); if (myWindowObject != NULL) { myMC = (**myWindowObject).fController; myMovie = (**myWindowObject).fMovie; myAppData = (ApplicationDataHdl)QTFrame_GetAppDataFromWindowObject(myWindowObject); } switch (theMenuItem) { case IDM_SET_TEXT: // put up a dialog box to get a text string QTText_SetSearchText(); myIsHandled = true; break; case IDM_FIND_TEXT: QTText_FindText(myWindowObject, gSearchText); myIsHandled = true; break; case IDM_EDIT_TEXT: QTText_EditText(myWindowObject); myIsHandled = true; break; case IDM_SEARCH_FORWARD: gSearchForward = true; myIsHandled = true; break; case IDM_SEARCH_BACKWARD: gSearchForward = false; myIsHandled = true; break; case IDM_WRAP_SEARCH: gSearchWrap = !gSearchWrap; myIsHandled = true; break; case IDM_USE_CASE: gSearchWithCase = !gSearchWithCase; myIsHandled = true; break; case IDM_ADD_TEXT_TRACK: { // add a text track to the specified movie; // for purposes of illustration, we'll add 11 (count 'em!) text strings to the movie, // with each string occupying about one-tenth of the movie duration Track myTypeTrack = NULL; Track myTextTrack = NULL; TimeValue myMovieDuration = 0; TimeValue mySampleDuration = 0; char *myStrings[] = {"0%", "10%", "20%", "30%", "40%", "50%", "60%", "70%", "80%", "90%", "100%"}; short myFrames[11]; Boolean isChapter = true; myTypeTrack = GetMovieIndTrackType(myMovie, 1, VideoMediaType, movieTrackMediaType); if (myTypeTrack == NULL) break; // get the duration of the movie and the duration of a single frame; // this tells us how many frames fit into one-tenth of the movie myMovieDuration = GetMovieDuration(myMovie); mySampleDuration = QTUtils_GetFrameDuration(myTypeTrack); myFrames[0] = (myMovieDuration / mySampleDuration) / 10; myFrames[1] = (myMovieDuration / mySampleDuration) / 10; myFrames[2] = (myMovieDuration / mySampleDuration) / 10; myFrames[3] = (myMovieDuration / mySampleDuration) / 10; myFrames[4] = (myMovieDuration / mySampleDuration) / 10; myFrames[5] = (myMovieDuration / mySampleDuration) / 10; myFrames[6] = (myMovieDuration / mySampleDuration) / 10; myFrames[7] = (myMovieDuration / mySampleDuration) / 10; myFrames[8] = (myMovieDuration / mySampleDuration) / 10; myFrames[9] = ((myMovieDuration / mySampleDuration) / 10) - 1; myFrames[10] = 1; myTextTrack = QTText_AddTextTrack(myMovie, myStrings, myFrames, 11, VideoMediaType, isChapter); if (myTextTrack != NULL) { MCMovieChanged(myMC, myMovie); // stamp the movie as dirty and update our saved data (**myWindowObject).fIsDirty = true; (**myAppData).fMovieHasText = true; (**myAppData).fTextIsChapter = isChapter; (**myAppData).fTextTrack = myTextTrack; (**myAppData).fTextHandler = GetMediaHandler(GetTrackMedia(myTextTrack)); } } myIsHandled = true; break; case IDM_CUT_TEXT_TRACK: // remove all existing text tracks from the specified movie myErr = QTText_RemoveIndTextTrack(myWindowObject, kAllTextTracks); if (myErr == noErr) { MCMovieChanged(myMC, myMovie); // stamp the movie as dirty and update our saved data (**myWindowObject).fIsDirty = true; (**myAppData).fMovieHasText = false; (**myAppData).fTextIsChapter = false; (**myAppData).fTextIsHREF = false; (**myAppData).fTextTrack = NULL; (**myAppData).fTextHandler = NULL; } myIsHandled = true; break; case IDM_CHAPTER_TRACK: (**myAppData).fTextIsChapter = !(**myAppData).fTextIsChapter; QTText_SetTextTrackAsChapterTrack(myWindowObject, VideoMediaType, (**myAppData).fTextIsChapter); (**myWindowObject).fIsDirty = true; myIsHandled = true; break; case IDM_HREF_TRACK: (**myAppData).fTextIsHREF = !(**myAppData).fTextIsHREF; QTText_SetTextTrackAsHREFTrack((**myAppData).fTextTrack, (**myAppData).fTextIsHREF); (**myWindowObject).fIsDirty = true; myIsHandled = true; break; default: break; } // switch (theMenuItem) return(myIsHandled); }
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; }