--- a/qtmobility/plugins/multimedia/qt7/qt7movieviewrenderer.mm Fri Jun 11 14:26:25 2010 +0300
+++ b/qtmobility/plugins/multimedia/qt7/qt7movieviewrenderer.mm Wed Jun 23 19:08:38 2010 +0300
@@ -46,14 +46,17 @@
#include "qt7playercontrol.h"
#include "qt7movieviewrenderer.h"
#include "qt7playersession.h"
+#include "qt7ciimagevideobuffer.h"
#include <QtCore/qdebug.h>
#include <QtCore/qcoreevent.h>
#include <QtCore/qcoreapplication.h>
-#include <QtMultimedia/qabstractvideobuffer.h>
-#include <QtMultimedia/qabstractvideosurface.h>
-#include <QtMultimedia/qvideosurfaceformat.h>
+#include <qabstractvideobuffer.h>
+#include <qabstractvideosurface.h>
+#include <qvideosurfaceformat.h>
+#include <QuartzCore/CIFilter.h>
+#include <QuartzCore/CIVector.h>
QT_USE_NAMESPACE
@@ -112,6 +115,7 @@
- (HiddenQTMovieView *) initWithRenderer:(QT7MovieViewRenderer *)renderer;
- (void) setRenderer:(QT7MovieViewRenderer *)renderer;
- (void) setDrawRect:(const QRect &)rect;
+- (CIImage *) view:(QTMovieView *)view willDisplayImage:(CIImage *)img;
@end
@implementation HiddenQTMovieView
@@ -162,34 +166,38 @@
// before the image will be drawn.
Q_UNUSED(view);
if (m_renderer) {
- NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithCIImage:img];
CGRect bounds = [img extent];
int w = bounds.size.width;
int h = bounds.size.height;
- // Swap red and blue (same as QImage::rgbSwapped, but without copy)
- uchar *data = [bitmap bitmapData];
- //qDebug() << data << w << h;
- int bytesPerLine = [bitmap bytesPerRow];
- for (int i=0; i<h; ++i) {
- quint32 *p = (quint32*)data;
- data += bytesPerLine;
- quint32 *end = p + w;
- while (p < end) {
- *p = ((*p << 16) & 0xff0000) | ((*p >> 16) & 0xff) | (*p & 0xff00ff00);
- p++;
- }
+ QVideoFrame frame;
+
+ QAbstractVideoSurface *surface = m_renderer->surface();
+ if (!surface || !surface->isActive())
+ return img;
+
+ if (surface->surfaceFormat().handleType() == QAbstractVideoBuffer::CoreImageHandle) {
+ //surface supports rendering of opengl based CIImage
+ frame = QVideoFrame(new QT7CIImageVideoBuffer(img), QSize(w,h), QVideoFrame::Format_RGB32 );
+ } else {
+ //Swap R and B colors
+ CIFilter *colorSwapFilter = [CIFilter filterWithName: @"CIColorMatrix" keysAndValues:
+ @"inputImage", img,
+ @"inputRVector", [CIVector vectorWithX: 0 Y: 0 Z: 1 W: 0],
+ @"inputGVector", [CIVector vectorWithX: 0 Y: 1 Z: 0 W: 0],
+ @"inputBVector", [CIVector vectorWithX: 1 Y: 0 Z: 0 W: 0],
+ @"inputAVector", [CIVector vectorWithX: 0 Y: 0 Z: 0 W: 1],
+ @"inputBiasVector", [CIVector vectorWithX: 0 Y: 0 Z: 0 W: 0],
+ nil];
+ CIImage *img = [colorSwapFilter valueForKey: @"outputImage"];
+ NSBitmapImageRep *bitmap =[[NSBitmapImageRep alloc] initWithCIImage:img];
+ //requesting the bitmap data is slow,
+ //but it's better to do it here to avoid blocking the main thread for a long.
+ [bitmap bitmapData];
+ frame = QVideoFrame(new NSBitmapVideoBuffer(bitmap), QSize(w,h), QVideoFrame::Format_RGB32 );
+ [bitmap release];
}
- QVideoFrame frame( new NSBitmapVideoBuffer(bitmap), QSize(w,h), QVideoFrame::Format_RGB32 );
-
- //static int i=0;
- //i++;
- //QImage img([bitmap bitmapData], w, h, QImage::Format_RGB32);
- //img.save(QString("img%1.jpg").arg(i));
-
- [bitmap release];
-
if (m_renderer)
m_renderer->renderFrame(frame);
}
@@ -228,7 +236,8 @@
:QT7VideoRendererControl(parent),
m_movie(0),
m_movieView(0),
- m_surface(0)
+ m_surface(0),
+ m_pendingRenderEvent(false)
{
}
@@ -265,11 +274,15 @@
}
[movieView setMovie:(QTMovie*)m_movie];
- //[movieView setDrawRect:QRect(QPoint(0,0), m_nativeSize)];
+ [movieView setDrawRect:QRect(QPoint(0,0), m_nativeSize)];
}
if (m_surface && !m_nativeSize.isEmpty()) {
- QVideoSurfaceFormat format(m_nativeSize, QVideoFrame::Format_RGB32);
+ bool coreImageFrameSupported = !m_surface->supportedPixelFormats(QAbstractVideoBuffer::CoreImageHandle).isEmpty() &&
+ !m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).isEmpty();
+
+ QVideoSurfaceFormat format(m_nativeSize, QVideoFrame::Format_RGB32,
+ coreImageFrameSupported ? QAbstractVideoBuffer::CoreImageHandle : QAbstractVideoBuffer::NoHandle);
if (m_surface->isActive() && m_surface->surfaceFormat() != format) {
qDebug() << "Surface format was changed, stop the surface.";
@@ -284,10 +297,6 @@
}
}
-void QT7MovieViewRenderer::setEnabled(bool)
-{
-}
-
void QT7MovieViewRenderer::setMovie(void *movie)
{
if (movie == m_movie)
@@ -298,6 +307,14 @@
setupVideoOutput();
}
+void QT7MovieViewRenderer::updateNaturalSize(const QSize &newSize)
+{
+ if (m_nativeSize != newSize) {
+ m_nativeSize = newSize;
+ setupVideoOutput();
+ }
+}
+
QAbstractVideoSurface *QT7MovieViewRenderer::surface() const
{
return m_surface;
@@ -319,18 +336,21 @@
void QT7MovieViewRenderer::renderFrame(const QVideoFrame &frame)
{
- {
- QMutexLocker locker(&m_mutex);
- m_currentFrame = frame;
- }
+
+ QMutexLocker locker(&m_mutex);
+ m_currentFrame = frame;
- qApp->postEvent(this, new QEvent(QEvent::User), Qt::HighEventPriority);
+ if (!m_pendingRenderEvent)
+ qApp->postEvent(this, new QEvent(QEvent::User), Qt::HighEventPriority);
+
+ m_pendingRenderEvent = true;
}
bool QT7MovieViewRenderer::event(QEvent *event)
{
if (event->type() == QEvent::User) {
QMutexLocker locker(&m_mutex);
+ m_pendingRenderEvent = false;
if (m_surface->isActive())
m_surface->present(m_currentFrame);
}