summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/phonon/qt7
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/phonon/qt7')
-rw-r--r--src/3rdparty/phonon/qt7/backend.mm2
-rw-r--r--src/3rdparty/phonon/qt7/mediaobject.h22
-rw-r--r--src/3rdparty/phonon/qt7/mediaobject.mm163
-rw-r--r--src/3rdparty/phonon/qt7/quicktimevideoplayer.h8
-rw-r--r--src/3rdparty/phonon/qt7/quicktimevideoplayer.mm101
-rw-r--r--src/3rdparty/phonon/qt7/videoframe.mm24
6 files changed, 261 insertions, 59 deletions
diff --git a/src/3rdparty/phonon/qt7/backend.mm b/src/3rdparty/phonon/qt7/backend.mm
index 327ddd7..b3ca106 100644
--- a/src/3rdparty/phonon/qt7/backend.mm
+++ b/src/3rdparty/phonon/qt7/backend.mm
@@ -59,7 +59,7 @@ Backend::Backend(QObject *parent, const QStringList &) : QObject(parent)
setProperty("backendComment", QLatin1String("Developed by Trolltech"));
setProperty("backendVersion", QLatin1String("0.1"));
setProperty("backendIcon", QLatin1String(""));
- setProperty("backendWebsite", QLatin1String("http://qtsoftware.com/"));
+ setProperty("backendWebsite", QLatin1String("http://qt.nokia.com/"));
}
Backend::~Backend()
diff --git a/src/3rdparty/phonon/qt7/mediaobject.h b/src/3rdparty/phonon/qt7/mediaobject.h
index d59ee77..c93eddc 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
@@ -95,6 +99,10 @@ namespace QT7
int videoOutputCount();
+#if QT_ALLOW_QUICKTIME
+ void displayLinkEvent();
+#endif
+
signals:
void stateChanged(Phonon::State,Phonon::State);
void tick(qint64);
@@ -132,6 +140,14 @@ namespace QT7
QuickTimeAudioPlayer *m_nextAudioPlayer;
MediaObjectAudioNode *m_mediaObjectAudioNode;
+#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;
@@ -139,7 +155,8 @@ namespace QT7
float m_percentageLoaded;
int m_tickTimer;
- int m_bufferTimer;
+ int m_videoTimer;
+ int m_audioTimer;
int m_rapidTimer;
bool m_waitNextSwap;
@@ -154,8 +171,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 95859ef..677640c 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;
@@ -87,7 +96,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;
}
}
@@ -330,13 +339,91 @@ 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)
{
- if (timer)
- killTimer(timer);
- timer = 0;
- if (interval >= 0)
- timer = startTimer(interval);
+ 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 (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()
@@ -350,8 +437,9 @@ void MediaObject::play_internal()
m_nextVideoPlayer->play();
m_nextAudioPlayer->play();
}
- bufferAudioVideo();
- updateTimer(m_rapidTimer, 100);
+ restartAudioVideoTimers();
+ if (!m_rapidTimer)
+ m_rapidTimer = startTimer(100);
}
void MediaObject::pause_internal()
@@ -361,9 +449,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());
}
@@ -771,16 +865,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();
@@ -805,8 +889,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:
@@ -817,7 +901,7 @@ void MediaObject::mediaNodeEvent(const MediaNodeEvent *event)
checkForError();
m_mediaObjectAudioNode->setMute(false);
}
- break;
+ break;
default:
break;
}
@@ -826,16 +910,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 8495e18..98eacb5 100644
--- a/src/3rdparty/phonon/qt7/quicktimevideoplayer.h
+++ b/src/3rdparty/phonon/qt7/quicktimevideoplayer.h
@@ -68,11 +68,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);
@@ -126,6 +128,9 @@ namespace QT7
QGLPixelBuffer *m_QImagePixelBuffer;
QuickTimeMetaData *m_metaData;
+ CVOpenGLTextureRef m_cachedCVTextureRef;
+ QImage m_cachedQImage;
+
bool m_playbackRateSat;
bool m_isDrmProtected;
bool m_isDrmAuthorized;
@@ -135,8 +140,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;
@@ -171,6 +178,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 02a594b..23c76e3 100644
--- a/src/3rdparty/phonon/qt7/quicktimevideoplayer.mm
+++ b/src/3rdparty/phonon/qt7/quicktimevideoplayer.mm
@@ -63,12 +63,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;
m_folderTracks = 0;
m_currentTrack = 0;
@@ -81,6 +83,7 @@ QuickTimeVideoPlayer::QuickTimeVideoPlayer() : QObject(0)
QuickTimeVideoPlayer::~QuickTimeVideoPlayer()
{
+ PhononAutoReleasePool pool;
unsetCurrentMediaSource();
delete m_metaData;
[(NSObject*)m_primaryRenderingTarget release];
@@ -91,6 +94,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
@@ -130,7 +142,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;
@@ -145,10 +160,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;
@@ -157,6 +173,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();
@@ -186,12 +205,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)
@@ -200,10 +218,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
}
@@ -255,8 +273,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
@@ -278,7 +295,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,
@@ -307,7 +324,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)];
}
@@ -318,7 +335,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)];
@@ -331,7 +348,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)];
@@ -350,7 +367,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);
@@ -374,11 +391,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;
@@ -390,6 +412,7 @@ void QuickTimeVideoPlayer::setColors(qreal brightness, qreal contrast, qreal hue
value = saturation;
SetMovieVisualSaturation([m_QTMovie quickTimeMovie], value, 0);
#endif
+ releaseImageCache();
}
QRect QuickTimeVideoPlayer::videoRect() const
@@ -415,12 +438,15 @@ void QuickTimeVideoPlayer::unsetCurrentMediaSource()
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;
}
@@ -572,6 +598,7 @@ void QuickTimeVideoPlayer::prepareCurrentMovieForPlayback()
if (!m_playbackRateSat)
m_playbackRate = prefferedPlaybackRate();
checkIfVideoAwailable();
+ calculateStaticFps();
enableAudio(m_audioEnabled);
setMute(m_mute);
setVolume(m_masterVolume, m_relativeVolume);
@@ -780,6 +807,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;
}