src/3rdparty/phonon/qt7/quicktimevideoplayer.mm
changeset 30 5dc02b23752f
parent 0 1918ee327afb
--- a/src/3rdparty/phonon/qt7/quicktimevideoplayer.mm	Wed Jun 23 19:07:03 2010 +0300
+++ b/src/3rdparty/phonon/qt7/quicktimevideoplayer.mm	Tue Jul 06 15:10:48 2010 +0300
@@ -20,7 +20,6 @@
 #include "videowidget.h"
 #include "audiodevice.h"
 #include "quicktimestreamreader.h"
-#include "quicktimemetadata.h"
 
 #include <QtCore/QCoreApplication>
 #include <QtCore/QEventLoop>
@@ -53,7 +52,6 @@
 {
     m_state = NoMedia;
     m_mediaSource = MediaSource();
-    m_metaData = new QuickTimeMetaData(this);
     m_QTMovie = 0;
     m_streamReader = 0;
     m_playbackRate = 1.0f;
@@ -63,16 +61,12 @@
     m_mute = false;
     m_audioEnabled = false;
     m_hasVideo = false;
-    m_staticFps = 0;
     m_playbackRateSat = false;
     m_isDrmProtected = false;
     m_isDrmAuthorized = true;
 	m_primaryRenderingTarget = 0;
 	m_primaryRenderingCIImage = 0;
     m_QImagePixelBuffer = 0;
-    m_cachedCVTextureRef = 0;
-    m_folderTracks = 0;
-    m_currentTrack = 0;
 
 #ifdef QUICKTIME_C_API_AVAILABLE
     OSStatus err = EnterMovies();
@@ -83,9 +77,7 @@
 
 QuickTimeVideoPlayer::~QuickTimeVideoPlayer()
 {
-	PhononAutoReleasePool pool;
-    unsetCurrentMediaSource();
-    delete m_metaData;
+    unsetVideo();
     [(NSObject*)m_primaryRenderingTarget release];
     m_primaryRenderingTarget = 0;
 #ifdef QUICKTIME_C_API_AVAILABLE
@@ -94,15 +86,6 @@
 #endif
 }
 
-void QuickTimeVideoPlayer::releaseImageCache()
-{
-    if (m_cachedCVTextureRef){
-        CVOpenGLTextureRelease(m_cachedCVTextureRef);
-        m_cachedCVTextureRef = 0;
-    }
-    m_cachedQImage = QImage();
-}
-
 void QuickTimeVideoPlayer::createVisualContext()
 {
 #ifdef QUICKTIME_C_API_AVAILABLE
@@ -142,10 +125,7 @@
 		return false;
 
     QTVisualContextTask(m_visualContext);
-    bool changed = QTVisualContextIsNewImageAvailable(m_visualContext, 0);
-    if (changed)
-        releaseImageCache();
-    return changed;
+    return QTVisualContextIsNewImageAvailable(m_visualContext, 0);
 
 #elif defined(QT_MAC_USE_COCOA)
     return true;
@@ -160,11 +140,10 @@
 #ifdef QUICKTIME_C_API_AVAILABLE
     if (!m_visualContext)
         return 0;
-    if (!m_cachedCVTextureRef){
-        OSStatus err = QTVisualContextCopyImageForTime(m_visualContext, 0, 0, &m_cachedCVTextureRef);
-        BACKEND_ASSERT3(err == noErr, "Could not copy image for time in QuickTime player", FATAL_ERROR, 0)
-    }
-    return m_cachedCVTextureRef;
+    CVOpenGLTextureRef texture = 0;
+    OSStatus err = QTVisualContextCopyImageForTime(m_visualContext, 0, 0, &texture);
+    BACKEND_ASSERT3(err == noErr, "Could not copy image for time in QuickTime player", FATAL_ERROR, 0)
+    return texture;
 
 #else
     return 0;
@@ -173,9 +152,6 @@
 
 QImage QuickTimeVideoPlayer::currentFrameAsQImage()
 {
-    if (!m_cachedQImage.isNull())
-        return m_cachedQImage;
-
 #ifdef QUICKTIME_C_API_AVAILABLE
     QGLContext *prevContext = const_cast<QGLContext *>(QGLContext::currentContext());
     CVOpenGLTextureRef texture = currentFrameAsCVTexture();
@@ -205,11 +181,12 @@
         glVertex2i(-1, -1);
     glEnd();
 
-    m_cachedQImage = m_QImagePixelBuffer->toImage();
+    QImage image = m_QImagePixelBuffer->toImage();
+    CVOpenGLTextureRelease(texture);
     // Because of QuickTime, m_QImagePixelBuffer->doneCurrent() will fail.
     // So we store, and restore, the context our selves:
     prevContext->makeCurrent();
-    return m_cachedQImage;
+    return image;
 #else
 	CIImage *img = (CIImage *)currentFrameAsCIImage();
 	if (!img)
@@ -218,10 +195,10 @@
 	NSBitmapImageRep* bitmap = [[NSBitmapImageRep alloc] initWithCIImage:img];
 	CGRect bounds = [img extent];
 	QImage qImg([bitmap bitmapData], bounds.size.width, bounds.size.height, QImage::Format_ARGB32);
-	m_cachedQImage = qImg.rgbSwapped();
+	QImage swapped = qImg.rgbSwapped();
 	[bitmap release];
 	[img release];
-	return m_cachedQImage;
+	return swapped;
 #endif
 }
 
@@ -273,7 +250,8 @@
 #ifdef QUICKTIME_C_API_AVAILABLE
 	CVOpenGLTextureRef cvImg = currentFrameAsCVTexture();
 	CIImage *img = [[CIImage alloc] initWithCVImageBuffer:cvImg];
-	return img;
+	CVOpenGLTextureRelease(cvImg);
+	return img;	
 #else
 	return 0;
 #endif
@@ -295,7 +273,7 @@
 
     int samplesPerPixel = [bitmap samplesPerPixel];
     if (![bitmap isPlanar] && (samplesPerPixel == 3 || samplesPerPixel == 4)){
-        glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0,
+        glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, 
             samplesPerPixel == 4 ? GL_RGBA8 : GL_RGB8,
             [bitmap pixelsWide], [bitmap pixelsHigh],
             0, samplesPerPixel == 4 ? GL_RGBA : GL_RGB,
@@ -324,7 +302,7 @@
     m_masterVolume = masterVolume;
     m_relativeVolume = relativeVolume;
     if (!m_QTMovie || !m_audioEnabled || m_mute)
-        return;
+        return;                
     [m_QTMovie setVolume:(m_masterVolume * m_relativeVolume)];
 }
 
@@ -335,7 +313,7 @@
         return;
 
     // Work-around bug that happends if you set/unset mute
-    // before movie is playing, and audio is not played
+    // before movie is playing, and audio is not played 
     // through graph. Then audio is delayed.
     [m_QTMovie setMuted:mute];
     [m_QTMovie setVolume:(mute ? 0 : m_masterVolume * m_relativeVolume)];
@@ -348,7 +326,7 @@
         return;
 
     // Work-around bug that happends if you set/unset mute
-    // before movie is playing, and audio is not played
+    // before movie is playing, and audio is not played 
     // through graph. Then audio is delayed.
     [m_QTMovie setMuted:(!enable || m_mute)];
     [m_QTMovie setVolume:((!enable || m_mute) ? 0 : m_masterVolume * m_relativeVolume)];
@@ -367,7 +345,7 @@
 #ifdef QUICKTIME_C_API_AVAILABLE
     // The following code will not work for some media codecs that
     // typically mingle audio/video frames (e.g mpeg).
-    CFStringRef idString = PhononCFString::toCFStringRef(AudioDevice::deviceUID(id));
+    CFStringRef idString = PhononCFString::toCFStringRef(AudioDevice::deviceUID(id));        
     QTAudioContextRef context;
     QTAudioContextCreateForAudioDevice(kCFAllocatorDefault, idString, 0, &context);
     OSStatus err = SetMovieAudioContext([m_QTMovie quickTimeMovie], context);
@@ -391,16 +369,11 @@
     contrast += 1;
     saturation += 1;
 
-    if (m_brightness == brightness
-        && m_contrast == contrast
-        && m_hue == hue
-        && m_saturation == saturation)
-        return;
-
 	m_brightness = brightness;
 	m_contrast = contrast;
 	m_hue = hue;
 	m_saturation = saturation;
+	
 #ifdef QUICKTIME_C_API_AVAILABLE
     Float32 value;
     value = brightness;
@@ -412,7 +385,6 @@
     value = saturation;
     SetMovieVisualSaturation([m_QTMovie quickTimeMovie], value, 0);
 #endif
-    releaseImageCache();
 }
 
 QRect QuickTimeVideoPlayer::videoRect() const
@@ -425,7 +397,7 @@
     return QRect(0, 0, size.width, size.height);
 }
 
-void QuickTimeVideoPlayer::unsetCurrentMediaSource()
+void QuickTimeVideoPlayer::unsetVideo()
 {
     if (!m_QTMovie)
         return;
@@ -438,17 +410,11 @@
     m_state = NoMedia;
     m_isDrmProtected = false;
     m_isDrmAuthorized = true;
-    m_hasVideo = false;
-    m_staticFps = 0;
     m_mediaSource = MediaSource();
-    m_movieCompactDiscPath.clear();
 	[(CIImage *)m_primaryRenderingCIImage release];
 	m_primaryRenderingCIImage = 0;
     delete m_QImagePixelBuffer;
     m_QImagePixelBuffer = 0;
-    releaseImageCache();
-    [m_folderTracks release];
-    m_folderTracks = 0;
 }
 
 QuickTimeVideoPlayer::State QuickTimeVideoPlayer::state() const
@@ -558,25 +524,18 @@
 void QuickTimeVideoPlayer::setMediaSource(const MediaSource &mediaSource)
 {
     PhononAutoReleasePool pool;
-    unsetCurrentMediaSource();
-
+    unsetVideo();
     m_mediaSource = mediaSource;
     if (mediaSource.type() == MediaSource::Empty || mediaSource.type() == MediaSource::Invalid){
         m_state = NoMedia;
         return;
     }
-
     openMovieFromCurrentMediaSource();
     if (errorOccured()){
-        unsetCurrentMediaSource();
+        unsetVideo();
         return;
     }
 
-    prepareCurrentMovieForPlayback();
-}
-
-void QuickTimeVideoPlayer::prepareCurrentMovieForPlayback()
-{
 #ifdef QUICKTIME_C_API_AVAILABLE
     if (m_visualContext)
         SetMovieVisualContext([m_QTMovie quickTimeMovie], m_visualContext);
@@ -584,25 +543,23 @@
 
     waitStatePlayable();
     if (errorOccured()){
-        unsetCurrentMediaSource();
+        unsetVideo();
         return;
     }
 
     readProtection();
     preRollMovie();
     if (errorOccured()){
-        unsetCurrentMediaSource();
+        unsetVideo();
         return;
     }
 
     if (!m_playbackRateSat)
         m_playbackRate = prefferedPlaybackRate();
     checkIfVideoAwailable();
-    calculateStaticFps();
     enableAudio(m_audioEnabled);
     setMute(m_mute);
     setVolume(m_masterVolume, m_relativeVolume);
-    m_metaData->update();
     pause();
 }
 
@@ -616,7 +573,7 @@
         openMovieFromUrl();
         break;
     case MediaSource::Disc:
-        openMovieFromCompactDisc();
+        CASE_UNSUPPORTED("Could not open media source.", FATAL_ERROR)
         break;
     case MediaSource::Stream:
         openMovieFromStream();
@@ -678,7 +635,7 @@
     // than using e.g [QTMovie movieFileTypes:QTIncludeCommonTypes]. Some
     // codecs *think* they can decode the stream, and crash...
 #define TryOpenMovieWithCodec(type) gClearError(); \
-    openMovieFromData(data, (char *)"."type); \
+    openMovieFromData(data, "."type); \
     if (m_QTMovie) return;
 
     TryOpenMovieWithCodec("avi");
@@ -718,50 +675,6 @@
     openMovieFromDataGuessType(m_streamReader->pointerToData());
 }
 
-typedef void (*qt_sighandler_t)(int);
-static void sigtest(int) {
-    qApp->exit(0);
-}
-
-void QuickTimeVideoPlayer::openMovieFromCompactDisc()
-{
-    // Interrupting the application while the device is open
-    // causes the application to hang. So we need to handle
-    // this in a more graceful way:
-    qt_sighandler_t hndl = signal(SIGINT, sigtest);
-    if (hndl)
-        signal(SIGINT, hndl);
-
-    PhononAutoReleasePool pool;
-    NSString *cd = 0;
-    QString devName = m_mediaSource.deviceName();
-    if (devName.isEmpty()) {
-        cd = pathToCompactDisc();
-        if (!cd) {
-            SET_ERROR("Could not open media source.", NORMAL_ERROR)
-            return;
-        }
-        m_movieCompactDiscPath = PhononCFString::toQString(reinterpret_cast<CFStringRef>(cd));
-    } else {
-       if (!QFileInfo(devName).isAbsolute())
-           devName = QLatin1String("/Volumes/") + devName;
-       cd = [reinterpret_cast<const NSString *>(PhononCFString::toCFStringRef(devName)) autorelease];
-       if (!isCompactDisc(cd)) {
-           SET_ERROR("Could not open media source.", NORMAL_ERROR)
-           return;
-       }
-       m_movieCompactDiscPath = devName;
-    }
-
-    m_folderTracks = [scanFolder(cd) retain];
-    setCurrentTrack(0);
-}
-
-QString QuickTimeVideoPlayer::movieCompactDiscPath() const
-{
-    return m_movieCompactDiscPath;
-}
-
 MediaSource QuickTimeVideoPlayer::mediaSource() const
 {
     return m_mediaSource;
@@ -807,44 +720,6 @@
     return [[m_QTMovie attributeForKey:@"QTMovieTimeScaleAttribute"] longValue];
 }
 
-float QuickTimeVideoPlayer::staticFps()
-{
-    return m_staticFps;
-}
-
-void QuickTimeVideoPlayer::calculateStaticFps()
-{
-    if (!m_hasVideo){
-        m_staticFps = 0;
-        return;
-    }
-
-#ifdef QT_ALLOW_QUICKTIME
-    Boolean isMpeg = false;
-    Track videoTrack = GetMovieIndTrackType([m_QTMovie quickTimeMovie], 1,
-            FOUR_CHAR_CODE('vfrr'), // 'vfrr' means: has frame rate
-            movieTrackCharacteristic | movieTrackEnabledOnly);
-    Media media = GetTrackMedia(videoTrack);
-    MediaHandler mediaH = GetMediaHandler(media);
-    MediaHasCharacteristic(mediaH, FOUR_CHAR_CODE('mpeg'), &isMpeg);
-
-    if (isMpeg){
-        MHInfoEncodedFrameRateRecord frameRate;
-        Size frameRateSize = sizeof(frameRate);
-        MediaGetPublicInfo(mediaH, kMHInfoEncodedFrameRate, &frameRate, &frameRateSize);
-        m_staticFps = float(Fix2X(frameRate.encodedFrameRate));
-    } else {
-        Media media = GetTrackMedia(videoTrack);
-        long sampleCount = GetMediaSampleCount(media);
-        TimeValue64 duration = GetMediaDisplayDuration(media);
-        TimeValue64 timeScale = GetMediaTimeScale(media);
-        m_staticFps = float((double)sampleCount * (double)timeScale / (double)duration);
-    }
-#else
-    m_staticFps = 30.0f;
-#endif
-}
-
 QString QuickTimeVideoPlayer::timeToString(quint64 ms)
 {
     int sec = ms/1000;
@@ -1075,94 +950,6 @@
     }
 }
 
-QMultiMap<QString, QString> QuickTimeVideoPlayer::metaData()
-{
-    return m_metaData->metaData();
-}
-
-int QuickTimeVideoPlayer::trackCount() const
-{
-    if (!m_folderTracks)
-        return 0;
-    return [m_folderTracks count];
-}
-
-int QuickTimeVideoPlayer::currentTrack() const
-{
-    return m_currentTrack;
-}
-
-QString QuickTimeVideoPlayer::currentTrackPath() const
-{
-    if (!m_folderTracks)
-        return QString();
-
-    PhononAutoReleasePool pool;
-    NSString *trackPath = [m_folderTracks objectAtIndex:m_currentTrack];
-    return PhononCFString::toQString(reinterpret_cast<CFStringRef>(trackPath));
-}
-
-NSString* QuickTimeVideoPlayer::pathToCompactDisc()
-{
-    PhononAutoReleasePool pool;
-    NSArray *devices = [[NSWorkspace sharedWorkspace] mountedRemovableMedia];
-    for (unsigned int i=0; i<[devices count]; ++i) {
-        NSString *dev = [devices objectAtIndex:i];
-        if (isCompactDisc(dev))
-            return [dev retain];
-    }
-    return 0;
-}
-
-bool QuickTimeVideoPlayer::isCompactDisc(NSString *path)
-{
-    PhononAutoReleasePool pool;
-    NSString *type = [NSString string];
-    [[NSWorkspace sharedWorkspace] getFileSystemInfoForPath:path
-        isRemovable:0
-        isWritable:0
-        isUnmountable:0
-        description:0
-        type:&type];
-    return [type hasPrefix:@"cdd"];
-}
-
-NSArray* QuickTimeVideoPlayer::scanFolder(NSString *path)
-{
-    NSMutableArray *tracks = [NSMutableArray arrayWithCapacity:20];
-    if (!path)
-        return tracks;
-
-    NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtPath:path];
-    while (NSString *track = [enumerator nextObject]) {
-        if (![track hasPrefix:@"."])
-            [tracks addObject:[path stringByAppendingPathComponent:track]];
-    }
-    return tracks;
-}
-
-void QuickTimeVideoPlayer::setCurrentTrack(int track)
-{
-    PhononAutoReleasePool pool;
-    [m_QTMovie release];
-	m_QTMovie = 0;
-    m_currentTime = 0;
-    m_currentTrack = track;
-
-    if (!m_folderTracks)
-        return;
-    if (track < 0 || track >= (int)[m_folderTracks count])
-        return;
-
-    NSString *trackPath = [m_folderTracks objectAtIndex:track];
-    QTDataReference *dataRef = [QTDataReference dataReferenceWithReferenceToFile:trackPath];
-    State currentState = m_state;
-    openMovieFromDataRef(dataRef);
-    prepareCurrentMovieForPlayback();
-    if (currentState == Playing)
-        play();
-}
-
 }}
 
 QT_END_NAMESPACE