diff options
Diffstat (limited to 'src/3rdparty')
-rw-r--r-- | src/3rdparty/phonon/qt7/mediaobject.h | 22 | ||||
-rw-r--r-- | src/3rdparty/phonon/qt7/mediaobject.mm | 199 | ||||
-rw-r--r-- | src/3rdparty/phonon/qt7/quicktimevideoplayer.h | 8 | ||||
-rw-r--r-- | src/3rdparty/phonon/qt7/quicktimevideoplayer.mm | 101 | ||||
-rw-r--r-- | src/3rdparty/phonon/qt7/videoframe.mm | 24 | ||||
-rw-r--r-- | src/3rdparty/webkit/WebCore/dom/XMLTokenizerQt.cpp | 2 |
6 files changed, 279 insertions, 77 deletions
diff --git a/src/3rdparty/phonon/qt7/mediaobject.h b/src/3rdparty/phonon/qt7/mediaobject.h index 27949ec..ae623a9 100644 --- a/src/3rdparty/phonon/qt7/mediaobject.h +++ b/src/3rdparty/phonon/qt7/mediaobject.h @@ -25,6 +25,10 @@ #include "medianode.h" +#if QT_ALLOW_QUICKTIME + #include <QuickTime/QuickTime.h> +#endif + QT_BEGIN_NAMESPACE namespace Phonon @@ -92,6 +96,10 @@ namespace QT7 int videoOutputCount(); +#if QT_ALLOW_QUICKTIME + void displayLinkEvent(); +#endif + signals: void stateChanged(Phonon::State,Phonon::State); void tick(qint64); @@ -120,6 +128,14 @@ namespace QT7 MediaObjectAudioNode *m_mediaObjectAudioNode; QuickTimeMetaData *m_metaData; +#if QT_ALLOW_QUICKTIME + CVDisplayLinkRef m_displayLink; + QMutex m_displayLinkMutex; + bool m_pendingDisplayLinkEvent; + void startDisplayLink(); + void stopDisplayLink(); +#endif + qint32 m_tickInterval; qint32 m_transitionTime; quint32 m_prefinishMark; @@ -127,7 +143,8 @@ namespace QT7 float m_percentageLoaded; int m_tickTimer; - int m_bufferTimer; + int m_videoTimer; + int m_audioTimer; int m_rapidTimer; bool m_waitNextSwap; @@ -141,8 +158,7 @@ namespace QT7 void pause_internal(); void play_internal(); void setupAudioSystem(); - void updateTimer(int &timer, int interval); - void bufferAudioVideo(); + void restartAudioVideoTimers(); void updateRapidly(); void updateCrossFade(); void updateAudioBuffers(); diff --git a/src/3rdparty/phonon/qt7/mediaobject.mm b/src/3rdparty/phonon/qt7/mediaobject.mm index 002c337..6886a3c 100644 --- a/src/3rdparty/phonon/qt7/mediaobject.mm +++ b/src/3rdparty/phonon/qt7/mediaobject.mm @@ -63,15 +63,24 @@ MediaObject::MediaObject(QObject *parent) : MediaNode(AudioSource | VideoSource, m_errorType = Phonon::NoError; m_tickTimer = 0; - m_bufferTimer = 0; + m_videoTimer = 0; + m_audioTimer = 0; m_rapidTimer = 0; +#if QT_ALLOW_QUICKTIME + m_displayLink = 0; + m_pendingDisplayLinkEvent = false; +#endif + checkForError(); } MediaObject::~MediaObject() -{ - // m_mediaObjectAudioNode is owned by super class. +{ + // m_mediaObjectAudioNode is owned by super class. +#if QT_ALLOW_QUICKTIME + stopDisplayLink(); +#endif m_audioPlayer->unsetVideoPlayer(); m_nextAudioPlayer->unsetVideoPlayer(); delete m_videoPlayer; @@ -88,7 +97,7 @@ bool MediaObject::setState(Phonon::State state) emit stateChanged(m_state, prevState); if (m_state != state){ // End-application did something - // upon receiving the signal. + // upon receiving the signal. return false; } } @@ -214,28 +223,28 @@ void MediaObject::setSource(const MediaSource &source) IMPLEMENTED; PhononAutoReleasePool pool; setState(Phonon::LoadingState); - + // Save current state for event/signal handling below: bool prevHasVideo = m_videoPlayer->hasVideo(); qint64 prevTotalTime = totalTime(); m_waitNextSwap = false; - + // Cancel cross-fade if any: m_nextVideoPlayer->pause(); m_nextAudioPlayer->pause(); m_mediaObjectAudioNode->cancelCrossFade(); - + // Set new source: m_audioPlayer->unsetVideoPlayer(); m_videoPlayer->setMediaSource(source); m_audioPlayer->setVideoPlayer(m_videoPlayer); - m_metaData->setVideo(m_videoPlayer); + m_metaData->setVideo(m_videoPlayer); - m_audioGraph->updateStreamSpecifications(); + m_audioGraph->updateStreamSpecifications(); m_nextAudioPlayer->unsetVideoPlayer(); m_nextVideoPlayer->unsetVideo(); m_currentTime = 0; - + // Emit/notify information about the new source: QRect videoRect = m_videoPlayer->videoRect(); MediaNodeEvent e1(MediaNodeEvent::VideoFrameSizeChanged, &videoRect); @@ -296,7 +305,7 @@ void MediaObject::swapCurrentWithNext(qint32 transitionTime) m_waitNextSwap = false; m_currentTime = 0; - + // Emit/notify information about the new source: QRect videoRect = m_videoPlayer->videoRect(); MediaNodeEvent e1(MediaNodeEvent::VideoFrameSizeChanged, &videoRect); @@ -306,7 +315,7 @@ void MediaObject::swapCurrentWithNext(qint32 transitionTime) emit metaDataChanged(m_metaData->metaData()); if (prevHasVideo != m_videoPlayer->hasVideo()) - emit hasVideoChanged(m_videoPlayer->hasVideo()); + emit hasVideoChanged(m_videoPlayer->hasVideo()); if (prevTotalTime != totalTime()) emit totalTimeChanged(totalTime()); if (checkForError()) @@ -327,28 +336,107 @@ void MediaObject::swapCurrentWithNext(qint32 transitionTime) } } -void MediaObject::updateTimer(int &timer, int interval) +#if QT_ALLOW_QUICKTIME +static CVReturn displayLinkCallback(CVDisplayLinkRef /*displayLink*/, + const CVTimeStamp */*inNow*/, + const CVTimeStamp */*inOutputTime*/, + CVOptionFlags /*flagsIn*/, + CVOptionFlags */*flagsOut*/, + void *userData) +{ + MediaObject *mediaObject = static_cast<MediaObject *>(userData); + mediaObject->displayLinkEvent(); + return kCVReturnSuccess; +} + +void MediaObject::displayLinkEvent() +{ + // This function is called from a + // thread != gui thread. So we post the event. + // But we need to make sure that we don't post faster + // than the event loop can eat: + m_displayLinkMutex.lock(); + bool pending = m_pendingDisplayLinkEvent; + m_pendingDisplayLinkEvent = true; + m_displayLinkMutex.unlock(); + + if (!pending) + qApp->postEvent(this, new QEvent(QEvent::User), Qt::HighEventPriority); +} + +void MediaObject::startDisplayLink() { - if (timer) - killTimer(timer); - timer = 0; - if (interval >= 0) - timer = startTimer(interval); + if (m_displayLink) + return; + OSStatus err = CVDisplayLinkCreateWithCGDisplay(kCGDirectMainDisplay, &m_displayLink); + if (err != noErr) + goto fail; + err = CVDisplayLinkSetCurrentCGDisplay(m_displayLink, kCGDirectMainDisplay); + if (err != noErr) + goto fail; + err = CVDisplayLinkSetOutputCallback(m_displayLink, displayLinkCallback, this); + if (err != noErr) + goto fail; + err = CVDisplayLinkStart(m_displayLink); + if (err != noErr) + goto fail; + return; +fail: + stopDisplayLink(); +} + +void MediaObject::stopDisplayLink() +{ + if (!m_displayLink) + return; + CVDisplayLinkStop(m_displayLink); + CFRelease(m_displayLink); + m_displayLink = 0; +} +#endif + +void MediaObject::restartAudioVideoTimers() +{ + if (m_videoTimer) + killTimer(m_videoTimer); + if (m_audioTimer) + killTimer(m_audioTimer); + +#if QT_ALLOW_QUICKTIME + // We prefer to use a display link as timer if available, since + // it is more steady, and results in better and smoother frame drawing: + startDisplayLink(); + if (!m_displayLink){ + float fps = m_videoPlayer->staticFps(); + long videoUpdateFrequency = fps ? long(1000.0f / fps) : 0.001; + m_videoTimer = startTimer(videoUpdateFrequency); + } +#else + float fps = m_videoPlayer->staticFps(); + long videoUpdateFrequency = fps ? long(1000.0f / fps) : 0.001; + m_videoTimer = startTimer(videoUpdateFrequency); +#endif + + long audioUpdateFrequency = m_audioPlayer->regularTaskFrequency(); + m_audioTimer = startTimer(audioUpdateFrequency); + updateVideoFrames(); + updateAudioBuffers(); } void MediaObject::play_internal() { // Play main audio/video: m_videoPlayer->play(); - m_audioPlayer->play(); + m_audioPlayer->play(); updateLipSynch(0); // Play old audio/video to finish cross-fade: if (m_nextVideoPlayer->currentTime() > 0){ m_nextVideoPlayer->play(); m_nextAudioPlayer->play(); } - bufferAudioVideo(); - updateTimer(m_rapidTimer, 100); + restartAudioVideoTimers(); + if (!m_rapidTimer) + m_rapidTimer = startTimer(100); } void MediaObject::pause_internal() @@ -358,9 +446,15 @@ void MediaObject::pause_internal() m_nextAudioPlayer->pause(); m_videoPlayer->pause(); m_nextVideoPlayer->pause(); - updateTimer(m_rapidTimer, -1); - updateTimer(m_bufferTimer, -1); - + killTimer(m_rapidTimer); + killTimer(m_videoTimer); + killTimer(m_audioTimer); + m_rapidTimer = 0; + m_videoTimer = 0; + m_audioTimer = 0; +#if QT_ALLOW_QUICKTIME + stopDisplayLink(); +#endif if (m_waitNextSwap) m_swapTimeLeft = m_swapTime.msecsTo(QTime::currentTime()); } @@ -382,7 +476,7 @@ void MediaObject::play() if (!m_videoPlayer->canPlayMedia()) return; if (!setState(Phonon::PlayingState)) - return; + return; if (m_audioSystem == AS_Graph){ m_audioGraph->start(); m_mediaObjectAudioNode->setMute(true); @@ -435,7 +529,7 @@ void MediaObject::seek(qint64 milliseconds) IMPLEMENTED; if (m_state == Phonon::ErrorState) return; - + // Stop cross-fade if any: m_nextVideoPlayer->unsetVideo(); m_nextAudioPlayer->unsetVideoPlayer(); @@ -446,7 +540,7 @@ void MediaObject::seek(qint64 milliseconds) m_videoPlayer->seek(milliseconds); m_audioPlayer->seek(m_videoPlayer->currentTime()); m_mediaObjectAudioNode->setMute(false); - + // Update time and cancel pending swap: if (m_currentTime < m_videoPlayer->duration()) m_waitNextSwap = false; @@ -699,7 +793,7 @@ void MediaObject::updateCrossFade() m_nextVideoPlayer->unsetVideo(); m_nextAudioPlayer->unsetVideoPlayer(); } - } + } } void MediaObject::updateBufferStatus() @@ -728,7 +822,7 @@ void MediaObject::updateVideoFrames() // Draw next frame if awailable: if (m_videoPlayer->videoFrameChanged()){ updateLipSynch(50); - VideoFrame frame(m_videoPlayer); + VideoFrame frame(m_videoPlayer); if (m_nextVideoPlayer->isPlaying() && m_nextVideoPlayer->hasVideo() && isCrossFading()){ @@ -736,9 +830,9 @@ void MediaObject::updateVideoFrames() frame.setBackgroundFrame(bgFrame); frame.setBaseOpacity(m_mediaObjectAudioNode->m_volume1); } - + // Send the frame through the graph: - updateVideo(frame); + updateVideo(frame); checkForError(); } } @@ -749,7 +843,7 @@ void MediaObject::updateLipSynch(int allowedOffset) return; if (m_videoSinkList.isEmpty() || m_audioSinkList.isEmpty()) return; - + if (m_videoPlayer->hasVideo()){ qint64 diff = m_audioPlayer->currentTime() - m_videoPlayer->currentTime(); if (-allowedOffset > diff || diff > allowedOffset) @@ -763,16 +857,6 @@ void MediaObject::updateLipSynch(int allowedOffset) } } -void MediaObject::bufferAudioVideo() -{ - long nextVideoUpdate = m_videoPlayer->hasVideo() ? 30 : INT_MAX; - long nextAudioUpdate = m_audioPlayer->regularTaskFrequency(); - updateAudioBuffers(); - updateVideoFrames(); - if (m_state == Phonon::PlayingState) - updateTimer(m_bufferTimer, qMin(nextVideoUpdate, nextAudioUpdate)); -} - void MediaObject::updateRapidly() { updateCurrentTime(); @@ -797,8 +881,8 @@ void MediaObject::mediaNodeEvent(const MediaNodeEvent *event) synchAudioVideo(); checkForError(); m_mediaObjectAudioNode->setMute(false); - if (m_state == Phonon::PlayingState) - bufferAudioVideo(); + if (m_state == Phonon::PlayingState) + restartAudioVideoTimers(); break; case MediaNodeEvent::AudioGraphCannotPlay: case MediaNodeEvent::AudioGraphInitialized: @@ -809,7 +893,7 @@ void MediaObject::mediaNodeEvent(const MediaNodeEvent *event) checkForError(); m_mediaObjectAudioNode->setMute(false); } - break; + break; default: break; } @@ -818,16 +902,25 @@ void MediaObject::mediaNodeEvent(const MediaNodeEvent *event) bool MediaObject::event(QEvent *event) { switch (event->type()){ - case QEvent::Timer: { - QTimerEvent *timerEvent = static_cast<QTimerEvent *>(event); - if (timerEvent->timerId() == m_rapidTimer) +#if QT_ALLOW_QUICKTIME + case QEvent::User:{ + m_displayLinkMutex.lock(); + m_pendingDisplayLinkEvent = false; + m_displayLinkMutex.unlock(); + updateVideoFrames(); + break; } +#endif + case QEvent::Timer:{ + int timerId = static_cast<QTimerEvent *>(event)->timerId(); + if (timerId == m_rapidTimer) updateRapidly(); - else if (timerEvent->timerId() == m_tickTimer) + else if (timerId == m_tickTimer) emit tick(currentTime()); - else if (timerEvent->timerId() == m_bufferTimer) - bufferAudioVideo(); - } - break; + else if (timerId == m_videoTimer) + updateVideoFrames(); + else if (timerId == m_audioTimer) + updateAudioBuffers(); + break; } default: break; } diff --git a/src/3rdparty/phonon/qt7/quicktimevideoplayer.h b/src/3rdparty/phonon/qt7/quicktimevideoplayer.h index 0b3aec2..3fa815e 100644 --- a/src/3rdparty/phonon/qt7/quicktimevideoplayer.h +++ b/src/3rdparty/phonon/qt7/quicktimevideoplayer.h @@ -66,11 +66,13 @@ namespace QT7 GLuint currentFrameAsGLTexture(); void *currentFrameAsCIImage(); QImage currentFrameAsQImage(); + void releaseImageCache(); QRect videoRect() const; quint64 duration() const; quint64 currentTime() const; long timeScale() const; + float staticFps(); QString currentTimeString(); void setColors(qreal brightness = 0, qreal contrast = 1, qreal hue = 0, qreal saturation = 1); @@ -116,6 +118,9 @@ namespace QT7 State m_state; QGLPixelBuffer *m_QImagePixelBuffer; + CVOpenGLTextureRef m_cachedCVTextureRef; + QImage m_cachedQImage; + bool m_playbackRateSat; bool m_isDrmProtected; bool m_isDrmAuthorized; @@ -125,8 +130,10 @@ namespace QT7 float m_masterVolume; float m_relativeVolume; float m_playbackRate; + float m_staticFps; quint64 m_currentTime; MediaSource m_mediaSource; + void *m_primaryRenderingCIImage; qreal m_brightness; qreal m_contrast; @@ -153,6 +160,7 @@ namespace QT7 void setError(NSError *error); bool errorOccured(); void readProtection(); + void calculateStaticFps(); void checkIfVideoAwailable(); bool movieNotLoaded(); void waitStatePlayable(); diff --git a/src/3rdparty/phonon/qt7/quicktimevideoplayer.mm b/src/3rdparty/phonon/qt7/quicktimevideoplayer.mm index 3f76132..de7c6ed 100644 --- a/src/3rdparty/phonon/qt7/quicktimevideoplayer.mm +++ b/src/3rdparty/phonon/qt7/quicktimevideoplayer.mm @@ -61,12 +61,14 @@ QuickTimeVideoPlayer::QuickTimeVideoPlayer() : QObject(0) 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; #ifdef QUICKTIME_C_API_AVAILABLE OSStatus err = EnterMovies(); @@ -77,6 +79,7 @@ QuickTimeVideoPlayer::QuickTimeVideoPlayer() : QObject(0) QuickTimeVideoPlayer::~QuickTimeVideoPlayer() { + PhononAutoReleasePool pool; unsetVideo(); [(NSObject*)m_primaryRenderingTarget release]; m_primaryRenderingTarget = 0; @@ -86,6 +89,15 @@ QuickTimeVideoPlayer::~QuickTimeVideoPlayer() #endif } +void QuickTimeVideoPlayer::releaseImageCache() +{ + if (m_cachedCVTextureRef){ + CVOpenGLTextureRelease(m_cachedCVTextureRef); + m_cachedCVTextureRef = 0; + } + m_cachedQImage = QImage(); +} + void QuickTimeVideoPlayer::createVisualContext() { #ifdef QUICKTIME_C_API_AVAILABLE @@ -125,7 +137,10 @@ bool QuickTimeVideoPlayer::videoFrameChanged() return false; QTVisualContextTask(m_visualContext); - return QTVisualContextIsNewImageAvailable(m_visualContext, 0); + bool changed = QTVisualContextIsNewImageAvailable(m_visualContext, 0); + if (changed) + releaseImageCache(); + return changed; #elif defined(QT_MAC_USE_COCOA) return true; @@ -140,10 +155,11 @@ CVOpenGLTextureRef QuickTimeVideoPlayer::currentFrameAsCVTexture() #ifdef QUICKTIME_C_API_AVAILABLE if (!m_visualContext) return 0; - 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; + 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; #else return 0; @@ -152,6 +168,9 @@ CVOpenGLTextureRef QuickTimeVideoPlayer::currentFrameAsCVTexture() 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(); @@ -181,12 +200,11 @@ QImage QuickTimeVideoPlayer::currentFrameAsQImage() glVertex2i(-1, -1); glEnd(); - QImage image = m_QImagePixelBuffer->toImage(); - CVOpenGLTextureRelease(texture); + m_cachedQImage = m_QImagePixelBuffer->toImage(); // Because of QuickTime, m_QImagePixelBuffer->doneCurrent() will fail. // So we store, and restore, the context our selves: prevContext->makeCurrent(); - return image; + return m_cachedQImage; #else CIImage *img = (CIImage *)currentFrameAsCIImage(); if (!img) @@ -195,10 +213,10 @@ QImage QuickTimeVideoPlayer::currentFrameAsQImage() NSBitmapImageRep* bitmap = [[NSBitmapImageRep alloc] initWithCIImage:img]; CGRect bounds = [img extent]; QImage qImg([bitmap bitmapData], bounds.size.width, bounds.size.height, QImage::Format_ARGB32); - QImage swapped = qImg.rgbSwapped(); + m_cachedQImage = qImg.rgbSwapped(); [bitmap release]; [img release]; - return swapped; + return m_cachedQImage; #endif } @@ -250,8 +268,7 @@ void *QuickTimeVideoPlayer::currentFrameAsCIImage() #ifdef QUICKTIME_C_API_AVAILABLE CVOpenGLTextureRef cvImg = currentFrameAsCVTexture(); CIImage *img = [[CIImage alloc] initWithCVImageBuffer:cvImg]; - CVOpenGLTextureRelease(cvImg); - return img; + return img; #else return 0; #endif @@ -273,7 +290,7 @@ GLuint QuickTimeVideoPlayer::currentFrameAsGLTexture() 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, @@ -302,7 +319,7 @@ void QuickTimeVideoPlayer::setVolume(float masterVolume, float relativeVolume) m_masterVolume = masterVolume; m_relativeVolume = relativeVolume; if (!m_QTMovie || !m_audioEnabled || m_mute) - return; + return; [m_QTMovie setVolume:(m_masterVolume * m_relativeVolume)]; } @@ -313,7 +330,7 @@ void QuickTimeVideoPlayer::setMute(bool mute) 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)]; @@ -326,7 +343,7 @@ void QuickTimeVideoPlayer::enableAudio(bool enable) 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)]; @@ -345,7 +362,7 @@ bool QuickTimeVideoPlayer::setAudioDevice(int id) #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); @@ -369,11 +386,16 @@ void QuickTimeVideoPlayer::setColors(qreal brightness, qreal contrast, qreal hue 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; @@ -385,6 +407,7 @@ void QuickTimeVideoPlayer::setColors(qreal brightness, qreal contrast, qreal hue value = saturation; SetMovieVisualSaturation([m_QTMovie quickTimeMovie], value, 0); #endif + releaseImageCache(); } QRect QuickTimeVideoPlayer::videoRect() const @@ -410,11 +433,14 @@ void QuickTimeVideoPlayer::unsetVideo() m_state = NoMedia; m_isDrmProtected = false; m_isDrmAuthorized = true; + m_hasVideo = false; + m_staticFps = 0; m_mediaSource = MediaSource(); [(CIImage *)m_primaryRenderingCIImage release]; m_primaryRenderingCIImage = 0; delete m_QImagePixelBuffer; m_QImagePixelBuffer = 0; + releaseImageCache(); } QuickTimeVideoPlayer::State QuickTimeVideoPlayer::state() const @@ -557,6 +583,7 @@ void QuickTimeVideoPlayer::setMediaSource(const MediaSource &mediaSource) if (!m_playbackRateSat) m_playbackRate = prefferedPlaybackRate(); checkIfVideoAwailable(); + calculateStaticFps(); enableAudio(m_audioEnabled); setMute(m_mute); setVolume(m_masterVolume, m_relativeVolume); @@ -720,6 +747,44 @@ long QuickTimeVideoPlayer::timeScale() const 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; diff --git a/src/3rdparty/phonon/qt7/videoframe.mm b/src/3rdparty/phonon/qt7/videoframe.mm index 92a3cd5..7b67b5e 100644 --- a/src/3rdparty/phonon/qt7/videoframe.mm +++ b/src/3rdparty/phonon/qt7/videoframe.mm @@ -20,6 +20,8 @@ #import <QuartzCore/CIFilter.h> #import <QuartzCore/CIContext.h> +//#define CACHE_CV_TEXTURE + QT_BEGIN_NAMESPACE namespace Phonon @@ -70,7 +72,9 @@ namespace QT7 void VideoFrame::copyMembers(const VideoFrame& frame) { +#ifdef CACHE_CV_TEXTURE m_cachedCVTextureRef = frame.m_cachedCVTextureRef; +#endif m_cachedCIImage = frame.m_cachedCIImage; m_cachedQImage = frame.m_cachedQImage; m_cachedNSBitmap = frame.m_cachedNSBitmap; @@ -105,11 +109,20 @@ namespace QT7 CVOpenGLTextureRef VideoFrame::cachedCVTexture() const { +#ifdef CACHE_CV_TEXTURE if (!m_cachedCVTextureRef && m_videoPlayer){ m_videoPlayer->setColors(m_brightness, m_contrast, m_hue, m_saturation); (const_cast<VideoFrame *>(this))->m_cachedCVTextureRef = m_videoPlayer->currentFrameAsCVTexture(); + CVOpenGLTextureRetain((const_cast<VideoFrame *>(this))->m_cachedCVTextureRef); } return m_cachedCVTextureRef; +#else + if (m_videoPlayer){ + m_videoPlayer->setColors(m_brightness, m_contrast, m_hue, m_saturation); + return m_videoPlayer->currentFrameAsCVTexture(); + } + return 0; +#endif } void *VideoFrame::cachedCIImage() const @@ -329,10 +342,12 @@ namespace QT7 void VideoFrame::invalidateImage() const { +#ifdef CACHE_CV_TEXTURE if (m_cachedCVTextureRef){ CVOpenGLTextureRelease(m_cachedCVTextureRef); (const_cast<VideoFrame *>(this))->m_cachedCVTextureRef = 0; } +#endif if (m_cachedCIImage){ [(CIImage *) m_cachedCIImage release]; (const_cast<VideoFrame *>(this))->m_cachedCIImage = 0; @@ -346,8 +361,10 @@ namespace QT7 void VideoFrame::retain() const { +#ifdef CACHE_CV_TEXTURE if (m_cachedCVTextureRef) CVOpenGLTextureRetain(m_cachedCVTextureRef); +#endif if (m_cachedCIImage) [(CIImage *) m_cachedCIImage retain]; if (m_backgroundFrame) @@ -358,8 +375,12 @@ namespace QT7 void VideoFrame::release() const { - if (m_cachedCVTextureRef) +#ifdef CACHE_CV_TEXTURE + if (m_cachedCVTextureRef){ CVOpenGLTextureRelease(m_cachedCVTextureRef); + (const_cast<VideoFrame *>(this))->m_cachedCVTextureRef = 0; + } +#endif if (m_cachedCIImage) [(CIImage *) m_cachedCIImage release]; if (m_backgroundFrame) @@ -368,7 +389,6 @@ namespace QT7 [m_cachedNSBitmap release]; (const_cast<VideoFrame *>(this))->m_backgroundFrame = 0; - (const_cast<VideoFrame *>(this))->m_cachedCVTextureRef = 0; (const_cast<VideoFrame *>(this))->m_cachedCIImage = 0; (const_cast<VideoFrame *>(this))->m_cachedNSBitmap = 0; } diff --git a/src/3rdparty/webkit/WebCore/dom/XMLTokenizerQt.cpp b/src/3rdparty/webkit/WebCore/dom/XMLTokenizerQt.cpp index 30926e1..2050a70 100644 --- a/src/3rdparty/webkit/WebCore/dom/XMLTokenizerQt.cpp +++ b/src/3rdparty/webkit/WebCore/dom/XMLTokenizerQt.cpp @@ -622,7 +622,7 @@ void XMLTokenizer::parseProcessingInstruction() #if ENABLE(XSLT) m_sawXSLTransform = !m_sawFirstElement && pi->isXSL(); - if (m_sawXSLTransform && !m_doc->transformSourceDocument())) + if (m_sawXSLTransform && !m_doc->transformSourceDocument()) stopParsing(); #endif } |