Changeset 561 for trunk/src/3rdparty/phonon/qt7
- Timestamp:
- Feb 11, 2010, 11:19:06 PM (16 years ago)
- Location:
- trunk
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
-
Property svn:mergeinfo
set to (toggle deleted branches)
/branches/vendor/nokia/qt/4.6.1 merged eligible /branches/vendor/nokia/qt/current merged eligible /branches/vendor/trolltech/qt/current 3-149
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
trunk/src/3rdparty/phonon/qt7/backend.mm
r2 r561 60 60 setProperty("backendVersion", QLatin1String("0.1")); 61 61 setProperty("backendIcon", QLatin1String("")); 62 setProperty("backendWebsite", QLatin1String("http://qt software.com/"));62 setProperty("backendWebsite", QLatin1String("http://qt.nokia.com/")); 63 63 } 64 64 -
trunk/src/3rdparty/phonon/qt7/mediaobject.h
r2 r561 25 25 26 26 #include "medianode.h" 27 28 #if QT_ALLOW_QUICKTIME 29 #include <QuickTime/QuickTime.h> 30 #endif 27 31 28 32 QT_BEGIN_NAMESPACE … … 39 43 40 44 class MediaObject : public MediaNode, 41 public Phonon::MediaObjectInterface, public Phonon::AddonInterface 45 public Phonon::MediaObjectInterface 46 #ifndef QT_NO_PHONON_MEDIACONTROLLER 47 , public Phonon::AddonInterface 48 #endif 42 49 { 43 50 Q_OBJECT … … 92 99 93 100 int videoOutputCount(); 101 102 #if QT_ALLOW_QUICKTIME 103 void displayLinkEvent(); 104 #endif 94 105 95 106 signals: … … 106 117 void currentSourceChanged(const MediaSource &newSource); 107 118 119 // Add-on interface: 120 void availableSubtitlesChanged(); 121 void availableAudioChannelsChanged(); 122 void titleChanged(int); 123 void availableTitlesChanged(int); 124 void chapterChanged(int); 125 void availableChaptersChanged(int); 126 void angleChanged(int); 127 void availableAnglesChanged(int); 128 108 129 protected: 109 130 void mediaNodeEvent(const MediaNodeEvent *event); … … 119 140 QuickTimeAudioPlayer *m_nextAudioPlayer; 120 141 MediaObjectAudioNode *m_mediaObjectAudioNode; 121 QuickTimeMetaData *m_metaData; 142 143 #if QT_ALLOW_QUICKTIME 144 CVDisplayLinkRef m_displayLink; 145 QMutex m_displayLinkMutex; 146 bool m_pendingDisplayLinkEvent; 147 void startDisplayLink(); 148 void stopDisplayLink(); 149 #endif 122 150 123 151 qint32 m_tickInterval; … … 128 156 129 157 int m_tickTimer; 130 int m_bufferTimer; 158 int m_videoTimer; 159 int m_audioTimer; 131 160 int m_rapidTimer; 132 161 … … 134 163 int m_swapTimeLeft; 135 164 QTime m_swapTime; 165 bool m_autoplayTitles; 136 166 137 167 void synchAudioVideo(); … … 142 172 void play_internal(); 143 173 void setupAudioSystem(); 144 void updateTimer(int &timer, int interval); 145 void bufferAudioVideo(); 174 void restartAudioVideoTimers(); 146 175 void updateRapidly(); 147 176 void updateCrossFade(); … … 155 184 void inspectGraph(); 156 185 bool isCrossFading(); 186 void setCurrentTrack(int track); 157 187 158 188 QString m_errorString; -
trunk/src/3rdparty/phonon/qt7/mediaobject.mm
r2 r561 47 47 setAudioNode(m_mediaObjectAudioNode); 48 48 49 m_metaData = new QuickTimeMetaData();50 49 m_audioGraph = new AudioGraph(this); 51 50 … … 56 55 m_percentageLoaded = 0; 57 56 m_waitNextSwap = false; 57 m_autoplayTitles = true; 58 58 m_audioEffectCount = 0; 59 59 m_audioOutputCount = 0; … … 64 64 65 65 m_tickTimer = 0; 66 m_bufferTimer = 0; 66 m_videoTimer = 0; 67 m_audioTimer = 0; 67 68 m_rapidTimer = 0; 68 69 70 #if QT_ALLOW_QUICKTIME 71 m_displayLink = 0; 72 m_pendingDisplayLinkEvent = false; 73 #endif 74 69 75 checkForError(); 70 76 } 71 77 72 78 MediaObject::~MediaObject() 73 { 74 // m_mediaObjectAudioNode is owned by super class. 79 { 80 // m_mediaObjectAudioNode is owned by super class. 81 #if QT_ALLOW_QUICKTIME 82 stopDisplayLink(); 83 #endif 75 84 m_audioPlayer->unsetVideoPlayer(); 76 85 m_nextAudioPlayer->unsetVideoPlayer(); 77 86 delete m_videoPlayer; 78 87 delete m_nextVideoPlayer; 79 delete m_metaData;80 88 checkForError(); 81 89 } … … 89 97 if (m_state != state){ 90 98 // End-application did something 91 // upon receiving the signal. 99 // upon receiving the signal. 92 100 return false; 93 101 } … … 123 131 // effects or outputs connected. This will have 124 132 // influence on the audio system and video system that ends up beeing used: 125 int prevVideoOutputCount = m_videoOutputCount; 133 int prevVideoOutputCount = m_videoOutputCount; 126 134 m_audioEffectCount = 0; 127 135 m_audioOutputCount = 0; … … 135 143 MediaNodeEvent e1(MediaNodeEvent::VideoOutputCountChanged, &m_videoOutputCount); 136 144 notify(&e1); 137 } 145 } 138 146 } 139 147 … … 168 176 if (newAudioSystem == m_audioSystem) 169 177 return; 170 178 171 179 // Enable selected audio system: 172 m_audioSystem = newAudioSystem; 180 m_audioSystem = newAudioSystem; 173 181 switch (newAudioSystem){ 174 182 case AS_Silent: 175 183 m_audioGraph->stop(); 176 184 m_videoPlayer->enableAudio(false); 177 m_nextVideoPlayer->enableAudio(false); 185 m_nextVideoPlayer->enableAudio(false); 178 186 m_audioPlayer->enableAudio(false); 179 187 m_nextAudioPlayer->enableAudio(false); … … 215 223 PhononAutoReleasePool pool; 216 224 setState(Phonon::LoadingState); 217 225 218 226 // Save current state for event/signal handling below: 219 227 bool prevHasVideo = m_videoPlayer->hasVideo(); 220 228 qint64 prevTotalTime = totalTime(); 229 int prevTrackCount = m_videoPlayer->trackCount(); 221 230 m_waitNextSwap = false; 222 231 223 232 // Cancel cross-fade if any: 224 233 m_nextVideoPlayer->pause(); 225 234 m_nextAudioPlayer->pause(); 226 235 m_mediaObjectAudioNode->cancelCrossFade(); 227 236 228 237 // Set new source: 229 238 m_audioPlayer->unsetVideoPlayer(); 230 239 m_videoPlayer->setMediaSource(source); 231 240 m_audioPlayer->setVideoPlayer(m_videoPlayer); 232 m_metaData->setVideo(m_videoPlayer); 233 234 m_audioGraph->updateStreamSpecifications(); 241 242 m_audioGraph->updateStreamSpecifications(); 235 243 m_nextAudioPlayer->unsetVideoPlayer(); 236 m_nextVideoPlayer->unset Video();244 m_nextVideoPlayer->unsetCurrentMediaSource(); 237 245 m_currentTime = 0; 238 246 239 247 // Emit/notify information about the new source: 240 248 QRect videoRect = m_videoPlayer->videoRect(); … … 247 255 248 256 emit currentSourceChanged(source); 249 emit metaDataChanged(m_ metaData->metaData());257 emit metaDataChanged(m_videoPlayer->metaData()); 250 258 251 259 if (prevHasVideo != m_videoPlayer->hasVideo()) 252 emit hasVideoChanged(m_videoPlayer->hasVideo()); 260 emit hasVideoChanged(m_videoPlayer->hasVideo()); 253 261 if (prevTotalTime != totalTime()) 254 emit totalTimeChanged(totalTime()); 262 emit totalTimeChanged(totalTime()); 263 if (prevTrackCount != m_videoPlayer->trackCount()) 264 emit availableTitlesChanged(m_videoPlayer->trackCount()); 255 265 if (checkForError()) 256 266 return; … … 261 271 if (!m_videoPlayer->canPlayMedia()) 262 272 SET_ERROR("Cannot play media.", FATAL_ERROR) 263 273 264 274 // The state might have changed from LoadingState 265 275 // as a response to an error state change. So we … … 288 298 bool prevHasVideo = m_videoPlayer->hasVideo(); 289 299 qint64 prevTotalTime = totalTime(); 300 int prevTrackCount = m_videoPlayer->trackCount(); 290 301 291 302 qSwap(m_audioPlayer, m_nextAudioPlayer); … … 293 304 m_mediaObjectAudioNode->startCrossFade(transitionTime); 294 305 m_audioGraph->updateStreamSpecifications(); 295 m_metaData->setVideo(m_videoPlayer);296 306 297 307 m_waitNextSwap = false; 298 308 m_currentTime = 0; 299 309 300 310 // Emit/notify information about the new source: 301 311 QRect videoRect = m_videoPlayer->videoRect(); … … 304 314 305 315 emit currentSourceChanged(m_videoPlayer->mediaSource()); 306 emit metaDataChanged(m_ metaData->metaData());316 emit metaDataChanged(m_videoPlayer->metaData()); 307 317 308 318 if (prevHasVideo != m_videoPlayer->hasVideo()) 309 emit hasVideoChanged(m_videoPlayer->hasVideo()); 319 emit hasVideoChanged(m_videoPlayer->hasVideo()); 310 320 if (prevTotalTime != totalTime()) 311 321 emit totalTimeChanged(totalTime()); 322 if (prevTrackCount != m_videoPlayer->trackCount()) 323 emit availableTitlesChanged(m_videoPlayer->trackCount()); 312 324 if (checkForError()) 313 325 return; … … 328 340 } 329 341 330 void MediaObject::updateTimer(int &timer, int interval) 331 { 332 if (timer) 333 killTimer(timer); 334 timer = 0; 335 if (interval >= 0) 336 timer = startTimer(interval); 342 #if QT_ALLOW_QUICKTIME 343 static CVReturn displayLinkCallback(CVDisplayLinkRef /*displayLink*/, 344 const CVTimeStamp */*inNow*/, 345 const CVTimeStamp */*inOutputTime*/, 346 CVOptionFlags /*flagsIn*/, 347 CVOptionFlags */*flagsOut*/, 348 void *userData) 349 { 350 MediaObject *mediaObject = static_cast<MediaObject *>(userData); 351 mediaObject->displayLinkEvent(); 352 return kCVReturnSuccess; 353 } 354 355 void MediaObject::displayLinkEvent() 356 { 357 // This function is called from a 358 // thread != gui thread. So we post the event. 359 // But we need to make sure that we don't post faster 360 // than the event loop can eat: 361 m_displayLinkMutex.lock(); 362 bool pending = m_pendingDisplayLinkEvent; 363 m_pendingDisplayLinkEvent = true; 364 m_displayLinkMutex.unlock(); 365 366 if (!pending) 367 qApp->postEvent(this, new QEvent(QEvent::User), Qt::HighEventPriority); 368 } 369 370 void MediaObject::startDisplayLink() 371 { 372 if (m_displayLink) 373 return; 374 OSStatus err = CVDisplayLinkCreateWithCGDisplay(kCGDirectMainDisplay, &m_displayLink); 375 if (err != noErr) 376 goto fail; 377 err = CVDisplayLinkSetCurrentCGDisplay(m_displayLink, kCGDirectMainDisplay); 378 if (err != noErr) 379 goto fail; 380 err = CVDisplayLinkSetOutputCallback(m_displayLink, displayLinkCallback, this); 381 if (err != noErr) 382 goto fail; 383 err = CVDisplayLinkStart(m_displayLink); 384 if (err != noErr) 385 goto fail; 386 return; 387 fail: 388 stopDisplayLink(); 389 } 390 391 void MediaObject::stopDisplayLink() 392 { 393 if (!m_displayLink) 394 return; 395 CVDisplayLinkStop(m_displayLink); 396 CFRelease(m_displayLink); 397 m_displayLink = 0; 398 } 399 #endif 400 401 void MediaObject::restartAudioVideoTimers() 402 { 403 if (m_videoTimer) 404 killTimer(m_videoTimer); 405 if (m_audioTimer) 406 killTimer(m_audioTimer); 407 408 #if QT_ALLOW_QUICKTIME 409 // We prefer to use a display link as timer if available, since 410 // it is more steady, and results in better and smoother frame drawing: 411 startDisplayLink(); 412 if (!m_displayLink){ 413 float fps = m_videoPlayer->staticFps(); 414 long videoUpdateFrequency = fps ? long(1000.0f / fps) : 0.001; 415 m_videoTimer = startTimer(videoUpdateFrequency); 416 } 417 #else 418 float fps = m_videoPlayer->staticFps(); 419 long videoUpdateFrequency = fps ? long(1000.0f / fps) : 0.001; 420 m_videoTimer = startTimer(videoUpdateFrequency); 421 #endif 422 423 long audioUpdateFrequency = m_audioPlayer->regularTaskFrequency(); 424 m_audioTimer = startTimer(audioUpdateFrequency); 425 updateVideoFrames(); 426 updateAudioBuffers(); 337 427 } 338 428 … … 341 431 // Play main audio/video: 342 432 m_videoPlayer->play(); 343 m_audioPlayer->play(); 433 m_audioPlayer->play(); 344 434 updateLipSynch(0); 345 435 // Play old audio/video to finish cross-fade: … … 348 438 m_nextAudioPlayer->play(); 349 439 } 350 bufferAudioVideo(); 351 updateTimer(m_rapidTimer, 100); 440 restartAudioVideoTimers(); 441 if (!m_rapidTimer) 442 m_rapidTimer = startTimer(100); 352 443 } 353 444 … … 359 450 m_videoPlayer->pause(); 360 451 m_nextVideoPlayer->pause(); 361 updateTimer(m_rapidTimer, -1); 362 updateTimer(m_bufferTimer, -1); 363 452 killTimer(m_rapidTimer); 453 killTimer(m_videoTimer); 454 killTimer(m_audioTimer); 455 m_rapidTimer = 0; 456 m_videoTimer = 0; 457 m_audioTimer = 0; 458 #if QT_ALLOW_QUICKTIME 459 stopDisplayLink(); 460 #endif 364 461 if (m_waitNextSwap) 365 462 m_swapTimeLeft = m_swapTime.msecsTo(QTime::currentTime()); … … 383 480 return; 384 481 if (!setState(Phonon::PlayingState)) 385 return; 482 return; 386 483 if (m_audioSystem == AS_Graph){ 387 484 m_audioGraph->start(); … … 424 521 return; 425 522 m_waitNextSwap = false; 426 m_nextVideoPlayer->unset Video();523 m_nextVideoPlayer->unsetCurrentMediaSource(); 427 524 m_nextAudioPlayer->unsetVideoPlayer(); 428 525 pause_internal(); … … 436 533 if (m_state == Phonon::ErrorState) 437 534 return; 438 535 439 536 // Stop cross-fade if any: 440 m_nextVideoPlayer->unset Video();537 m_nextVideoPlayer->unsetCurrentMediaSource(); 441 538 m_nextAudioPlayer->unsetVideoPlayer(); 442 539 m_mediaObjectAudioNode->cancelCrossFade(); … … 447 544 m_audioPlayer->seek(m_videoPlayer->currentTime()); 448 545 m_mediaObjectAudioNode->setMute(false); 449 546 450 547 // Update time and cancel pending swap: 451 548 if (m_currentTime < m_videoPlayer->duration()) … … 558 655 { 559 656 IMPLEMENTED_SILENT; 560 const_cast<MediaObject *>(this)->updateCurrentTime(); 657 const_cast<MediaObject *>(this)->updateCurrentTime(); 561 658 return m_currentTime; 562 659 } … … 568 665 quint64 total = m_videoPlayer->duration(); 569 666 570 // Check if it's time to emit aboutToFinish: 571 quint32 mark = qMax(quint64(0), qMin(total, total + m_transitionTime - 2000)); 572 if (lastUpdateTime < mark && mark <= m_currentTime) 573 emit aboutToFinish(); 574 575 // Check if it's time to emit prefinishMarkReached: 576 mark = qMax(quint64(0), total - m_prefinishMark); 577 if (lastUpdateTime < mark && mark <= m_currentTime) 578 emit prefinishMarkReached(total - m_currentTime); 579 580 if (m_nextVideoPlayer->state() == QuickTimeVideoPlayer::NoMedia){ 581 // There is no next source in que. 582 // Check if it's time to emit finished: 667 if (m_videoPlayer->currentTrack() < m_videoPlayer->trackCount() - 1){ 668 // There are still more tracks to play after the current track. 669 if (m_autoplayTitles) { 670 if (lastUpdateTime < m_currentTime && m_currentTime == total) 671 setCurrentTrack(m_videoPlayer->currentTrack() + 1); 672 } 673 } else if (m_nextVideoPlayer->state() == QuickTimeVideoPlayer::NoMedia){ 674 // There is no more sources or tracks to play after the current source. 675 // Check if it's time to emit aboutToFinish: 676 quint32 mark = qMax(quint64(0), qMin(total, total + m_transitionTime - 2000)); 677 if (lastUpdateTime < mark && mark <= m_currentTime) 678 emit aboutToFinish(); 679 680 // Check if it's time to emit prefinishMarkReached: 681 mark = qMax(quint64(0), total - m_prefinishMark); 682 if (lastUpdateTime < mark && mark <= m_currentTime) 683 emit prefinishMarkReached(total - m_currentTime); 684 583 685 if (lastUpdateTime < m_currentTime && m_currentTime == total){ 584 686 emit finished(); … … 590 692 // We have a next source. 591 693 // Check if it's time to swap to next source: 592 mark = qMax(quint64(0), total + m_transitionTime);694 quint32 mark = qMax(quint64(0), total + m_transitionTime); 593 695 if (m_waitNextSwap && m_state == Phonon::PlayingState && 594 696 m_transitionTime < m_swapTime.msecsTo(QTime::currentTime())){ … … 693 795 void MediaObject::updateCrossFade() 694 796 { 695 m_mediaObjectAudioNode->updateCrossFade(m_currentTime); 797 m_mediaObjectAudioNode->updateCrossFade(m_currentTime); 696 798 // Clean-up previous movie if done fading: 697 799 if (m_mediaObjectAudioNode->m_fadeDuration == 0){ 698 800 if (m_nextVideoPlayer->isPlaying() || m_nextAudioPlayer->isPlaying()){ 699 m_nextVideoPlayer->unset Video();801 m_nextVideoPlayer->unsetCurrentMediaSource(); 700 802 m_nextAudioPlayer->unsetVideoPlayer(); 701 803 } 702 } 804 } 703 805 } 704 806 … … 729 831 if (m_videoPlayer->videoFrameChanged()){ 730 832 updateLipSynch(50); 731 VideoFrame frame(m_videoPlayer); 833 VideoFrame frame(m_videoPlayer); 732 834 if (m_nextVideoPlayer->isPlaying() 733 835 && m_nextVideoPlayer->hasVideo() … … 737 839 frame.setBaseOpacity(m_mediaObjectAudioNode->m_volume1); 738 840 } 739 841 740 842 // Send the frame through the graph: 741 updateVideo(frame); 843 updateVideo(frame); 742 844 checkForError(); 743 845 } … … 750 852 if (m_videoSinkList.isEmpty() || m_audioSinkList.isEmpty()) 751 853 return; 752 854 753 855 if (m_videoPlayer->hasVideo()){ 754 856 qint64 diff = m_audioPlayer->currentTime() - m_videoPlayer->currentTime(); … … 762 864 m_nextAudioPlayer->seek(m_nextVideoPlayer->currentTime()); 763 865 } 764 }765 766 void MediaObject::bufferAudioVideo()767 {768 long nextVideoUpdate = m_videoPlayer->hasVideo() ? 30 : INT_MAX;769 long nextAudioUpdate = m_audioPlayer->regularTaskFrequency();770 updateAudioBuffers();771 updateVideoFrames();772 if (m_state == Phonon::PlayingState)773 updateTimer(m_bufferTimer, qMin(nextVideoUpdate, nextAudioUpdate));774 866 } 775 867 … … 798 890 checkForError(); 799 891 m_mediaObjectAudioNode->setMute(false); 800 801 bufferAudioVideo();892 if (m_state == Phonon::PlayingState) 893 restartAudioVideoTimers(); 802 894 break; 803 895 case MediaNodeEvent::AudioGraphCannotPlay: … … 810 902 m_mediaObjectAudioNode->setMute(false); 811 903 } 812 break;813 default:814 break;815 }816 }817 818 bool MediaObject::event(QEvent *event)819 {820 switch (event->type()){821 case QEvent::Timer: {822 QTimerEvent *timerEvent = static_cast<QTimerEvent *>(event);823 if (timerEvent->timerId() == m_rapidTimer)824 updateRapidly();825 else if (timerEvent->timerId() == m_tickTimer)826 emit tick(currentTime());827 else if (timerEvent->timerId() == m_bufferTimer)828 bufferAudioVideo();829 }830 904 break; 831 905 default: 832 906 break; 833 907 } 908 } 909 910 bool MediaObject::event(QEvent *event) 911 { 912 switch (event->type()){ 913 #if QT_ALLOW_QUICKTIME 914 case QEvent::User:{ 915 m_displayLinkMutex.lock(); 916 m_pendingDisplayLinkEvent = false; 917 m_displayLinkMutex.unlock(); 918 updateVideoFrames(); 919 break; } 920 #endif 921 case QEvent::Timer:{ 922 int timerId = static_cast<QTimerEvent *>(event)->timerId(); 923 if (timerId == m_rapidTimer) 924 updateRapidly(); 925 else if (timerId == m_tickTimer) 926 emit tick(currentTime()); 927 else if (timerId == m_videoTimer) 928 updateVideoFrames(); 929 else if (timerId == m_audioTimer) 930 updateAudioBuffers(); 931 break; } 932 default: 933 break; 934 } 834 935 return QObject::event(event); 835 936 } 836 937 837 bool MediaObject::hasInterface(Interface /*interface*/) const 838 { 839 return false; 840 } 841 842 QVariant MediaObject::interfaceCall(Interface /*interface*/, int /*command*/, const QList<QVariant> &/*arguments*/) 843 { 938 void MediaObject::setCurrentTrack(int track) 939 { 940 if (track == m_videoPlayer->currentTrack() || track < 0 || track >= m_videoPlayer->trackCount()) 941 return; 942 943 m_videoPlayer->setCurrentTrack(track); 944 emit titleChanged(track); 945 emit metaDataChanged(m_videoPlayer->metaData()); 946 } 947 948 bool MediaObject::hasInterface(Interface iface) const 949 { 950 return iface == AddonInterface::TitleInterface; 951 } 952 953 QVariant MediaObject::interfaceCall(Interface iface, int command, const QList<QVariant> ¶ms) 954 { 955 switch (iface) { 956 case TitleInterface: 957 switch (command) { 958 case availableTitles: 959 return m_videoPlayer->trackCount(); 960 case title: 961 return m_videoPlayer->currentTrack(); 962 case setTitle: 963 setCurrentTrack(params.first().toInt()); 964 break; 965 case autoplayTitles: 966 return m_autoplayTitles; 967 case setAutoplayTitles: 968 m_autoplayTitles = params.first().toBool(); 969 break; 970 } 971 default: 972 break; 973 } 844 974 return QVariant(); 845 975 } -
trunk/src/3rdparty/phonon/qt7/quicktimemetadata.h
r2 r561 39 39 { 40 40 public: 41 QuickTimeMetaData(); 42 virtual ~QuickTimeMetaData(); 43 44 void setVideo(QuickTimeVideoPlayer *videoPlayer); 41 QuickTimeMetaData(QuickTimeVideoPlayer *videoPlayer); 42 void update(); 45 43 QMultiMap<QString, QString> metaData(); 46 44 … … 50 48 QuickTimeVideoPlayer *m_videoPlayer; 51 49 void readMetaData(); 50 void guessMetaDataForCD(); 51 void readMetaDataFromMovie(); 52 52 53 53 #ifdef QUICKTIME_C_API_AVAILABLE -
trunk/src/3rdparty/phonon/qt7/quicktimemetadata.mm
r2 r561 16 16 */ 17 17 18 #include <QtCore/QFileInfo> 18 19 #include "quicktimemetadata.h" 19 20 #include "quicktimevideoplayer.h" … … 26 27 { 27 28 28 QuickTimeMetaData::QuickTimeMetaData( )29 { 30 m_videoPlayer = 0;29 QuickTimeMetaData::QuickTimeMetaData(QuickTimeVideoPlayer *videoPlayer) 30 { 31 m_videoPlayer = videoPlayer; 31 32 m_movieChanged = false; 32 33 } 33 34 34 QuickTimeMetaData::~QuickTimeMetaData() 35 { 36 } 37 38 void QuickTimeMetaData::setVideo(QuickTimeVideoPlayer *videoPlayer) 39 { 40 m_videoPlayer = videoPlayer; 35 void QuickTimeMetaData::update() 36 { 41 37 m_movieChanged = true; 42 38 m_metaData.clear(); … … 146 142 #endif // QUICKTIME_C_API_AVAILABLE 147 143 148 void QuickTimeMetaData::readMetaData() 149 { 150 if (!m_videoPlayer) 151 return; 144 void QuickTimeMetaData::guessMetaDataForCD() 145 { 146 QString album = QFileInfo(m_videoPlayer->movieCompactDiscPath()).fileName(); 147 QString title = QFileInfo(m_videoPlayer->currentTrackPath()).fileName(); 148 title = title.left(title.lastIndexOf('.')); 149 m_metaData.insert(QLatin1String("ALBUM"), album); 150 m_metaData.insert(QLatin1String("TITLE"), title); 151 m_metaData.insert(QLatin1String("TRACKNUMBER"), QString::number(m_videoPlayer->currentTrack())); 152 } 153 154 void QuickTimeMetaData::readMetaDataFromMovie() 155 { 152 156 QMultiMap<QString, QString> metaMap; 153 157 154 158 #ifdef QUICKTIME_C_API_AVAILABLE 155 QTMetaDataRef metaDataRef; 159 QTMetaDataRef metaDataRef; 156 160 OSStatus err = QTCopyMovieMetaData([m_videoPlayer->qtMovie() quickTimeMovie], &metaDataRef); 157 161 BACKEND_ASSERT2(err == noErr, "Could not read QuickTime meta data", NORMAL_ERROR) … … 174 178 } 175 179 180 void QuickTimeMetaData::readMetaData() 181 { 182 if (!m_videoPlayer) 183 return; 184 185 if (m_videoPlayer->mediaSource().type() == Phonon::MediaSource::Disc) 186 guessMetaDataForCD(); 187 else 188 readMetaDataFromMovie(); 189 } 190 176 191 QMultiMap<QString, QString> QuickTimeMetaData::metaData() 177 192 { -
trunk/src/3rdparty/phonon/qt7/quicktimevideoplayer.h
r2 r561 40 40 { 41 41 class QuickTimeStreamReader; 42 class QuickTimeMetaData; 42 43 class VideoRenderWidgetQTMovieView; 43 44 … … 57 58 void setMediaSource(const MediaSource &source); 58 59 MediaSource mediaSource() const; 59 void unset Video();60 void unsetCurrentMediaSource(); 60 61 61 62 void play(); … … 68 69 void *currentFrameAsCIImage(); 69 70 QImage currentFrameAsQImage(); 71 void releaseImageCache(); 70 72 QRect videoRect() const; 71 73 … … 73 75 quint64 currentTime() const; 74 76 long timeScale() const; 77 float staticFps(); 75 78 QString currentTimeString(); 76 79 … … 85 88 void setPlaybackRate(float rate); 86 89 QTMovie *qtMovie() const; 90 QMultiMap<QString, QString> metaData(); 87 91 88 92 float playbackRate() const; … … 104 108 quint64 timeLoaded(); 105 109 110 int trackCount() const; 111 int currentTrack() const; 112 void setCurrentTrack(int track); 113 QString movieCompactDiscPath() const; 114 QString currentTrackPath() const; 115 106 116 static QString timeToString(quint64 ms); 107 117 … … 117 127 State m_state; 118 128 QGLPixelBuffer *m_QImagePixelBuffer; 129 QuickTimeMetaData *m_metaData; 130 131 CVOpenGLTextureRef m_cachedCVTextureRef; 132 QImage m_cachedQImage; 119 133 120 134 bool m_playbackRateSat; … … 127 141 float m_relativeVolume; 128 142 float m_playbackRate; 143 float m_staticFps; 129 144 quint64 m_currentTime; 130 145 MediaSource m_mediaSource; 146 131 147 void *m_primaryRenderingCIImage; 132 148 qreal m_brightness; … … 134 150 qreal m_hue; 135 151 qreal m_saturation; 152 NSArray *m_folderTracks; 153 int m_currentTrack; 154 QString m_movieCompactDiscPath; 136 155 137 156 #ifdef QUICKTIME_C_API_AVAILABLE … … 141 160 QuickTimeStreamReader *m_streamReader; 142 161 162 void prepareCurrentMovieForPlayback(); 143 163 void createVisualContext(); 144 164 void openMovieFromCurrentMediaSource(); … … 147 167 void openMovieFromUrl(); 148 168 void openMovieFromStream(); 169 void openMovieFromCompactDisc(); 149 170 void openMovieFromData(QByteArray *data, char *fileType); 150 171 void openMovieFromDataGuessType(QByteArray *data); 151 172 QString mediaSourcePath(); 152 173 bool codecExistsAccordingToSuffix(const QString &fileName); 174 NSString* pathToCompactDisc(); 175 bool isCompactDisc(NSString *path); 176 NSArray* scanFolder(NSString *path); 153 177 154 178 void setError(NSError *error); 155 179 bool errorOccured(); 156 180 void readProtection(); 181 void calculateStaticFps(); 157 182 void checkIfVideoAwailable(); 158 183 bool movieNotLoaded(); -
trunk/src/3rdparty/phonon/qt7/quicktimevideoplayer.mm
r2 r561 21 21 #include "audiodevice.h" 22 22 #include "quicktimestreamreader.h" 23 #include "quicktimemetadata.h" 23 24 24 25 #include <QtCore/QCoreApplication> … … 53 54 m_state = NoMedia; 54 55 m_mediaSource = MediaSource(); 56 m_metaData = new QuickTimeMetaData(this); 55 57 m_QTMovie = 0; 56 58 m_streamReader = 0; … … 62 64 m_audioEnabled = false; 63 65 m_hasVideo = false; 66 m_staticFps = 0; 64 67 m_playbackRateSat = false; 65 68 m_isDrmProtected = false; … … 68 71 m_primaryRenderingCIImage = 0; 69 72 m_QImagePixelBuffer = 0; 73 m_cachedCVTextureRef = 0; 74 m_folderTracks = 0; 75 m_currentTrack = 0; 70 76 71 77 #ifdef QUICKTIME_C_API_AVAILABLE … … 78 84 QuickTimeVideoPlayer::~QuickTimeVideoPlayer() 79 85 { 80 unsetVideo(); 86 PhononAutoReleasePool pool; 87 unsetCurrentMediaSource(); 88 delete m_metaData; 81 89 [(NSObject*)m_primaryRenderingTarget release]; 82 90 m_primaryRenderingTarget = 0; … … 85 93 CFRelease(m_visualContext); 86 94 #endif 95 } 96 97 void QuickTimeVideoPlayer::releaseImageCache() 98 { 99 if (m_cachedCVTextureRef){ 100 CVOpenGLTextureRelease(m_cachedCVTextureRef); 101 m_cachedCVTextureRef = 0; 102 } 103 m_cachedQImage = QImage(); 87 104 } 88 105 … … 126 143 127 144 QTVisualContextTask(m_visualContext); 128 return QTVisualContextIsNewImageAvailable(m_visualContext, 0); 145 bool changed = QTVisualContextIsNewImageAvailable(m_visualContext, 0); 146 if (changed) 147 releaseImageCache(); 148 return changed; 129 149 130 150 #elif defined(QT_MAC_USE_COCOA) … … 141 161 if (!m_visualContext) 142 162 return 0; 143 CVOpenGLTextureRef texture = 0; 144 OSStatus err = QTVisualContextCopyImageForTime(m_visualContext, 0, 0, &texture); 145 BACKEND_ASSERT3(err == noErr, "Could not copy image for time in QuickTime player", FATAL_ERROR, 0) 146 return texture; 163 if (!m_cachedCVTextureRef){ 164 OSStatus err = QTVisualContextCopyImageForTime(m_visualContext, 0, 0, &m_cachedCVTextureRef); 165 BACKEND_ASSERT3(err == noErr, "Could not copy image for time in QuickTime player", FATAL_ERROR, 0) 166 } 167 return m_cachedCVTextureRef; 147 168 148 169 #else … … 153 174 QImage QuickTimeVideoPlayer::currentFrameAsQImage() 154 175 { 176 if (!m_cachedQImage.isNull()) 177 return m_cachedQImage; 178 155 179 #ifdef QUICKTIME_C_API_AVAILABLE 156 180 QGLContext *prevContext = const_cast<QGLContext *>(QGLContext::currentContext()); … … 182 206 glEnd(); 183 207 184 QImage image = m_QImagePixelBuffer->toImage(); 185 CVOpenGLTextureRelease(texture); 208 m_cachedQImage = m_QImagePixelBuffer->toImage(); 186 209 // Because of QuickTime, m_QImagePixelBuffer->doneCurrent() will fail. 187 210 // So we store, and restore, the context our selves: 188 211 prevContext->makeCurrent(); 189 return image;212 return m_cachedQImage; 190 213 #else 191 214 CIImage *img = (CIImage *)currentFrameAsCIImage(); … … 196 219 CGRect bounds = [img extent]; 197 220 QImage qImg([bitmap bitmapData], bounds.size.width, bounds.size.height, QImage::Format_ARGB32); 198 QImage swapped= qImg.rgbSwapped();221 m_cachedQImage = qImg.rgbSwapped(); 199 222 [bitmap release]; 200 223 [img release]; 201 return swapped;224 return m_cachedQImage; 202 225 #endif 203 226 } … … 251 274 CVOpenGLTextureRef cvImg = currentFrameAsCVTexture(); 252 275 CIImage *img = [[CIImage alloc] initWithCVImageBuffer:cvImg]; 253 CVOpenGLTextureRelease(cvImg); 254 return img; 276 return img; 255 277 #else 256 278 return 0; … … 274 296 int samplesPerPixel = [bitmap samplesPerPixel]; 275 297 if (![bitmap isPlanar] && (samplesPerPixel == 3 || samplesPerPixel == 4)){ 276 glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, 298 glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, 277 299 samplesPerPixel == 4 ? GL_RGBA8 : GL_RGB8, 278 300 [bitmap pixelsWide], [bitmap pixelsHigh], … … 303 325 m_relativeVolume = relativeVolume; 304 326 if (!m_QTMovie || !m_audioEnabled || m_mute) 305 return; 327 return; 306 328 [m_QTMovie setVolume:(m_masterVolume * m_relativeVolume)]; 307 329 } … … 314 336 315 337 // Work-around bug that happends if you set/unset mute 316 // before movie is playing, and audio is not played 338 // before movie is playing, and audio is not played 317 339 // through graph. Then audio is delayed. 318 340 [m_QTMovie setMuted:mute]; … … 327 349 328 350 // Work-around bug that happends if you set/unset mute 329 // before movie is playing, and audio is not played 351 // before movie is playing, and audio is not played 330 352 // through graph. Then audio is delayed. 331 353 [m_QTMovie setMuted:(!enable || m_mute)]; … … 346 368 // The following code will not work for some media codecs that 347 369 // typically mingle audio/video frames (e.g mpeg). 348 CFStringRef idString = PhononCFString::toCFStringRef(AudioDevice::deviceUID(id)); 370 CFStringRef idString = PhononCFString::toCFStringRef(AudioDevice::deviceUID(id)); 349 371 QTAudioContextRef context; 350 372 QTAudioContextCreateForAudioDevice(kCFAllocatorDefault, idString, 0, &context); … … 370 392 saturation += 1; 371 393 394 if (m_brightness == brightness 395 && m_contrast == contrast 396 && m_hue == hue 397 && m_saturation == saturation) 398 return; 399 372 400 m_brightness = brightness; 373 401 m_contrast = contrast; 374 402 m_hue = hue; 375 403 m_saturation = saturation; 376 377 404 #ifdef QUICKTIME_C_API_AVAILABLE 378 405 Float32 value; … … 386 413 SetMovieVisualSaturation([m_QTMovie quickTimeMovie], value, 0); 387 414 #endif 415 releaseImageCache(); 388 416 } 389 417 … … 398 426 } 399 427 400 void QuickTimeVideoPlayer::unset Video()428 void QuickTimeVideoPlayer::unsetCurrentMediaSource() 401 429 { 402 430 if (!m_QTMovie) … … 411 439 m_isDrmProtected = false; 412 440 m_isDrmAuthorized = true; 441 m_hasVideo = false; 442 m_staticFps = 0; 413 443 m_mediaSource = MediaSource(); 444 m_movieCompactDiscPath.clear(); 414 445 [(CIImage *)m_primaryRenderingCIImage release]; 415 446 m_primaryRenderingCIImage = 0; 416 447 delete m_QImagePixelBuffer; 417 448 m_QImagePixelBuffer = 0; 449 releaseImageCache(); 450 [m_folderTracks release]; 451 m_folderTracks = 0; 418 452 } 419 453 … … 525 559 { 526 560 PhononAutoReleasePool pool; 527 unsetVideo(); 561 unsetCurrentMediaSource(); 562 528 563 m_mediaSource = mediaSource; 529 564 if (mediaSource.type() == MediaSource::Empty || mediaSource.type() == MediaSource::Invalid){ … … 531 566 return; 532 567 } 568 533 569 openMovieFromCurrentMediaSource(); 534 570 if (errorOccured()){ 535 unsetVideo(); 536 return; 537 } 538 571 unsetCurrentMediaSource(); 572 return; 573 } 574 575 prepareCurrentMovieForPlayback(); 576 } 577 578 void QuickTimeVideoPlayer::prepareCurrentMovieForPlayback() 579 { 539 580 #ifdef QUICKTIME_C_API_AVAILABLE 540 581 if (m_visualContext) … … 544 585 waitStatePlayable(); 545 586 if (errorOccured()){ 546 unset Video();587 unsetCurrentMediaSource(); 547 588 return; 548 589 } … … 551 592 preRollMovie(); 552 593 if (errorOccured()){ 553 unset Video();594 unsetCurrentMediaSource(); 554 595 return; 555 596 } … … 558 599 m_playbackRate = prefferedPlaybackRate(); 559 600 checkIfVideoAwailable(); 601 calculateStaticFps(); 560 602 enableAudio(m_audioEnabled); 561 603 setMute(m_mute); 562 604 setVolume(m_masterVolume, m_relativeVolume); 605 m_metaData->update(); 563 606 pause(); 564 607 } … … 574 617 break; 575 618 case MediaSource::Disc: 576 CASE_UNSUPPORTED("Could not open media source.", FATAL_ERROR)619 openMovieFromCompactDisc(); 577 620 break; 578 621 case MediaSource::Stream: … … 636 679 // codecs *think* they can decode the stream, and crash... 637 680 #define TryOpenMovieWithCodec(type) gClearError(); \ 638 openMovieFromData(data, "."type); \681 openMovieFromData(data, (char *)"."type); \ 639 682 if (m_QTMovie) return; 640 683 … … 676 719 } 677 720 721 typedef void (*qt_sighandler_t)(int); 722 static void sigtest(int) { 723 qApp->exit(0); 724 } 725 726 void QuickTimeVideoPlayer::openMovieFromCompactDisc() 727 { 728 // Interrupting the application while the device is open 729 // causes the application to hang. So we need to handle 730 // this in a more graceful way: 731 qt_sighandler_t hndl = signal(SIGINT, sigtest); 732 if (hndl) 733 signal(SIGINT, hndl); 734 735 PhononAutoReleasePool pool; 736 NSString *cd = 0; 737 QString devName = m_mediaSource.deviceName(); 738 if (devName.isEmpty()) { 739 cd = pathToCompactDisc(); 740 if (!cd) { 741 SET_ERROR("Could not open media source.", NORMAL_ERROR) 742 return; 743 } 744 m_movieCompactDiscPath = PhononCFString::toQString(reinterpret_cast<CFStringRef>(cd)); 745 } else { 746 if (!QFileInfo(devName).isAbsolute()) 747 devName = QLatin1String("/Volumes/") + devName; 748 cd = [reinterpret_cast<const NSString *>(PhononCFString::toCFStringRef(devName)) autorelease]; 749 if (!isCompactDisc(cd)) { 750 SET_ERROR("Could not open media source.", NORMAL_ERROR) 751 return; 752 } 753 m_movieCompactDiscPath = devName; 754 } 755 756 m_folderTracks = [scanFolder(cd) retain]; 757 setCurrentTrack(0); 758 } 759 760 QString QuickTimeVideoPlayer::movieCompactDiscPath() const 761 { 762 return m_movieCompactDiscPath; 763 } 764 678 765 MediaSource QuickTimeVideoPlayer::mediaSource() const 679 766 { … … 719 806 PhononAutoReleasePool pool; 720 807 return [[m_QTMovie attributeForKey:@"QTMovieTimeScaleAttribute"] longValue]; 808 } 809 810 float QuickTimeVideoPlayer::staticFps() 811 { 812 return m_staticFps; 813 } 814 815 void QuickTimeVideoPlayer::calculateStaticFps() 816 { 817 if (!m_hasVideo){ 818 m_staticFps = 0; 819 return; 820 } 821 822 #ifdef QT_ALLOW_QUICKTIME 823 Boolean isMpeg = false; 824 Track videoTrack = GetMovieIndTrackType([m_QTMovie quickTimeMovie], 1, 825 FOUR_CHAR_CODE('vfrr'), // 'vfrr' means: has frame rate 826 movieTrackCharacteristic | movieTrackEnabledOnly); 827 Media media = GetTrackMedia(videoTrack); 828 MediaHandler mediaH = GetMediaHandler(media); 829 MediaHasCharacteristic(mediaH, FOUR_CHAR_CODE('mpeg'), &isMpeg); 830 831 if (isMpeg){ 832 MHInfoEncodedFrameRateRecord frameRate; 833 Size frameRateSize = sizeof(frameRate); 834 MediaGetPublicInfo(mediaH, kMHInfoEncodedFrameRate, &frameRate, &frameRateSize); 835 m_staticFps = float(Fix2X(frameRate.encodedFrameRate)); 836 } else { 837 Media media = GetTrackMedia(videoTrack); 838 long sampleCount = GetMediaSampleCount(media); 839 TimeValue64 duration = GetMediaDisplayDuration(media); 840 TimeValue64 timeScale = GetMediaTimeScale(media); 841 m_staticFps = float((double)sampleCount * (double)timeScale / (double)duration); 842 } 843 #else 844 m_staticFps = 30.0f; 845 #endif 721 846 } 722 847 … … 951 1076 } 952 1077 1078 QMultiMap<QString, QString> QuickTimeVideoPlayer::metaData() 1079 { 1080 return m_metaData->metaData(); 1081 } 1082 1083 int QuickTimeVideoPlayer::trackCount() const 1084 { 1085 if (!m_folderTracks) 1086 return 0; 1087 return [m_folderTracks count]; 1088 } 1089 1090 int QuickTimeVideoPlayer::currentTrack() const 1091 { 1092 return m_currentTrack; 1093 } 1094 1095 QString QuickTimeVideoPlayer::currentTrackPath() const 1096 { 1097 if (!m_folderTracks) 1098 return QString(); 1099 1100 PhononAutoReleasePool pool; 1101 NSString *trackPath = [m_folderTracks objectAtIndex:m_currentTrack]; 1102 return PhononCFString::toQString(reinterpret_cast<CFStringRef>(trackPath)); 1103 } 1104 1105 NSString* QuickTimeVideoPlayer::pathToCompactDisc() 1106 { 1107 PhononAutoReleasePool pool; 1108 NSArray *devices = [[NSWorkspace sharedWorkspace] mountedRemovableMedia]; 1109 for (unsigned int i=0; i<[devices count]; ++i) { 1110 NSString *dev = [devices objectAtIndex:i]; 1111 if (isCompactDisc(dev)) 1112 return [dev retain]; 1113 } 1114 return 0; 1115 } 1116 1117 bool QuickTimeVideoPlayer::isCompactDisc(NSString *path) 1118 { 1119 PhononAutoReleasePool pool; 1120 NSString *type = [NSString string]; 1121 [[NSWorkspace sharedWorkspace] getFileSystemInfoForPath:path 1122 isRemovable:0 1123 isWritable:0 1124 isUnmountable:0 1125 description:0 1126 type:&type]; 1127 return [type hasPrefix:@"cdd"]; 1128 } 1129 1130 NSArray* QuickTimeVideoPlayer::scanFolder(NSString *path) 1131 { 1132 NSMutableArray *tracks = [NSMutableArray arrayWithCapacity:20]; 1133 if (!path) 1134 return tracks; 1135 1136 NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtPath:path]; 1137 while (NSString *track = [enumerator nextObject]) { 1138 if (![track hasPrefix:@"."]) 1139 [tracks addObject:[path stringByAppendingPathComponent:track]]; 1140 } 1141 return tracks; 1142 } 1143 1144 void QuickTimeVideoPlayer::setCurrentTrack(int track) 1145 { 1146 PhononAutoReleasePool pool; 1147 [m_QTMovie release]; 1148 m_QTMovie = 0; 1149 m_currentTime = 0; 1150 m_currentTrack = track; 1151 1152 if (!m_folderTracks) 1153 return; 1154 if (track < 0 || track >= (int)[m_folderTracks count]) 1155 return; 1156 1157 NSString *trackPath = [m_folderTracks objectAtIndex:track]; 1158 QTDataReference *dataRef = [QTDataReference dataReferenceWithReferenceToFile:trackPath]; 1159 State currentState = m_state; 1160 openMovieFromDataRef(dataRef); 1161 prepareCurrentMovieForPlayback(); 1162 if (currentState == Playing) 1163 play(); 1164 } 1165 953 1166 }} 954 1167 -
trunk/src/3rdparty/phonon/qt7/videoframe.mm
r2 r561 20 20 #import <QuartzCore/CIFilter.h> 21 21 #import <QuartzCore/CIContext.h> 22 23 //#define CACHE_CV_TEXTURE 22 24 23 25 QT_BEGIN_NAMESPACE … … 71 73 void VideoFrame::copyMembers(const VideoFrame& frame) 72 74 { 75 #ifdef CACHE_CV_TEXTURE 73 76 m_cachedCVTextureRef = frame.m_cachedCVTextureRef; 77 #endif 74 78 m_cachedCIImage = frame.m_cachedCIImage; 75 79 m_cachedQImage = frame.m_cachedQImage; … … 106 110 CVOpenGLTextureRef VideoFrame::cachedCVTexture() const 107 111 { 112 #ifdef CACHE_CV_TEXTURE 108 113 if (!m_cachedCVTextureRef && m_videoPlayer){ 109 114 m_videoPlayer->setColors(m_brightness, m_contrast, m_hue, m_saturation); 110 115 (const_cast<VideoFrame *>(this))->m_cachedCVTextureRef = m_videoPlayer->currentFrameAsCVTexture(); 116 CVOpenGLTextureRetain((const_cast<VideoFrame *>(this))->m_cachedCVTextureRef); 111 117 } 112 118 return m_cachedCVTextureRef; 119 #else 120 if (m_videoPlayer){ 121 m_videoPlayer->setColors(m_brightness, m_contrast, m_hue, m_saturation); 122 return m_videoPlayer->currentFrameAsCVTexture(); 123 } 124 return 0; 125 #endif 113 126 } 114 127 … … 330 343 void VideoFrame::invalidateImage() const 331 344 { 345 #ifdef CACHE_CV_TEXTURE 332 346 if (m_cachedCVTextureRef){ 333 347 CVOpenGLTextureRelease(m_cachedCVTextureRef); 334 348 (const_cast<VideoFrame *>(this))->m_cachedCVTextureRef = 0; 335 349 } 350 #endif 336 351 if (m_cachedCIImage){ 337 352 [(CIImage *) m_cachedCIImage release]; … … 347 362 void VideoFrame::retain() const 348 363 { 364 #ifdef CACHE_CV_TEXTURE 349 365 if (m_cachedCVTextureRef) 350 366 CVOpenGLTextureRetain(m_cachedCVTextureRef); 367 #endif 351 368 if (m_cachedCIImage) 352 369 [(CIImage *) m_cachedCIImage retain]; … … 359 376 void VideoFrame::release() const 360 377 { 361 if (m_cachedCVTextureRef) 378 #ifdef CACHE_CV_TEXTURE 379 if (m_cachedCVTextureRef){ 362 380 CVOpenGLTextureRelease(m_cachedCVTextureRef); 381 (const_cast<VideoFrame *>(this))->m_cachedCVTextureRef = 0; 382 } 383 #endif 363 384 if (m_cachedCIImage) 364 385 [(CIImage *) m_cachedCIImage release]; … … 369 390 370 391 (const_cast<VideoFrame *>(this))->m_backgroundFrame = 0; 371 (const_cast<VideoFrame *>(this))->m_cachedCVTextureRef = 0;372 392 (const_cast<VideoFrame *>(this))->m_cachedCIImage = 0; 373 393 (const_cast<VideoFrame *>(this))->m_cachedNSBitmap = 0;
Note:
See TracChangeset
for help on using the changeset viewer.