vout_manager.cpp
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:9k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * vout_manager.cpp
  3.  *****************************************************************************
  4.  * Copyright (C) 2009 the VideoLAN team
  5.  * $Id: f164d8d7022cdeb5178ead67133fd91585cf6910 $
  6.  *
  7.  * Authors: Erwan Tulou <brezhoneg1 at yahoo.fr>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  22.  *****************************************************************************/
  23. #ifdef HAVE_CONFIG_H
  24. # include "config.h"
  25. #endif
  26. #include <vlc_vout.h>
  27. #include <vlc_window.h>
  28. #include "vout_manager.hpp"
  29. #include "window_manager.hpp"
  30. #include "vlcproc.hpp"
  31. #include "../commands/async_queue.hpp"
  32. #include "../commands/cmd_show_window.hpp"
  33. #include "../commands/cmd_resize.hpp"
  34. VoutManager *VoutManager::instance( intf_thread_t *pIntf )
  35. {
  36.     if( pIntf->p_sys->p_voutManager == NULL )
  37.     {
  38.         pIntf->p_sys->p_voutManager = new VoutManager( pIntf );
  39.     }
  40.     return pIntf->p_sys->p_voutManager;
  41. }
  42. void VoutManager::destroy( intf_thread_t *pIntf )
  43. {
  44.     if( pIntf->p_sys->p_voutManager )
  45.     {
  46.         delete pIntf->p_sys->p_voutManager;
  47.         pIntf->p_sys->p_voutManager = NULL;
  48.     }
  49. }
  50. VoutManager::VoutManager( intf_thread_t *pIntf ): SkinObject( pIntf ),
  51.      m_pVoutMainWindow( NULL ), m_pCtrlVideoVec(),
  52.      m_pCtrlVideoVecBackup(), m_SavedVoutVec()
  53. {
  54.     vlc_mutex_init( &vout_lock );
  55.     m_pVoutMainWindow = new VoutMainWindow( getIntf() );
  56. }
  57. VoutManager::~VoutManager( )
  58. {
  59.     vlc_mutex_destroy( &vout_lock );
  60.     delete m_pVoutMainWindow;
  61. }
  62. void VoutManager::registerCtrlVideo( CtrlVideo* p_CtrlVideo )
  63. {
  64.     m_pCtrlVideoVec.push_back( p_CtrlVideo );
  65. }
  66. void VoutManager::saveVoutConfig( )
  67. {
  68.     // Save width/height to be consistent across themes
  69.     // and detach Video Controls
  70.     vector<SavedVout>::iterator it;
  71.     for( it = m_SavedVoutVec.begin(); it != m_SavedVoutVec.end(); it++ )
  72.     {
  73.         if( (*it).pCtrlVideo )
  74.         {
  75.             // detach vout thread from VideoControl
  76.             (*it).pCtrlVideo->detachVoutWindow( );
  77.             // memorize width/height before VideoControl is destroyed
  78.             (*it).width = (*it).pCtrlVideo->getPosition()->getWidth();
  79.             (*it).height = (*it).pCtrlVideo->getPosition()->getHeight();
  80.             (*it).pCtrlVideo = NULL;
  81.        }
  82.     }
  83.     // Create a backup copy and reset original for new theme
  84.     m_pCtrlVideoVecBackup = m_pCtrlVideoVec;
  85.     m_pCtrlVideoVec.clear();
  86. }
  87. void VoutManager::restoreVoutConfig( bool b_success )
  88. {
  89.     if( !b_success )
  90.     {
  91.         // loading new theme failed, restoring previous theme
  92.         m_pCtrlVideoVec = m_pCtrlVideoVecBackup;
  93.     }
  94.     // reattach vout(s) to Video Controls
  95.     vector<SavedVout>::iterator it;
  96.     for( it = m_SavedVoutVec.begin(); it != m_SavedVoutVec.end(); it++ )
  97.     {
  98.         CtrlVideo* pCtrlVideo = getBestCtrlVideo();
  99.         if( pCtrlVideo )
  100.         {
  101.             pCtrlVideo->attachVoutWindow( (*it).pVoutWindow );
  102.            (*it).pCtrlVideo = pCtrlVideo;
  103.         }
  104.     }
  105. }
  106. void VoutManager::discardVout( CtrlVideo* pCtrlVideo )
  107. {
  108.     vector<SavedVout>::iterator it;
  109.     for( it = m_SavedVoutVec.begin(); it != m_SavedVoutVec.end(); it++ )
  110.     {
  111.         if( (*it).pCtrlVideo == pCtrlVideo )
  112.         {
  113.             // detach vout thread from VideoControl
  114.             (*it).pCtrlVideo->detachVoutWindow( );
  115.             (*it).width = (*it).pCtrlVideo->getPosition()->getWidth();
  116.             (*it).height = (*it).pCtrlVideo->getPosition()->getHeight();
  117.             (*it).pCtrlVideo = NULL;
  118.             break;
  119.         }
  120.     }
  121. }
  122. void VoutManager::requestVout( CtrlVideo* pCtrlVideo )
  123. {
  124.     vector<SavedVout>::iterator it;
  125.     for( it = m_SavedVoutVec.begin(); it != m_SavedVoutVec.end(); it++ )
  126.     {
  127.         if( (*it).pCtrlVideo == NULL )
  128.         {
  129.             pCtrlVideo->attachVoutWindow( (*it).pVoutWindow,
  130.                                           (*it).width, (*it).height );
  131.             (*it).pCtrlVideo = pCtrlVideo;
  132.             break;
  133.         }
  134.     }
  135. }
  136. CtrlVideo* VoutManager::getBestCtrlVideo( )
  137. {
  138.     // try to find an unused useable VideoControl
  139.     vector<CtrlVideo*>::const_iterator it;
  140.     for( it = m_pCtrlVideoVec.begin(); it != m_pCtrlVideoVec.end(); it++ )
  141.     {
  142.         if( (*it)->isUseable() && !(*it)->isUsed() )
  143.         {
  144.             return (*it);
  145.         }
  146.     }
  147.     return NULL;
  148. }
  149. void* VoutManager::acceptVout( vout_thread_t* pVout, int width, int height )
  150. {
  151.     // Creation of a dedicated Window per vout thread
  152.     VoutWindow* pVoutWindow = new VoutWindow( getIntf(), pVout, width, height,
  153.                                          (GenericWindow*) m_pVoutMainWindow );
  154.     void* handle = pVoutWindow->getOSHandle();
  155.     // try to find a video Control within the theme
  156.     CtrlVideo* pCtrlVideo = getBestCtrlVideo();
  157.     if( pCtrlVideo )
  158.     {
  159.         // A Video Control is available
  160.         // directly attach vout thread to it
  161.         pCtrlVideo->attachVoutWindow( pVoutWindow );
  162.     }
  163.     // save vout characteristics
  164.     m_SavedVoutVec.push_back( SavedVout( pVout, pVoutWindow, pCtrlVideo ) );
  165.     msg_Dbg( getIntf(), "New incoming vout=0x%p, handle=0x%p, VideoCtrl=0x%p",
  166.                         pVout, handle, pCtrlVideo );
  167.     return handle;
  168. }
  169. // Functions called by window provider
  170. // ///////////////////////////////////
  171. void *VoutManager::getWindow( intf_thread_t *pIntf, vout_window_t *pWnd )
  172. {
  173. #ifdef WIN32
  174.     if( pIntf->p_sys->b_exitRequested )
  175.         return NULL;
  176. #endif
  177.     // Theme may have been destroyed
  178.     if( !pIntf->p_sys->p_theme )
  179.         return NULL;
  180.     VoutManager *pThis = pIntf->p_sys->p_voutManager;
  181.     vout_thread_t* pVout = pWnd->vout;
  182.     int width = (int)pWnd->width;
  183.     int height = (int)pWnd->height;
  184.     pThis->lockVout();
  185.     void* handle = pThis->acceptVout( pVout, width, height );
  186.     pThis->unlockVout();
  187.     return handle;
  188. }
  189. void VoutManager::releaseWindow( intf_thread_t *pIntf, vout_window_t *pWnd )
  190. {
  191.     VoutManager *pThis = pIntf->p_sys->p_voutManager;
  192.     // Theme may have been destroyed
  193.     if( !pIntf->p_sys->p_theme )
  194.         return;
  195.     vout_thread_t* pVout = pWnd->vout;
  196.     pThis->lockVout();
  197.     // remove vout thread from savedVec
  198.     vector<SavedVout>::iterator it;
  199.     for( it = pThis->m_SavedVoutVec.begin(); it != pThis->m_SavedVoutVec.end(); it++ )
  200.     {
  201.         if( (*it).pVout == pVout )
  202.         {
  203.             msg_Dbg( pIntf, "vout released vout=0x%p, VideoCtrl=0x%p",
  204.                              pVout, (*it).pCtrlVideo );
  205.             // if a video control was being used, detach from it
  206.             if( (*it).pCtrlVideo )
  207.             {
  208.                 (*it).pCtrlVideo->detachVoutWindow( );
  209.             }
  210.             // remove resources
  211.             delete (*it).pVoutWindow;
  212.             pThis->m_SavedVoutVec.erase( it );
  213.             break;
  214.         }
  215.     }
  216. #ifdef WIN32
  217.     if( pIntf->p_sys->b_exitRequested )
  218.         pIntf->p_sys->b_exitOK = ( pThis->m_SavedVoutVec.size() == 0 );
  219. #endif
  220.     pThis->unlockVout();
  221. }
  222. int VoutManager::controlWindow( struct vout_window_t *pWnd,
  223.                             int query, va_list args )
  224. {
  225.     intf_thread_t *pIntf = (intf_thread_t *)pWnd->p_private;
  226.     VoutManager *pThis = pIntf->p_sys->p_voutManager;
  227.     vout_thread_t* pVout = pWnd->vout;
  228.     switch( query )
  229.     {
  230.         case VOUT_SET_SIZE:
  231.         {
  232.             unsigned int i_width  = va_arg( args, unsigned int );
  233.             unsigned int i_height = va_arg( args, unsigned int );
  234.             if( i_width && i_height )
  235.             {
  236.                 pThis->lockVout();
  237.                 vector<SavedVout>::iterator it;
  238.                 for( it = pThis->m_SavedVoutVec.begin();
  239.                      it != pThis->m_SavedVoutVec.end(); it++ )
  240.                 {
  241.                     if( (*it).pVout == pVout )
  242.                     {
  243.                         // Post a vout resize command
  244.                         CmdResizeVout *pCmd =
  245.                             new CmdResizeVout( pThis->getIntf(),
  246.                                                (*it).pVoutWindow,
  247.                                                (int)i_width, (int)i_height );
  248.                         AsyncQueue *pQueue =
  249.                             AsyncQueue::instance( pThis->getIntf() );
  250.                         pQueue->push( CmdGenericPtr( pCmd ) );
  251.                         break;
  252.                     }
  253.                 }
  254.                 pThis->unlockVout();
  255.             }
  256.         }
  257.         default:
  258.             msg_Dbg( pWnd, "control query not supported" );
  259.             break;
  260.     }
  261.     return VLC_SUCCESS;
  262. }