LCOV - code coverage report
Current view: top level - avmedia/source/opengl - oglplayer.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 59 167 35.3 %
Date: 2015-06-13 12:38:46 Functions: 10 29 34.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : 
      10             : #include "oglplayer.hxx"
      11             : #include "oglframegrabber.hxx"
      12             : #include "oglwindow.hxx"
      13             : 
      14             : #include <cppuhelper/supportsservice.hxx>
      15             : #include <tools/stream.hxx>
      16             : #include <vcl/graph.hxx>
      17             : #include <vcl/graphicfilter.hxx>
      18             : #include <tools/urlobj.hxx>
      19             : #include <vcl/opengl/OpenGLHelper.hxx>
      20             : 
      21             : #include <cassert>
      22             : 
      23             : using namespace com::sun::star;
      24             : using namespace libgltf;
      25             : 
      26             : namespace avmedia { namespace ogl {
      27             : 
      28           1 : OGLPlayer::OGLPlayer()
      29             :     : Player_BASE(m_aMutex)
      30             :     , m_pHandle(NULL)
      31             :     , m_pOGLWindow(NULL)
      32           1 :     , m_bIsRendering(false)
      33             : {
      34           1 : }
      35             : 
      36           3 : OGLPlayer::~OGLPlayer()
      37             : {
      38           1 :     osl::MutexGuard aGuard(m_aMutex);
      39           1 :     if( m_pHandle )
      40             :     {
      41           1 :         m_aContext.makeCurrent();
      42           1 :         gltf_renderer_release(m_pHandle);
      43             :     }
      44           1 :     releaseInputFiles();
      45           2 : }
      46             : 
      47           3 : static bool lcl_LoadFile( glTFFile* io_pFile, const OUString& rURL)
      48             : {
      49           3 :     SvFileStream aStream( rURL, StreamMode::READ );
      50           3 :     if( !aStream.IsOpen() )
      51           0 :         return false;
      52             : 
      53           3 :     const sal_Int64 nBytes = aStream.remainingSize();
      54           3 :     char* pBuffer = new char[nBytes];
      55           3 :     aStream.Read( pBuffer, nBytes );
      56           3 :     aStream.Close();
      57             : 
      58           3 :     io_pFile->buffer = pBuffer;
      59           3 :     io_pFile->size = nBytes;
      60             : 
      61           3 :     return true;
      62             : }
      63             : 
      64           1 : bool OGLPlayer::create( const OUString& rURL )
      65             : {
      66           1 :     osl::MutexGuard aGuard(m_aMutex);
      67             : 
      68           1 :     m_sURL = rURL;
      69             : 
      70             :     // Convert URL to a system path
      71           2 :     const INetURLObject aURLObj(m_sURL);
      72           2 :     const std::string sFilePath = OUStringToOString( aURLObj.getFSysPath(INetURLObject::FSYS_DETECT), RTL_TEXTENCODING_UTF8 ).getStr();
      73             : 
      74             :     // Load *.json file and init renderer
      75           1 :     m_pHandle = gltf_renderer_init(sFilePath, m_vInputFiles);
      76             : 
      77           1 :     if( !m_pHandle )
      78             :     {
      79             :         SAL_WARN("avmedia.opengl", "gltf_renderer_init returned an invalid glTFHandle");
      80           0 :         return false;
      81             :     }
      82             : 
      83             :     // Load external resources
      84           5 :     for( size_t i = 0; i < m_vInputFiles.size(); ++i )
      85             :     {
      86           4 :         glTFFile& rFile = m_vInputFiles[i];
      87           4 :         if( !rFile.filename.empty() )
      88             :         {
      89             :             const OUString sFilesURL =
      90           4 :                 INetURLObject::GetAbsURL(m_sURL,OStringToOUString(OString(rFile.filename.c_str()),RTL_TEXTENCODING_UTF8));
      91           4 :             if( rFile.type == GLTF_IMAGE )
      92             :             {
      93             :                 // Load images as bitmaps
      94           1 :                 GraphicFilter aFilter;
      95           2 :                 Graphic aGraphic;
      96           1 :                 if( aFilter.ImportGraphic(aGraphic, INetURLObject(sFilesURL)) != GRFILTER_OK )
      97             :                 {
      98           0 :                     rFile.buffer = 0;
      99           0 :                     rFile.imagewidth = 0;
     100           0 :                     rFile.imageheight = 0;
     101             :                     SAL_WARN("avmedia.opengl", "Can't load texture file: " + sFilesURL);
     102           0 :                     return false;
     103             :                 }
     104           2 :                 BitmapEx aBitmapEx = aGraphic.GetBitmapEx();
     105           1 :                 rFile.buffer = new char[4 * aBitmapEx.GetSizePixel().Width() * aBitmapEx.GetSizePixel().Height()];
     106           1 :                 OpenGLHelper::ConvertBitmapExToRGBATextureBuffer(aBitmapEx, reinterpret_cast<sal_uInt8*>(rFile.buffer), true);
     107           1 :                 rFile.imagewidth = aBitmapEx.GetSizePixel().Width();
     108           2 :                 rFile.imageheight = aBitmapEx.GetSizePixel().Height();
     109             :             }
     110           3 :             else if( rFile.type == GLTF_BINARY || rFile.type == GLTF_GLSL )
     111             :             {
     112           3 :                 if( !lcl_LoadFile(&rFile, sFilesURL) )
     113             :                 {
     114           0 :                     rFile.buffer = 0;
     115           0 :                     rFile.size = 0;
     116             :                     SAL_WARN("avmedia.opengl", "Can't load glTF file: " + sFilesURL);
     117           0 :                     return false;
     118             :                 }
     119           4 :             }
     120             :         }
     121             :     }
     122             : 
     123             :     // Set timer
     124           1 :     m_aTimer.SetTimeout(1);
     125           1 :     m_aTimer.SetTimeoutHdl(LINK(this,OGLPlayer,TimerHandler));
     126           2 :     return true;
     127             : }
     128             : 
     129           1 : void OGLPlayer::releaseInputFiles()
     130             : {
     131           5 :     for (size_t i = 0; i < m_vInputFiles.size() && m_vInputFiles[i].buffer; ++i)
     132             :     {
     133           4 :         delete [] m_vInputFiles[i].buffer;
     134           4 :         m_vInputFiles[i].buffer = 0;
     135             :     }
     136           1 :     m_vInputFiles.clear();
     137           1 : }
     138             : 
     139           0 : void SAL_CALL OGLPlayer::start() throw ( uno::RuntimeException, std::exception )
     140             : {
     141           0 :     osl::MutexGuard aGuard(m_aMutex);
     142             :     assert(m_pHandle);
     143             : 
     144           0 :     if(!m_pOGLWindow)
     145           0 :         return;
     146             : 
     147           0 :     gltf_animation_resume(m_pHandle);
     148           0 :     m_aTimer.Start();
     149           0 :     m_bIsRendering = true;
     150             : }
     151             : 
     152           0 : void SAL_CALL OGLPlayer::stop() throw ( uno::RuntimeException, std::exception )
     153             : {
     154           0 :     osl::MutexGuard aGuard(m_aMutex);
     155             :     assert(m_pHandle);
     156           0 :     m_aTimer.Stop();
     157           0 :     gltf_animation_stop(m_pHandle);
     158           0 :     m_bIsRendering = false;
     159           0 : }
     160             : 
     161           0 : sal_Bool SAL_CALL OGLPlayer::isPlaying() throw ( uno::RuntimeException, std::exception )
     162             : {
     163           0 :     osl::MutexGuard aGuard(m_aMutex);
     164             :     assert(m_pHandle);
     165             :     // Here isPlaying means model is rendered in the window and
     166             :     // able to interact with the user (e.g. moving camera)
     167           0 :     if( getDuration() > 0.0 )
     168           0 :         return gltf_animation_is_playing(m_pHandle);
     169             :     else
     170           0 :         return m_bIsRendering;
     171             : }
     172             : 
     173           0 : double SAL_CALL OGLPlayer::getDuration() throw ( uno::RuntimeException, std::exception )
     174             : {
     175           0 :     osl::MutexGuard aGuard(m_aMutex);
     176             :     assert(m_pHandle);
     177           0 :     return gltf_animation_get_duration(m_pHandle);
     178             : }
     179             : 
     180           0 : void SAL_CALL OGLPlayer::setMediaTime( double fTime ) throw ( uno::RuntimeException, std::exception )
     181             : {
     182           0 :     osl::MutexGuard aGuard(m_aMutex);
     183             :     assert(m_pHandle);
     184           0 :     gltf_animation_set_time(m_pHandle, fTime);
     185           0 : }
     186             : 
     187           0 : double SAL_CALL OGLPlayer::getMediaTime() throw ( ::com::sun::star::uno::RuntimeException, std::exception )
     188             : {
     189           0 :     osl::MutexGuard aGuard(m_aMutex);
     190             :     assert(m_pHandle);
     191           0 :     return gltf_animation_get_time(m_pHandle);
     192             : }
     193             : 
     194           0 : void SAL_CALL OGLPlayer::setPlaybackLoop( sal_Bool bSet ) throw ( uno::RuntimeException, std::exception )
     195             : {
     196           0 :     osl::MutexGuard aGuard(m_aMutex);
     197             :     assert(m_pHandle);
     198           0 :     gltf_animation_set_looping(m_pHandle, bSet);
     199           0 : }
     200             : 
     201           0 : sal_Bool SAL_CALL OGLPlayer::isPlaybackLoop() throw ( uno::RuntimeException, std::exception )
     202             : {
     203           0 :     osl::MutexGuard aGuard(m_aMutex);
     204             :     assert(m_pHandle);
     205           0 :     return gltf_animation_get_looping(m_pHandle);
     206             : }
     207             : 
     208           0 : void SAL_CALL OGLPlayer::setVolumeDB( sal_Int16 /*nVolumDB*/ ) throw ( uno::RuntimeException, std::exception )
     209             : {
     210             :     // OpenGL models have no sound.
     211           0 : }
     212             : 
     213           0 : sal_Int16 SAL_CALL OGLPlayer::getVolumeDB() throw ( uno::RuntimeException, std::exception )
     214             : {
     215             :     // OpenGL models have no sound.
     216           0 :     return 0;
     217             : }
     218             : 
     219           0 : void SAL_CALL OGLPlayer::setMute( sal_Bool /*bSet*/ ) throw ( uno::RuntimeException, std::exception )
     220             : {
     221             :     // OpenGL models have no sound.
     222           0 : }
     223             : 
     224           0 : sal_Bool SAL_CALL OGLPlayer::isMute() throw ( uno::RuntimeException, std::exception )
     225             : {
     226             :     // OpenGL models have no sound.
     227           0 :     return false;
     228             : }
     229             : 
     230           1 : awt::Size SAL_CALL OGLPlayer::getPreferredPlayerWindowSize() throw ( uno::RuntimeException, std::exception )
     231             : {
     232           1 :     return awt::Size( 480, 360 );
     233             : }
     234             : 
     235           0 : static bool lcl_CheckOpenGLRequirements()
     236             : {
     237           0 :     return OpenGLHelper::getGLVersion() >= 3.0;
     238             : }
     239             : 
     240           0 : uno::Reference< media::XPlayerWindow > SAL_CALL OGLPlayer::createPlayerWindow( const uno::Sequence< uno::Any >& rArguments )
     241             :      throw ( uno::RuntimeException, std::exception )
     242             : {
     243           0 :     osl::MutexGuard aGuard( m_aMutex );
     244             : 
     245             :     assert( rArguments.getLength() >= 3 );
     246             :     assert(m_pHandle);
     247             : 
     248           0 :     sal_IntPtr pIntPtr = 0;
     249           0 :     rArguments[ 2 ] >>= pIntPtr;
     250           0 :     SystemChildWindow *pChildWindow = reinterpret_cast< SystemChildWindow* >( pIntPtr );
     251             : 
     252           0 :     if( !pChildWindow )
     253             :     {
     254             :         SAL_WARN("avmedia.opengl", "Failed to get the SystemChildWindow for rendering!");
     255           0 :         return uno::Reference< media::XPlayerWindow >();
     256             :     }
     257             :     assert(pChildWindow->GetParent());
     258             : 
     259           0 :     if( !m_aContext.init(pChildWindow) )
     260             :     {
     261             :         SAL_WARN("avmedia.opengl", "Context initialization failed");
     262           0 :         return uno::Reference< media::XPlayerWindow >();
     263             :     }
     264             : 
     265           0 :     if( !m_aContext.supportMultiSampling() )
     266             :     {
     267             :         SAL_WARN("avmedia.opengl", "Context does not support multisampling!");
     268           0 :         return uno::Reference< media::XPlayerWindow >();
     269             :     }
     270             : 
     271           0 :     if( !lcl_CheckOpenGLRequirements() )
     272             :     {
     273             :         SAL_WARN("avmedia.opengl", "Your platform does not have the minimal OpenGL requiremenets!");
     274           0 :         return uno::Reference< media::XPlayerWindow >();
     275             :     }
     276             : 
     277           0 :     Size aSize = pChildWindow->GetSizePixel();
     278           0 :     m_aContext.setWinSize(aSize);
     279           0 :     m_pHandle->viewport.x = 0;
     280           0 :     m_pHandle->viewport.y = 0;
     281           0 :     m_pHandle->viewport.width = aSize.Width();
     282           0 :     m_pHandle->viewport.height = aSize.Height();
     283             : 
     284             :     // TODO: Use the error codes to print a readable error message
     285           0 :     int nRet = gltf_renderer_set_content(m_pHandle, m_vInputFiles);
     286           0 :     releaseInputFiles();
     287           0 :     if( nRet != 0 )
     288             :     {
     289             :         SAL_WARN("avmedia.opengl", "Error occurred while setting up the scene! Error code: " << nRet);
     290           0 :         return uno::Reference< media::XPlayerWindow >();
     291             :     }
     292             :     // The background color is white by default, but we need to separate the
     293             :     // OpenGL window from the main window so set background color to grey
     294           0 :     glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
     295           0 :     m_pOGLWindow = new OGLWindow(*m_pHandle, m_aContext, *pChildWindow->GetParent());
     296           0 :     return uno::Reference< media::XPlayerWindow >( m_pOGLWindow );
     297             : }
     298             : 
     299           1 : uno::Reference< media::XFrameGrabber > SAL_CALL OGLPlayer::createFrameGrabber()
     300             :      throw ( uno::RuntimeException, std::exception )
     301             : {
     302           1 :     osl::MutexGuard aGuard(m_aMutex);
     303             :     assert(m_pHandle);
     304             : 
     305           1 :     if( !m_aContext.init() )
     306             :     {
     307             :         SAL_WARN("avmedia.opengl", "Offscreen context initialization failed");
     308           1 :         return uno::Reference< media::XFrameGrabber >();
     309             :     }
     310             : 
     311           0 :     if( !m_aContext.supportMultiSampling() )
     312             :     {
     313             :         SAL_WARN("avmedia.opengl", "Context does not support multisampling!");
     314           0 :         return uno::Reference< media::XFrameGrabber >();
     315             :     }
     316             : 
     317           0 :     if( !lcl_CheckOpenGLRequirements() )
     318             :     {
     319             :         SAL_WARN("avmedia.opengl", "Your platform does not have the minimal OpenGL requiremenets!");
     320           0 :         return uno::Reference< media::XFrameGrabber >();
     321             :     }
     322             : 
     323           0 :     m_pHandle->viewport.x = 0;
     324           0 :     m_pHandle->viewport.y = 0;
     325           0 :     m_pHandle->viewport.width = getPreferredPlayerWindowSize().Width;
     326           0 :     m_pHandle->viewport.height = getPreferredPlayerWindowSize().Height;
     327             : 
     328           0 :     int nRet = gltf_renderer_set_content(m_pHandle, m_vInputFiles);
     329           0 :     releaseInputFiles();
     330           0 :     if( nRet != 0 )
     331             :     {
     332             :         SAL_WARN("avmedia.opengl", "Error occurred while setting up the scene! Error code: " << nRet);
     333           0 :         return uno::Reference< media::XFrameGrabber >();
     334             :     }
     335           0 :     glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
     336           0 :     OGLFrameGrabber *pFrameGrabber = new OGLFrameGrabber( *m_pHandle );
     337           0 :     return uno::Reference< media::XFrameGrabber >( pFrameGrabber );
     338             : }
     339             : 
     340           0 : OUString SAL_CALL OGLPlayer::getImplementationName()
     341             :      throw ( ::com::sun::star::uno::RuntimeException, std::exception )
     342             : {
     343           0 :     return OUString("com.sun.star.comp.avmedia.Player_OpenGL");
     344             : }
     345             : 
     346           0 : sal_Bool SAL_CALL OGLPlayer::supportsService( const OUString& rServiceName )
     347             :      throw ( uno::RuntimeException, std::exception )
     348             : {
     349           0 :     return cppu::supportsService(this, rServiceName);
     350             : }
     351             : 
     352           0 : uno::Sequence< OUString > SAL_CALL OGLPlayer::getSupportedServiceNames()
     353             :      throw ( uno::RuntimeException, std::exception )
     354             : {
     355           0 :     uno::Sequence< OUString > aRet(1);
     356           0 :     aRet[0] = "com.sun.star.media.Player_OpenGL";
     357           0 :     return aRet;
     358             : }
     359             : 
     360           0 : IMPL_LINK_TYPED(OGLPlayer,TimerHandler,Timer*,pTimer,void)
     361             : {
     362           0 :     if (pTimer == &m_aTimer)
     363             :     {
     364           0 :         osl::MutexGuard aGuard(m_aMutex);
     365             :         assert(m_pOGLWindow);
     366           0 :         m_pOGLWindow->update();
     367             :     }
     368           0 : }
     369             : 
     370             : } // namespace ogl
     371           3 : } // namespace avmedia
     372             : 
     373             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11