Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/3rdparty/phonon/qt7/quicktimevideoplayer.mm

    r561 r846  
    2121#include "audiodevice.h"
    2222#include "quicktimestreamreader.h"
    23 #include "quicktimemetadata.h"
    2423
    2524#include <QtCore/QCoreApplication>
     
    5453    m_state = NoMedia;
    5554    m_mediaSource = MediaSource();
    56     m_metaData = new QuickTimeMetaData(this);
    5755    m_QTMovie = 0;
    5856    m_streamReader = 0;
     
    6462    m_audioEnabled = false;
    6563    m_hasVideo = false;
    66     m_staticFps = 0;
    6764    m_playbackRateSat = false;
    6865    m_isDrmProtected = false;
     
    7168        m_primaryRenderingCIImage = 0;
    7269    m_QImagePixelBuffer = 0;
    73     m_cachedCVTextureRef = 0;
    74     m_folderTracks = 0;
    75     m_currentTrack = 0;
    7670
    7771#ifdef QUICKTIME_C_API_AVAILABLE
     
    8478QuickTimeVideoPlayer::~QuickTimeVideoPlayer()
    8579{
    86         PhononAutoReleasePool pool;
    87     unsetCurrentMediaSource();
    88     delete m_metaData;
     80    unsetVideo();
    8981    [(NSObject*)m_primaryRenderingTarget release];
    9082    m_primaryRenderingTarget = 0;
     
    9385        CFRelease(m_visualContext);
    9486#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();
    10487}
    10588
     
    143126
    144127    QTVisualContextTask(m_visualContext);
    145     bool changed = QTVisualContextIsNewImageAvailable(m_visualContext, 0);
    146     if (changed)
    147         releaseImageCache();
    148     return changed;
     128    return QTVisualContextIsNewImageAvailable(m_visualContext, 0);
    149129
    150130#elif defined(QT_MAC_USE_COCOA)
     
    161141    if (!m_visualContext)
    162142        return 0;
    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;
     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;
    168147
    169148#else
     
    174153QImage QuickTimeVideoPlayer::currentFrameAsQImage()
    175154{
    176     if (!m_cachedQImage.isNull())
    177         return m_cachedQImage;
    178 
    179155#ifdef QUICKTIME_C_API_AVAILABLE
    180156    QGLContext *prevContext = const_cast<QGLContext *>(QGLContext::currentContext());
     
    206182    glEnd();
    207183
    208     m_cachedQImage = m_QImagePixelBuffer->toImage();
     184    QImage image = m_QImagePixelBuffer->toImage();
     185    CVOpenGLTextureRelease(texture);
    209186    // Because of QuickTime, m_QImagePixelBuffer->doneCurrent() will fail.
    210187    // So we store, and restore, the context our selves:
    211188    prevContext->makeCurrent();
    212     return m_cachedQImage;
     189    return image;
    213190#else
    214191        CIImage *img = (CIImage *)currentFrameAsCIImage();
     
    219196        CGRect bounds = [img extent];
    220197        QImage qImg([bitmap bitmapData], bounds.size.width, bounds.size.height, QImage::Format_ARGB32);
    221         m_cachedQImage = qImg.rgbSwapped();
     198        QImage swapped = qImg.rgbSwapped();
    222199        [bitmap release];
    223200        [img release];
    224         return m_cachedQImage;
     201        return swapped;
    225202#endif
    226203}
     
    274251        CVOpenGLTextureRef cvImg = currentFrameAsCVTexture();
    275252        CIImage *img = [[CIImage alloc] initWithCVImageBuffer:cvImg];
    276         return img;
     253        CVOpenGLTextureRelease(cvImg);
     254        return img;     
    277255#else
    278256        return 0;
     
    296274    int samplesPerPixel = [bitmap samplesPerPixel];
    297275    if (![bitmap isPlanar] && (samplesPerPixel == 3 || samplesPerPixel == 4)){
    298         glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0,
     276        glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, 
    299277            samplesPerPixel == 4 ? GL_RGBA8 : GL_RGB8,
    300278            [bitmap pixelsWide], [bitmap pixelsHigh],
     
    325303    m_relativeVolume = relativeVolume;
    326304    if (!m_QTMovie || !m_audioEnabled || m_mute)
    327         return;
     305        return;               
    328306    [m_QTMovie setVolume:(m_masterVolume * m_relativeVolume)];
    329307}
     
    336314
    337315    // Work-around bug that happends if you set/unset mute
    338     // before movie is playing, and audio is not played
     316    // before movie is playing, and audio is not played 
    339317    // through graph. Then audio is delayed.
    340318    [m_QTMovie setMuted:mute];
     
    349327
    350328    // Work-around bug that happends if you set/unset mute
    351     // before movie is playing, and audio is not played
     329    // before movie is playing, and audio is not played 
    352330    // through graph. Then audio is delayed.
    353331    [m_QTMovie setMuted:(!enable || m_mute)];
     
    368346    // The following code will not work for some media codecs that
    369347    // typically mingle audio/video frames (e.g mpeg).
    370     CFStringRef idString = PhononCFString::toCFStringRef(AudioDevice::deviceUID(id));
     348    CFStringRef idString = PhononCFString::toCFStringRef(AudioDevice::deviceUID(id));       
    371349    QTAudioContextRef context;
    372350    QTAudioContextCreateForAudioDevice(kCFAllocatorDefault, idString, 0, &context);
     
    392370    saturation += 1;
    393371
    394     if (m_brightness == brightness
    395         && m_contrast == contrast
    396         && m_hue == hue
    397         && m_saturation == saturation)
    398         return;
    399 
    400372        m_brightness = brightness;
    401373        m_contrast = contrast;
    402374        m_hue = hue;
    403375        m_saturation = saturation;
     376       
    404377#ifdef QUICKTIME_C_API_AVAILABLE
    405378    Float32 value;
     
    413386    SetMovieVisualSaturation([m_QTMovie quickTimeMovie], value, 0);
    414387#endif
    415     releaseImageCache();
    416388}
    417389
     
    426398}
    427399
    428 void QuickTimeVideoPlayer::unsetCurrentMediaSource()
     400void QuickTimeVideoPlayer::unsetVideo()
    429401{
    430402    if (!m_QTMovie)
     
    439411    m_isDrmProtected = false;
    440412    m_isDrmAuthorized = true;
    441     m_hasVideo = false;
    442     m_staticFps = 0;
    443413    m_mediaSource = MediaSource();
    444     m_movieCompactDiscPath.clear();
    445414        [(CIImage *)m_primaryRenderingCIImage release];
    446415        m_primaryRenderingCIImage = 0;
    447416    delete m_QImagePixelBuffer;
    448417    m_QImagePixelBuffer = 0;
    449     releaseImageCache();
    450     [m_folderTracks release];
    451     m_folderTracks = 0;
    452418}
    453419
     
    559525{
    560526    PhononAutoReleasePool pool;
    561     unsetCurrentMediaSource();
    562 
     527    unsetVideo();
    563528    m_mediaSource = mediaSource;
    564529    if (mediaSource.type() == MediaSource::Empty || mediaSource.type() == MediaSource::Invalid){
     
    566531        return;
    567532    }
    568 
    569533    openMovieFromCurrentMediaSource();
    570534    if (errorOccured()){
    571         unsetCurrentMediaSource();
    572         return;
    573     }
    574 
    575     prepareCurrentMovieForPlayback();
    576 }
    577 
    578 void QuickTimeVideoPlayer::prepareCurrentMovieForPlayback()
    579 {
     535        unsetVideo();
     536        return;
     537    }
     538
    580539#ifdef QUICKTIME_C_API_AVAILABLE
    581540    if (m_visualContext)
     
    585544    waitStatePlayable();
    586545    if (errorOccured()){
    587         unsetCurrentMediaSource();
     546        unsetVideo();
    588547        return;
    589548    }
     
    592551    preRollMovie();
    593552    if (errorOccured()){
    594         unsetCurrentMediaSource();
     553        unsetVideo();
    595554        return;
    596555    }
     
    599558        m_playbackRate = prefferedPlaybackRate();
    600559    checkIfVideoAwailable();
    601     calculateStaticFps();
    602560    enableAudio(m_audioEnabled);
    603561    setMute(m_mute);
    604562    setVolume(m_masterVolume, m_relativeVolume);
    605     m_metaData->update();
    606563    pause();
    607564}
     
    617574        break;
    618575    case MediaSource::Disc:
    619         openMovieFromCompactDisc();
     576        CASE_UNSUPPORTED("Could not open media source.", FATAL_ERROR)
    620577        break;
    621578    case MediaSource::Stream:
     
    679636    // codecs *think* they can decode the stream, and crash...
    680637#define TryOpenMovieWithCodec(type) gClearError(); \
    681     openMovieFromData(data, (char *)"."type); \
     638    openMovieFromData(data, "."type); \
    682639    if (m_QTMovie) return;
    683640
     
    719676}
    720677
    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 
    765678MediaSource QuickTimeVideoPlayer::mediaSource() const
    766679{
     
    806719        PhononAutoReleasePool pool;
    807720    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
    846721}
    847722
     
    1076951}
    1077952
    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 
    1166953}}
    1167954
Note: See TracChangeset for help on using the changeset viewer.