vlc | branch: master | Francois Cartegnie <[email protected]> | 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 ); _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
