[vlc-commits] Qt: fix EPG high CPU usage on update
Francois Cartegnie
git at videolan.org
Mon Sep 5 18:48:56 CEST 2016
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Fri Sep 2 02:06:50 2016 +0900| [b6804ed118376eb9c336106a3eb6610da2188902] | committer: Francois Cartegnie
Qt: fix EPG high CPU usage on update
temporary fix until EIT api changes
refs #17031
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=b6804ed118376eb9c336106a3eb6610da2188902
---
modules/gui/qt/components/epg/EPGView.cpp | 135 ++++++++++++++++------------
modules/gui/qt/components/epg/EPGView.hpp | 2 +-
modules/gui/qt/components/epg/EPGWidget.cpp | 10 +--
3 files changed, 83 insertions(+), 64 deletions(-)
diff --git a/modules/gui/qt/components/epg/EPGView.cpp b/modules/gui/qt/components/epg/EPGView.cpp
index 96420fa..5835e01 100644
--- a/modules/gui/qt/components/epg/EPGView.cpp
+++ b/modules/gui/qt/components/epg/EPGView.cpp
@@ -131,46 +131,19 @@ bool EPGView::hasValidData() const
return !epgitemsByChannel.isEmpty();
}
-static void cleanOverlapped( EPGEventByTimeQMap *epgItemByTime, EPGItem *epgItem, QGraphicsScene *scene )
-{
- QDateTime epgItemTime = epgItem->start();
- QDateTime epgItemTimeEnd = epgItem->end();
- /* Clean overlapped programs */
- foreach(const QDateTime existingTimes, epgItemByTime->keys())
- {
- if ( existingTimes > epgItemTimeEnd ) break; /* Can't overlap later items */
- if ( existingTimes != epgItemTime )
- {
- EPGItem *otherEPGItem = epgItemByTime->value( existingTimes );
- if ( otherEPGItem->playsAt( epgItemTime.addSecs( 1 ) )
- || /* add/minus one sec because next one can start at prev end min */
- otherEPGItem->playsAt( epgItemTimeEnd.addSecs( -1 ) ) )
- {
- epgItemByTime->remove( otherEPGItem->start() );
- scene->removeItem( otherEPGItem );
- delete otherEPGItem;
- }
- }
- }
-}
-
-bool EPGView::addEPGEvent( vlc_epg_event_t *eventdata, QString channelName, bool b_current )
+bool EPGView::addEPGEvents( vlc_epg_event_t **pp_events, size_t i_events,
+ QString channelName, const vlc_epg_event_t *p_current )
{
/* Init our nested map if required */
EPGEventByTimeQMap *epgItemByTime;
EPGItem *epgItem;
bool b_refresh_channels = false;
- QDateTime eventStart = QDateTime::fromTime_t( eventdata->i_start );
- if ( eventStart.addSecs( eventdata->i_duration ) < m_baseTime )
- return false; /* EPG feed sent expired item */
- if ( eventStart < m_startTime )
- {
- m_startTime = eventStart;
- emit startTimeChanged( m_startTime );
- }
+ if( i_events < 1 )
+ return false;
mutex.lock();
+ /* First check and create channel if missing */
if ( !epgitemsByChannel.contains( channelName ) )
{
epgItemByTime = new EPGEventByTimeQMap();
@@ -181,37 +154,87 @@ bool EPGView::addEPGEvent( vlc_epg_event_t *eventdata, QString channelName, bool
epgItemByTime = epgitemsByChannel.value( channelName );
}
- if ( epgItemByTime->contains( eventStart ) )
+ QDateTime rangeStart = QDateTime::fromTime_t( pp_events[0]->i_start );
+ QDateTime rangeEnd = QDateTime::fromTime_t( pp_events[i_events - 1]->i_start );
+ rangeEnd.addSecs( pp_events[i_events - 1]->i_duration );
+
+ EPGEventByTimeQMap::iterator itRangeBegin =
+ epgItemByTime->lowerBound( rangeStart );
+ EPGEventByTimeQMap::iterator itRangeEnd =
+ epgItemByTime->upperBound( rangeEnd );
+
+ EPGEventByTimeQMap::iterator it = itRangeBegin;
+ for( size_t i=0; i<i_events; i++ )
{
- /* Update our existing programs */
- epgItem = epgItemByTime->value( eventStart );
- epgItem->setCurrent( b_current );
- if ( epgItem->setData( eventdata ) ) /* updates our entry */
- cleanOverlapped( epgItemByTime, epgItem, scene() );
- mutex.unlock();
- return false;
- } else {
- /* Insert a new program entry */
- epgItem = new EPGItem( eventdata, this );
- cleanOverlapped( epgItemByTime, epgItem, scene() );
- /* Effectively insert our new program */
- epgItem->setCurrent( b_current );
- epgItemByTime->insert( eventStart, epgItem );
- scene()->addItem( epgItem );
- /* update only our row (without calling the updatechannels()) */
- epgItem->setRow( epgitemsByChannel.keys().indexOf( channelName ) );
-
- /* First Insert, needs to focus by default then */
- if ( epgitemsByChannel.keys().count() == 1 &&
- epgItemByTime->count() == 1 )
- focusItem( epgItem );
+ const vlc_epg_event_t *p_event = pp_events[i];
+
+ for( ; it != itRangeEnd; ++it )
+ {
+ EPGItem *epgItem = *it;
+ QDateTime eventStart = QDateTime::fromTime_t( p_event->i_start );
+ if( epgItem->start() < eventStart )
+ {
+ if( it != itRangeBegin ||
+ epgItem->start().addSecs( epgItem->duration() ) > eventStart )
+ delete *it++;
+ }
+ else if( epgItem->start() > eventStart )
+ {
+ break;
+ }
+ }
}
+
mutex.unlock();
+
+ bool b_added = false;
+ for( size_t i=0; i<i_events; i++ )
+ {
+ const vlc_epg_event_t *p_event = pp_events[i];
+
+ QDateTime eventStart = QDateTime::fromTime_t( p_event->i_start );
+ if ( eventStart.addSecs( p_event->i_duration ) < m_baseTime )
+ continue; /* EPG feed sent expired item */
+ if ( eventStart < m_startTime )
+ {
+ m_startTime = eventStart;
+ emit startTimeChanged( m_startTime );
+ }
+
+ mutex.lock();
+
+ if ( epgItemByTime->contains( eventStart ) )
+ {
+ /* Update our existing programs */
+ epgItem = epgItemByTime->value( eventStart );
+ epgItem->setCurrent( ( p_event == p_current ) );
+ epgItem->setData( p_event ); /* updates our entry */
+ } else {
+ /* Insert a new program entry */
+ epgItem = new EPGItem( p_event, this );
+ /* Effectively insert our new program */
+ epgItem->setCurrent( ( p_event == p_current ) );
+ epgItemByTime->insert( eventStart, epgItem );
+ scene()->addItem( epgItem );
+ /* update only our row (without calling the updatechannels()) */
+ epgItem->setRow( epgitemsByChannel.keys().indexOf( channelName ) );
+
+ /* First Insert, needs to focus by default then */
+ if ( epgitemsByChannel.keys().count() == 1 &&
+ epgItemByTime->count() == 1 )
+ focusItem( epgItem );
+ b_added = true;
+ }
+
+ mutex.unlock();
+ }
+
+
/* Update rows on each item */
if ( b_refresh_channels ) updateChannels();
- return true;
+ return b_added;
}
void EPGView::removeEPGEvent( vlc_epg_event_t *eventdata, QString channelName )
diff --git a/modules/gui/qt/components/epg/EPGView.hpp b/modules/gui/qt/components/epg/EPGView.hpp
index 3e5c770..c74413c 100644
--- a/modules/gui/qt/components/epg/EPGView.hpp
+++ b/modules/gui/qt/components/epg/EPGView.hpp
@@ -65,7 +65,7 @@ public:
const QDateTime& startTime() const;
const QDateTime& baseTime() const;
- bool addEPGEvent( vlc_epg_event_t*, QString, bool );
+ bool addEPGEvents( vlc_epg_event_t **, size_t, QString, const vlc_epg_event_t * );
void removeEPGEvent( vlc_epg_event_t*, QString );
void updateDuration();
void reset();
diff --git a/modules/gui/qt/components/epg/EPGWidget.cpp b/modules/gui/qt/components/epg/EPGWidget.cpp
index a385c84..ec113b4 100644
--- a/modules/gui/qt/components/epg/EPGWidget.cpp
+++ b/modules/gui/qt/components/epg/EPGWidget.cpp
@@ -113,14 +113,10 @@ void EPGWidget::updateEPG( input_item_t *p_input_item )
for ( int i = 0; i < p_input_item->i_epg; ++i )
{
vlc_epg_t *p_epg = p_input_item->pp_epg[i];
-
/* Read current epg events from libvlc and try to insert them */
- for ( int j = 0; j < p_epg->i_event; ++j )
- {
- vlc_epg_event_t *p_event = p_epg->pp_event[j];
- m_epgView->addEPGEvent( p_event, qfu( p_epg->psz_name ),
- ( p_epg->p_current == p_event ) );
- }
+ m_epgView->addEPGEvents( p_epg->pp_event, p_epg->i_event,
+ qfu( p_epg->psz_name ),
+ p_epg->p_current );
}
vlc_mutex_unlock( & p_input_item->lock );
More information about the vlc-commits
mailing list