qtmobility/plugins/multimedia/qt7/qt7movieviewrenderer.mm
changeset 14 6fbed849b4f4
parent 11 06b8e2af4411
equal deleted inserted replaced
11:06b8e2af4411 14:6fbed849b4f4
    44 #include "qt7backend.h"
    44 #include "qt7backend.h"
    45 
    45 
    46 #include "qt7playercontrol.h"
    46 #include "qt7playercontrol.h"
    47 #include "qt7movieviewrenderer.h"
    47 #include "qt7movieviewrenderer.h"
    48 #include "qt7playersession.h"
    48 #include "qt7playersession.h"
       
    49 #include "qt7ciimagevideobuffer.h"
    49 #include <QtCore/qdebug.h>
    50 #include <QtCore/qdebug.h>
    50 #include <QtCore/qcoreevent.h>
    51 #include <QtCore/qcoreevent.h>
    51 #include <QtCore/qcoreapplication.h>
    52 #include <QtCore/qcoreapplication.h>
    52 
    53 
    53 #include <QtMultimedia/qabstractvideobuffer.h>
    54 #include <qabstractvideobuffer.h>
    54 #include <QtMultimedia/qabstractvideosurface.h>
    55 #include <qabstractvideosurface.h>
    55 #include <QtMultimedia/qvideosurfaceformat.h>
    56 #include <qvideosurfaceformat.h>
    56 
    57 
       
    58 #include <QuartzCore/CIFilter.h>
       
    59 #include <QuartzCore/CIVector.h>
    57 
    60 
    58 QT_USE_NAMESPACE
    61 QT_USE_NAMESPACE
    59 
    62 
    60 class NSBitmapVideoBuffer : public QAbstractVideoBuffer
    63 class NSBitmapVideoBuffer : public QAbstractVideoBuffer
    61 {
    64 {
   110 }
   113 }
   111 
   114 
   112 - (HiddenQTMovieView *) initWithRenderer:(QT7MovieViewRenderer *)renderer;
   115 - (HiddenQTMovieView *) initWithRenderer:(QT7MovieViewRenderer *)renderer;
   113 - (void) setRenderer:(QT7MovieViewRenderer *)renderer;
   116 - (void) setRenderer:(QT7MovieViewRenderer *)renderer;
   114 - (void) setDrawRect:(const QRect &)rect;
   117 - (void) setDrawRect:(const QRect &)rect;
       
   118 - (CIImage *) view:(QTMovieView *)view willDisplayImage:(CIImage *)img;
   115 @end
   119 @end
   116 
   120 
   117 @implementation HiddenQTMovieView
   121 @implementation HiddenQTMovieView
   118 
   122 
   119 - (HiddenQTMovieView *) initWithRenderer:(QT7MovieViewRenderer *)renderer
   123 - (HiddenQTMovieView *) initWithRenderer:(QT7MovieViewRenderer *)renderer
   160 {
   164 {
   161     // This method is called from QTMovieView just
   165     // This method is called from QTMovieView just
   162     // before the image will be drawn.
   166     // before the image will be drawn.
   163     Q_UNUSED(view);
   167     Q_UNUSED(view);
   164     if (m_renderer) {
   168     if (m_renderer) {
   165         NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithCIImage:img];
       
   166         CGRect bounds = [img extent];
   169         CGRect bounds = [img extent];
   167         int w = bounds.size.width;
   170         int w = bounds.size.width;
   168         int h = bounds.size.height;
   171         int h = bounds.size.height;
   169 
   172 
   170         // Swap red and blue (same as QImage::rgbSwapped, but without copy)
   173         QVideoFrame frame;
   171         uchar *data = [bitmap bitmapData];
   174 
   172         //qDebug() << data << w << h;
   175         QAbstractVideoSurface *surface = m_renderer->surface();
   173         int bytesPerLine = [bitmap bytesPerRow];
   176         if (!surface || !surface->isActive())
   174         for (int i=0; i<h; ++i) {
   177             return img;
   175             quint32 *p = (quint32*)data;
   178 
   176             data += bytesPerLine;
   179         if (surface->surfaceFormat().handleType() == QAbstractVideoBuffer::CoreImageHandle) {
   177             quint32 *end = p + w;
   180             //surface supports rendering of opengl based CIImage
   178             while (p < end) {
   181             frame = QVideoFrame(new QT7CIImageVideoBuffer(img), QSize(w,h), QVideoFrame::Format_RGB32 );
   179                 *p = ((*p << 16) & 0xff0000) | ((*p >> 16) & 0xff) | (*p & 0xff00ff00);
   182         } else {
   180                 p++;
   183             //Swap R and B colors
   181             }
   184             CIFilter *colorSwapFilter = [CIFilter filterWithName: @"CIColorMatrix"  keysAndValues:
   182         }
   185                                          @"inputImage", img,
   183 
   186                                          @"inputRVector", [CIVector vectorWithX: 0  Y: 0  Z: 1  W: 0],
   184         QVideoFrame frame( new NSBitmapVideoBuffer(bitmap), QSize(w,h), QVideoFrame::Format_RGB32 );
   187                                          @"inputGVector", [CIVector vectorWithX: 0  Y: 1  Z: 0  W: 0],
   185 
   188                                          @"inputBVector", [CIVector vectorWithX: 1  Y: 0  Z: 0  W: 0],
   186         //static int i=0;
   189                                          @"inputAVector", [CIVector vectorWithX: 0  Y: 0  Z: 0  W: 1],
   187         //i++;
   190                                          @"inputBiasVector", [CIVector vectorWithX: 0  Y: 0  Z: 0  W: 0],
   188         //QImage img([bitmap bitmapData], w, h, QImage::Format_RGB32);
   191                                          nil];
   189         //img.save(QString("img%1.jpg").arg(i));
   192             CIImage *img = [colorSwapFilter valueForKey: @"outputImage"];
   190 
   193             NSBitmapImageRep *bitmap =[[NSBitmapImageRep alloc] initWithCIImage:img];
   191         [bitmap release];
   194             //requesting the bitmap data is slow,
       
   195             //but it's better to do it here to avoid blocking the main thread for a long.
       
   196             [bitmap bitmapData];
       
   197             frame = QVideoFrame(new NSBitmapVideoBuffer(bitmap), QSize(w,h), QVideoFrame::Format_RGB32 );
       
   198             [bitmap release];
       
   199         }
   192 
   200 
   193         if (m_renderer)
   201         if (m_renderer)
   194             m_renderer->renderFrame(frame);
   202             m_renderer->renderFrame(frame);
   195     }
   203     }
   196 
   204 
   226 
   234 
   227 QT7MovieViewRenderer::QT7MovieViewRenderer(QObject *parent)
   235 QT7MovieViewRenderer::QT7MovieViewRenderer(QObject *parent)
   228    :QT7VideoRendererControl(parent),
   236    :QT7VideoRendererControl(parent),
   229     m_movie(0),
   237     m_movie(0),
   230     m_movieView(0),
   238     m_movieView(0),
   231     m_surface(0)
   239     m_surface(0),
       
   240     m_pendingRenderEvent(false)
   232 {    
   241 {    
   233 }
   242 }
   234 
   243 
   235 QT7MovieViewRenderer::~QT7MovieViewRenderer()
   244 QT7MovieViewRenderer::~QT7MovieViewRenderer()
   236 {
   245 {
   263             m_movieView = movieView;
   272             m_movieView = movieView;
   264             [movieView setControllerVisible:NO];
   273             [movieView setControllerVisible:NO];
   265         }
   274         }
   266 
   275 
   267         [movieView setMovie:(QTMovie*)m_movie];
   276         [movieView setMovie:(QTMovie*)m_movie];
   268         //[movieView setDrawRect:QRect(QPoint(0,0), m_nativeSize)];
   277         [movieView setDrawRect:QRect(QPoint(0,0), m_nativeSize)];
   269     }
   278     }
   270 
   279 
   271     if (m_surface && !m_nativeSize.isEmpty()) {
   280     if (m_surface && !m_nativeSize.isEmpty()) {
   272         QVideoSurfaceFormat format(m_nativeSize, QVideoFrame::Format_RGB32);
   281         bool coreImageFrameSupported = !m_surface->supportedPixelFormats(QAbstractVideoBuffer::CoreImageHandle).isEmpty() &&
       
   282                                        !m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).isEmpty();
       
   283 
       
   284         QVideoSurfaceFormat format(m_nativeSize, QVideoFrame::Format_RGB32,
       
   285                                    coreImageFrameSupported ? QAbstractVideoBuffer::CoreImageHandle : QAbstractVideoBuffer::NoHandle);
   273 
   286 
   274         if (m_surface->isActive() && m_surface->surfaceFormat() != format) {
   287         if (m_surface->isActive() && m_surface->surfaceFormat() != format) {
   275             qDebug() << "Surface format was changed, stop the surface.";
   288             qDebug() << "Surface format was changed, stop the surface.";
   276             m_surface->stop();
   289             m_surface->stop();
   277         }
   290         }
   282                 qDebug() << "failed to start video surface" << m_surface->error();
   295                 qDebug() << "failed to start video surface" << m_surface->error();
   283         }
   296         }
   284     }
   297     }
   285 }
   298 }
   286 
   299 
   287 void QT7MovieViewRenderer::setEnabled(bool)
       
   288 {
       
   289 }
       
   290 
       
   291 void QT7MovieViewRenderer::setMovie(void *movie)
   300 void QT7MovieViewRenderer::setMovie(void *movie)
   292 {
   301 {
   293     if (movie == m_movie)
   302     if (movie == m_movie)
   294         return;
   303         return;
   295 
   304 
   296     QMutexLocker locker(&m_mutex);
   305     QMutexLocker locker(&m_mutex);
   297     m_movie = movie;
   306     m_movie = movie;
   298     setupVideoOutput();
   307     setupVideoOutput();
   299 }
   308 }
   300 
   309 
       
   310 void QT7MovieViewRenderer::updateNaturalSize(const QSize &newSize)
       
   311 {
       
   312     if (m_nativeSize != newSize) {
       
   313         m_nativeSize = newSize;
       
   314         setupVideoOutput();
       
   315     }
       
   316 }
       
   317 
   301 QAbstractVideoSurface *QT7MovieViewRenderer::surface() const
   318 QAbstractVideoSurface *QT7MovieViewRenderer::surface() const
   302 {
   319 {
   303     return m_surface;
   320     return m_surface;
   304 }
   321 }
   305 
   322 
   317     setupVideoOutput();
   334     setupVideoOutput();
   318 }
   335 }
   319 
   336 
   320 void QT7MovieViewRenderer::renderFrame(const QVideoFrame &frame)
   337 void QT7MovieViewRenderer::renderFrame(const QVideoFrame &frame)
   321 {
   338 {
   322     {
   339 
   323         QMutexLocker locker(&m_mutex);
   340     QMutexLocker locker(&m_mutex);
   324         m_currentFrame = frame;
   341     m_currentFrame = frame;
   325     }
   342 
   326 
   343     if (!m_pendingRenderEvent)
   327     qApp->postEvent(this, new QEvent(QEvent::User), Qt::HighEventPriority);
   344         qApp->postEvent(this, new QEvent(QEvent::User), Qt::HighEventPriority);
       
   345 
       
   346     m_pendingRenderEvent = true;
   328 }
   347 }
   329 
   348 
   330 bool QT7MovieViewRenderer::event(QEvent *event)
   349 bool QT7MovieViewRenderer::event(QEvent *event)
   331 {
   350 {
   332     if (event->type() == QEvent::User) {
   351     if (event->type() == QEvent::User) {
   333         QMutexLocker locker(&m_mutex);
   352         QMutexLocker locker(&m_mutex);
       
   353         m_pendingRenderEvent = false;
   334         if (m_surface->isActive())
   354         if (m_surface->isActive())
   335             m_surface->present(m_currentFrame);
   355             m_surface->present(m_currentFrame);
   336     }
   356     }
   337 
   357 
   338     return QT7VideoRendererControl::event(event);
   358     return QT7VideoRendererControl::event(event);