You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

192 lines
5.8 KiB

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "renderer_manager.hpp"
#include "player/player_controller.hpp"
#include <QApplication>
#include <vlc_common.h>
#include <vlc_renderer_discovery.h>
#include <vlc_player.h>
const QEvent::Type RendererManagerEvent::AddedEvent =
(QEvent::Type)QEvent::registerEventType();
const QEvent::Type RendererManagerEvent::RemovedEvent =
(QEvent::Type)QEvent::registerEventType();
RendererManagerEvent::RendererManagerEvent(Type type, vlc_renderer_item_t* p_item_)
: QEvent( type ), p_item( p_item_ )
{
vlc_renderer_item_hold( p_item );
}
RendererManagerEvent::~RendererManagerEvent()
{
vlc_renderer_item_release( p_item );
}
RendererManager::RendererManager( qt_intf_t *p_intf_ ) :
p_intf( p_intf_ ), p_selected_item( NULL )
{
connect( &m_stop_scan_timer, &QTimer::timeout, this, &RendererManager::RendererMenuCountdown );
}
RendererManager::~RendererManager()
{
StopScan();
foreach( ItemEntry entry, m_items )
{
emit rendererItemRemoved( entry.second );
vlc_renderer_item_release( entry.second );
}
}
void RendererManager::customEvent( QEvent *event )
{
if( event->type() == RendererManagerEvent::AddedEvent ||
event->type() == RendererManagerEvent::RemovedEvent )
{
RendererManagerEvent *ev = static_cast<RendererManagerEvent *>(event);
QString souturi( vlc_renderer_item_sout( ev->getItem() ) );
vlc_renderer_item_t *p_item = ev->getItem();
if( event->type() == RendererManagerEvent::AddedEvent )
{
if( !m_items.contains( souturi ) )
{
vlc_renderer_item_hold( p_item );
ItemEntry entry( true, p_item );
m_items.insert( souturi, entry );
emit rendererItemAdded( p_item );
}
else /* incref for now */
{
ItemEntry &entry = m_items[ souturi ];
entry.first = true; /* to be kept */
}
}
else /* remove event */
{
if( m_items.contains( souturi ) )
{
p_item = m_items[ souturi ].second;
if( p_selected_item != p_item )
{
m_items.remove( souturi );
emit rendererItemRemoved( p_item );
vlc_renderer_item_release( p_item );
}
else m_items[ souturi ].first = true; /* keep */
}
/* else ignore */
}
}
}
void RendererManager::StartScan()
{
if( m_stop_scan_timer.isActive() )
return;
/* SD subnodes */
char **ppsz_longnames;
char **ppsz_names;
if( vlc_rd_get_names( p_intf, &ppsz_names, &ppsz_longnames ) != VLC_SUCCESS )
{
emit statusUpdated( RendererManager::RendererStatus::FAILED );
return;
}
struct vlc_renderer_discovery_owner owner =
{
this,
renderer_event_item_added,
renderer_event_item_removed,
};
char **ppsz_name = ppsz_names, **ppsz_longname = ppsz_longnames;
for( ; *ppsz_name; ppsz_name++, ppsz_longname++ )
{
msg_Dbg( p_intf, "starting renderer discovery service %s", *ppsz_longname );
vlc_renderer_discovery_t* p_rd = vlc_rd_new( VLC_OBJECT(p_intf), *ppsz_name, &owner );
if( p_rd != NULL )
m_rds.push_back( p_rd );
free( *ppsz_name );
free( *ppsz_longname );
}
free( ppsz_names );
free( ppsz_longnames );
emit statusUpdated( RendererManager::RendererStatus::RUNNING );
m_scan_remain = 20000;
m_stop_scan_timer.setInterval( 1000 );
m_stop_scan_timer.start();
}
void RendererManager::StopScan()
{
m_stop_scan_timer.stop();
foreach ( vlc_renderer_discovery_t* p_rd, m_rds )
vlc_rd_release( p_rd );
/* Cleanup of outdated items, and notify removal */
QHash<QString, ItemEntry>::iterator it = m_items.begin();
while ( it != m_items.end() )
{
ItemEntry &entry = it.value();
if( !entry.first /* don't keep */ && entry.second != p_selected_item )
{
emit rendererItemRemoved( entry.second );
vlc_renderer_item_release( entry.second );
it = m_items.erase( it );
}
else
{
entry.first = false; /* don't keep if not updated by new detect */
assert( it.value().first == false );
++it;
}
}
m_rds.clear();
emit statusUpdated( RendererManager::RendererStatus::IDLE );
}
void RendererManager::RendererMenuCountdown()
{
if( m_stop_scan_timer.isActive() && m_scan_remain > 0 )
{
m_scan_remain -= 1000;
emit statusUpdated( RendererManager::RendererStatus::RUNNING + m_scan_remain / 1000 );
}
else
{
StopScan();
}
}
void RendererManager::SelectRenderer( vlc_renderer_item_t *p_item )
{
p_selected_item = p_item;
vlc_player_locker lock{ p_intf->p_player };
vlc_player_SetRenderer( p_intf->p_player, p_item );
}
void RendererManager::renderer_event_item_added( vlc_renderer_discovery_t* p_rd,
vlc_renderer_item_t *p_item )
{
RendererManager *self = reinterpret_cast<RendererManager*>( p_rd->owner.sys );
QEvent *ev = new RendererManagerEvent( RendererManagerEvent::AddedEvent,
p_item );
QApplication::postEvent( self, ev );
}
void RendererManager::renderer_event_item_removed( vlc_renderer_discovery_t *p_rd,
vlc_renderer_item_t *p_item )
{
RendererManager *self = reinterpret_cast<RendererManager*>( p_rd->owner.sys );
QEvent *ev = new RendererManagerEvent( RendererManagerEvent::RemovedEvent,
p_item );
QApplication::postEvent( self, ev );
}