Projects
home:sagiben
kodi-next
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 60
View file
_service:download_files:master.tar.gz/addons/resource.language.en_gb/resources/strings.po
Changed
@@ -2589,6 +2589,7 @@ #: xbmc/dialogs/GUIDialogMediaFilter.cpp #: xbmc/playlists/SmartPlaylist.cpp +#: xbmc/music/MusicUtils.cpp #: xbmc/video/dialogs/GUIDialogVideoInfo.cpp #: addons/skin.estuary/xml/DialogVideoInfo.xml #: addons/skin.estuary/xml/DialogFullScreenInfo.xml @@ -3955,7 +3956,6 @@ #: xbmc/dialogs/GUIDialogFavourites.cpp #: xbmc/music/dialogs/GUIDialogMusicInfo.cpp -#: xbmc/music/dialogs/GUIDialogSongInfo.cpp msgctxt "#1030" msgid "Browse for image" msgstr "" @@ -7171,11 +7171,13 @@ msgid "Sync playback to display" msgstr "" +#: xbmc/music/dialogs/GUIDialogSongInfo.cpp #: xbmc/video/dialogs/GUIDialogVideoInfo.cpp msgctxt "#13511" msgid "Choose art" msgstr "" +#: xbmc/music/dialogs/GUIDialogSongInfo.cpp #: xbmc/video/dialogs/GUIDialogVideoInfo.cpp msgctxt "#13512" msgid "Current art" @@ -7191,14 +7193,17 @@ msgid "Local art" msgstr "" +#: xbmc/music/dialogs/GUIDialogSongInfo.cpp #: xbmc/video/dialogs/GUIDialogVideoInfo.cpp msgctxt "#13515" msgid "No art" msgstr "" +#. Button to add a new type of art e.g. "thumb", "poster", "fanart" etc. +#: xbmc/music/MusicUtils.cpp #: xbmc/video/dialogs/GUIDialogVideoInfo.cpp msgctxt "#13516" -msgid "Add art" +msgid "Add art type" msgstr "" #: system/settings/settings.xml @@ -7221,7 +7226,13 @@ msgid "Embedded fanart" msgstr "" -#empty strings from id 13521 to 13549 +#. Heading for selection of a type of art e.g. "thumb", "poster", "fanart" etc. +#: xbmc/music/MusicUtils.cpp +msgctxt "#13521" +msgid "Choose art type" +msgstr "" + +#empty strings from id 13522 to 13549 #: system/settings/settings.xml msgctxt "#13550" @@ -11804,7 +11815,6 @@ #: xbmc/dialogs/GUIDialogContextMenu.cpp #: xbmc/music/dialogs/GUIDialogMusicInfo.cpp -#: xbmc/music/dialogs/GUIDialogSongInfo.cpp msgctxt "#20016" msgid "Current thumb" msgstr "" @@ -11818,7 +11828,6 @@ #: xbmc/dialogs/GUIDialogContextMenu.cpp #: xbmc/music/dialogs/GUIDialogMusicInfo.cpp -#: xbmc/music/dialogs/GUIDialogSongInfo.cpp msgctxt "#20018" msgid "No thumb" msgstr "" @@ -11830,6 +11839,7 @@ msgstr "" #. Name of an artwork type +#: xbmc/music/MusicUtils.cpp #: xbmc/video/dialogs/GUIDialogVideoInfo.cpp #: addons/skin.estuary/xml/View_501_Banner.xml msgctxt "#20020" @@ -11837,6 +11847,7 @@ msgstr "" #. Name of an artwork type +#: xbmc/music/MusicUtils.cpp #: xbmc/video/dialogs/GUIDialogVideoInfo.cpp #: addons/skin.estuary/xml/View_51_Poster.xml msgctxt "#20021" @@ -13397,6 +13408,8 @@ msgid "Add to library" msgstr "" +#. Name of an artwork type +#: xbmc/music/MusicUtils.cpp #: xbmc/music/dialogs/GUIDialogMusicInfo.cpp #: addons/skin.estuary/xml/View_502_FanArt.xml msgctxt "#20445" @@ -13669,6 +13682,11 @@ msgid "Play GUI sounds during media playback" msgstr "" +#. Name of an artwork type +#: xbmc/music/MusicUtils.cpp +#: xbmc/music/dialogs/GUIDialogSongInfo.cpp +#: xbmc/video/dialogs/GUIDialogVideoInfo.cpp +#: xbmc/dialogs/GUIDialogFileBrowser.h msgctxt "#21371" msgid "Thumbnail" msgstr "" @@ -20857,12 +20875,16 @@ #empty strings from id 38019 to 38021 -#. Used for the viewstate selection +#. Used for the rating selection +#: xbmc/music/MusicUtils.cpp #: xbmc/video/dialogs/GUIDialogVideoInfo.cpp msgctxt "#38022" msgid "No rating" msgstr "" +#. Used for the rating selection +#: xbmc/music/MusicUtils.cpp +#: xbmc/video/dialogs/GUIDialogVideoInfo.cpp msgctxt "#38023" msgid "Set my rating" msgstr ""
View file
_service:download_files:master.tar.gz/cmake/modules/FindAlsa.cmake
Changed
@@ -15,7 +15,7 @@ # ALSA::ALSA - The Alsa library if(PKG_CONFIG_FOUND) - pkg_check_modules(PC_ALSA alsa QUIET) + pkg_check_modules(PC_ALSA alsa>=0.9 QUIET) endif() find_path(ALSA_INCLUDE_DIR NAMES alsa/asoundlib.h
View file
_service:download_files:master.tar.gz/cmake/modules/FindCdio.cmake
Changed
@@ -14,7 +14,7 @@ # CDIO::CDIO - The cdio library if(PKG_CONFIG_FOUND) - pkg_check_modules(PC_CDIO libcdio libiso9660 QUIET) + pkg_check_modules(PC_CDIO libcdio>=0.78 libiso9660 QUIET) endif() find_path(CDIO_INCLUDE_DIR NAMES cdio/cdio.h
View file
_service:download_files:master.tar.gz/cmake/modules/FindMicroHttpd.cmake
Changed
@@ -15,7 +15,7 @@ # MicroHttpd::MicroHttpd - The MicroHttpd library if(PKG_CONFIG_FOUND) - pkg_check_modules(PC_MICROHTTPD libmicrohttpd>=0.4 QUIET) + pkg_check_modules(PC_MICROHTTPD libmicrohttpd>=0.9.40 QUIET) endif() find_path(MICROHTTPD_INCLUDE_DIR NAMES microhttpd.h
View file
_service:download_files:master.tar.gz/cmake/modules/FindSSH.cmake
Changed
@@ -15,7 +15,7 @@ # SSH::SSH - The SSH library if(PKG_CONFIG_FOUND) - pkg_check_modules(PC_SSH libssh QUIET) + pkg_check_modules(PC_SSH libssh>=0.6 QUIET) endif() find_path(SSH_INCLUDE_DIR NAMES libssh/libssh.h
View file
_service:download_files:master.tar.gz/system/shaders/GL/4.0/gl_yuv2rgb_filter4.glsl
Changed
@@ -111,7 +111,7 @@ rgb.a = m_alpha; #if defined(XBMC_COL_CONVERSION) - rgb.rgb = pow(rgb.rgb, vec3(m_gammaSrc)); + rgb.rgb = pow(max(vec3(0), rgb.rgb), vec3(m_gammaSrc)); rgb.rgb = max(vec3(0), m_primMat * rgb.rgb); rgb.rgb = pow(rgb.rgb, vec3(m_gammaDstInv));
View file
_service:download_files:master.tar.gz/xbmc/Application.cpp
Changed
@@ -126,6 +126,7 @@ #include "peripherals/Peripherals.h" #include "peripherals/devices/PeripheralImon.h" #include "music/infoscanner/MusicInfoScanner.h" +#include "music/MusicUtils.h" // Windows includes #include "guilib/GUIWindowManager.h" @@ -1977,69 +1978,87 @@ return true; } - if ((action.GetID() == ACTION_INCREASE_RATING || action.GetID() == ACTION_DECREASE_RATING) && m_appPlayer.IsPlayingAudio()) + if ((action.GetID() == ACTION_SET_RATING) && m_appPlayer.IsPlayingAudio()) { - const CMusicInfoTag *tag = g_infoManager.GetCurrentSongTag(); - if (tag) + int userrating = MUSIC_UTILS::ShowSelectRatingDialog(m_itemCurrentFile->GetMusicInfoTag()->GetUserrating()); + if (userrating < 0) // Nothing selected, so user rating unchanged + return true; + userrating = std::min(userrating, 10); + if (userrating != m_itemCurrentFile->GetMusicInfoTag()->GetUserrating()) { - *m_itemCurrentFile->GetMusicInfoTag() = *tag; - int userrating = tag->GetUserrating(); - bool needsUpdate(false); - if (userrating > 0 && action.GetID() == ACTION_DECREASE_RATING) - { - m_itemCurrentFile->GetMusicInfoTag()->SetUserrating(userrating - 1); - needsUpdate = true; - } - else if (userrating < 10 && action.GetID() == ACTION_INCREASE_RATING) - { - m_itemCurrentFile->GetMusicInfoTag()->SetUserrating(userrating + 1); - needsUpdate = true; - } - if (needsUpdate) - { - CMusicDatabase db; - if (db.Open()) // OpenForWrite() ? - { - db.SetSongUserrating(m_itemCurrentFile->GetPath(), m_itemCurrentFile->GetMusicInfoTag()->GetUserrating()); - db.Close(); - } - // send a message to all windows to tell them to update the fileitem (eg playlistplayer, media windows) - CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE_ITEM, 0, m_itemCurrentFile); - g_windowManager.SendMessage(msg); - } + m_itemCurrentFile->GetMusicInfoTag()->SetUserrating(userrating); + // Mirror changes to GUI item + g_infoManager.SetCurrentItem(*m_itemCurrentFile); + + // Asynchronously update song userrating in music library + MUSIC_UTILS::UpdateSongRatingJob(m_itemCurrentFile, userrating); + + // Tell all windows (e.g. playlistplayer, media windows) to update the fileitem + CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE_ITEM, 0, m_itemCurrentFile); + g_windowManager.SendMessage(msg); + } + return true; + } + + else if ((action.GetID() == ACTION_INCREASE_RATING || action.GetID() == ACTION_DECREASE_RATING) && m_appPlayer.IsPlayingAudio()) + { + int userrating = m_itemCurrentFile->GetMusicInfoTag()->GetUserrating(); + bool needsUpdate(false); + if (userrating > 0 && action.GetID() == ACTION_DECREASE_RATING) + { + m_itemCurrentFile->GetMusicInfoTag()->SetUserrating(userrating - 1); + needsUpdate = true; + } + else if (userrating < 10 && action.GetID() == ACTION_INCREASE_RATING) + { + m_itemCurrentFile->GetMusicInfoTag()->SetUserrating(userrating + 1); + needsUpdate = true; } + if (needsUpdate) + { + // Mirror changes to current GUI item + g_infoManager.SetCurrentItem(*m_itemCurrentFile); + + // Asynchronously update song userrating in music library + MUSIC_UTILS::UpdateSongRatingJob(m_itemCurrentFile, m_itemCurrentFile->GetMusicInfoTag()->GetUserrating()); + + // send a message to all windows to tell them to update the fileitem (eg playlistplayer, media windows) + CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE_ITEM, 0, m_itemCurrentFile); + g_windowManager.SendMessage(msg); + } + return true; } else if ((action.GetID() == ACTION_INCREASE_RATING || action.GetID() == ACTION_DECREASE_RATING) && m_appPlayer.IsPlayingVideo()) { - const CVideoInfoTag *tag = g_infoManager.GetCurrentMovieTag(); - if (tag) + int rating = m_itemCurrentFile->GetVideoInfoTag()->m_iUserRating; + bool needsUpdate(false); + if (rating > 1 && action.GetID() == ACTION_DECREASE_RATING) { - *m_itemCurrentFile->GetVideoInfoTag() = *tag; - int rating = tag->m_iUserRating; - bool needsUpdate(false); - if (rating > 1 && action.GetID() == ACTION_DECREASE_RATING) - { - m_itemCurrentFile->GetVideoInfoTag()->m_iUserRating = rating - 1; - needsUpdate = true; - } - else if (rating < 10 && action.GetID() == ACTION_INCREASE_RATING) - { - m_itemCurrentFile->GetVideoInfoTag()->m_iUserRating = rating + 1; - needsUpdate = true; - } - if (needsUpdate) + m_itemCurrentFile->GetVideoInfoTag()->m_iUserRating = rating - 1; + needsUpdate = true; + } + else if (rating < 10 && action.GetID() == ACTION_INCREASE_RATING) + { + m_itemCurrentFile->GetVideoInfoTag()->m_iUserRating = rating + 1; + needsUpdate = true; + } + if (needsUpdate) + { + // Mirror changes to GUI item + g_infoManager.SetCurrentItem(*m_itemCurrentFile); + + CVideoDatabase db; + if (db.Open()) { - CVideoDatabase db; - if (db.Open()) - { - db.SetVideoUserRating(m_itemCurrentFile->GetVideoInfoTag()->m_iDbId, m_itemCurrentFile->GetVideoInfoTag()->m_iUserRating, m_itemCurrentFile->GetVideoInfoTag()->m_type); - db.Close(); - } - // send a message to all windows to tell them to update the fileitem (eg playlistplayer, media windows) - CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE_ITEM, 0, m_itemCurrentFile); - g_windowManager.SendMessage(msg); + db.SetVideoUserRating(m_itemCurrentFile->GetVideoInfoTag()->m_iDbId, + m_itemCurrentFile->GetVideoInfoTag()->m_iUserRating, + m_itemCurrentFile->GetVideoInfoTag()->m_type); + db.Close(); } + // send a message to all windows to tell them to update the fileitem (eg playlistplayer, media windows) + CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE_ITEM, 0, m_itemCurrentFile); + g_windowManager.SendMessage(msg); } return true; } @@ -3850,6 +3869,15 @@ m_bInitializing = false; } + else if (message.GetParam1() == GUI_MSG_UPDATE_ITEM && message.GetItem()) + { + CFileItemPtr item = std::static_pointer_cast<CFileItem>(message.GetItem()); + if (m_itemCurrentFile->IsSamePath(item.get())) + { + m_itemCurrentFile->UpdateInfo(*item); + g_infoManager.SetCurrentItem(*m_itemCurrentFile); + } + } } break;
View file
_service:download_files:master.tar.gz/xbmc/FileItem.cpp
Changed
@@ -1506,6 +1506,12 @@ return (item->GetProperty("item_start") == GetProperty("item_start")); return true; } + if (HasMusicInfoTag() && item->HasMusicInfoTag()) + { + if (GetMusicInfoTag()->GetDatabaseId() != -1 && item->GetMusicInfoTag()->GetDatabaseId() != -1) + return ((GetMusicInfoTag()->GetDatabaseId() == item->GetMusicInfoTag()->GetDatabaseId()) && + (GetMusicInfoTag()->GetType() == item->GetMusicInfoTag()->GetType())); + } if (HasVideoInfoTag() && item->HasVideoInfoTag()) { if (GetVideoInfoTag()->m_iDbId != -1 && item->GetVideoInfoTag()->m_iDbId != -1) @@ -1600,8 +1606,8 @@ SetLabel(item.GetLabel()); if (replaceLabels && !item.GetLabel2().empty()) SetLabel2(item.GetLabel2()); - if (!item.GetArt("thumb").empty()) - SetArt("thumb", item.GetArt("thumb")); + if (!item.GetArt().empty()) + SetArt(item.GetArt()); if (!item.GetIconImage().empty()) SetIconImage(item.GetIconImage()); AppendProperties(item);
View file
_service:download_files:master.tar.gz/xbmc/GUIInfoManager.cpp
Changed
@@ -89,6 +89,7 @@ #include "utils/log.h" #include "pvr/PVRGUIActions.h" +#include "pvr/PVRItem.h" #include "pvr/PVRManager.h" #include "pvr/channels/PVRChannelGroupsContainer.h" #include "pvr/channels/PVRRadioRDSInfoTag.h" @@ -178,18 +179,6 @@ bool CGUIInfoManager::OnMessage(CGUIMessage &message) { - if (message.GetMessage() == GUI_MSG_NOTIFY_ALL) - { - if (message.GetParam1() == GUI_MSG_UPDATE_ITEM && message.GetItem()) - { - CFileItemPtr item = std::static_pointer_cast<CFileItem>(message.GetItem()); - if (m_currentFile->IsSamePath(item.get())) - { - m_currentFile->UpdateInfo(*item); - return true; - } - } - } return false; } @@ -5953,6 +5942,16 @@ return TIME_FORMAT_GUESS; } +std::string CGUIInfoManager::GetEpgEventTitle(const CPVREpgInfoTagPtr& epgTag) +{ + if (epgTag) + return epgTag->Title(); + else if (CServiceBroker::GetSettings().GetBool(CSettings::SETTING_EPG_HIDENOINFOAVAILABLE)) + return std::string(); + else + return g_localizeStrings.Get(19055); // no information available +} + std::string CGUIInfoManager::GetLabel(int info, int contextWindow, std::string *fallback) { if (info >= CONDITIONAL_LABEL_START && info <= CONDITIONAL_LABEL_END) @@ -6137,35 +6136,27 @@ strLabel = URIUtils::GetFileName(strLabel); break; case PLAYER_TITLE: + if (m_currentFile) { - if(m_currentFile) + if (m_currentFile->HasPVRRadioRDSInfoTag()) { - if (m_currentFile->HasPVRRadioRDSInfoTag()) - { - /*! Load the RDS Radiotext+ if present */ - if (!m_currentFile->GetPVRRadioRDSInfoTag()->GetTitle().empty()) - return m_currentFile->GetPVRRadioRDSInfoTag()->GetTitle(); - /*! If no plus present load the RDS Radiotext info line 0 if present */ - if (!g_application.GetAppPlayer().GetRadioText(0).empty()) - return g_application.GetAppPlayer().GetRadioText(0); - } - if (m_currentFile->HasPVRChannelInfoTag()) - { - CPVREpgInfoTagPtr tag(m_currentFile->GetPVRChannelInfoTag()->GetEPGNow()); - return tag ? - tag->Title() : - CServiceBroker::GetSettings().GetBool(CSettings::SETTING_EPG_HIDENOINFOAVAILABLE) ? - "" : g_localizeStrings.Get(19055); // no information available - } - if (m_currentFile->HasVideoInfoTag() && !m_currentFile->GetVideoInfoTag()->m_strTitle.empty()) - return m_currentFile->GetVideoInfoTag()->m_strTitle; - if (m_currentFile->HasMusicInfoTag() && !m_currentFile->GetMusicInfoTag()->GetTitle().empty()) - return m_currentFile->GetMusicInfoTag()->GetTitle(); - // don't have the title, so use label or drop down to title from path - if (!m_currentFile->GetLabel().empty()) - return m_currentFile->GetLabel(); - return CUtil::GetTitleFromPath(m_currentFile->GetPath()); + /*! Load the RDS Radiotext+ if present */ + if (!m_currentFile->GetPVRRadioRDSInfoTag()->GetTitle().empty()) + return m_currentFile->GetPVRRadioRDSInfoTag()->GetTitle(); + /*! If no plus present load the RDS Radiotext info line 0 if present */ + if (!g_application.GetAppPlayer().GetRadioText(0).empty()) + return g_application.GetAppPlayer().GetRadioText(0); } + if (m_currentFile->HasPVRChannelInfoTag()) + return GetEpgEventTitle(m_currentFile->GetPVRChannelInfoTag()->GetEPGNow()); + if (m_currentFile->HasVideoInfoTag() && !m_currentFile->GetVideoInfoTag()->m_strTitle.empty()) + return m_currentFile->GetVideoInfoTag()->m_strTitle; + if (m_currentFile->HasMusicInfoTag() && !m_currentFile->GetMusicInfoTag()->GetTitle().empty()) + return m_currentFile->GetMusicInfoTag()->GetTitle(); + // don't have the title, so use label or drop down to title from path + if (!m_currentFile->GetLabel().empty()) + return m_currentFile->GetLabel(); + return CUtil::GetTitleFromPath(m_currentFile->GetPath()); } break; case PLAYER_PLAYSPEED: @@ -7427,15 +7418,16 @@ break; case VIDEOPLAYER_HAS_EPG: if (m_currentFile->HasPVRChannelInfoTag()) - bReturn = (m_currentFile->GetPVRChannelInfoTag()->GetEPGNow().get() != NULL); + bReturn = (m_currentFile->GetPVRChannelInfoTag()->GetEPGNow() != nullptr); break; case VIDEOPLAYER_IS_STEREOSCOPIC: - bReturn = !CServiceBroker::GetDataCacheCore().GetVideoStereoMode().empty(); + bReturn = !CServiceBroker::GetDataCacheCore().GetVideoStereoMode().empty(); break; case VIDEOPLAYER_CAN_RESUME_LIVE_TV: if (m_currentFile->HasPVRRecordingInfoTag()) { - CPVREpgInfoTagPtr epgTag = CServiceBroker::GetPVRManager().EpgContainer().GetTagById(m_currentFile->GetPVRRecordingInfoTag()->Channel(), m_currentFile->GetPVRRecordingInfoTag()->BroadcastUid()); + const CPVRRecordingPtr recording = m_currentFile->GetPVRRecordingInfoTag(); + const CPVREpgInfoTagPtr epgTag = CServiceBroker::GetPVRManager().EpgContainer().GetTagById(recording->Channel(), recording->BroadcastUid()); bReturn = (epgTag && epgTag->IsActive() && epgTag->Channel()); } break; @@ -8497,7 +8489,7 @@ !m_currentFile->HasPVRRadioRDSInfoTag()) return ""; - const PVR::CPVRRadioRDSInfoTag &tag = *m_currentFile->GetPVRRadioRDSInfoTag(); + const CPVRRadioRDSInfoTag &tag = *m_currentFile->GetPVRRadioRDSInfoTag(); switch (item) { case RDS_CHANNEL_COUNTRY: @@ -8602,28 +8594,16 @@ } case RDS_PROG_NOW: - { - if (!tag.GetProgNow().empty()) - return tag.GetProgNow(); + if (!tag.GetProgNow().empty()) + return tag.GetProgNow(); - CPVREpgInfoTagPtr epgNow(m_currentFile->GetPVRChannelInfoTag()->GetEPGNow()); - return epgNow ? - epgNow->Title() : - CServiceBroker::GetSettings().GetBool("epg.hidenoinfoavailable") ? "" : g_localizeStrings.Get(19055); // no information available - break; - } + return GetEpgEventTitle(m_currentFile->GetPVRChannelInfoTag()->GetEPGNow()); case RDS_PROG_NEXT: - { - if (!tag.GetProgNext().empty()) - return tag.GetProgNext(); + if (!tag.GetProgNext().empty()) + return tag.GetProgNext(); - CPVREpgInfoTagPtr epgNext(m_currentFile->GetPVRChannelInfoTag()->GetEPGNext()); - return epgNext ? - epgNext->Title() : - CServiceBroker::GetSettings().GetBool("epg.hidenoinfoavailable") ? "" : g_localizeStrings.Get(19055); // no information available - break; - } + return GetEpgEventTitle(m_currentFile->GetPVRChannelInfoTag()->GetEPGNext()); case RDS_PROG_HOST: return tag.GetProgHost(); @@ -9092,17 +9072,6 @@ else SetCurrentMovie(*item); - if (item->HasPVRRadioRDSInfoTag()) - m_currentFile->SetPVRRadioRDSInfoTag(item->GetPVRRadioRDSInfoTag()); - if (item->HasEPGInfoTag()) - m_currentFile->SetEPGInfoTag(item->GetEPGInfoTag()); - else if (item->HasPVRChannelInfoTag()) - { - CPVREpgInfoTagPtr tag(item->GetPVRChannelInfoTag()->GetEPGNow()); - if (tag) - m_currentFile->SetEPGInfoTag(tag); - } - SetChanged(); NotifyObservers(ObservableMessageCurrentItem); } @@ -9451,18 +9420,13 @@ if (item->IsFileItem()) { const CFileItem *pItem = static_cast<const CFileItem*>(item); - if (pItem && pItem->HasPVRChannelInfoTag()) - { - CPVREpgInfoTagPtr epgNow(pItem->GetPVRChannelInfoTag()->GetEPGNow()); - if (epgNow) - value = (int) epgNow->ProgressPercentage(); - } - else if (pItem && pItem->HasEPGInfoTag()) + if (pItem->IsPVRChannel() || pItem->IsEPG()) { - value = (int) pItem->GetEPGInfoTag()->ProgressPercentage(); + const CPVREpgInfoTagPtr epgTag = CPVRItem(pItem).GetEpgInfoTag(); + if (epgTag) + value = static_cast<int>(epgTag->ProgressPercentage()); } } - return true; } break; @@ -9497,19 +9461,19 @@ return item->GetArt(art); } - if (info >= LISTITEM_PROPERTY_START + LISTITEM_RATING_OFFSET && info - (LISTITEM_PROPERTY_START + LISTITEM_RATING_OFFSET) < (int)m_listitemProperties.size()) + if (info >= LISTITEM_PROPERTY_START + LISTITEM_RATING_OFFSET && info - (LISTITEM_PROPERTY_START + LISTITEM_RATING_OFFSET) < (int)m_listitemProperties.size() && item->HasVideoInfoTag()) { // grab the rating std::string rating = m_listitemProperties[info - (LISTITEM_PROPERTY_START + LISTITEM_RATING_OFFSET)]; return StringUtils::FormatNumber(item->GetVideoInfoTag()->GetRating(rating).rating); } - if (info >= LISTITEM_PROPERTY_START + LISTITEM_VOTES_OFFSET && info - (LISTITEM_PROPERTY_START + LISTITEM_VOTES_OFFSET) < (int)m_listitemProperties.size()) + if (info >= LISTITEM_PROPERTY_START + LISTITEM_VOTES_OFFSET && info - (LISTITEM_PROPERTY_START + LISTITEM_VOTES_OFFSET) < (int)m_listitemProperties.size() && item->HasVideoInfoTag()) { // grab the votes std::string votes = m_listitemProperties[info - (LISTITEM_PROPERTY_START + LISTITEM_VOTES_OFFSET)]; return StringUtils::FormatNumber(item->GetVideoInfoTag()->GetRating(votes).votes); } - if (info >= LISTITEM_PROPERTY_START + LISTITEM_RATING_AND_VOTES_OFFSET && info - (LISTITEM_PROPERTY_START + LISTITEM_RATING_AND_VOTES_OFFSET) < (int)m_listitemProperties.size()) + if (info >= LISTITEM_PROPERTY_START + LISTITEM_RATING_AND_VOTES_OFFSET && info - (LISTITEM_PROPERTY_START + LISTITEM_RATING_AND_VOTES_OFFSET) < (int)m_listitemProperties.size() && item->HasVideoInfoTag()) { // grab the rating and the votes std::string ratingName = m_listitemProperties[info - (LISTITEM_PROPERTY_START + LISTITEM_RATING_AND_VOTES_OFFSET)]; CRating rating = item->GetVideoInfoTag()->GetRating(ratingName); @@ -9545,16 +9509,8 @@ case LISTITEM_LABEL2: return item->GetLabel2(); case LISTITEM_TITLE: - if (item->HasPVRChannelInfoTag()) - { - CPVREpgInfoTagPtr epgTag(item->GetPVRChannelInfoTag()->GetEPGNow()); - return epgTag ? - epgTag->Title() : - CServiceBroker::GetSettings().GetBool(CSettings::SETTING_EPG_HIDENOINFOAVAILABLE) ? - "" : g_localizeStrings.Get(19055); // no information available - } - if (item->HasEPGInfoTag()) - return item->GetEPGInfoTag()->Title(); + if (item->IsPVRChannel() || item->IsEPG()) + return GetEpgEventTitle(CPVRItem(item).GetEpgInfoTag()); if (item->HasPVRTimerInfoTag()) return item->GetPVRTimerInfoTag()->Title(); if (item->HasVideoInfoTag()) @@ -9563,33 +9519,17 @@ return item->GetMusicInfoTag()->GetTitle(); break; case LISTITEM_EPG_EVENT_TITLE: - if (item->HasEPGInfoTag()) - return item->GetEPGInfoTag()->Title(); - if (item->HasPVRTimerInfoTag()) + if (item->IsPVRChannel() || item->IsEPG() || item->IsPVRTimer()) { - const CPVREpgInfoTagPtr epgTag(item->GetPVRTimerInfoTag()->GetEpgInfoTag()); - if (epgTag) - return epgTag->Title(); - } - if (item->HasPVRChannelInfoTag()) - { - CPVREpgInfoTagPtr epgTag(item->GetPVRChannelInfoTag()->GetEPGNow()); + const CPVREpgInfoTagPtr epgTag = CPVRItem(item).GetEpgInfoTag(); if (epgTag) return epgTag->Title(); } break; case LISTITEM_ORIGINALTITLE: - if (item->HasPVRChannelInfoTag()) + if (item->IsPVRChannel() || item->IsEPG() || item->IsPVRTimer()) { - CPVREpgInfoTagPtr tag(item->GetPVRChannelInfoTag()->GetEPGNow()); - if (tag) - return tag->OriginalTitle(); - } - if (item->HasEPGInfoTag()) - return item->GetEPGInfoTag()->OriginalTitle(); - if (item->HasPVRTimerInfoTag()) - { - const CPVREpgInfoTagPtr epgTag(item->GetPVRTimerInfoTag()->GetEpgInfoTag()); + const CPVREpgInfoTagPtr epgTag = CPVRItem(item).GetEpgInfoTag(); if (epgTag) return epgTag->OriginalTitle(); } @@ -9651,17 +9591,9 @@ return item->GetMusicInfoTag()->GetContributorsAndRolesText(); break; case LISTITEM_DIRECTOR: - if (item->HasPVRChannelInfoTag()) + if (item->IsPVRChannel() || item->IsEPG() || item->IsPVRTimer()) { - CPVREpgInfoTagPtr tag(item->GetPVRChannelInfoTag()->GetEPGNow()); - if (tag) - return tag->GetDirectorsLabel(); - } - if (item->HasEPGInfoTag()) - return item->GetEPGInfoTag()->GetDirectorsLabel(); - if (item->HasPVRTimerInfoTag()) - { - const CPVREpgInfoTagPtr epgTag(item->GetPVRTimerInfoTag()->GetEpgInfoTag()); + const CPVREpgInfoTagPtr epgTag = CPVRItem(item).GetEpgInfoTag(); if (epgTag) return epgTag->GetDirectorsLabel(); } @@ -9677,21 +9609,25 @@ case LISTITEM_YEAR: { std::string year; + if (item->IsPVRChannel() || item->IsEPG() || item->IsPVRTimer()) + { + const CPVREpgInfoTagPtr epgTag = CPVRItem(item).GetEpgInfoTag(); + if (epgTag && epgTag->Year() > 0) + year = StringUtils::Format("%i", epgTag->Year()); + } if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->HasYear()) year = StringUtils::Format("%i", item->GetVideoInfoTag()->GetYear()); if (item->HasMusicInfoTag()) year = item->GetMusicInfoTag()->GetYearString(); - if (item->HasEPGInfoTag() && item->GetEPGInfoTag()->Year() > 0) - year = StringUtils::Format("%i", item->GetEPGInfoTag()->Year()); - if (item->HasPVRTimerInfoTag()) - { - const CPVREpgInfoTagPtr tag(item->GetPVRTimerInfoTag()->GetEpgInfoTag()); - if (tag && tag->Year() > 0) - year = StringUtils::Format("%i", tag->Year()); - } return year; } case LISTITEM_PREMIERED: + if (item->IsPVRChannel() || item->IsEPG() || item->IsPVRTimer()) + { + const CPVREpgInfoTagPtr epgTag = CPVRItem(item).GetEpgInfoTag(); + if (epgTag && epgTag->FirstAiredAsLocalTime().IsValid()) + return epgTag->FirstAiredAsLocalTime().GetAsLocalizedDate(true); + } if (item->HasVideoInfoTag()) { CDateTime dateTime; @@ -9703,29 +9639,11 @@ if (dateTime.IsValid()) return dateTime.GetAsLocalizedDate(); } - else if (item->HasEPGInfoTag()) - { - if (item->GetEPGInfoTag()->FirstAiredAsLocalTime().IsValid()) - return item->GetEPGInfoTag()->FirstAiredAsLocalTime().GetAsLocalizedDate(true); - } - else if (item->HasPVRTimerInfoTag()) - { - const CPVREpgInfoTagPtr tag(item->GetPVRTimerInfoTag()->GetEpgInfoTag()); - if (tag && tag->FirstAiredAsLocalTime().IsValid()) - return tag->FirstAiredAsLocalTime().GetAsLocalizedDate(true); - } break; case LISTITEM_GENRE: - if (item->HasPVRChannelInfoTag()) + if (item->IsPVRChannel() || item->IsEPG() || item->IsPVRTimer()) { - CPVREpgInfoTagPtr epgTag(item->GetPVRChannelInfoTag()->GetEPGNow()); - return epgTag ? epgTag->GetGenresLabel() : ""; - } - if (item->HasEPGInfoTag()) - return item->GetEPGInfoTag()->GetGenresLabel(); - if (item->HasPVRTimerInfoTag()) - { - const CPVREpgInfoTagPtr epgTag(item->GetPVRTimerInfoTag()->GetEpgInfoTag()); + const CPVREpgInfoTagPtr epgTag = CPVRItem(item).GetEpgInfoTag(); if (epgTag) return epgTag->GetGenresLabel(); } @@ -9754,12 +9672,13 @@ } break; case LISTITEM_DATE: - if (item->HasEPGInfoTag()) - return item->GetEPGInfoTag()->StartAsLocalTime().GetAsLocalizedDateTime(false, false); - if (item->HasPVRChannelInfoTag()) + if (item->IsPVRChannel() || item->IsEPG()) { - CPVREpgInfoTagPtr epgTag(item->GetPVRChannelInfoTag()->GetEPGNow()); - return epgTag ? epgTag->StartAsLocalTime().GetAsLocalizedDateTime(false, false) : CDateTime::GetCurrentDateTime().GetAsLocalizedDateTime(false, false); + const CPVREpgInfoTagPtr epgTag = CPVRItem(item).GetEpgInfoTag(); + if (epgTag) + return epgTag->StartAsLocalTime().GetAsLocalizedDateTime(false, false); + else + return CDateTime::GetCurrentDateTime().GetAsLocalizedDateTime(false, false); } if (item->HasPVRRecordingInfoTag()) return item->GetPVRRecordingInfoTag()->RecordingTimeAsLocalTime().GetAsLocalizedDateTime(false, false); @@ -9837,21 +9756,13 @@ case LISTITEM_DURATION: { std::string duration; - if (item->HasPVRChannelInfoTag()) - { - CPVREpgInfoTagPtr tag(item->GetPVRChannelInfoTag()->GetEPGNow()); - return tag ? StringUtils::SecondsToTimeString(tag->GetDuration()) : ""; - } - else if (item->HasEPGInfoTag()) - { - if (item->GetEPGInfoTag()->GetDuration() > 0) - duration = StringUtils::SecondsToTimeString(item->GetEPGInfoTag()->GetDuration()); - } - else if (item->HasPVRTimerInfoTag()) + if (item->IsPVRChannel() || item->IsEPG() || item->IsPVRTimer()) { - const CPVREpgInfoTagPtr tag(item->GetPVRTimerInfoTag()->GetEpgInfoTag()); - if (tag && tag->GetDuration() > 0) - duration = StringUtils::SecondsToTimeString(tag->GetDuration()); + const CPVREpgInfoTagPtr epgTag = CPVRItem(item).GetEpgInfoTag(); + if (epgTag) + return StringUtils::SecondsToTimeString(epgTag->GetDuration()); + else + return std::string(); } else if (item->HasVideoInfoTag()) { @@ -9871,18 +9782,13 @@ return duration; } case LISTITEM_PLOT: - if (item->HasPVRChannelInfoTag()) + if (item->IsPVRChannel() || item->IsEPG() || item->IsPVRTimer()) { - CPVREpgInfoTagPtr tag(item->GetPVRChannelInfoTag()->GetEPGNow()); - return tag ? tag->Plot() : ""; - } - if (item->HasEPGInfoTag()) - return item->GetEPGInfoTag()->Plot(); - if (item->HasPVRTimerInfoTag()) - { - const CPVREpgInfoTagPtr epgTag(item->GetPVRTimerInfoTag()->GetEpgInfoTag()); + const CPVREpgInfoTagPtr epgTag = CPVRItem(item).GetEpgInfoTag(); if (epgTag) return epgTag->Plot(); + else + return std::string(); } if (item->HasVideoInfoTag()) { @@ -9894,18 +9800,13 @@ } break; case LISTITEM_PLOT_OUTLINE: - if (item->HasPVRChannelInfoTag()) + if (item->IsPVRChannel() || item->IsEPG() || item->IsPVRTimer()) { - CPVREpgInfoTagPtr tag(item->GetPVRChannelInfoTag()->GetEPGNow()); - return tag ? tag->PlotOutline() : ""; - } - if (item->HasEPGInfoTag()) - return item->GetEPGInfoTag()->PlotOutline(); - if (item->HasPVRTimerInfoTag()) - { - const CPVREpgInfoTagPtr epgTag(item->GetPVRTimerInfoTag()->GetEpgInfoTag()); + const CPVREpgInfoTagPtr epgTag = CPVRItem(item).GetEpgInfoTag(); if (epgTag) return epgTag->PlotOutline(); + else + return std::string(); } if (item->HasVideoInfoTag()) return item->GetVideoInfoTag()->m_strPlotOutline; @@ -9913,28 +9814,13 @@ case LISTITEM_EPISODE: { int iSeason = -1, iEpisode = -1; - if (item->HasPVRChannelInfoTag()) + if (item->IsPVRChannel() || item->IsEPG() || item->IsPVRTimer()) { - CPVREpgInfoTagPtr tag(item->GetPVRChannelInfoTag()->GetEPGNow()); - if (tag && tag->EpisodeNumber() > 0) + const CPVREpgInfoTagPtr epgTag = CPVRItem(item).GetEpgInfoTag(); + if (epgTag && epgTag->EpisodeNumber() > 0) { - iEpisode = tag->EpisodeNumber(); - iSeason = tag->SeriesNumber(); - } - } - else if (item->HasEPGInfoTag() && - item->GetEPGInfoTag()->EpisodeNumber() > 0) - { - iSeason = item->GetEPGInfoTag()->SeriesNumber(); - iEpisode = item->GetEPGInfoTag()->EpisodeNumber(); - } - else if (item->HasPVRTimerInfoTag()) - { - const CPVREpgInfoTagPtr tag(item->GetPVRTimerInfoTag()->GetEpgInfoTag()); - if (tag && tag->EpisodeNumber() > 0) - { - iSeason = tag->SeriesNumber(); - iEpisode = tag->EpisodeNumber(); + iEpisode = epgTag->EpisodeNumber(); + iSeason = epgTag->SeriesNumber(); } } else if (item->HasVideoInfoTag() && @@ -9956,18 +9842,9 @@ case LISTITEM_SEASON: { int iSeason = -1; - if (item->HasPVRChannelInfoTag()) + if (item->IsPVRChannel() || item->IsEPG() || item->IsPVRTimer()) { - CPVREpgInfoTagPtr tag(item->GetPVRChannelInfoTag()->GetEPGNow()); - if (tag && tag->SeriesNumber() > 0) - iSeason = tag->SeriesNumber(); - } - else if (item->HasEPGInfoTag() && - item->GetEPGInfoTag()->SeriesNumber() > 0) - iSeason = item->GetEPGInfoTag()->SeriesNumber(); - else if (item->HasPVRTimerInfoTag()) - { - const CPVREpgInfoTagPtr epgTag(item->GetPVRTimerInfoTag()->GetEpgInfoTag()); + const CPVREpgInfoTagPtr epgTag = CPVRItem(item).GetEpgInfoTag(); if (epgTag && epgTag->SeriesNumber() > 0) iSeason = epgTag->SeriesNumber(); } @@ -10062,20 +9939,28 @@ return item->GetVideoInfoTag()->m_strMPAARating; break; case LISTITEM_CAST: + if (item->IsPVRChannel() || item->IsEPG()) + { + const CPVREpgInfoTagPtr epgTag = CPVRItem(item).GetEpgInfoTag(); + if (epgTag) + return epgTag->GetCastLabel(); + } if (item->HasVideoInfoTag()) return item->GetVideoInfoTag()->GetCast(); - if (item->HasEPGInfoTag()) - return item->GetEPGInfoTag()->GetCastLabel(); break; case LISTITEM_CAST_AND_ROLE: if (item->HasVideoInfoTag()) return item->GetVideoInfoTag()->GetCast(true); break; case LISTITEM_WRITER: + if (item->IsPVRChannel() || item->IsEPG()) + { + const CPVREpgInfoTagPtr epgTag = CPVRItem(item).GetEpgInfoTag(); + if (epgTag) + return epgTag->GetWritersLabel(); + } if (item->HasVideoInfoTag()) return StringUtils::Join(item->GetVideoInfoTag()->m_writingCredits, g_advancedSettings.m_videoItemSeparator); - if (item->HasEPGInfoTag()) - return item->GetEPGInfoTag()->GetWritersLabel(); break; case LISTITEM_TAGLINE: if (item->HasVideoInfoTag()) @@ -10160,14 +10045,12 @@ return item->GetVideoInfoTag()->m_streamDetails.GetSubtitleLanguage(); break; case LISTITEM_STARTTIME: - if (item->HasPVRChannelInfoTag()) + if (item->IsPVRChannel() || item->IsEPG()) { - CPVREpgInfoTagPtr tag(item->GetPVRChannelInfoTag()->GetEPGNow()); - if (tag) - return tag->StartAsLocalTime().GetAsLocalizedTime("", false); + const CPVREpgInfoTagPtr epgTag = CPVRItem(item).GetEpgInfoTag(); + if (epgTag) + return epgTag->StartAsLocalTime().GetAsLocalizedTime("", false); } - if (item->HasEPGInfoTag()) - return item->GetEPGInfoTag()->StartAsLocalTime().GetAsLocalizedTime("", false); if (item->HasPVRTimerInfoTag()) return item->GetPVRTimerInfoTag()->StartAsLocalTime().GetAsLocalizedTime("", false); if (item->HasPVRRecordingInfoTag()) @@ -10178,20 +10061,18 @@ case LISTITEM_ENDTIME_RESUME: if (item->HasVideoInfoTag()) { - auto* tag = item->GetVideoInfoTag(); + const CVideoInfoTag* tag = item->GetVideoInfoTag(); CDateTimeSpan duration(0, 0, 0, tag->GetDuration() - tag->GetResumePoint().timeInSeconds); return (CDateTime::GetCurrentDateTime() + duration).GetAsLocalizedTime("", false); } break; case LISTITEM_ENDTIME: - if (item->HasPVRChannelInfoTag()) + if (item->IsPVRChannel() || item->IsEPG()) { - CPVREpgInfoTagPtr tag(item->GetPVRChannelInfoTag()->GetEPGNow()); - if (tag) - return tag->EndAsLocalTime().GetAsLocalizedTime("", false); + const CPVREpgInfoTagPtr epgTag = CPVRItem(item).GetEpgInfoTag(); + if (epgTag) + return epgTag->EndAsLocalTime().GetAsLocalizedTime("", false); } - else if (item->HasEPGInfoTag()) - return item->GetEPGInfoTag()->EndAsLocalTime().GetAsLocalizedTime("", false); else if (item->HasPVRTimerInfoTag()) return item->GetPVRTimerInfoTag()->EndAsLocalTime().GetAsLocalizedTime("", false); else if (item->HasPVRRecordingInfoTag()) @@ -10203,14 +10084,12 @@ } break; case LISTITEM_STARTDATE: - if (item->HasPVRChannelInfoTag()) + if (item->IsPVRChannel() || item->IsEPG()) { - CPVREpgInfoTagPtr tag(item->GetPVRChannelInfoTag()->GetEPGNow()); - if (tag) - return tag->StartAsLocalTime().GetAsLocalizedDate(true); + const CPVREpgInfoTagPtr epgTag = CPVRItem(item).GetEpgInfoTag(); + if (epgTag) + return epgTag->StartAsLocalTime().GetAsLocalizedDate(true); } - if (item->HasEPGInfoTag()) - return item->GetEPGInfoTag()->StartAsLocalTime().GetAsLocalizedDate(true); if (item->HasPVRTimerInfoTag()) return item->GetPVRTimerInfoTag()->StartAsLocalTime().GetAsLocalizedDate(true); if (item->HasPVRRecordingInfoTag()) @@ -10219,14 +10098,12 @@ return item->m_dateTime.GetAsLocalizedDate(true); break; case LISTITEM_ENDDATE: - if (item->HasPVRChannelInfoTag()) + if (item->IsPVRChannel() || item->IsEPG()) { - CPVREpgInfoTagPtr tag(item->GetPVRChannelInfoTag()->GetEPGNow()); - if (tag) - return tag->EndAsLocalTime().GetAsLocalizedDate(true); + const CPVREpgInfoTagPtr epgTag = CPVRItem(item).GetEpgInfoTag(); + if (epgTag) + return epgTag->EndAsLocalTime().GetAsLocalizedDate(true); } - if (item->HasEPGInfoTag()) - return item->GetEPGInfoTag()->EndAsLocalTime().GetAsLocalizedDate(true); if (item->HasPVRTimerInfoTag()) return item->GetPVRTimerInfoTag()->EndAsLocalTime().GetAsLocalizedDate(true); break; @@ -10239,23 +10116,20 @@ return item->GetPVRRecordingInfoTag()->ExpirationTimeAsLocalTime().GetAsLocalizedTime("", false);; break; case LISTITEM_CHANNEL_NUMBER: + if (item->IsPVRChannel() || item->IsEPG() || item->IsPVRTimer()) { - CPVRChannelPtr channel; - if (item->HasPVRChannelInfoTag()) - channel = item->GetPVRChannelInfoTag(); - else if (item->HasEPGInfoTag() && item->GetEPGInfoTag()->HasChannel()) - channel = item->GetEPGInfoTag()->Channel(); - else if (item->HasPVRTimerInfoTag()) - channel = item->GetPVRTimerInfoTag()->Channel(); - - return channel ? channel->ChannelNumber().FormattedChannelNumber() : ""; + const CPVRChannelPtr channel = CPVRItem(item).GetChannel(); + if (channel) + return channel->ChannelNumber().FormattedChannelNumber(); } break; case LISTITEM_CHANNEL_NAME: - if (item->HasPVRChannelInfoTag()) - return item->GetPVRChannelInfoTag()->ChannelName(); - if (item->HasEPGInfoTag() && item->GetEPGInfoTag()->HasChannel()) - return item->GetEPGInfoTag()->Channel()->ChannelName(); + if (item->IsPVRChannel() || item->IsEPG()) + { + const CPVRChannelPtr channel = CPVRItem(item).GetChannel(); + if (channel) + return channel->ChannelName(); + } if (item->HasPVRRecordingInfoTag()) return item->GetPVRRecordingInfoTag()->m_strChannelName; if (item->HasPVRTimerInfoTag()) @@ -10336,8 +10210,12 @@ case LISTITEM_PARENTALRATING: { std::string rating; - if (item->HasEPGInfoTag() && item->GetEPGInfoTag()->ParentalRating() > 0) - rating = StringUtils::Format("%i", item->GetEPGInfoTag()->ParentalRating()); + if (item->IsPVRChannel() || item->IsEPG()) + { + const CPVREpgInfoTagPtr epgTag = CPVRItem(item).GetEpgInfoTag(); + if (epgTag && epgTag->ParentalRating() > 0) + rating = StringUtils::Format("%i", epgTag->ParentalRating()); + } return rating; } break; @@ -10362,17 +10240,17 @@ break; case LISTITEM_DBID: if (item->HasVideoInfoTag()) - { - int dbId = item->GetVideoInfoTag()->m_iDbId; - if (dbId > -1) - return StringUtils::Format("%i", dbId); - } + { + int dbId = item->GetVideoInfoTag()->m_iDbId; + if (dbId > -1) + return StringUtils::Format("%i", dbId); + } if (item->HasMusicInfoTag()) - { - int dbId = item->GetMusicInfoTag()->GetDatabaseId(); - if (dbId > -1) - return StringUtils::Format("%i", dbId); - } + { + int dbId = item->GetMusicInfoTag()->GetDatabaseId(); + if (dbId > -1) + return StringUtils::Format("%i", dbId); + } break; case LISTITEM_APPEARANCES: if (item->HasVideoInfoTag()) @@ -10390,44 +10268,28 @@ return stereoMode; } case LISTITEM_IMDBNUMBER: + if (item->IsPVRChannel() || item->IsEPG()) { - if (item->HasPVRChannelInfoTag()) - { - CPVREpgInfoTagPtr tag(item->GetPVRChannelInfoTag()->GetEPGNow()); - if (tag) - return tag->IMDBNumber(); - } - if (item->HasEPGInfoTag()) - return item->GetEPGInfoTag()->IMDBNumber(); - if (item->HasVideoInfoTag()) - return item->GetVideoInfoTag()->GetUniqueID(); - break; + const CPVREpgInfoTagPtr epgTag = CPVRItem(item).GetEpgInfoTag(); + if (epgTag) + return epgTag->IMDBNumber(); } + if (item->HasVideoInfoTag()) + return item->GetVideoInfoTag()->GetUniqueID(); + break; case LISTITEM_EPISODENAME: + if (item->IsPVRChannel() || item->IsEPG() || item->IsPVRTimer()) { - if (item->HasPVRChannelInfoTag()) - { - CPVREpgInfoTagPtr tag(item->GetPVRChannelInfoTag()->GetEPGNow()); - if (tag) - return tag->EpisodeName(); - } - if (item->HasEPGInfoTag()) - return item->GetEPGInfoTag()->EpisodeName(); - if (item->HasPVRTimerInfoTag()) - { - const CPVREpgInfoTagPtr epgTag(item->GetPVRTimerInfoTag()->GetEpgInfoTag()); - if (epgTag) - return epgTag->EpisodeName(); - } - if (item->HasPVRRecordingInfoTag()) - return item->GetPVRRecordingInfoTag()->EpisodeName(); - break; + const CPVREpgInfoTagPtr epgTag = CPVRItem(item).GetEpgInfoTag(); + if (epgTag) + return epgTag->EpisodeName(); } + if (item->HasPVRRecordingInfoTag()) + return item->GetPVRRecordingInfoTag()->EpisodeName(); + break; case LISTITEM_TIMERTYPE: - { - if (item->HasPVRTimerInfoTag()) - return item->GetPVRTimerInfoTag()->GetTypeAsString(); - } + if (item->HasPVRTimerInfoTag()) + return item->GetPVRTimerInfoTag()->GetTypeAsString(); break; case LISTITEM_ADDON_NAME: if (item->HasAddonInfo()) @@ -10553,22 +10415,13 @@ const CFileItem *pItem = static_cast<const CFileItem*>(item); if (condition == LISTITEM_ISRECORDING) { - if (!CServiceBroker::GetPVRManager().IsStarted()) - return false; - if (pItem->HasPVRChannelInfoTag()) { return pItem->GetPVRChannelInfoTag()->IsRecording(); } - else if (pItem->HasPVRTimerInfoTag()) - { - const CPVRTimerInfoTagPtr timer = pItem->GetPVRTimerInfoTag(); - if (timer) - return timer->IsRecording(); - } - else if (pItem->HasEPGInfoTag()) + else if (pItem->IsEPG() || pItem->IsPVRTimer()) { - const CPVRTimerInfoTagPtr timer = pItem->GetEPGInfoTag()->Timer(); + const CPVRTimerInfoTagPtr timer = CPVRItem(pItem).GetTimerInfoTag(); if (timer) return timer->IsRecording(); } @@ -10579,85 +10432,82 @@ } else if (condition == LISTITEM_INPROGRESS) { - if (!CServiceBroker::GetPVRManager().IsStarted()) - return false; - - if (pItem->HasEPGInfoTag()) - return pItem->GetEPGInfoTag()->IsActive(); + if (pItem->IsPVRChannel() || pItem->IsEPG()) + { + const CPVREpgInfoTagPtr epgTag = CPVRItem(pItem).GetEpgInfoTag(); + if (epgTag) + return epgTag->IsActive(); + } } else if (condition == LISTITEM_HASTIMER) { - if (pItem->HasEPGInfoTag()) - return pItem->GetEPGInfoTag()->HasTimer(); + if (pItem->IsPVRChannel() || pItem->IsEPG()) + { + const CPVREpgInfoTagPtr epgTag = CPVRItem(pItem).GetEpgInfoTag(); + if (epgTag) + return epgTag->HasTimer(); + } } else if (condition == LISTITEM_HASTIMERSCHEDULE) { - if (pItem->HasPVRTimerInfoTag()) - { - return pItem->GetPVRTimerInfoTag()->GetTimerRuleId() != PVR_TIMER_NO_PARENT; - } - else if (pItem->HasEPGInfoTag()) + if (pItem->IsPVRChannel() || pItem->IsEPG() || pItem->IsPVRTimer()) { - CPVRTimerInfoTagPtr timer = pItem->GetEPGInfoTag()->Timer(); + const CPVRTimerInfoTagPtr timer = CPVRItem(pItem).GetTimerInfoTag(); if (timer) return timer->GetTimerRuleId() != PVR_TIMER_NO_PARENT; } } else if (condition == LISTITEM_TIMERISACTIVE) { - if (pItem->HasEPGInfoTag()) + if (pItem->IsPVRChannel() || pItem->IsEPG()) { - CPVRTimerInfoTagPtr timer = pItem->GetEPGInfoTag()->Timer(); + const CPVRTimerInfoTagPtr timer = CPVRItem(pItem).GetTimerInfoTag(); if (timer) return timer->IsActive(); } } else if (condition == LISTITEM_TIMERHASCONFLICT) { - if (pItem->HasEPGInfoTag()) + if (pItem->IsPVRChannel() || pItem->IsEPG()) { - CPVRTimerInfoTagPtr timer = pItem->GetEPGInfoTag()->Timer(); + const CPVRTimerInfoTagPtr timer = CPVRItem(pItem).GetTimerInfoTag(); if (timer) return timer->HasConflict(); } } else if (condition == LISTITEM_TIMERHASERROR) { - if (pItem->HasEPGInfoTag()) + if (pItem->IsPVRChannel() || pItem->IsEPG()) { - CPVRTimerInfoTagPtr timer = pItem->GetEPGInfoTag()->Timer(); + const CPVRTimerInfoTagPtr timer = CPVRItem(pItem).GetTimerInfoTag(); if (timer) return (timer->IsBroken() && !timer->HasConflict()); } } else if (condition == LISTITEM_HASRECORDING) { - return pItem->HasEPGInfoTag() && pItem->GetEPGInfoTag()->HasRecording(); + if (pItem->IsPVRChannel() || pItem->IsEPG()) + { + const CPVREpgInfoTagPtr epgTag = CPVRItem(pItem).GetEpgInfoTag(); + if (epgTag) + return epgTag->HasRecording(); + } } else if (condition == LISTITEM_HAS_EPG) { - if (pItem->HasPVRChannelInfoTag()) - { - return (pItem->GetPVRChannelInfoTag()->GetEPGNow().get() != NULL); - } - if (pItem->HasPVRTimerInfoTag() && pItem->GetPVRTimerInfoTag()->GetEpgInfoTag()) - { - return true; - } - else + if (pItem->IsPVRChannel() || pItem->IsEPG() || pItem->IsPVRTimer()) { - return pItem->HasEPGInfoTag(); + const CPVREpgInfoTagPtr epgTag = CPVRItem(pItem).GetEpgInfoTag(); + return epgTag != nullptr; } } else if (condition == LISTITEM_ISENCRYPTED) { - if (pItem->HasPVRChannelInfoTag()) - { - return pItem->GetPVRChannelInfoTag()->IsEncrypted(); - } - else if (pItem->HasEPGInfoTag() && pItem->GetEPGInfoTag()->HasChannel()) + if (pItem->IsPVRChannel() || pItem->IsEPG()) { - return pItem->GetEPGInfoTag()->Channel()->IsEncrypted(); + const CPVRChannelPtr channel = CPVRItem(pItem).GetChannel(); + if (channel) + return channel->IsEncrypted(); } } else if (condition == LISTITEM_IS_STEREOSCOPIC) @@ -11032,18 +10882,6 @@ return bReturn; } -CPVREpgInfoTagPtr CGUIInfoManager::GetEpgInfoTag() const -{ - CPVREpgInfoTagPtr currentTag; - if (m_currentFile->HasEPGInfoTag()) - { - currentTag = m_currentFile->GetEPGInfoTag(); - while (currentTag && !currentTag->IsActive()) - currentTag = currentTag->GetNextEvent(); - } - return currentTag; -} - int CGUIInfoManager::GetMessageMask() { return TMSG_MASK_GUIINFOMANAGER;
View file
_service:download_files:master.tar.gz/xbmc/GUIInfoManager.h
Changed
@@ -285,12 +285,6 @@ int AddMultiInfo(const GUIInfo &info); int AddListItemProp(const std::string &str, int offset=0); - /*! - * @brief Get the EPG tag that is currently active - * @return the currently active tag or NULL if no active tag was found - */ - PVR::CPVREpgInfoTagPtr GetEpgInfoTag() const; - void SetCurrentItemJob(const CFileItemPtr item); // Conditional string parameters are stored here @@ -351,6 +345,7 @@ CCriticalSection m_critInfo; private: + static std::string GetEpgEventTitle(const PVR::CPVREpgInfoTagPtr& epgTag); static std::string FormatRatingAndVotes(float rating, int votes); bool IsPlayerChannelPreviewActive() const; };
View file
_service:download_files:master.tar.gz/xbmc/addons/kodi-addon-dev-kit/include/kodi/AddonBase.h
Changed
@@ -40,13 +40,9 @@ #undef PRAGMA_PACK_END #if defined(__GNUC__) - #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) - #define ATTRIBUTE_PACKED __attribute__ ((packed)) - #define PRAGMA_PACK 0 - #if __GNUC__ >= 4 - #define ATTRIBUTE_HIDDEN __attribute__ ((visibility ("hidden"))) - #endif - #endif + #define ATTRIBUTE_PACKED __attribute__ ((packed)) + #define PRAGMA_PACK 0 + #define ATTRIBUTE_HIDDEN __attribute__ ((visibility ("hidden"))) #endif #if !defined(ATTRIBUTE_PACKED)
View file
_service:download_files:master.tar.gz/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_game_types.h
Changed
@@ -40,10 +40,8 @@ #undef PRAGMA_PACK_END #if defined(__GNUC__) - #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) - #define ATTRIBUTE_PACKED __attribute__ ((packed)) - #define PRAGMA_PACK 0 - #endif + #define ATTRIBUTE_PACKED __attribute__ ((packed)) + #define PRAGMA_PACK 0 #endif #if !defined(ATTRIBUTE_PACKED)
View file
_service:download_files:master.tar.gz/xbmc/addons/kodi-addon-dev-kit/include/kodi/xbmc_epg_types.h
Changed
@@ -27,11 +27,9 @@ #undef PRAGMA_PACK_END #if defined(__GNUC__) -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) #define ATTRIBUTE_PACKED __attribute__ ((packed)) #define PRAGMA_PACK 0 #endif -#endif #if !defined(ATTRIBUTE_PACKED) #define ATTRIBUTE_PACKED
View file
_service:download_files:master.tar.gz/xbmc/addons/kodi-addon-dev-kit/include/kodi/xbmc_pvr_types.h
Changed
@@ -50,11 +50,9 @@ #undef PRAGMA_PACK_END #if defined(__GNUC__) -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) #define ATTRIBUTE_PACKED __attribute__ ((packed)) #define PRAGMA_PACK 0 #endif -#endif #if !defined(ATTRIBUTE_PACKED) #define ATTRIBUTE_PACKED
View file
_service:download_files:master.tar.gz/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp
Changed
@@ -926,9 +926,7 @@ if (frames < 0) { -#if SND_LIB_VERSION >= 0x000901 /* snd_pcm_forward() exists since 0.9.0rc8 */ snd_pcm_forward(m_pcm, -frames); -#endif frames = 0; }
View file
_service:download_files:master.tar.gz/xbmc/cores/DllLoader/ldt_keeper.c
Changed
@@ -44,11 +44,6 @@ #if defined( __linux__ ) && !defined(__powerpc__) #include <asm/unistd.h> #include <asm/ldt.h> -/* 2.5.xx+ calls this user_desc: */ -#include <linux/version.h> -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,47) -#define modify_ldt_ldt_s user_desc -#endif /* prototype it here, so we won't depend on kernel headers */ #ifdef __cplusplus extern "C" { @@ -100,7 +95,7 @@ #define LDT_ENTRIES 8192 #define LDT_ENTRY_SIZE 8 #pragma pack(4) -struct modify_ldt_ldt_s { +struct user_desc { unsigned int entry_number; unsigned long base_addr; unsigned int limit; @@ -152,7 +147,7 @@ } #if defined(__NetBSD__) || defined(TARGET_FREEBSD) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(TARGET_DARWIN) -static void LDT_EntryToBytes( unsigned long *buffer, const struct modify_ldt_ldt_s *content ) +static void LDT_EntryToBytes( unsigned long *buffer, const struct user_desc *content ) { *buffer++ = ((content->base_addr & 0x0000ffff) << 16) | (content->limit & 0x0ffff); @@ -171,7 +166,7 @@ ldt_fs_t* Setup_LDT_Keeper(void) { - struct modify_ldt_ldt_s array; + struct user_desc array; int ret; int sret; ldt_fs_t* ldt_fs = (ldt_fs_t*) malloc(sizeof(ldt_fs_t)); @@ -210,8 +205,8 @@ array.contents=MODIFY_LDT_CONTENTS_DATA; array.limit_in_pages = 0; #ifdef __linux__ - /* ret=LDT_Modify(0x1, &array, sizeof(struct modify_ldt_ldt_s)); */ - ret = modify_ldt(0x1, &array, sizeof(struct modify_ldt_ldt_s)); + /* ret=LDT_Modify(0x1, &array, sizeof(struct user_desc)); */ + ret = modify_ldt(0x1, &array, sizeof(struct user_desc)); if (ret < 0) { perror("install_fs");
View file
_service:download_files:master.tar.gz/xbmc/cores/RetroPlayer/process/rbpi/RenderBufferPoolMMAL.cpp
Changed
@@ -66,7 +66,7 @@ m_alignedWidth = m_width; m_alignedHeight = m_height; - const unsigned int bpp = g_RBP.GetFrameGeometry(m_mmal_format, m_width, m_height).bytes_per_pixel; + const unsigned int bpp = g_RBP.GetFrameGeometry(m_mmal_format, m_width, m_height).getBytesPerPixel(); m_frameSize = m_width * m_height * bpp; if (m_frameSize == 0)
View file
_service:download_files:master.tar.gz/xbmc/cores/VideoPlayer/DVDCodecs/Video/AddonVideoCodec.cpp
Changed
@@ -281,7 +281,7 @@ bool CAddonVideoCodec::GetFrameBuffer(VIDEOCODEC_PICTURE &picture) { - CVideoBuffer *videoBuffer = m_processInfo.GetVideoBufferManager().Get(AV_PIX_FMT_YUV420P, picture.decodedDataSize); + CVideoBuffer *videoBuffer = m_processInfo.GetVideoBufferManager().Get(AV_PIX_FMT_YUV420P, picture.decodedDataSize, nullptr); if (!videoBuffer) { CLog::Log(LOGERROR,"CAddonVideoCodec::GetFrameBuffer Failed to allocate buffer");
View file
_service:download_files:master.tar.gz/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoPPFFmpeg.cpp
Changed
@@ -96,7 +96,7 @@ void CDVDVideoPPFFmpeg::Process(VideoPicture* pPicture) { VideoPicture* pSource = pPicture; - VideoPicture target; + CVideoBuffer *videoBuffer; if (pSource->videoBuffer->GetFormat() != AV_PIX_FMT_YUV420P) return; @@ -107,8 +107,9 @@ return; } - target.videoBuffer = m_processInfo.GetVideoBufferManager().Get(AV_PIX_FMT_YUV420P, pPicture->iWidth * pPicture->iHeight * 3/2); - if (!target.videoBuffer) + videoBuffer = m_processInfo.GetVideoBufferManager().Get(AV_PIX_FMT_YUV420P, + pPicture->iWidth * pPicture->iHeight * 3/2, nullptr); + if (!videoBuffer) { return; } @@ -117,8 +118,8 @@ int srcStrides[YuvImage::MAX_PLANES]; pSource->videoBuffer->GetPlanes(srcPlanes); pSource->videoBuffer->GetStrides(srcStrides); - target.videoBuffer->SetDimensions(pPicture->iWidth, pPicture->iHeight, srcStrides); - target.videoBuffer->GetPlanes(dstPlanes); + videoBuffer->SetDimensions(pPicture->iWidth, pPicture->iHeight, srcStrides); + videoBuffer->GetPlanes(dstPlanes); pp_postprocess((const uint8_t **)srcPlanes, srcStrides, dstPlanes, srcStrides, pSource->iWidth, pSource->iHeight, @@ -128,7 +129,9 @@ pPicture->SetParams(*pSource); - pPicture->videoBuffer = target.videoBuffer; + if (pPicture->videoBuffer) + pPicture->videoBuffer->Release(); + pPicture->videoBuffer = videoBuffer; if (m_deinterlace) pPicture->iFlags &= ~DVP_FLAG_INTERLACED;
View file
_service:download_files:master.tar.gz/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALCodec.cpp
Changed
@@ -379,6 +379,14 @@ { case AV_CODEC_ID_H264: // H.264 + switch (hints.profile) + { + // Cannot hardware decode Hi10P without artifacts - switch to software on Pi2/Pi3 + case FF_PROFILE_H264_HIGH_10: + case FF_PROFILE_H264_HIGH_10_INTRA: + if (g_RBP.RaspberryPiVersion() > 1) + return false; + } m_codingType = MMAL_ENCODING_H264; m_pFormatName = "mmal-h264"; if (CServiceBroker::GetSettings().GetBool(CSettings::SETTING_VIDEOPLAYER_SUPPORTMVC))
View file
_service:download_files:master.tar.gz/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp
Changed
@@ -64,22 +64,19 @@ { for (int i = 0; i < YuvImage::MAX_PLANES; i++) planes[i] = nullptr; - if (!m_gmem) - return; std::shared_ptr<CMMALPool> pool = std::dynamic_pointer_cast<CMMALPool>(m_pool); assert(pool); AVRpiZcFrameGeometry geo = pool->GetGeometry(); - const int size_y = geo.stride_y * geo.height_y; - const int size_c = geo.stride_c * geo.height_c; - CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s %dx%d %dx%d (%dx%d %dx%d)", CLASSNAME, __FUNCTION__, geo.stride_y, geo.height_y, geo.stride_c, geo.height_c, Width(), Height(), AlignedWidth(), AlignedHeight()); + if (VERBOSE) + CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s %dx%d %dx%d (%dx%d %dx%d)", CLASSNAME, __FUNCTION__, geo.getStrideY(), geo.getHeightY(), geo.getStrideC(), geo.getHeightC(), Width(), Height(), AlignedWidth(), AlignedHeight()); - planes[0] = static_cast<uint8_t *>(m_gmem->m_arm); - if (geo.planes_c >= 1) - planes[1] = planes[0] + size_y; - if (geo.planes_c >= 2) - planes[2] = planes[1] + size_c; + planes[0] = GetMemPtr(); + if (planes[0] && geo.getPlanesC() >= 1) + planes[1] = planes[0] + geo.getSizeY(); + if (planes[1] && geo.getPlanesC() >= 2) + planes[2] = planes[1] + geo.getSizeC(); } void CMMALYUVBuffer::GetStrides(int(&strides)[YuvImage::MAX_PLANES]) @@ -89,18 +86,40 @@ std::shared_ptr<CMMALPool> pool = std::dynamic_pointer_cast<CMMALPool>(m_pool); assert(pool); AVRpiZcFrameGeometry geo = pool->GetGeometry(); - strides[0] = geo.stride_y; - strides[1] = geo.stride_c; - strides[2] = geo.stride_c; + strides[0] = geo.getStrideY(); + strides[1] = geo.getStrideC(); + strides[2] = geo.getStrideC(); } -void CMMALYUVBuffer::SetDimensions(int width, int height, const int (&strides)[YuvImage::MAX_PLANES]) +void CMMALYUVBuffer::SetDimensions(int width, int height, const int (&strides)[YuvImage::MAX_PLANES], const int (&planeOffsets)[YuvImage::MAX_PLANES]) { std::shared_ptr<CMMALPool> pool = std::dynamic_pointer_cast<CMMALPool>(m_pool); assert(pool); - pool->SetDimensions(width, height, strides[0], height); + pool->SetDimensions(width, height, strides, planeOffsets); +} + +void CMMALYUVBuffer::SetDimensions(int width, int height, const int (&strides)[YuvImage::MAX_PLANES]) +{ + const int (&planeOffsets)[YuvImage::MAX_PLANES] = {}; + SetDimensions(width, height, strides, planeOffsets); } +CGPUMEM *CMMALYUVBuffer::Allocate(int size, void *opaque) +{ + m_gmem = new CGPUMEM(size, true); + if (m_gmem && m_gmem->m_vc) + { + m_gmem->m_opaque = opaque; + } + else + { + delete m_gmem; + m_gmem = nullptr; + } + return m_gmem; +} + + //----------------------------------------------------------------------------- // MMAL Decoder //----------------------------------------------------------------------------- @@ -181,18 +200,27 @@ { int aligned_width = frame->width; int aligned_height = frame->height; - // ffmpeg requirements - AlignedSize(dec->m_avctx, aligned_width, aligned_height); + if (pool->Encoding() != MMAL_ENCODING_YUVUV128 && pool->Encoding() != MMAL_ENCODING_YUVUV64_16) + { + // ffmpeg requirements + AlignedSize(dec->m_avctx, aligned_width, aligned_height); + // GPU requirements + aligned_width = ALIGN_UP(aligned_width, 32); + aligned_height = ALIGN_UP(aligned_height, 16); + } pool->Configure(dec->m_fmt, frame->width, frame->height, aligned_width, aligned_height, 0); } CMMALYUVBuffer *YUVBuffer = dynamic_cast<CMMALYUVBuffer *>(pool->Get()); - if (!YUVBuffer || !YUVBuffer->mmal_buffer || !YUVBuffer->GetMem()) + if (!YUVBuffer) { CLog::Log(LOGERROR,"%s::%s Failed to allocated buffer in time", CLASSNAME, __FUNCTION__); return -1; } + assert(YUVBuffer->mmal_buffer); CGPUMEM *gmem = YUVBuffer->GetMem(); + assert(gmem); + AVBufferRef *buf = av_buffer_create((uint8_t *)gmem->m_arm, gmem->m_numbytes, CDecoder::FFReleaseBuffer, gmem, AV_BUFFER_FLAG_READONLY); if (!buf) { @@ -267,7 +295,8 @@ if (frame) { - if ((frame->format != AV_PIX_FMT_YUV420P && frame->format != AV_PIX_FMT_BGR0 && frame->format != AV_PIX_FMT_RGB565LE) || + if ((frame->format != AV_PIX_FMT_YUV420P && frame->format != AV_PIX_FMT_YUV420P10 && frame->format != AV_PIX_FMT_YUV420P12 && frame->format != AV_PIX_FMT_YUV420P14 && frame->format != AV_PIX_FMT_YUV420P16 && + frame->format != AV_PIX_FMT_BGR0 && frame->format != AV_PIX_FMT_RGB565LE) || frame->buf[1] != nullptr || frame->buf[0] == nullptr) { CLog::Log(LOGERROR, "%s::%s frame format invalid format:%d buf:%p,%p", CLASSNAME, __func__,
View file
_service:download_files:master.tar.gz/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.h
Changed
@@ -40,10 +40,11 @@ CMMALYUVBuffer(int id); virtual ~CMMALYUVBuffer(); uint8_t* GetMemPtr() override; - virtual void GetPlanes(uint8_t*(&planes)[YuvImage::MAX_PLANES]); - virtual void GetStrides(int(&strides)[YuvImage::MAX_PLANES]); - virtual void SetDimensions(int width, int height, const int (&strides)[YuvImage::MAX_PLANES]); - CGPUMEM *Allocate(int size, void *opaque) { m_gmem = new CGPUMEM(size, true); if (m_gmem) m_gmem->m_opaque = opaque; return m_gmem; } + virtual void GetPlanes(uint8_t*(&planes)[YuvImage::MAX_PLANES]) override; + virtual void GetStrides(int(&strides)[YuvImage::MAX_PLANES]) override; + virtual void SetDimensions(int width, int height, const int (&strides)[YuvImage::MAX_PLANES]) override; + virtual void SetDimensions(int width, int height, const int (&strides)[YuvImage::MAX_PLANES], const int (&planeOffsets)[YuvImage::MAX_PLANES]) override; + CGPUMEM *Allocate(int size, void *opaque); CGPUMEM *GetMem() { return m_gmem; } protected: CGPUMEM *m_gmem = nullptr;
View file
_service:download_files:master.tar.gz/xbmc/cores/VideoPlayer/DVDFileInfo.cpp
Changed
@@ -254,11 +254,11 @@ if (iDecoderState == CDVDVideoCodec::VC_PICTURE && !(picture.iFlags & DVP_FLAG_DROPPED)) { { - unsigned int nWidth = g_advancedSettings.m_imageRes; + unsigned int nWidth = std::min(picture.iDisplayWidth, g_advancedSettings.m_imageRes); double aspect = (double)picture.iDisplayWidth / (double)picture.iDisplayHeight; if(hint.forced_aspect && hint.aspect != 0) aspect = hint.aspect; - unsigned int nHeight = (unsigned int)((double)g_advancedSettings.m_imageRes / aspect); + unsigned int nHeight = (unsigned int)((double)nWidth / aspect); uint8_t *pOutBuf = (uint8_t*)av_malloc(nWidth * nHeight * 4); struct SwsContext *context = sws_getContext(picture.iWidth, picture.iHeight,
View file
_service:download_files:master.tar.gz/xbmc/cores/VideoPlayer/Process/VideoBuffer.cpp
Changed
@@ -286,6 +286,16 @@ // CVideoBufferPool //----------------------------------------------------------------------------- +CVideoBufferPoolSysMem::~CVideoBufferPoolSysMem() +{ + CSingleLock lock(m_critSection); + + for (auto buf : m_all) + { + delete buf; + } +} + CVideoBuffer* CVideoBufferPoolSysMem::Get() { CSingleLock lock(m_critSection); @@ -327,6 +337,11 @@ ++it; } m_free.push_back(id); + + if (m_bm && m_used.empty()) + { + (m_bm->*m_cbDispose)(this); + } } void CVideoBufferPoolSysMem::Configure(AVPixelFormat format, int size) @@ -350,6 +365,21 @@ return false; } +void CVideoBufferPoolSysMem::Discard(CVideoBufferManager *bm, ReadyToDispose cb) +{ + CSingleLock lock(m_critSection); + m_bm = bm; + m_cbDispose = cb; + + if (m_used.empty()) + (m_bm->*m_cbDispose)(this); +} + +std::shared_ptr<IVideoBufferPool> CVideoBufferPoolSysMem::CreatePool() +{ + return std::make_shared<CVideoBufferPoolSysMem>(); +} + //----------------------------------------------------------------------------- // CVideoBufferManager //----------------------------------------------------------------------------- @@ -357,8 +387,7 @@ CVideoBufferManager::CVideoBufferManager() { CSingleLock lock(m_critSection); - std::shared_ptr<IVideoBufferPool> pool = std::make_shared<CVideoBufferPoolSysMem>(); - RegisterPool(pool); + RegisterPoolFactory("SysMem", &CVideoBufferPoolSysMem::CreatePool); } void CVideoBufferManager::RegisterPool(std::shared_ptr<IVideoBufferPool> pool) @@ -368,21 +397,57 @@ m_pools.push_front(pool); } +void CVideoBufferManager::RegisterPoolFactory(std::string id, CreatePoolFunc createFunc) +{ + CSingleLock lock(m_critSection); + m_poolFactories[id] = createFunc; +} + void CVideoBufferManager::ReleasePools() { CSingleLock lock(m_critSection); std::list<std::shared_ptr<IVideoBufferPool>> pools = m_pools; m_pools.clear(); - std::shared_ptr<IVideoBufferPool> pool = std::make_shared<CVideoBufferPoolSysMem>(); - RegisterPool(pool); + + m_discardedPools = pools; for (auto pool : pools) { - pool->Released(*this); + pool->Discard(this, &CVideoBufferManager::ReadyForDisposal); } } -CVideoBuffer* CVideoBufferManager::Get(AVPixelFormat format, int size) +void CVideoBufferManager::ReleasePool(IVideoBufferPool *pool) +{ + CSingleLock lock(m_critSection); + + for (auto it = m_pools.begin(); it != m_pools.end(); ++it) + { + if ((*it).get() == pool) + { + m_discardedPools.push_back(*it); + m_pools.erase(it); + pool->Discard(this, &CVideoBufferManager::ReadyForDisposal); + } + } +} + +void CVideoBufferManager::ReadyForDisposal(IVideoBufferPool *pool) +{ + CSingleLock lock(m_critSection); + + for (auto it = m_discardedPools.begin(); it != m_discardedPools.end(); ++it) + { + if ((*it).get() == pool) + { + pool->Released(*this); + m_discardedPools.erase(it); + break; + } + } +} + +CVideoBuffer* CVideoBufferManager::Get(AVPixelFormat format, int size, IVideoBufferPool **pPool) { CSingleLock lock(m_critSection); for (auto pool: m_pools) @@ -396,5 +461,15 @@ return pool->Get(); } } + + for (auto fact : m_poolFactories) + { + std::shared_ptr<IVideoBufferPool> pool = fact.second(); + m_pools.push_front(pool); + pool->Configure(format, size); + if (pPool) + *pPool = pool.get(); + return pool->Get(); + } return nullptr; }
View file
_service:download_files:master.tar.gz/xbmc/cores/VideoPlayer/Process/VideoBuffer.h
Changed
@@ -23,7 +23,9 @@ #include <atomic> #include <deque> #include <list> +#include <map> #include <memory> +#include <string> #include <vector> extern "C" { @@ -55,6 +57,8 @@ class IVideoBufferPool; class CVideoBufferManager; +typedef void (CVideoBufferManager::*ReadyToDispose)(IVideoBufferPool *pool); + class IVideoBufferPool : public std::enable_shared_from_this<IVideoBufferPool> { public: @@ -81,6 +85,10 @@ // clients can register a new pool on this callback virtual void Released(CVideoBufferManager &videoBufferManager) {}; + // called by BM when buffer is discarded + // pool calls back when all buffers are back home + virtual void Discard(CVideoBufferManager *bm, ReadyToDispose cb) { (bm->*cb)(this); }; + // call on Get() before returning buffer to caller std::shared_ptr<IVideoBufferPool> GetPtr() { return shared_from_this(); }; }; @@ -141,11 +149,15 @@ class CVideoBufferPoolSysMem : public IVideoBufferPool { public: + ~CVideoBufferPoolSysMem() override; CVideoBuffer* Get() override; void Return(int id) override; void Configure(AVPixelFormat format, int size) override; bool IsConfigured() override; bool IsCompatible(AVPixelFormat format, int size) override; + void Discard(CVideoBufferManager *bm, ReadyToDispose cb) override; + + static std::shared_ptr<IVideoBufferPool> CreatePool(); protected: int m_width = 0; @@ -154,6 +166,8 @@ AVPixelFormat m_pixFormat = AV_PIX_FMT_NONE; bool m_configured = false; CCriticalSection m_critSection; + CVideoBufferManager *m_bm = nullptr; + ReadyToDispose m_cbDispose; std::vector<CVideoBufferSysMem*> m_all; std::deque<int> m_used; @@ -164,17 +178,24 @@ // //----------------------------------------------------------------------------- +typedef std::shared_ptr<IVideoBufferPool> (*CreatePoolFunc)(); + class CVideoBufferManager { public: CVideoBufferManager(); void RegisterPool(std::shared_ptr<IVideoBufferPool> pool); + void RegisterPoolFactory(std::string id, CreatePoolFunc createFunc); void ReleasePools(); - CVideoBuffer* Get(AVPixelFormat format, int size); + void ReleasePool(IVideoBufferPool *pool); + CVideoBuffer* Get(AVPixelFormat format, int size, IVideoBufferPool **pPool); + void ReadyForDisposal(IVideoBufferPool *pool); protected: CCriticalSection m_critSection; std::list<std::shared_ptr<IVideoBufferPool>> m_pools; + std::list<std::shared_ptr<IVideoBufferPool>> m_discardedPools; + std::map<std::string, CreatePoolFunc> m_poolFactories; private: CVideoBufferManager (const CVideoBufferManager&) = delete;
View file
_service:download_files:master.tar.gz/xbmc/cores/VideoPlayer/VideoPlayer.cpp
Changed
@@ -695,6 +695,9 @@ { CLog::Log(LOGNOTICE, "VideoPlayer::OpenFile: %s", CURL::GetRedacted(file.GetPath()).c_str()); + if (m_omxplayer_mode && IsRunning()) + CloseFile(); + if (IsRunning()) { CDVDMsgOpenFile::FileParams params;
View file
_service:download_files:master.tar.gz/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp
Changed
@@ -130,8 +130,6 @@ CSingleLock lock(m_critSection); MMAL_STATUS_T status; - memset(&m_geo, 0, sizeof m_geo); - status = mmal_component_create(component_name, &m_component); if (status != MMAL_SUCCESS) CLog::Log(LOGERROR, "%s::%s Failed to create component %s", CLASSNAME, __func__, component_name); @@ -200,6 +198,11 @@ std::vector<CMMALPool::MMALEncodingTable> CMMALPool::mmal_encoding_table = { { AV_PIX_FMT_YUV420P, MMAL_ENCODING_I420 }, + { AV_PIX_FMT_YUVJ420P, MMAL_ENCODING_I420 }, + { AV_PIX_FMT_YUV420P10,MMAL_ENCODING_I420_16, }, + { AV_PIX_FMT_YUV420P12,MMAL_ENCODING_I420_16, }, + { AV_PIX_FMT_YUV420P14,MMAL_ENCODING_I420_16, }, + { AV_PIX_FMT_YUV420P16,MMAL_ENCODING_I420_16, }, { AV_PIX_FMT_RGBA, MMAL_ENCODING_RGBA, }, { AV_PIX_FMT_BGRA, MMAL_ENCODING_BGRA }, { AV_PIX_FMT_RGB0, MMAL_ENCODING_RGBA }, @@ -227,7 +230,7 @@ void CMMALPool::Configure(AVPixelFormat format, int width, int height, int alignedWidth, int alignedHeight, int size) { CSingleLock lock(m_critSection); - if (m_mmal_format == MMAL_ENCODING_UNKNOWN) + if (format != AV_PIX_FMT_NONE) m_mmal_format = TranslateFormat(format); m_width = width; m_height = height; @@ -238,26 +241,22 @@ if (m_mmal_format != MMAL_ENCODING_UNKNOWN) { m_geo = g_RBP.GetFrameGeometry(m_mmal_format, alignedWidth, alignedHeight); - if (m_mmal_format != MMAL_ENCODING_YUVUV128) + if (m_mmal_format != MMAL_ENCODING_YUVUV128 && m_mmal_format != MMAL_ENCODING_YUVUV64_16 ) { if (alignedWidth) { - m_geo.stride_y = alignedWidth; - m_geo.stride_c = alignedWidth>>1; + m_geo.setStrideY(alignedWidth * m_geo.getBytesPerPixel()); + m_geo.setStrideC(alignedWidth * m_geo.getBytesPerPixel() >> 1); } if (alignedHeight) { - m_geo.height_y = alignedHeight; - m_geo.height_c = alignedHeight>>1; + m_geo.setHeightY(alignedHeight); + m_geo.setHeightC(alignedHeight >> 1); } } } if (m_size == 0) - { - const unsigned int size_y = m_geo.stride_y * m_geo.height_y; - const unsigned int size_c = m_geo.stride_c * m_geo.height_c; - m_size = (size_y + size_c * m_geo.planes_c) * m_geo.stripes; - } + m_size = m_geo.getSize(); CLog::Log(LOGDEBUG, "%s::%s pool:%p %dx%d (%dx%d) pix:%d size:%d fmt:%.4s", CLASSNAME, __func__, static_cast<void*>(m_mmal_pool), width, height, alignedWidth, alignedHeight, format, size, (char*)&m_mmal_format); @@ -268,9 +267,15 @@ Configure(format, 0, 0, 0, 0, size); } -void CMMALPool::SetDimensions(int width, int height, int alignedWidth, int alignedHeight) +void CMMALPool::SetDimensions(int width, int height, const int (&strides)[YuvImage::MAX_PLANES], const int (&planeOffsets)[YuvImage::MAX_PLANES]) { + assert(m_geo.getBytesPerPixel()); + int alignedWidth = strides[0] ? strides[0] / m_geo.getBytesPerPixel() : width; + int alignedHeight = planeOffsets[1] ? planeOffsets[1] / strides[0] : height; Configure(AV_PIX_FMT_NONE, width, height, alignedWidth, alignedHeight, 0); + // libwv side-by-side UV format + if (planeOffsets[2] - planeOffsets[1] == strides[1] >> 1) + m_mmal_format = MMAL_ENCODING_I420_S; } inline bool CMMALPool::IsConfigured() @@ -283,6 +288,8 @@ { CSingleLock lock(m_critSection); uint32_t mmal_format = TranslateFormat(format); + if (m_mmal_format == MMAL_ENCODING_I420_S && mmal_format == MMAL_ENCODING_I420) + return true; if (m_mmal_format == mmal_format && m_size == size) return true; @@ -596,6 +603,7 @@ m_deint_aligned_height = 0; m_cachedSourceRect.SetRect(0, 0, 0, 0); m_cachedDestRect.SetRect(0, 0, 0, 0); + m_isPi1 = g_RBP.RaspberryPiVersion() == 1; m_queue_process = mmal_queue_create(); m_processThread.Create(); @@ -731,13 +739,14 @@ { if (buffer->length > 0) { + int yuv16 = omvb->Encoding() == MMAL_ENCODING_I420_16 || omvb->Encoding() == MMAL_ENCODING_YUVUV64_16; EINTERLACEMETHOD last_interlace_method = m_interlace_method; EINTERLACEMETHOD interlace_method = m_videoSettings.m_InterlaceMethod; if (interlace_method == VS_INTERLACEMETHOD_AUTO) { interlace_method = VS_INTERLACEMETHOD_MMAL_ADVANCED; // avoid advanced deinterlace when using software decode and HD resolution - if (omvb->m_state == MMALStateFFDec && omvb->Width() * omvb->Height() > 720*576) + if ((omvb->m_state == MMALStateFFDec || m_isPi1) && omvb->Width() * omvb->Height() > 720*576) interlace_method = VS_INTERLACEMETHOD_MMAL_BOB; } bool interlace = (omvb->mmal_buffer->flags & MMAL_BUFFER_HEADER_VIDEO_FLAG_INTERLACED) ? true:false; @@ -760,13 +769,17 @@ interlace_method = VS_INTERLACEMETHOD_MMAL_BOB_HALF; } - if (interlace_method == VS_INTERLACEMETHOD_NONE) + if (interlace_method == VS_INTERLACEMETHOD_NONE && !yuv16) { if (m_deint_input) DestroyDeinterlace(); } - else if (m_deint_input || interlace) - CheckConfigurationDeint(omvb->Width(), omvb->Height(), omvb->AlignedWidth(), omvb->AlignedHeight(), omvb->Encoding(), interlace_method); + + if (yuv16) + interlace_method = VS_INTERLACEMETHOD_NONE; + + if (yuv16 || (interlace_method != VS_INTERLACEMETHOD_NONE && (m_deint_input || interlace))) + CheckConfigurationDeint(omvb->Width(), omvb->Height(), omvb->AlignedWidth(), omvb->AlignedHeight(), omvb->Encoding(), interlace_method, omvb->BitsPerPixel()); if (!m_deint_input) m_interlace_method = VS_INTERLACEMETHOD_NONE; @@ -1365,7 +1378,7 @@ m_deint = nullptr; } -bool CMMALRenderer::CheckConfigurationDeint(uint32_t width, uint32_t height, uint32_t aligned_width, uint32_t aligned_height, uint32_t encoding, EINTERLACEMETHOD interlace_method) +bool CMMALRenderer::CheckConfigurationDeint(uint32_t width, uint32_t height, uint32_t aligned_width, uint32_t aligned_height, uint32_t encoding, EINTERLACEMETHOD interlace_method, int bitsPerPixel) { MMAL_STATUS_T status; bool sizeChanged = width != m_deint_width || height != m_deint_height || aligned_width != m_deint_aligned_width || aligned_height != m_deint_aligned_height; @@ -1374,6 +1387,7 @@ bool advanced_deinterlace = interlace_method == VS_INTERLACEMETHOD_MMAL_ADVANCED || interlace_method == VS_INTERLACEMETHOD_MMAL_ADVANCED_HALF; bool half_framerate = interlace_method == VS_INTERLACEMETHOD_MMAL_ADVANCED_HALF || interlace_method == VS_INTERLACEMETHOD_MMAL_BOB_HALF; uint32_t output_encoding = advanced_deinterlace ? MMAL_ENCODING_YUVUV128 : MMAL_ENCODING_I420; + const char *component = interlace_method == VS_INTERLACEMETHOD_NONE ? "vc.ril.isp" : "vc.ril.image_fx"; if (!m_bConfigured) { @@ -1386,7 +1400,7 @@ CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s CreateDeinterlace", CLASSNAME, __func__); /* Create deinterlace component with attached pool */ - m_deint_output_pool = std::make_shared<CMMALPool>("vc.ril.image_fx", false, 3, 0, output_encoding, MMALStateDeint); + m_deint_output_pool = std::make_shared<CMMALPool>(component, false, 3, 0, output_encoding, MMALStateDeint); if (!m_deint_output_pool) { CLog::Log(LOGERROR, "%s::%s Failed to create pool for deint output", CLASSNAME, __func__); @@ -1405,10 +1419,10 @@ if (m_deint_input && (sizeChanged || deinterlaceChanged || encodingChanged)) { assert(m_deint_input != nullptr && m_deint_input->format != nullptr && m_deint_input->format->es != nullptr); - CLog::Log(LOGDEBUG, "%s::%s Changing Deint dimensions from %dx%d (%dx%d) to %dx%d (%dx%d) %.4s->%.4s mode %d->%d", CLASSNAME, __func__, + CLog::Log(LOGDEBUG, "%s::%s Changing Deint dimensions from %dx%d (%dx%d) to %dx%d (%dx%d) %.4s->%.4s mode %d->%d bpp:%d", CLASSNAME, __func__, m_deint_input->format->es->video.crop.width, m_deint_input->format->es->video.crop.height, m_deint_input->format->es->video.width, m_deint_input->format->es->video.height, width, height, aligned_width, aligned_height, - (char *)&m_deint_input->format->encoding, (char *)&encoding, m_interlace_method, interlace_method); + (char *)&m_deint_input->format->encoding, (char *)&encoding, m_interlace_method, interlace_method, bitsPerPixel); // we need to disable port when parameters change if (m_deint_input && m_deint_input->is_enabled) @@ -1470,22 +1484,36 @@ } } + if (m_deint_output && (sizeChanged || deinterlaceChanged || encodingChanged)) { - MMAL_PARAMETER_IMAGEFX_PARAMETERS_T imfx_param = {{MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS, sizeof(imfx_param)}, - advanced_deinterlace ? MMAL_PARAM_IMAGEFX_DEINTERLACE_ADV : MMAL_PARAM_IMAGEFX_DEINTERLACE_FAST, 4, {5, 0, half_framerate, 1 }}; + if (interlace_method != VS_INTERLACEMETHOD_NONE) + { + MMAL_PARAMETER_IMAGEFX_PARAMETERS_T imfx_param = {{MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS, sizeof(imfx_param)}, + advanced_deinterlace ? MMAL_PARAM_IMAGEFX_DEINTERLACE_ADV : MMAL_PARAM_IMAGEFX_DEINTERLACE_FAST, 4, {5, 0, half_framerate, 1 }}; - status = mmal_port_parameter_set(m_deint_output, &imfx_param.hdr); - if (status != MMAL_SUCCESS) + status = mmal_port_parameter_set(m_deint_output, &imfx_param.hdr); + if (status != MMAL_SUCCESS) + { + CLog::Log(LOGERROR, "%s::%s Failed to set deinterlace parameters (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status)); + return false; + } + + // Image_fx assumed 3 frames of context. simple deinterlace doesn't require this + status = mmal_port_parameter_set_uint32(m_deint_input, MMAL_PARAMETER_EXTRA_BUFFERS, 6 - 5 + advanced_deinterlace ? 2:0); + if (status != MMAL_SUCCESS) + CLog::Log(LOGERROR, "%s::%s Failed to enable extra buffers on %s (status=%x %s)", CLASSNAME, __func__, m_deint_input->name, status, mmal_status_to_string(status)); + } + else { - CLog::Log(LOGERROR, "%s::%s Failed to set deinterlace parameters (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status)); - return false; + // We need to scale the YUV to 16-bit + status = mmal_port_parameter_set_int32(m_deint_input, MMAL_PARAMETER_CCM_SHIFT, 16-bitsPerPixel-1); + if (status != MMAL_SUCCESS) + CLog::Log(LOGERROR, "%s::%s Failed to configure MMAL_PARAMETER_CCM_SHIFT on %s (status=%x %s)", CLASSNAME, __func__, m_deint_input->name, status, mmal_status_to_string(status)); + status = mmal_port_parameter_set_uint32(m_deint_output, MMAL_PARAMETER_OUTPUT_SHIFT, 1); + if (status != MMAL_SUCCESS) + CLog::Log(LOGERROR, "%s::%s Failed to configure MMAL_PARAMETER_OUTPUT_SHIFT on %s (status=%x %s)", CLASSNAME, __func__, m_deint_output->name, status, mmal_status_to_string(status)); } - - // Image_fx assumed 3 frames of context. simple deinterlace doesn't require this - status = mmal_port_parameter_set_uint32(m_deint_input, MMAL_PARAMETER_EXTRA_BUFFERS, 6 - 5 + advanced_deinterlace ? 2:0); - if (status != MMAL_SUCCESS) - CLog::Log(LOGERROR, "%s::%s Failed to enable extra buffers on %s (status=%x %s)", CLASSNAME, __func__, m_deint_input->name, status, mmal_status_to_string(status)); } if (m_deint_output && (sizeChanged || deinterlaceChanged || encodingChanged))
View file
_service:download_files:master.tar.gz/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.h
Changed
@@ -58,7 +58,7 @@ virtual bool IsConfigured() override; virtual bool IsCompatible(AVPixelFormat format, int size) override; - void SetDimensions(int width, int height, int alignedWidth, int alignedHeight); + void SetDimensions(int width, int height, const int (&strides)[YuvImage::MAX_PLANES], const int (&planeOffsets)[YuvImage::MAX_PLANES]); MMAL_COMPONENT_T *GetComponent() { return m_component; } CMMALBuffer *GetBuffer(uint32_t timeout); void Prime(); @@ -69,8 +69,9 @@ static uint32_t TranslateFormat(AVPixelFormat pixfmt); virtual int Width() { return m_width; } virtual int Height() { return m_height; } - virtual int AlignedWidth() { return m_geo.stride_y / m_geo.bytes_per_pixel; } - virtual int AlignedHeight() { return m_geo.height_y; } + virtual int AlignedWidth() { return m_mmal_format == MMAL_ENCODING_YUVUV128 || m_mmal_format == MMAL_ENCODING_YUVUV64_16 ? 0 : m_geo.getStrideY() / m_geo.getBytesPerPixel(); } + virtual int AlignedHeight() { return m_mmal_format == MMAL_ENCODING_YUVUV128 || m_mmal_format == MMAL_ENCODING_YUVUV64_16 ? 0 : m_geo.getHeightY(); } + virtual int BitsPerPixel() { return m_geo.getBitsPerPixel(); } virtual uint32_t &Encoding() { return m_mmal_format; } virtual int Size() { return m_size; } AVRpiZcFrameGeometry &GetGeometry() { return m_geo; } @@ -110,7 +111,6 @@ CMMALBuffer(int id); virtual ~CMMALBuffer(); MMAL_BUFFER_HEADER_T *mmal_buffer = nullptr; - uint32_t m_encoding = MMAL_ENCODING_UNKNOWN; float m_aspect_ratio = 0.0f; MMALState m_state = MMALStateNone; bool m_rendered = false; @@ -123,6 +123,7 @@ virtual int AlignedWidth() { return Pool()->AlignedWidth(); } virtual int AlignedHeight() { return Pool()->AlignedHeight(); } virtual uint32_t &Encoding() { return Pool()->Encoding(); } + virtual int BitsPerPixel() { return Pool()->BitsPerPixel(); } virtual void Update(); void SetVideoDeintMethod(std::string method); @@ -188,6 +189,7 @@ RENDER_STEREO_MODE m_video_stereo_mode; RENDER_STEREO_MODE m_display_stereo_mode; bool m_StereoInvert; + bool m_isPi1; CCriticalSection m_sharedSection; MMAL_COMPONENT_T *m_vout; @@ -211,7 +213,7 @@ uint32_t m_deint_width, m_deint_height, m_deint_aligned_width, m_deint_aligned_height; MMAL_FOURCC_T m_deinterlace_out_encoding; void DestroyDeinterlace(); - bool CheckConfigurationDeint(uint32_t width, uint32_t height, uint32_t aligned_width, uint32_t aligned_height, uint32_t encoding, EINTERLACEMETHOD interlace_method); + bool CheckConfigurationDeint(uint32_t width, uint32_t height, uint32_t aligned_width, uint32_t aligned_height, uint32_t encoding, EINTERLACEMETHOD interlace_method, int bitsPerPixel); bool CheckConfigurationVout(uint32_t width, uint32_t height, uint32_t aligned_width, uint32_t aligned_height, uint32_t encoding); uint32_t m_vsync_count;
View file
_service:download_files:master.tar.gz/xbmc/cores/omxplayer/OMXImage.cpp
Changed
@@ -620,7 +620,7 @@ unsigned short block_size = 0; bool nMarker = false; - while(p < q) + while(p < q && !progressive) { switch(marker) {
View file
_service:download_files:master.tar.gz/xbmc/cores/omxplayer/OMXVideo.cpp
Changed
@@ -82,6 +82,7 @@ m_settings_changed = false; m_setStartTime = false; m_transform = OMX_DISPLAY_ROT0; + m_isPi1 = g_RBP.RaspberryPiVersion() == 1; } COMXVideo::~COMXVideo() @@ -232,7 +233,7 @@ EINTERLACEMETHOD interlace_method = m_processInfo.GetVideoSettings().m_InterlaceMethod; if (interlace_method == VS_INTERLACEMETHOD_AUTO) - interlace_method = VS_INTERLACEMETHOD_MMAL_ADVANCED; + interlace_method = m_isPi1 ? VS_INTERLACEMETHOD_MMAL_BOB : VS_INTERLACEMETHOD_MMAL_ADVANCED; if (m_deinterlace && interlace_method != VS_INTERLACEMETHOD_NONE) {
View file
_service:download_files:master.tar.gz/xbmc/cores/omxplayer/OMXVideo.h
Changed
@@ -109,6 +109,7 @@ bool m_failed_eos; OMX_DISPLAYTRANSFORMTYPE m_transform; bool m_settings_changed; + bool m_isPi1; CRenderManager& m_renderManager; CProcessInfo& m_processInfo; static bool NaluFormatStartCodes(enum AVCodecID codec, uint8_t *in_extradata, int in_extrasize);
View file
_service:download_files:master.tar.gz/xbmc/filesystem/SFTPFile.cpp
Changed
@@ -360,7 +360,6 @@ return false; } -#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,4,0) if (ssh_options_set(m_session, SSH_OPTIONS_USER, username.c_str()) < 0) { CLog::Log(LOGERROR, "SFTPSession: Failed to set username '%s' for session", username.c_str()); @@ -389,33 +388,6 @@ #endif ssh_options_set(m_session, SSH_OPTIONS_LOG_VERBOSITY, 0); ssh_options_set(m_session, SSH_OPTIONS_TIMEOUT, &timeout); -#else - SSH_OPTIONS* options = ssh_options_new(); - - if (ssh_options_set_username(options, username.c_str()) < 0) - { - CLog::Log(LOGERROR, "SFTPSession: Failed to set username '%s' for session", username.c_str()); - return false; - } - - if (ssh_options_set_host(options, host.c_str()) < 0) - { - CLog::Log(LOGERROR, "SFTPSession: Failed to set host '%s' for session", host.c_str()); - return false; - } - - if (ssh_options_set_port(options, port) < 0) - { - CLog::Log(LOGERROR, "SFTPSession: Failed to set port '%d' for session", port); - return false; - } - - ssh_options_set_timeout(options, timeout, 0); - - ssh_options_set_log_verbosity(options, 0); - - ssh_set_options(m_session, options); -#endif if(ssh_connect(m_session)) { @@ -437,19 +409,11 @@ return false; } -#if LIBSSH_VERSION_MINOR >= 6 int method = ssh_userauth_list(m_session, NULL); -#else - int method = ssh_auth_list(m_session); -#endif // Try to authenticate with public key first int publicKeyAuth = SSH_AUTH_DENIED; -#if LIBSSH_VERSION_MINOR >= 6 if (method & SSH_AUTH_METHOD_PUBLICKEY && (publicKeyAuth = ssh_userauth_publickey_auto(m_session, NULL, NULL)) == SSH_AUTH_ERROR) -#else - if (method & SSH_AUTH_METHOD_PUBLICKEY && (publicKeyAuth = ssh_userauth_autopubkey(m_session, NULL)) == SSH_AUTH_ERROR) -#endif { CLog::Log(LOGERROR, "SFTPSession: Failed to authenticate via publickey '%s'", ssh_get_error(m_session)); return false;
View file
_service:download_files:master.tar.gz/xbmc/filesystem/SFTPFile.h
Changed
@@ -37,18 +37,6 @@ class CURL; -#if LIBSSH_VERSION_INT < SSH_VERSION_INT(0,3,2) -#define ssh_session SSH_SESSION -#endif - -#if LIBSSH_VERSION_INT < SSH_VERSION_INT(0,4,0) -#define sftp_file SFTP_FILE* -#define sftp_session SFTP_SESSION* -#define sftp_attributes SFTP_ATTRIBUTES* -#define sftp_dir SFTP_DIR* -#define ssh_session ssh_session* -#endif - //five secs timeout for SFTP #define SFTP_TIMEOUT 5
View file
_service:download_files:master.tar.gz/xbmc/interfaces/swig/AddonModuleXbmc.i
Changed
@@ -34,7 +34,7 @@ using namespace XBMCAddon; using namespace xbmc; -#if defined(__GNUG__) && (__GNUC__>4) || (__GNUC__==4 && __GNUC_MINOR__>=2) +#if defined(__GNUG__) #pragma GCC diagnostic ignored "-Wstrict-aliasing" #endif %}
View file
_service:download_files:master.tar.gz/xbmc/interfaces/swig/AddonModuleXbmcaddon.i
Changed
@@ -30,7 +30,7 @@ using namespace XBMCAddon; using namespace xbmcaddon; -#if defined(__GNUG__) && (__GNUC__>4) || (__GNUC__==4 && __GNUC_MINOR__>=2) +#if defined(__GNUG__) #pragma GCC diagnostic ignored "-Wstrict-aliasing" #endif
View file
_service:download_files:master.tar.gz/xbmc/interfaces/swig/AddonModuleXbmcgui.i
Changed
@@ -38,7 +38,7 @@ using namespace XBMCAddon; using namespace xbmcgui; -#if defined(__GNUG__) && (__GNUC__>4) || (__GNUC__==4 && __GNUC_MINOR__>=2) +#if defined(__GNUG__) #pragma GCC diagnostic ignored "-Wstrict-aliasing" #endif
View file
_service:download_files:master.tar.gz/xbmc/interfaces/swig/AddonModuleXbmcplugin.i
Changed
@@ -30,7 +30,7 @@ using namespace XBMCAddon; using namespace xbmcplugin; -#if defined(__GNUG__) && (__GNUC__>4) || (__GNUC__==4 && __GNUC_MINOR__>=2) +#if defined(__GNUG__) #pragma GCC diagnostic ignored "-Wstrict-aliasing" #endif
View file
_service:download_files:master.tar.gz/xbmc/interfaces/swig/AddonModuleXbmcvfs.i
Changed
@@ -33,7 +33,7 @@ using namespace XBMCAddon; using namespace xbmcvfs; -#if defined(__GNUG__) && (__GNUC__>4) || (__GNUC__==4 && __GNUC_MINOR__>=2) +#if defined(__GNUG__) #pragma GCC diagnostic ignored "-Wstrict-aliasing" #endif
View file
_service:download_files:master.tar.gz/xbmc/interfaces/swig/AddonModuleXbmcwsgi.i
Changed
@@ -37,7 +37,7 @@ using namespace XBMCAddon; using namespace xbmcwsgi; -#if defined(__GNUG__) && (__GNUC__>4) || (__GNUC__==4 && __GNUC_MINOR__>=2) +#if defined(__GNUG__) #pragma GCC diagnostic ignored "-Wstrict-aliasing" #endif
View file
_service:download_files:master.tar.gz/xbmc/music/CMakeLists.txt
Changed
@@ -7,6 +7,7 @@ MusicInfoLoader.cpp MusicLibraryQueue.cpp MusicThumbLoader.cpp + MusicUtils.cpp Song.cpp) set(HEADERS Album.h @@ -18,6 +19,7 @@ MusicInfoLoader.h MusicLibraryQueue.h MusicThumbLoader.h + MusicUtils.h Song.h) core_add_library(music)
View file
_service:download_files:master.tar.gz/xbmc/music/MusicDatabase.cpp
Changed
@@ -5723,6 +5723,39 @@ return -1; } +bool CMusicDatabase::GetArtistFromSong(int idSong, CArtist &artist) +{ + try + { + if (NULL == m_pDB.get()) return false; + if (NULL == m_pDS.get()) return false; + + std::string strSQL = PrepareSQL( + "SELECT artistview.* FROM song_artist " + "JOIN artistview ON song_artist.idArtist = artistview.idArtist " + "WHERE song_artist.idSong= %i AND song_artist.idRole = 1 AND song_artist.iOrder = 0", + idSong); + if (!m_pDS->query(strSQL)) return false; + int iRowsFound = m_pDS->num_rows(); + if (iRowsFound != 1) + { + m_pDS->close(); + return false; + } + + artist = GetArtistFromDataset(m_pDS.get()); + + m_pDS->close(); + return true; + + } + catch (...) + { + CLog::Log(LOGERROR, "%s failed", __FUNCTION__); + } + return false; +} + int CMusicDatabase::GetAlbumByName(const std::string& strAlbum, const std::string& strArtist) { try @@ -6184,15 +6217,31 @@ if (NULL == m_pDS.get()) return false; int songID = GetSongIDFromPath(filePath); - if (-1 == songID) return false; + if (-1 == songID) return false; + + return SetSongUserrating(songID, userrating); + } + catch (...) + { + CLog::Log(LOGERROR, "%s (%s,%i) failed", __FUNCTION__, filePath.c_str(), userrating); + } + return false; +} - std::string sql = PrepareSQL("UPDATE song SET userrating='%i' WHERE idSong = %i", userrating, songID); +bool CMusicDatabase::SetSongUserrating(int idSong, int userrating) +{ + try + { + if (NULL == m_pDB.get()) return false; + if (NULL == m_pDS.get()) return false; + + std::string sql = PrepareSQL("UPDATE song SET userrating='%i' WHERE idSong = %i", userrating, idSong); m_pDS->exec(sql); return true; } catch (...) { - CLog::Log(LOGERROR, "%s (%s,%i) failed", __FUNCTION__, filePath.c_str(), userrating); + CLog::Log(LOGERROR, "%s (%i,%i) failed", __FUNCTION__, idSong, userrating); } return false; } @@ -7229,6 +7278,38 @@ return result; } +bool CMusicDatabase::GetArtTypes(const MediaType &mediaType, std::vector<std::string> &artTypes) +{ + try + { + if (NULL == m_pDB.get()) return false; + if (NULL == m_pDS.get()) return false; + + std::string strSQL = PrepareSQL("SELECT DISTINCT type FROM art WHERE media_type='%s'", mediaType.c_str()); + + if (!m_pDS->query(strSQL)) return false; + int iRowsFound = m_pDS->num_rows(); + if (iRowsFound == 0) + { + m_pDS->close(); + return false; + } + + while (!m_pDS->eof()) + { + artTypes.emplace_back(m_pDS->fv(0).get_asString()); + m_pDS->next(); + } + m_pDS->close(); + return true; + } + catch (...) + { + CLog::Log(LOGERROR, "%s(%s) failed", __FUNCTION__, mediaType.c_str()); + } + return false; +} + bool CMusicDatabase::GetFilter(CDbUrl &musicUrl, Filter &filter, SortDescription &sorting) { if (!musicUrl.IsValid())
View file
_service:download_files:master.tar.gz/xbmc/music/MusicDatabase.h
Changed
@@ -208,6 +208,7 @@ bool Search(const std::string& search, CFileItemList &items); bool RemoveSongsFromPath(const std::string &path, MAPSONGS& songs, bool exact=true); bool SetSongUserrating(const std::string &filePath, int userrating); + bool SetSongUserrating(int idSong, int userrating); bool SetSongVotes(const std::string &filePath, int votes); int GetSongByArtistAndAlbumAndTitle(const std::string& strArtist, const std::string& strAlbum, const std::string& strTitle); @@ -321,6 +322,7 @@ std::string GetArtistById(int id); int GetArtistByName(const std::string& strArtist); int GetArtistByMatch(const CArtist& artist); + bool GetArtistFromSong(int idSong, CArtist &artist); std::string GetRoleById(int id); /*! \brief Propagate artist sort name into the concatenated artist sort name strings @@ -552,6 +554,13 @@ */ bool RemoveArtForItem(int mediaId, const MediaType &mediaType, const std::set<std::string> &artTypes); + /*! \brief Fetch the distinct types of art held in the database for a type of media. + \param mediaType the type of media, which corresponds to the table the item resides in (song/artist/album). + \param artTypes [out] the types of art e.g. "thumb", "fanart", etc. + \return true if art is found, false if no art is found. + */ + bool GetArtTypes(const MediaType &mediaType, std::vector<std::string> &artTypes); + ///////////////////////////////////////////////// // Tag Scan Version /////////////////////////////////////////////////
View file
_service:download_files:master.tar.gz/xbmc/music/MusicInfoLoader.cpp
Changed
@@ -91,20 +91,36 @@ return false; // already have the information std::string path(pItem->GetPath()); - if (pItem->IsMusicDb()) + // For songs in library set the (primary) song artist and album properties + // Use song Id (not path) as called for items from either library or file view + if (pItem->GetMusicInfoTag()->GetDatabaseId() > 0) { - // set the artist / album properties - XFILE::MUSICDATABASEDIRECTORY::CQueryParams param; - XFILE::MUSICDATABASEDIRECTORY::CDirectoryNode::GetDatabaseInfo(pItem->GetPath(),param); - CArtist artist; CMusicDatabase database; database.Open(); - if (database.GetArtist(param.GetArtistId(), artist, false)) - CMusicDatabase::SetPropertiesFromArtist(*pItem,artist); + // May already have song artist ids as item property, otherwise fetch from song id + CArtist artist; + bool artistfound = false; + if (pItem->HasProperty("artistid")) + { + CVariant::const_iterator_array varid = pItem->GetProperty("artistid").begin_array(); + int idArtist = varid->asInteger(); + artistfound = database.GetArtist(idArtist, artist, false); + } + else + artistfound = database.GetArtistFromSong(pItem->GetMusicInfoTag()->GetDatabaseId(), artist); + if (artistfound) + CMusicDatabase::SetPropertiesFromArtist(*pItem, artist); + // May already have album id, otherwise fetch album from song id CAlbum album; - if (database.GetAlbum(param.GetAlbumId(), album, false)) - CMusicDatabase::SetPropertiesFromAlbum(*pItem,album); + bool albumfound = false; + int idAlbum = pItem->GetMusicInfoTag()->GetAlbumId(); + if (idAlbum > 0) + albumfound = database.GetAlbum(idAlbum, album, false); + else + albumfound = database.GetAlbumFromSong(pItem->GetMusicInfoTag()->GetDatabaseId(), album); + if (albumfound) + CMusicDatabase::SetPropertiesFromAlbum(*pItem, album); path = pItem->GetMusicInfoTag()->GetURL(); }
View file
_service:download_files:master.tar.gz/xbmc/music/MusicUtils.cpp
Added
@@ -0,0 +1,240 @@ +/* + * Copyright (C) 2018 Team Kodi + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "MusicUtils.h" +#include "dialogs/GUIDialogSelect.h" +#include "guilib/GUIKeyboardFactory.h" +#include "guilib/GUIWindowManager.h" +#include "guilib/LocalizeStrings.h" +#include "input/Key.h" +#include "music/MusicDatabase.h" +#include "music/tags/MusicInfoTag.h" +#include "Util.h" +#include "utils/JobManager.h" + +using namespace MUSIC_INFO; +using namespace XFILE; + +namespace MUSIC_UTILS +{ + class CSetArtJob : public CJob + { + CFileItemPtr pItem; + std::string m_artType; + std::string m_newArt; + public: + CSetArtJob(const CFileItemPtr item, const std::string& type, const std::string& newArt) : + pItem(item), + m_artType(type), + m_newArt(newArt) + { } + + ~CSetArtJob(void) override = default; + + // Asynchronously update song, album or artist art in library + bool DoWork(void) override + { + CMusicInfoTag& tag = *pItem->GetMusicInfoTag(); + CMusicDatabase db; + if (db.Open()) + { + if (!m_newArt.empty()) + db.SetArtForItem(tag.GetDatabaseId(), tag.GetType(), m_artType, m_newArt); + else + db.RemoveArtForItem(tag.GetDatabaseId(), tag.GetType(), m_artType); + db.Close(); + } + return true; + } + }; + + class CSetSongRatingJob : public CJob + { + std::string strPath; + int idSong; + int iUserrating; + public: + CSetSongRatingJob(const std::string& filePath, int userrating) : + strPath(filePath), + idSong(-1), + iUserrating(userrating) + { } + + CSetSongRatingJob(int songId, int userrating) : + strPath(), + idSong(songId), + iUserrating(userrating) + { } + + ~CSetSongRatingJob(void) override = default; + + bool DoWork(void) override + { + // Asynchronously update song userrating in library + CMusicDatabase db; + if (db.Open()) + { + if (idSong > 0) + db.SetSongUserrating(idSong, iUserrating); + else + db.SetSongUserrating(strPath, iUserrating); + db.Close(); + } + + return true; + } + }; + + void UpdateArtJob(const CFileItemPtr pItem, const std::string& strType, const std::string& strArt) + { + // Asynchronously update that type of art in the database + CSetArtJob *job = new CSetArtJob(pItem, strType, strArt); + CJobManager::GetInstance().AddJob(job, NULL); + } + + bool FillArtTypesList(CFileItem& musicitem, CFileItemList& artlist) + { + CMusicInfoTag &tag = *musicitem.GetMusicInfoTag(); + if (tag.GetDatabaseId() < 1 || tag.GetType().empty()) + return false; + if (tag.GetType() != MediaTypeArtist && tag.GetType() != MediaTypeAlbum && tag.GetType() != MediaTypeSong) + return false; + + artlist.Clear(); + // Songs, albums and artists all have thumbs by default + std::vector<std::string> artTypes = { "thumb" }; + if (tag.GetType() == MediaTypeArtist) + { + artTypes.emplace_back("fanart"); + } + + CMusicDatabase db; + db.Open(); + + // Add in any stored art for this item that is non-empty. + std::map<std::string, std::string> currentArt; + db.GetArtForItem(tag.GetDatabaseId(), tag.GetType(), currentArt); + for (const auto art : currentArt) + { + if (!art.second.empty() && find(artTypes.begin(), artTypes.end(), art.first) == artTypes.end()) + artTypes.push_back(art.first); + } + + // Add any art types that exist for other media items of the same type + std::vector<std::string> dbArtTypes; + db.GetArtTypes(tag.GetType(), dbArtTypes); + for (const auto it : dbArtTypes) + { + if (find(artTypes.begin(), artTypes.end(), it) == artTypes.end()) + artTypes.push_back(it); + } + db.Close(); + + for (const auto type : artTypes) + { + CFileItemPtr artitem(new CFileItem(type, false)); + // Localise the names of common types of art + if (type == "banner") + artitem->SetLabel(g_localizeStrings.Get(20020)); + else if (type == "fanart") + artitem->SetLabel(g_localizeStrings.Get(20445)); + else if (type == "poster") + artitem->SetLabel(g_localizeStrings.Get(20021)); + else if (type == "thumb") + artitem->SetLabel(g_localizeStrings.Get(21371)); + else + artitem->SetLabel(type); + // Set art type as art item property + artitem->SetProperty("arttype", type); + // Set current art as art item thumb + if (musicitem.HasArt(type)) + artitem->SetArt("thumb", musicitem.GetArt(type)); + artlist.Add(artitem); + } + + return !artlist.IsEmpty(); + } + + std::string ShowSelectArtTypeDialog(CFileItemList& artitems) + { + // Prompt for choice + CGUIDialogSelect *dialog = g_windowManager.GetWindow<CGUIDialogSelect>(WINDOW_DIALOG_SELECT); + if (!dialog) + return ""; + + dialog->SetHeading(CVariant{ 13521 }); + dialog->Reset(); + dialog->SetUseDetails(true); + dialog->EnableButton(true, 13516); + + dialog->SetItems(artitems); + dialog->Open(); + + if (dialog->IsButtonPressed()) + { + // Get the new art type name + std::string strArtTypeName; + if (!CGUIKeyboardFactory::ShowAndGetInput(strArtTypeName, CVariant{ g_localizeStrings.Get(13516) }, false)) + return ""; + // Add new type to the list of art types + CFileItemPtr artitem(new CFileItem(strArtTypeName, false)); + artitem->SetLabel(strArtTypeName); + artitem->SetProperty("arttype", strArtTypeName); + artitems.Add(artitem); + + return strArtTypeName; + } + + return dialog->GetSelectedFileItem()->GetProperty("arttype").asString(); + } + + int ShowSelectRatingDialog(int iSelected) + { + CGUIDialogSelect *dialog = g_windowManager.GetWindow<CGUIDialogSelect>(WINDOW_DIALOG_SELECT); + if (dialog) + { + dialog->SetHeading(CVariant{ 38023 }); + dialog->Add(g_localizeStrings.Get(38022)); + for (int i = 1; i <= 10; i++) + dialog->Add(StringUtils::Format("%s: %i", g_localizeStrings.Get(563).c_str(), i)); + dialog->SetSelected(iSelected); + dialog->Open(); + + int userrating = dialog->GetSelectedItem(); + userrating = std::max(userrating, -1); + userrating = std::min(userrating, 10); + return userrating; + } + return -1; + } + + void UpdateSongRatingJob(const CFileItemPtr pItem, int userrating) + { + // Asynchronously update the song user rating in music library + const CMusicInfoTag *tag = pItem->GetMusicInfoTag(); + CSetSongRatingJob *job; + if (tag && tag->GetType() == MediaTypeSong && tag->GetDatabaseId() > 0) + // Use song ID when known + job = new CSetSongRatingJob(tag->GetDatabaseId(), userrating); + else + job = new CSetSongRatingJob(pItem->GetPath(), userrating); + CJobManager::GetInstance().AddJob(job, NULL); + } +}
View file
_service:download_files:master.tar.gz/xbmc/music/MusicUtils.h
Added
@@ -0,0 +1,69 @@ +#pragma once + +/* + * Copyright (C) 2018 Team Kodi + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "FileItem.h" + +namespace MUSIC_UTILS +{ + /*! \brief Show a dialog to allow the selection of type of art from a list. + Input is a fileitem list, with each item having an "arttype" property + e.g. "thumb", current art URL (if art exists), and label. One of these art types + can be selected, or a new art type added. The new art type is added as a new item + in the list, as well as retuned as the selected art type. + \param artitems [in/out] a fileitem list to display + \return the selected art type e.g. "fanart" or empty string when cancelled. + \sa FillArtTypesList + */ + std::string ShowSelectArtTypeDialog(CFileItemList& artitems); + + /*! \brief Helper function to build a list of art types for a music library item. + This fetches the possible types of art for a song, album or artist, and the + current art URL (if the item has art of that type), for display on a dialog. + \param musicitem a music CFileItem (song, album or artist) + \param artitems [out] a fileitem list, each item having "arttype" property + e.g. "thumb", current art URL (if art exists), and localized label (for common arttypes) + \return true if art types are retrieved, false if none is found. + \sa ShowSelectArtTypeDialog + */ + bool FillArtTypesList(CFileItem& musicitem, CFileItemList& artlist); + + /*! \brief Helper function to asynchronously update art in the music database + For the song, album or artist this adds a job to the queue to update the art table + modifying, adding or deleting that type of art, + \param item a shared pointer to a music CFileItem (song, album or artist) + \param strType the type of art e.g. "fanart" or "thumb" etc. + \param strArt art URL, when empty the entry for that type of art is deleted. + */ + void UpdateArtJob(const CFileItemPtr pItem, const std::string& strType, const std::string& strArt); + + /*! \brief Show a dialog to allow the selection of user rating. + \param iSelected the rating to show initially + \return the selected rating, 0 (no rating), 1 to 10 or -1 no rating selected + */ + int ShowSelectRatingDialog(int iSelected); + +/*! \brief Helper function to asynchronously update the user rating of a song +\param pItem pointer to song item being rated +\param userrating the userrating 0 = no rating, 1 to 10 +*/ + void UpdateSongRatingJob(const CFileItemPtr pItem, int userrating); +}
View file
_service:download_files:master.tar.gz/xbmc/music/dialogs/GUIDialogMusicOSD.cpp
Changed
@@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2013 Team XBMC + * Copyright (C) 2005-2018 Team Kodi * http://kodi.tv * * This Program is free software; you can redistribute it and/or modify @@ -19,19 +19,12 @@ */ #include "GUIDialogMusicOSD.h" -#include "ServiceBroker.h" +#include "addons/GUIWindowAddonBrowser.h" #include "guilib/GUIWindowManager.h" -#include "guilib/LocalizeStrings.h" +#include "GUIUserMessages.h" #include "input/Key.h" #include "input/InputManager.h" -#include "GUIUserMessages.h" #include "settings/Settings.h" -#include "addons/GUIWindowAddonBrowser.h" -#include "xbmc/dialogs/GUIDialogSelect.h" -#include "xbmc/Application.h" -#include "xbmc/FileItem.h" -#include "xbmc/music/tags/MusicInfoTag.h" -#include "xbmc/music/MusicDatabase.h" #include "ServiceBroker.h" #define CONTROL_VIS_BUTTON 500 @@ -81,45 +74,6 @@ case ACTION_SHOW_OSD: Close(); return true; - - case ACTION_SET_RATING: - { - CGUIDialogSelect *dialog = g_windowManager.GetWindow<CGUIDialogSelect>(WINDOW_DIALOG_SELECT); - if (dialog) - { - dialog->SetHeading(CVariant{ 38023 }); - dialog->Add(g_localizeStrings.Get(38022)); - for (int i = 1; i <= 10; i++) - dialog->Add(StringUtils::Format("%s: %i", g_localizeStrings.Get(563).c_str(), i)); - - auto track = g_application.CurrentFileItemPtr(); - dialog->SetSelected(track->GetMusicInfoTag()->GetUserrating()); - - dialog->Open(); - - int userrating = dialog->GetSelectedItem(); - - if (userrating < 0) userrating = 0; - if (userrating > 10) userrating = 10; - if (userrating != track->GetMusicInfoTag()->GetUserrating()) - { - track->GetMusicInfoTag()->SetUserrating(userrating); - // send a message to all windows to tell them to update the fileitem (eg playlistplayer, media windows) - CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE_ITEM, 0, track); - g_windowManager.SendMessage(msg); - - CMusicDatabase db; - if (db.Open()) - { - db.SetSongUserrating(track->GetMusicInfoTag()->GetURL(), userrating); - db.Close(); - } - } - - } - return true; - } - default: break; }
View file
_service:download_files:master.tar.gz/xbmc/music/dialogs/GUIDialogSongInfo.cpp
Changed
@@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2013 Team XBMC + * Copyright (C) 2005-2018 Team XBMC * http://kodi.tv * * This Program is free software; you can redistribute it and/or modify @@ -19,26 +19,23 @@ */ #include "GUIDialogSongInfo.h" -#include "utils/URIUtils.h" -#include "utils/StringUtils.h" -#include "utils/Variant.h" +#include "dialogs/GUIDialogBusy.h" #include "dialogs/GUIDialogFileBrowser.h" #include "dialogs/GUIDialogSelect.h" -#include "GUIPassword.h" +#include "filesystem/File.h" +#include "guilib/GUIWindowManager.h" +#include "guilib/LocalizeStrings.h" +#include "GUIDialogMusicInfo.h" #include "GUIUserMessages.h" +#include "input/Key.h" +#include "music/Album.h" #include "music/MusicDatabase.h" -#include "music/windows/GUIWindowMusicBase.h" +#include "music/MusicUtils.h" #include "music/tags/MusicInfoTag.h" -#include "guilib/GUIWindowManager.h" -#include "input/Key.h" -#include "filesystem/File.h" -#include "filesystem/CurlFile.h" -#include "FileItem.h" +#include "music/windows/GUIWindowMusicBase.h" #include "settings/MediaSourceSettings.h" -#include "guilib/LocalizeStrings.h" -#include "music/Album.h" #include "storage/MediaManager.h" -#include "GUIDialogMusicInfo.h" +#include "Util.h" using namespace XFILE; @@ -49,14 +46,82 @@ #define CONTROL_LIST 50 +#define TIME_TO_BUSY_DIALOG 500 + + + +class CGetSongInfoJob : public CJob +{ +public: + ~CGetSongInfoJob(void) override = default; + + // Fetch full song information including art types list + bool DoWork() override + { + CGUIDialogSongInfo *dialog = g_windowManager.GetWindow<CGUIDialogSongInfo>(WINDOW_DIALOG_SONG_INFO); + if (!dialog) + return false; + if (dialog->IsCancelled()) + return false; + CFileItemPtr m_song = dialog->GetCurrentListItem(); + + // Fetch tag data from library using filename, or scanning file (if item not already have this loaded) + m_song->LoadMusicTag(); + if (dialog->IsCancelled()) + return false; + // Fetch album and primary song artist data from library as properties + // and lyrics by scanning tags from file + MUSIC_INFO::CMusicInfoLoader::LoadAdditionalTagInfo(m_song.get()); + if (dialog->IsCancelled()) + return false; + + // Load song art. + // For songs in library this includes related album and artist(s) art, + // otherwise just embedded or cached thumb is fetched. + CMusicThumbLoader loader; + loader.LoadItem(m_song.get()); + if (dialog->IsCancelled()) + return false; + + // For songs in library fill vector of possible art types, with current art when it exists + // for display on the art type selection dialog + CFileItemList artlist; + MUSIC_UTILS::FillArtTypesList(*m_song, artlist); + dialog->SetArtTypeList(artlist); + if (dialog->IsCancelled()) + return false; + + // Fetch artist art for non db songs when artist can be found uniquely by name + if (!m_song->IsMusicDb() && m_song->HasMusicInfoTag() && !m_song->GetMusicInfoTag()->GetArtist().empty()) + { + CMusicDatabase db; + db.Open(); + int idArtist = db.GetArtistByName(m_song->GetMusicInfoTag()->GetArtist()[0]); + if (idArtist > 0) + { + std::map<std::string, std::string> art; + if (db.GetArtForItem(idArtist, MediaTypeArtist, art)) + m_song->AppendArt(art, "artist"); + } + db.Close(); + } + + // Tell waiting SongInfoDialog that job is complete + dialog->FetchComplete(); + + return true; + } +}; + CGUIDialogSongInfo::CGUIDialogSongInfo(void) : CGUIDialog(WINDOW_DIALOG_SONG_INFO, "DialogMusicInfo.xml") , m_song(new CFileItem) , m_albumId(-1) { m_cancelled = false; - m_needsUpdate = false; + m_hasUpdatedUserrating = false; m_startUserrating = -1; + m_artTypeList.Clear(); m_loadType = KEEP_IN_MEMORY; } @@ -68,15 +133,20 @@ { case GUI_MSG_WINDOW_DEINIT: { + m_artTypeList.Clear(); if (m_startUserrating != m_song->GetMusicInfoTag()->GetUserrating()) { - CMusicDatabase db; - if (db.Open()) - { - m_needsUpdate = true; - db.SetSongUserrating(m_song->GetPath(), m_song->GetMusicInfoTag()->GetUserrating()); - db.Close(); - } + m_hasUpdatedUserrating = true; + + // Asynchronously update song userrating in library + MUSIC_UTILS::UpdateSongRatingJob(m_song, m_song->GetMusicInfoTag()->GetUserrating()); + + // Send a message to all windows to tell them to update the fileitem + // This communicates the rating change to the music lib window, current playlist and OSD. + // The music lib window item is updated to but changes to the rating when it is the sort + // do not show on screen until refresh() that fetchs the list from scratch, sorts etc. + CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE_ITEM, 0, m_song); + g_windowManager.SendMessage(msg); } CGUIMessage msg(GUI_MSG_LABEL_RESET, GetID(), CONTROL_LIST); OnMessage(msg); @@ -110,7 +180,7 @@ } else if (iControl == CONTROL_BTN_GET_THUMB) { - OnGetThumb(); + OnGetArt(); return true; } else if (iControl == CONTROL_LIST) @@ -146,7 +216,7 @@ return CGUIDialog::OnMessage(message); } -bool CGUIDialogSongInfo::OnAction(const CAction &action) +bool CGUIDialogSongInfo::OnAction(const CAction& action) { int userrating = m_song->GetMusicInfoTag()->GetUserrating(); if (action.GetID() == ACTION_INCREASE_RATING) @@ -173,29 +243,18 @@ return CGUIDialog::OnBack(actionID); } +void CGUIDialogSongInfo::FetchComplete() +{ + //Trigger the event to indicate data has been fetched + m_event.Set(); +} + void CGUIDialogSongInfo::OnInitWindow() { - // Normally have album id from song + // Enable album info button when we know album m_albumId = m_song->GetMusicInfoTag()->GetAlbumId(); - if (m_albumId < 0) - { - CMusicDatabase db; - db.Open(); - - // no known db info - check if parent dir is an album - if (m_song->GetMusicInfoTag()->GetDatabaseId() == -1) - { - std::string path = URIUtils::GetDirectory(m_song->GetPath()); - m_albumId = db.GetAlbumIdByPath(path); - } - else - { - CAlbum album; - db.GetAlbumFromSong(m_song->GetMusicInfoTag()->GetDatabaseId(), album); - m_albumId = album.idAlbum; - } - } - CONTROL_ENABLE_ON_CONDITION(CONTROL_ALBUMINFO, m_albumId > -1); + + CONTROL_ENABLE_ON_CONDITION(CONTROL_ALBUMINFO, m_albumId > 0); // Disable music user rating button for plugins as they don't have tables to save this if (m_song->IsPlugin()) @@ -205,7 +264,7 @@ SET_CONTROL_HIDDEN(CONTROL_BTN_REFRESH); SET_CONTROL_LABEL(CONTROL_USERRATING, 38023); - SET_CONTROL_LABEL(CONTROL_BTN_GET_THUMB, 13405); + SET_CONTROL_LABEL(CONTROL_BTN_GET_THUMB, 13511); SET_CONTROL_LABEL(CONTROL_ALBUMINFO, 10523); CGUIDialog::OnInitWindow(); @@ -227,179 +286,198 @@ void CGUIDialogSongInfo::SetUserrating(int userrating) { - if (userrating < 0) userrating = 0; - if (userrating > 10) userrating = 10; + userrating = std::max(userrating, 0); + userrating = std::min(userrating, 10); if (userrating != m_song->GetMusicInfoTag()->GetUserrating()) { m_song->GetMusicInfoTag()->SetUserrating(userrating); - // send a message to all windows to tell them to update the fileitem (eg playlistplayer, media windows) - CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE_ITEM, 0, m_song); - g_windowManager.SendMessage(msg); } } -void CGUIDialogSongInfo::SetSong(CFileItem *item) +bool CGUIDialogSongInfo::SetSong(CFileItem* item) { *m_song = *item; - m_song->LoadMusicTag(); - m_startUserrating = m_song->GetMusicInfoTag()->GetUserrating(); - MUSIC_INFO::CMusicInfoLoader::LoadAdditionalTagInfo(m_song.get()); - - // Load song art. - // For songs in library this includes related album and artist(s) art, - // otherwise just embedded or cached thumb is fetched. - CMusicThumbLoader loader; - loader.LoadItem(m_song.get()); - - // Set artist art for non db songs when artist can be found uniquely by name - if (!m_song->IsMusicDb() && m_song->HasMusicInfoTag() && !m_song->GetMusicInfoTag()->GetArtist().empty()) + m_event.Reset(); + m_cancelled = false; // SetSong happens before win_init + // In a separate job fetch song info and fill list of art types. + int jobid = CJobManager::GetInstance().AddJob(new CGetSongInfoJob(), nullptr, CJob::PRIORITY_LOW); + + // Wait to get all data before show, allowing user to to cancel if fetch is slow + if (!CGUIDialogBusy::WaitOnEvent(m_event, TIME_TO_BUSY_DIALOG)) { - CMusicDatabase db; - db.Open(); - int idArtist = db.GetArtistByName(m_song->GetMusicInfoTag()->GetArtist()[0]); - if (idArtist > 0) - { - std::map<std::string, std::string> art; - if (db.GetArtForItem(idArtist, MediaTypeArtist, art)) - m_song->SetArt(art); - } + // Cancel job still waiting in queue (unlikely) + CJobManager::GetInstance().CancelJob(jobid); + // Flag to stop job already in progress + m_cancelled = true; + return false; } - m_needsUpdate = false; + + // CurrentDirectory() returns m_artTypeList (a convenient CFileItemList) + // Set content so can return dialog CONTAINER_CONTENT as "songs" + m_artTypeList.SetContent("songs"); + // Copy art from ListItem so CONTAINER_ART returns song art + m_artTypeList.SetArt(m_song->GetArt()); + + // Store initial userrating + m_startUserrating = m_song->GetMusicInfoTag()->GetUserrating(); + m_hasUpdatedUserrating = false; + return true; } -CFileItemPtr CGUIDialogSongInfo::GetCurrentListItem(int offset) +void CGUIDialogSongInfo::SetArtTypeList(CFileItemList& artlist) { - return m_song; + m_artTypeList.Copy(artlist); } -bool CGUIDialogSongInfo::DownloadThumbnail(const std::string &thumbFile) +CFileItemPtr CGUIDialogSongInfo::GetCurrentListItem(int offset) { - //! @todo Obtain the source... - std::string source; - CCurlFile http; - http.Download(source, thumbFile); - return true; + return m_song; } -// Get Thumb from user choice. -// Options are: -// 1. Current thumb -// 2. AllMusic.com thumb -// 3. Local thumb -// 4. No thumb (if no Local thumb is available) - -//! @todo Currently no support for "embedded thumb" as there is no easy way to grab it -//! without sending a file that has this as it's album to this class -void CGUIDialogSongInfo::OnGetThumb() +/* + Allow user to choose artwork for the song + For each type of art the options are: + 1. Current art + 2. Local art (thumb found by filename) + 3. Embedded art (@todo) + 4. None + Note that songs are not scraped, hence there is no list of urls for possible remote art +*/ +void CGUIDialogSongInfo::OnGetArt() { - CFileItemList items; + std::string type = MUSIC_UTILS::ShowSelectArtTypeDialog(m_artTypeList); + if (type.empty()) + return; // Cancelled - - // Grab the thumbnail from the web - /* - std::string thumbFromWeb; - thumbFromWeb = URIUtils::AddFileToFolder(g_advancedSettings.m_cachePath, "allmusicThumb.jpg"); - if (DownloadThumbnail(thumbFromWeb)) + CFileItemList items; + CGUIListItem::ArtMap primeArt = m_song->GetArt(); // Song art without fallbacks + bool bHasArt = m_song->HasArt(type); + bool bFallback(false); + if (bHasArt) { - CFileItemPtr item(new CFileItem("thumb://allmusic.com", false)); - item->SetArt("thumb", thumbFromWeb); - item->SetLabel(g_localizeStrings.Get(20055)); - items.Add(item); - }*/ + // Check if that type of art is actually a fallback, e.g. album thumb or artist fanart + CGUIListItem::ArtMap::const_iterator i = primeArt.find(type); + bFallback = (i == primeArt.end()); + } - // Current thumb - if (CFile::Exists(m_song->GetArt("thumb"))) + // Build list of possible images of that art type + if (bHasArt) { + // Add item for current artwork, could a fallback from album/artist CFileItemPtr item(new CFileItem("thumb://Current", false)); - item->SetArt("thumb", m_song->GetArt("thumb")); - item->SetLabel(g_localizeStrings.Get(20016)); + item->SetArt("thumb", m_song->GetArt(type)); + item->SetIconImage("DefaultPicture.png"); + item->SetLabel(g_localizeStrings.Get(13512)); //! @todo: label fallback art so user knows? items.Add(item); } - - // local thumb - std::string cachedLocalThumb; - std::string localThumb(m_song->GetUserMusicThumb(true)); - if (m_song->IsMusicDb()) - { - CFileItem item(m_song->GetMusicInfoTag()->GetURL(), false); - localThumb = item.GetUserMusicThumb(true); + else if (m_song->HasArt("thumb")) + { // For missing art of that type add the thumb (when it exists and not a fallback) + CGUIListItem::ArtMap::const_iterator i = primeArt.find("thumb"); + if (i != primeArt.end()) + { + CFileItemPtr item(new CFileItem("thumb://Thumb", false)); + item->SetArt("thumb", m_song->GetArt("thumb")); + item->SetIconImage("DefaultAlbumCover.png"); + item->SetLabel(g_localizeStrings.Get(21371)); + items.Add(item); + } } - if (CFile::Exists(localThumb)) - { - CFileItemPtr item(new CFileItem("thumb://Local", false)); - item->SetArt("thumb", localThumb); - item->SetLabel(g_localizeStrings.Get(20017)); - items.Add(item); + + std::string localThumb; + if (type == "thumb") + { // Local thumb type art held in <filename>.tbn (for non-library items) + localThumb = m_song->GetUserMusicThumb(true); + if (m_song->IsMusicDb()) + { + CFileItem item(m_song->GetMusicInfoTag()->GetURL(), false); + localThumb = item.GetUserMusicThumb(true); + } + if (CFile::Exists(localThumb)) + { + CFileItemPtr item(new CFileItem("thumb://Local", false)); + item->SetArt("thumb", localThumb); + item->SetLabel(g_localizeStrings.Get(20017)); + items.Add(item); + } } - else - { // no local thumb exists, so we are just using the allmusic.com thumb or cached thumb - // which is probably the allmusic.com thumb. These could be wrong, so allow the user - // to delete the incorrect thumb + + if (bHasArt && !bFallback) + { // Actually has this type of art (not a fallback) so + // allow the user to delete it by selecting "no art". CFileItemPtr item(new CFileItem("thumb://None", false)); item->SetArt("thumb", "DefaultAlbumCover.png"); - item->SetLabel(g_localizeStrings.Get(20018)); + item->SetLabel(g_localizeStrings.Get(13515)); items.Add(item); } + //! @todo: Add support for extracting embedded art + + // Show list of possible art for user selection std::string result; VECSOURCES sources(*CMediaSourceSettings::GetInstance().GetSources("music")); CGUIDialogMusicInfo::AddItemPathToFileBrowserSources(sources, *m_song); g_mediaManager.GetLocalDrives(sources); - if (!CGUIDialogFileBrowser::ShowAndGetImage(items, sources, g_localizeStrings.Get(1030), result)) - return; // user cancelled - - if (result == "thumb://Current") - return; // user chose the one they have - - // delete the thumbnail if that's what the user wants, else overwrite with the - // new thumbnail - - std::string newThumb; - if (result == "thumb://None") - newThumb = ""; - else if (result == "thumb://allmusic.com") - newThumb.clear(); - else if (result == "thumb://Local") - newThumb = localThumb; - else - newThumb = result; - - // update thumb in the database - CMusicDatabase db; - if (db.Open()) + if (CGUIDialogFileBrowser::ShowAndGetImage(items, sources, g_localizeStrings.Get(13511), result) && + result != "thumb://Current") { - db.SetArtForItem(m_song->GetMusicInfoTag()->GetDatabaseId(), m_song->GetMusicInfoTag()->GetType(), "thumb", newThumb); - db.Close(); - } + // User didn't choose the one they have, or the fallback image. + // Overwrite with the new art or clear it + std::string newArt; + if (result == "thumb://Thumb") + newArt = m_song->GetArt("thumb"); + else if (result == "thumb://Local") + newArt = localThumb; +// else if (result == "thumb://Embedded") +// newArt = embeddedArt; + else if (CFile::Exists(result)) + newArt = result; + else // none + newArt.clear(); + + // Asynchronously update that type of art in the database + MUSIC_UTILS::UpdateArtJob(m_song, type, newArt); + + // Update local song with current art + if (newArt.empty()) + { + // Remove that type of art from the song + primeArt.erase(type); + m_song->SetArt(primeArt); + } + else + // Add or modify the type of art + m_song->SetArt(type, newArt); + + // Update local art list with current art + // Show any fallback art when song art removed + if (newArt.empty() && m_song->HasArt(type)) + newArt = m_song->GetArt(type); + for (const auto artitem : m_artTypeList) + { + if (artitem->GetProperty("artType") == type) + { + artitem->SetArt("thumb", newArt); + break; + } + } - m_song->SetArt("thumb", newThumb); + // Get new artwork to show in other places e.g. on music lib window, + // current playlist and player OSD. + CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE_ITEM, 0, m_song); + g_windowManager.SendMessage(msg); - // tell our GUI to completely reload all controls (as some of them - // are likely to have had this image in use so will need refreshing) - CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_REFRESH_THUMBS); - g_windowManager.SendMessage(msg); + } -// m_hasUpdatedThumb = true; + // Re-open the art type selection dialog as we come back from + // the image selection dialog + OnGetArt(); } void CGUIDialogSongInfo::OnSetUserrating() { - CGUIDialogSelect *dialog = g_windowManager.GetWindow<CGUIDialogSelect>(WINDOW_DIALOG_SELECT); - if (dialog) - { - dialog->SetHeading(CVariant{ 38023 }); - dialog->Add(g_localizeStrings.Get(38022)); - for (int i = 1; i <= 10; i++) - dialog->Add(StringUtils::Format("%s: %i", g_localizeStrings.Get(563).c_str(), i)); - - dialog->SetSelected(m_song->GetMusicInfoTag()->GetUserrating()); - - dialog->Open(); + int userrating = MUSIC_UTILS::ShowSelectRatingDialog(m_song->GetMusicInfoTag()->GetUserrating()); + if (userrating < 0) // Nothing selected, so rating unchanged + return; - int iItem = dialog->GetSelectedItem(); - if (iItem < 0) - return; - - SetUserrating(iItem); - } -} + SetUserrating(userrating); +} \ No newline at end of file
View file
_service:download_files:master.tar.gz/xbmc/music/dialogs/GUIDialogSongInfo.h
Changed
@@ -1,7 +1,7 @@ #pragma once /* - * Copyright (C) 2005-2013 Team XBMC + * Copyright (C) 2005-2018 Team XBMC * http://kodi.tv * * This Program is free software; you can redistribute it and/or modify @@ -21,8 +21,8 @@ */ #include "guilib/GUIDialog.h" - -class CFileItem; +#include "FileItem.h" +#include "threads/Event.h" class CGUIDialogSongInfo : public CGUIDialog @@ -31,24 +31,31 @@ CGUIDialogSongInfo(void); ~CGUIDialogSongInfo(void) override; bool OnMessage(CGUIMessage& message) override; - void SetSong(CFileItem *item); - bool OnAction(const CAction &action) override; + bool SetSong(CFileItem* item); + void SetArtTypeList(CFileItemList& artlist); + bool OnAction(const CAction& action) override; bool OnBack(int actionID) override; - bool NeedsUpdate() const { return m_needsUpdate; }; + bool HasUpdatedUserrating() const { return m_hasUpdatedUserrating; }; bool HasListItems() const override { return true; }; CFileItemPtr GetCurrentListItem(int offset = 0) override; + const CFileItemList& CurrentDirectory() const { return m_artTypeList; }; + bool IsCancelled() const { return m_cancelled; }; + void FetchComplete(); + protected: void OnInitWindow() override; void Update(); - bool DownloadThumbnail(const std::string &thumbFile); - void OnGetThumb(); + void OnGetArt(); void SetUserrating(int userrating); void OnSetUserrating(); CFileItemPtr m_song; + CFileItemList m_artTypeList; + CEvent m_event; int m_startUserrating; bool m_cancelled; - bool m_needsUpdate; + bool m_hasUpdatedUserrating; long m_albumId; + };
View file
_service:download_files:master.tar.gz/xbmc/music/tags/MusicInfoTagLoaderCDDA.cpp
Changed
@@ -33,10 +33,11 @@ using namespace CDDB; #endif -#if defined (LIBCDIO_VERSION_NUM) && (LIBCDIO_VERSION_NUM > 83) -#define CDTEXT_TITLE CDTEXT_FIELD_TITLE -#define CDTEXT_PERFORMER CDTEXT_FIELD_PERFORMER -#define CDTEXT_GENRE CDTEXT_FIELD_GENRE +//! @todo - remove after Ubuntu 16.04 (Xenial) is EOL +#if !defined(LIBCDIO_VERSION_NUM) || (LIBCDIO_VERSION_NUM <= 83) +#define CDTEXT_FIELD_TITLE CDTEXT_TITLE +#define CDTEXT_FIELD_PERFORMER CDTEXT_PERFORMER +#define CDTEXT_FIELD_GENRE CDTEXT_GENRE #endif CMusicInfoTagLoaderCDDA::CMusicInfoTagLoaderCDDA(void) = default; @@ -119,7 +120,7 @@ trackinfo ti = pCdInfo->GetTrackInformation(iTrack); // Fill the fileitems music tag with CD-Text information, if available - std::string strTitle = ti.cdtext[CDTEXT_TITLE]; + std::string strTitle = ti.cdtext[CDTEXT_FIELD_TITLE]; if (!strTitle.empty()) { // Tracknumber @@ -132,20 +133,20 @@ xbmc_cdtext_t discCDText = pCdInfo->GetDiscCDTextInformation(); // Artist: Use track artist or disc artist - std::string strArtist = ti.cdtext[CDTEXT_PERFORMER]; + std::string strArtist = ti.cdtext[CDTEXT_FIELD_PERFORMER]; if (strArtist.empty()) - strArtist = discCDText[CDTEXT_PERFORMER]; + strArtist = discCDText[CDTEXT_FIELD_PERFORMER]; tag.SetArtist(strArtist); // Album std::string strAlbum; - strAlbum = discCDText[CDTEXT_TITLE]; + strAlbum = discCDText[CDTEXT_FIELD_TITLE]; tag.SetAlbum(strAlbum); // Genre: use track or disc genre - std::string strGenre = ti.cdtext[CDTEXT_GENRE]; + std::string strGenre = ti.cdtext[CDTEXT_FIELD_GENRE]; if (strGenre.empty()) - strGenre = discCDText[CDTEXT_GENRE]; + strGenre = discCDText[CDTEXT_FIELD_GENRE]; tag.SetGenre( strGenre ); tag.SetLoaded(true);
View file
_service:download_files:master.tar.gz/xbmc/music/tags/TagLoaderTagLib.cpp
Changed
@@ -1247,11 +1247,7 @@ else if (aiffFile) id3v2 = aiffFile->tag(); else if (wavFile) -#if TAGLIB_MAJOR_VERSION > 1 || TAGLIB_MINOR_VERSION > 8 id3v2 = wavFile->ID3v2Tag(); -#else - id3v2 = wavFile->tag(); -#endif else if (wvFile) ape = wvFile->APETag(false); else if (mpcFile)
View file
_service:download_files:master.tar.gz/xbmc/music/windows/GUIWindowMusicBase.cpp
Changed
@@ -173,7 +173,7 @@ // update the display case GUI_MSG_SCAN_FINISHED: - case GUI_MSG_REFRESH_THUMBS: + case GUI_MSG_REFRESH_THUMBS: // Never called as is secondary msg sent as GUI_MSG_NOTIFY_ALL Refresh(); break; @@ -528,10 +528,13 @@ if (!pItem->HasMusicInfoTag()) return; - dialog->SetSong(pItem); - dialog->Open(); - if (dialog->NeedsUpdate()) - Refresh(true); // update our file list + if (dialog->SetSong(pItem)) // Fetch full song info asynchronously + { + dialog->Open(); + if (dialog->HasUpdatedUserrating() && m_vecItems->GetSortMethod() == SortByUserRating) + // Refresh list to sort items and show new userrating sort label + Refresh(); + } } }
View file
_service:download_files:master.tar.gz/xbmc/network/WebServer.cpp
Changed
@@ -103,16 +103,12 @@ static MHD_Response* create_response(size_t size, void* data, int free, int copy) { -#if (MHD_VERSION >= 0x00094001) MHD_ResponseMemoryMode mode = MHD_RESPMEM_PERSISTENT; if (copy) mode = MHD_RESPMEM_MUST_COPY; else if (free) mode = MHD_RESPMEM_MUST_FREE; return MHD_create_response_from_buffer(size, data, mode); -#else - return MHD_create_response_from_data(size, data, free, copy); -#endif } int CWebServer::AskForAuthentication(const HTTPRequest& request) const @@ -164,17 +160,10 @@ return authenticated; } -#if (MHD_VERSION >= 0x00040001) int CWebServer::AnswerToConnection(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls) -#else -int CWebServer::AnswerToConnection(void *cls, struct MHD_Connection *connection, - const char *url, const char *method, - const char *version, const char *upload_data, - unsigned int *upload_data_size, void **con_cls) -#endif { if (cls == nullptr || con_cls == nullptr || *con_cls == nullptr) { @@ -312,17 +301,10 @@ return SendErrorResponse(request, MHD_HTTP_NOT_FOUND, request.method); } -#if (MHD_VERSION >= 0x00040001) int CWebServer::HandlePostField(void *cls, enum MHD_ValueKind kind, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size) -#else -int CWebServer::HandlePostField(void *cls, enum MHD_ValueKind kind, const char *key, - const char *filename, const char *content_type, - const char *transfer_encoding, const char *data, uint64_t off, - unsigned int size) -#endif { ConnectionHandler *conHandler = (ConnectionHandler *)cls; @@ -974,23 +956,13 @@ CLog::Log(LOGDEBUG, "CWebServer[%hu]: request received for %s", m_port, uri); } -#if (MHD_VERSION >= 0x00090200) ssize_t CWebServer::ContentReaderCallback(void *cls, uint64_t pos, char *buf, size_t max) -#elif (MHD_VERSION >= 0x00040001) -int CWebServer::ContentReaderCallback(void *cls, uint64_t pos, char *buf, int max) -#else //libmicrohttpd < 0.4.0 -int CWebServer::ContentReaderCallback(void *cls, size_t pos, char *buf, int max) -#endif { HttpFileDownloadContext *context = (HttpFileDownloadContext *)cls; if (context == nullptr || context->file == nullptr) return -1; -#if (MHD_VERSION >= 0x00090200) CLog::Log(LOGDEBUG, LOGWEBSERVER, "CWebServer [OUT] write maximum %zu bytes from %" PRIu64 " (%" PRIu64 ")", max, context->writePosition, pos); -#else - CLog::Log(LOGDEBUG, LOGWEBSERVER, "CWebServer [OUT] write maximum %d bytes from %" PRIu64 " (%" PRIu64 ")", max, context->writePosition, pos); -#endif // check if we need to add the end-boundary if (context->rangeCountTotal > 1 && context->ranges.IsEmpty()) @@ -1153,31 +1125,21 @@ unsigned int timeout = 60 * 60 * 24; const char* ciphers = "NORMAL:-VERS-TLS1.0"; -#if MHD_VERSION >= 0x00040500 MHD_set_panic_func(&panicHandlerForMHD, nullptr); -#endif if (CServiceBroker::GetSettings().GetBool(CSettings::SETTING_SERVICES_WEBSERVERSSL) && MHD_is_feature_supported(MHD_FEATURE_SSL) == MHD_YES && LoadCert(m_key, m_cert)) // SSL enabled return MHD_start_daemon(flags | -#if (MHD_VERSION >= 0x00040002) && (MHD_VERSION < 0x00090B01) - // use main thread for each connection, can only handle one request at a - // time [unless you set the thread pool size] - MHD_USE_SELECT_INTERNALLY -#else // one thread per connection // WARNING: set MHD_OPTION_CONNECTION_TIMEOUT to something higher than 1 // otherwise on libmicrohttpd 0.4.4-1 it spins a busy loop MHD_USE_THREAD_PER_CONNECTION -#endif #if (MHD_VERSION >= 0x00095207) | MHD_USE_INTERNAL_POLLING_THREAD /* MHD_USE_THREAD_PER_CONNECTION must be used only with MHD_USE_INTERNAL_POLLING_THREAD since 0.9.54 */ #endif -#if (MHD_VERSION >= 0x00040001) | MHD_USE_DEBUG /* Print MHD error messages to log */ -#endif | MHD_USE_SSL , port, @@ -1186,15 +1148,10 @@ &CWebServer::AnswerToConnection, this, -#if (MHD_VERSION >= 0x00040002) && (MHD_VERSION < 0x00090B01) - MHD_OPTION_THREAD_POOL_SIZE, 4, -#endif MHD_OPTION_CONNECTION_LIMIT, 512, MHD_OPTION_CONNECTION_TIMEOUT, timeout, MHD_OPTION_URI_LOG_CALLBACK, &CWebServer::UriRequestLogger, this, -#if (MHD_VERSION >= 0x00040001) MHD_OPTION_EXTERNAL_LOGGER, &logFromMHD, 0, -#endif // MHD_VERSION >= 0x00040001 MHD_OPTION_THREAD_STACK_SIZE, m_thread_stacksize, MHD_OPTION_HTTPS_MEM_KEY, m_key.c_str(), MHD_OPTION_HTTPS_MEM_CERT, m_cert.c_str(), @@ -1203,22 +1160,14 @@ // No SSL return MHD_start_daemon(flags | -#if (MHD_VERSION >= 0x00040002) && (MHD_VERSION < 0x00090B01) - // use main thread for each connection, can only handle one request at a - // time [unless you set the thread pool size] - MHD_USE_SELECT_INTERNALLY -#else // one thread per connection // WARNING: set MHD_OPTION_CONNECTION_TIMEOUT to something higher than 1 // otherwise on libmicrohttpd 0.4.4-1 it spins a busy loop MHD_USE_THREAD_PER_CONNECTION -#endif #if (MHD_VERSION >= 0x00095207) | MHD_USE_INTERNAL_POLLING_THREAD /* MHD_USE_THREAD_PER_CONNECTION must be used only with MHD_USE_INTERNAL_POLLING_THREAD since 0.9.54 */ #endif -#if (MHD_VERSION >= 0x00040001) | MHD_USE_DEBUG /* Print MHD error messages to log */ -#endif , port, 0, @@ -1226,15 +1175,10 @@ &CWebServer::AnswerToConnection, this, -#if (MHD_VERSION >= 0x00040002) && (MHD_VERSION < 0x00090B01) - MHD_OPTION_THREAD_POOL_SIZE, 4, -#endif MHD_OPTION_CONNECTION_LIMIT, 512, MHD_OPTION_CONNECTION_TIMEOUT, timeout, MHD_OPTION_URI_LOG_CALLBACK, &CWebServer::UriRequestLogger, this, -#if (MHD_VERSION >= 0x00040001) MHD_OPTION_EXTERNAL_LOGGER, &logFromMHD, 0, -#endif // MHD_VERSION >= 0x00040001 MHD_OPTION_THREAD_STACK_SIZE, m_thread_stacksize, MHD_OPTION_END); }
View file
_service:download_files:master.tar.gz/xbmc/network/WebServer.h
Changed
@@ -108,16 +108,9 @@ // MHD callback implementations static void* UriRequestLogger(void *cls, const char *uri); -#if (MHD_VERSION >= 0x00090200) static ssize_t ContentReaderCallback (void *cls, uint64_t pos, char *buf, size_t max); -#elif (MHD_VERSION >= 0x00040001) - static int ContentReaderCallback (void *cls, uint64_t pos, char *buf, int max); -#else - static int ContentReaderCallback (void *cls, size_t pos, char *buf, int max); -#endif static void ContentReaderFreeCallback(void *cls); -#if (MHD_VERSION >= 0x00040001) static int AnswerToConnection (void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, @@ -126,16 +119,6 @@ const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size); -#else //libmicrohttpd < 0.4.0 - static int AnswerToConnection (void *cls, struct MHD_Connection *connection, - const char *url, const char *method, - const char *version, const char *upload_data, - unsigned int *upload_data_size, void **con_cls); - static int HandlePostField(void *cls, enum MHD_ValueKind kind, const char *key, - const char *filename, const char *content_type, - const char *transfer_encoding, const char *data, uint64_t off, - unsigned int size); -#endif bool LoadCert(std::string &skey, std::string &scert);
View file
_service:download_files:master.tar.gz/xbmc/network/httprequesthandler/HTTPJsonRpcHandler.cpp
Changed
@@ -130,11 +130,7 @@ return ranges; } -#if (MHD_VERSION >= 0x00040001) bool CHTTPJsonRpcHandler::appendPostData(const char *data, size_t size) -#else -bool CHTTPJsonRpcHandler::appendPostData(const char *data, unsigned int size) -#endif { if (m_requestData.size() + size > MAX_HTTP_POST_SIZE) {
View file
_service:download_files:master.tar.gz/xbmc/network/httprequesthandler/HTTPJsonRpcHandler.h
Changed
@@ -46,11 +46,7 @@ : IHTTPRequestHandler(request) { } -#if (MHD_VERSION >= 0x00040001) bool appendPostData(const char *data, size_t size) override; -#else - bool appendPostData(const char *data, unsigned int size) override; -#endif private: std::string m_requestData;
View file
_service:download_files:master.tar.gz/xbmc/network/httprequesthandler/HTTPPythonHandler.cpp
Changed
@@ -240,11 +240,7 @@ return true; } -#if (MHD_VERSION >= 0x00040001) bool CHTTPPythonHandler::appendPostData(const char *data, size_t size) -#else -bool CHTTPPythonHandler::appendPostData(const char *data, unsigned int size) -#endif { if (m_requestData.size() + size > MAX_STRING_POST_SIZE) {
View file
_service:download_files:master.tar.gz/xbmc/network/httprequesthandler/HTTPPythonHandler.h
Changed
@@ -47,11 +47,7 @@ protected: explicit CHTTPPythonHandler(const HTTPRequest &request); -#if (MHD_VERSION >= 0x00040001) bool appendPostData(const char *data, size_t size) override; -#else - bool appendPostData(const char *data, unsigned int size) override; -#endif private: std::string m_scriptPath;
View file
_service:download_files:master.tar.gz/xbmc/network/httprequesthandler/IHTTPRequestHandler.cpp
Changed
@@ -112,11 +112,7 @@ m_postFields[key].append(value); } -#if (MHD_VERSION >= 0x00040001) bool IHTTPRequestHandler::AddPostData(const char *data, size_t size) -#else -bool IHTTPRequestHandler::AddPostData(const char *data, unsigned int size) -#endif { if (size > 0) return appendPostData(data, size); @@ -166,4 +162,4 @@ port = 80; return true; -} \ No newline at end of file +}
View file
_service:download_files:master.tar.gz/xbmc/network/httprequesthandler/IHTTPRequestHandler.h
Changed
@@ -224,7 +224,6 @@ * \param value Value of the HTTP POST field */ void AddPostField(const std::string &key, const std::string &value); -#if (MHD_VERSION >= 0x00040001) /*! * \brief Adds the given raw HTTP POST data. * @@ -232,19 +231,12 @@ * \param size Size of the raw HTTP POST data */ bool AddPostData(const char *data, size_t size); -#else - bool AddPostData(const char *data, unsigned int size); -#endif protected: IHTTPRequestHandler(); explicit IHTTPRequestHandler(const HTTPRequest &request); -#if (MHD_VERSION >= 0x00040001) virtual bool appendPostData(const char *data, size_t size) -#else - virtual bool appendPostData(const char *data, unsigned int size) -#endif { return true; } bool GetRequestedRanges(uint64_t totalLength);
View file
_service:download_files:master.tar.gz/xbmc/platform/linux/RBP.cpp
Changed
@@ -401,9 +401,12 @@ CGPUMEM::~CGPUMEM() { - mem_unlock(g_RBP.GetMBox(), m_vc_handle); - vcsm_unlock_ptr(m_arm); - vcsm_free(m_vcsm_handle); + if (m_vc_handle) + mem_unlock(g_RBP.GetMBox(), m_vc_handle); + if (m_arm) + vcsm_unlock_ptr(m_arm); + if (m_vcsm_handle) + vcsm_free(m_vcsm_handle); } // Call this to clean and invalidate a region of memory @@ -419,37 +422,46 @@ AVRpiZcFrameGeometry CRBP::GetFrameGeometry(uint32_t encoding, unsigned short video_width, unsigned short video_height) { - AVRpiZcFrameGeometry geo = {}; - geo.stripes = 1; - geo.bytes_per_pixel = 1; + AVRpiZcFrameGeometry geo; + geo.setStripes(1); + geo.setBitsPerPixel(8); switch (encoding) { case MMAL_ENCODING_RGBA: case MMAL_ENCODING_BGRA: - geo.bytes_per_pixel = 4; - geo.stride_y = video_width * geo.bytes_per_pixel; - geo.height_y = video_height; + geo.setBitsPerPixel(32); + geo.setStrideY(video_width * geo.getBytesPerPixel()); + geo.setHeightY(video_height); break; case MMAL_ENCODING_RGB24: case MMAL_ENCODING_BGR24: - geo.bytes_per_pixel = 3; - geo.stride_y = video_width * geo.bytes_per_pixel; - geo.height_y = video_height; + geo.setBitsPerPixel(32); + geo.setStrideY(video_width * geo.getBytesPerPixel()); + geo.setHeightY(video_height); break; case MMAL_ENCODING_RGB16: case MMAL_ENCODING_BGR16: - geo.bytes_per_pixel = 2; - geo.stride_y = video_width * geo.bytes_per_pixel; - geo.height_y = video_height; + geo.setBitsPerPixel(16); + geo.setStrideY(video_width * geo.getBytesPerPixel()); + geo.setHeightY(video_height); break; case MMAL_ENCODING_I420: - geo.stride_y = (video_width + 31) & ~31; - geo.stride_c = geo.stride_y >> 1; - geo.height_y = (video_height + 15) & ~15; - geo.height_c = geo.height_y >> 1; - geo.planes_c = 2; + case MMAL_ENCODING_I420_S: + geo.setStrideY((video_width + 31) & ~31); + geo.setStrideC(geo.getStrideY() >> 1); + geo.setHeightY((video_height + 15) & ~15); + geo.setHeightC(geo.getHeightY() >> 1); + geo.setPlanesC(2); + break; + case MMAL_ENCODING_I420_16: + geo.setBitsPerPixel(10); + geo.setStrideY(((video_width + 31) & ~31) * geo.getBytesPerPixel()); + geo.setStrideC(geo.getStrideY() >> 1); + geo.setHeightY((video_height + 15) & ~15); + geo.setHeightC(geo.getHeightY() >> 1); + geo.setPlanesC(2); break; case MMAL_ENCODING_OPAQUE: - geo.stride_y = video_width; - geo.height_y = video_height; + geo.setStrideY(video_width); + geo.setHeightY(video_height); break; case MMAL_ENCODING_YUVUV128: { @@ -460,12 +472,30 @@ int rc = get_image_params(GetMBox(), &img); assert(rc == 0); const unsigned int stripe_w = 128; - geo.stride_y = stripe_w; - geo.stride_c = stripe_w; - geo.height_y = ((intptr_t)img.extra.uv.u - (intptr_t)img.image_data) / stripe_w; - geo.height_c = img.pitch / stripe_w - geo.height_y; - geo.planes_c = 1; - geo.stripes = (video_width + stripe_w - 1) / stripe_w; + geo.setStrideY(stripe_w); + geo.setStrideC(stripe_w); + geo.setHeightY(((intptr_t)img.extra.uv.u - (intptr_t)img.image_data) / stripe_w); + geo.setHeightC(img.pitch / stripe_w - geo.getHeightY()); + geo.setPlanesC(1); + geo.setStripes((video_width + stripe_w - 1) / stripe_w); + break; + } + case MMAL_ENCODING_YUVUV64_16: + { + VC_IMAGE_T img = {}; + img.type = VC_IMAGE_YUV_UV_16; + img.width = video_width; + img.height = video_height; + int rc = get_image_params(GetMBox(), &img); + assert(rc == 0); + const unsigned int stripe_w = 128; + geo.setBitsPerPixel(10); + geo.setStrideY(stripe_w); + geo.setStrideC(stripe_w); + geo.setHeightY(((intptr_t)img.extra.uv.u - (intptr_t)img.image_data) / stripe_w); + geo.setHeightC(img.pitch / stripe_w - geo.getHeightY()); + geo.setPlanesC(1); + geo.setStripes((video_width * 2 + stripe_w - 1) / stripe_w); break; } default: assert(0);
View file
_service:download_files:master.tar.gz/xbmc/platform/linux/RBP.h
Changed
@@ -36,16 +36,37 @@ #include "threads/Event.h" -typedef struct AVRpiZcFrameGeometry +class AVRpiZcFrameGeometry { - unsigned int stride_y; - unsigned int height_y; - unsigned int stride_c; - unsigned int height_c; - unsigned int planes_c; - unsigned int stripes; - unsigned int bytes_per_pixel; -} AVRpiZcFrameGeometry; +public: + unsigned int getStrideY() { return stride_y; } + unsigned int getHeightY() { return height_y; } + unsigned int getStrideC() { return stride_c; } + unsigned int getHeightC() { return height_c; } + unsigned int getPlanesC() { return planes_c; } + unsigned int getStripes() { return stripes; } + unsigned int getBitsPerPixel() { return bits_per_pixel; } + unsigned int getBytesPerPixel() { return (bits_per_pixel + 7) >> 3; } + unsigned int getSizeY() { return stride_y * height_y; } + unsigned int getSizeC() { return stride_c * height_c; } + unsigned int getSize() { return (getSizeY() + getSizeC() * getPlanesC()) * getStripes(); } + void setStrideY(unsigned int v) { stride_y = v; } + void setHeightY(unsigned int v) { height_y = v; } + void setStrideC(unsigned int v) { stride_c = v; } + void setHeightC(unsigned int v) { height_c = v; } + void setPlanesC(unsigned int v) { planes_c = v; } + void setStripes(unsigned int v) { stripes = v; } + void setBitsPerPixel(unsigned int v) { bits_per_pixel = v; } + void setBytesPerPixel(unsigned int v) { bits_per_pixel = v * 8; } +private: + unsigned int stride_y = 0; + unsigned int height_y = 0; + unsigned int stride_c = 0; + unsigned int height_c = 0; + unsigned int planes_c = 0; + unsigned int stripes = 0; + unsigned int bits_per_pixel = 0; +}; class CGPUMEM {
View file
_service:download_files:master.tar.gz/xbmc/platform/linux/input/LinuxInputDevices.cpp
Changed
@@ -28,12 +28,8 @@ * */ -#include <linux/version.h> - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) typedef unsigned long kernel_ulong_t; #define BITS_PER_LONG (sizeof(long)*8) -#endif #include <linux/input.h>
View file
_service:download_files:master.tar.gz/xbmc/platform/win32/PlatformDefs.h
Changed
@@ -40,9 +40,6 @@ #define SSIZE_MAX INTPTR_MAX #endif // !SSIZE_MAX -#if _MSC_VER < 1900 -#define snprintf _snprintf -#endif #define ftello64 _ftelli64 #define fseeko64 _fseeki64 #ifndef strcasecmp @@ -71,17 +68,6 @@ #define PIXEL_BSHIFT 0 #endif -#if _MSC_VER < 1800 -#ifndef va_copy -#define va_copy(dst, src) ((dst) = (src)) -#endif - -#define lrint(x) ((x) >= 0 ? ((int)((x) + 0.5)) : ((int)((x) - 0.5))) -#define llrint(x) ((x) >= 0 ? ((__int64)((x) + 0.5)) : ((__int64)((x) - 0.5))) - -#define strtoll(p, e, b) _strtoi64(p, e, b) -#endif - extern "C" char * strptime(const char *buf, const char *fmt, struct tm *tm); extern "C" int strverscmp (const char *s1, const char *s2); extern "C" char * strcasestr(const char* haystack, const char* needle);
View file
_service:download_files:master.tar.gz/xbmc/pvr/PVRGUIInfo.cpp
Changed
@@ -563,7 +563,13 @@ if (dwInfo == PVR_EPG_EVENT_PROGRESS) { - const CPVREpgInfoTagPtr epgTag = item.GetEPGInfoTag(); + CPVREpgInfoTagPtr epgTag; + + const CPVRChannelPtr channel = item.GetPVRChannelInfoTag(); + if (channel) + epgTag = channel->GetEPGNow(); + if (!epgTag) + epgTag = item.GetEPGInfoTag(); if (epgTag) iReturn = std::lrintf(epgTag->ProgressPercentage()); }
View file
_service:download_files:master.tar.gz/xbmc/pvr/PVRItem.cpp
Changed
@@ -66,9 +66,7 @@ } else if (m_item->IsPVRTimer()) { - const CPVREpgInfoTagPtr epgTag(m_item->GetPVRTimerInfoTag()->GetEpgInfoTag()); - if (epgTag) - return epgTag->Channel(); + return m_item->GetPVRTimerInfoTag()->Channel(); } else {
View file
_service:download_files:master.tar.gz/xbmc/pvr/PVRItem.h
Changed
@@ -31,7 +31,8 @@ class CPVRItem { public: - explicit CPVRItem(const CFileItemPtr &item) : m_item(item) {} + explicit CPVRItem(const CFileItemPtr &item) : m_item(item.get()) {} + explicit CPVRItem(const CFileItem *item) : m_item(item) {} CPVREpgInfoTagPtr GetEpgInfoTag() const; CPVRChannelPtr GetChannel() const; @@ -41,7 +42,7 @@ bool IsRadio() const; private: - CFileItemPtr m_item; + const CFileItem* m_item; }; } // namespace PVR
View file
_service:download_files:master.tar.gz/xbmc/settings/AdvancedSettings.cpp
Changed
@@ -180,6 +180,7 @@ m_songInfoDuration = 10; m_cddbAddress = "freedb.freedb.org"; + m_addSourceOnTop = false; m_handleMounting = g_application.IsStandAlone(); @@ -841,6 +842,7 @@ } XMLUtils::GetString(pRootElement, "cddbaddress", m_cddbAddress); + XMLUtils::GetBoolean(pRootElement, "addsourceontop", m_addSourceOnTop); //airtunes + airplay XMLUtils::GetInt(pRootElement, "airtunesport", m_airTunesPort); @@ -1009,8 +1011,8 @@ XMLUtils::GetInt(pRootElement, "remotedelay", m_remoteDelay, 0, 20); XMLUtils::GetFloat(pRootElement, "controllerdeadzone", m_controllerDeadzone, 0.0f, 1.0f); - XMLUtils::GetUInt(pRootElement, "fanartres", m_fanartRes, 0, 1080); - XMLUtils::GetUInt(pRootElement, "imageres", m_imageRes, 0, 1080); + XMLUtils::GetUInt(pRootElement, "fanartres", m_fanartRes, 0, 9999); + XMLUtils::GetUInt(pRootElement, "imageres", m_imageRes, 0, 9999); if (XMLUtils::GetString(pRootElement, "imagescalingalgorithm", tmp)) m_imageScalingAlgorithm = CPictureScalingAlgorithm::FromString(tmp); XMLUtils::GetBoolean(pRootElement, "playlistasfolders", m_playlistAsFolders);
View file
_service:download_files:master.tar.gz/xbmc/settings/AdvancedSettings.h
Changed
@@ -205,6 +205,7 @@ bool m_extraLogEnabled; int m_extraLogLevels; std::string m_cddbAddress; + bool m_addSourceOnTop; //!< True to put 'add source' buttons on top //airtunes + airplay int m_airTunesPort;
View file
_service:download_files:master.tar.gz/xbmc/storage/DetectDVDType.cpp
Changed
@@ -37,9 +37,6 @@ #include "settings/AdvancedSettings.h" #include "GUIUserMessages.h" #include "utils/URIUtils.h" -#if defined (LIBCDIO_VERSION_NUM) && (LIBCDIO_VERSION_NUM > 77) || defined (TARGET_DARWIN) -#define USING_CDIO78 -#endif #include "guilib/GUIWindowManager.h" #include "FileItem.h" #include "Application.h" @@ -314,49 +311,6 @@ if (strlen(dvdDevice) == 0) return DRIVE_NONE; -#ifndef USING_CDIO78 - - int fd = 0; - - fd = open(dvdDevice, O_RDONLY | O_NONBLOCK); - if (fd<0) - { - CLog::Log(LOGERROR, "Unable to open CD-ROM device %s for polling.", dvdDevice); - return DRIVE_NOT_READY; - } - - int drivestatus = ioctl(fd, CDROM_DRIVE_STATUS, 0); - - switch(drivestatus) - { - case CDS_NO_INFO: - m_dwTrayState = TRAY_CLOSED_NO_MEDIA; - break; - - case CDS_NO_DISC: - m_dwTrayState = TRAY_CLOSED_NO_MEDIA; - break; - - case CDS_TRAY_OPEN: - m_dwTrayState = TRAY_OPEN; - break; - - case CDS_DISC_OK: - m_dwTrayState = TRAY_CLOSED_MEDIA_PRESENT; - break; - - case CDS_DRIVE_NOT_READY: - close(fd); - return DRIVE_NOT_READY; - - default: - m_dwTrayState = TRAY_CLOSED_NO_MEDIA; - } - - close(fd); - -#else - // The following code works with libcdio >= 0.78 // To enable it, download and install the latest version from // http://www.gnu.org/software/libcdio/ @@ -393,7 +347,6 @@ else return DRIVE_NOT_READY; -#endif // USING_CDIO78 #endif // TARGET_POSIX if (m_dwTrayState == TRAY_CLOSED_MEDIA_PRESENT)
View file
_service:download_files:master.tar.gz/xbmc/storage/cdioSupport.cpp
Changed
@@ -637,20 +637,22 @@ CSingleLock lock(*m_cdio); // Get the CD-Text , if any -#if defined (LIBCDIO_VERSION_NUM) && (LIBCDIO_VERSION_NUM > 83) +#if defined(LIBCDIO_VERSION_NUM) && (LIBCDIO_VERSION_NUM >= 84) cdtext_t *pcdtext = static_cast<cdtext_t*>( cdio_get_cdtext(cdio) ); #else + //! @todo - remove after Ubuntu 16.04 (Xenial) is EOL cdtext_t *pcdtext = (cdtext_t *)::cdio_get_cdtext(cdio, trackNum); #endif if (pcdtext == NULL) return ; -#if defined (LIBCDIO_VERSION_NUM) && (LIBCDIO_VERSION_NUM > 83) +#if defined(LIBCDIO_VERSION_NUM) && (LIBCDIO_VERSION_NUM >= 84) for (int i=0; i < MAX_CDTEXT_FIELDS; i++) if (cdtext_get_const(pcdtext, (cdtext_field_t)i, trackNum)) xcdt[(cdtext_field_t)i] = cdtext_field2str((cdtext_field_t)i); #else + //! @todo - remove after Ubuntu 16.04 (Xenial) is EOL // Same ids used in libcdio and for our structure + the ids are consecutive make this copy loop safe. for (int i = 0; i < MAX_CDTEXT_FIELDS; i++) if (pcdtext->field[i])
View file
_service:download_files:master.tar.gz/xbmc/threads/platform/pthreads/ThreadImpl.cpp
Changed
@@ -28,12 +28,8 @@ #include <string.h> #ifdef TARGET_FREEBSD #include <sys/param.h> -#if __FreeBSD_version < 900031 -#include <sys/thr.h> -#else #include <pthread_np.h> #endif -#endif #include <signal.h> #include "utils/log.h" @@ -89,13 +85,7 @@ void CThread::SetThreadInfo() { #ifdef TARGET_FREEBSD -#if __FreeBSD_version < 900031 - long lwpid; - thr_self(&lwpid); - m_ThreadOpaque.LwpId = lwpid; -#else m_ThreadOpaque.LwpId = pthread_getthreadid_np(); -#endif #elif defined(TARGET_ANDROID) m_ThreadOpaque.LwpId = gettid(); #else @@ -104,9 +94,7 @@ #if defined(HAVE_PTHREAD_SETNAME_NP) #ifdef TARGET_DARWIN -#if(__MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 || __IPHONE_OS_VERSION_MIN_REQUIRED >= 30200) pthread_setname_np(m_ThreadName.c_str()); -#endif #else pthread_setname_np(m_ThreadId, m_ThreadName.c_str()); #endif
View file
_service:download_files:master.tar.gz/xbmc/utils/CryptThreading.cpp
Changed
@@ -34,16 +34,6 @@ #include <openssl/crypto.h> #endif -#ifdef HAVE_GCRYPT -#include <gcrypt.h> -#include <errno.h> - -#if GCRYPT_VERSION_NUMBER < 0x010600 -GCRY_THREAD_OPTION_PTHREAD_IMPL; -#endif - -#endif - /* ========================================================================= */ /* openssl locking implementation for curl */ #if defined(HAVE_OPENSSL) && OPENSSL_VERSION_NUMBER < 0x10100000L @@ -84,14 +74,6 @@ for (int i = 0; i < numlocks; i++) locks[i] = NULL; -#ifdef HAVE_GCRYPT -#if GCRYPT_VERSION_NUMBER < 0x010600 - // set up gcrypt - gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); - attemptedToSetSSLMTHook = true; -#endif -#endif - if (!attemptedToSetSSLMTHook) CLog::Log(LOGWARNING, "Could not determine the libcurl security library to set the locking scheme. This may cause problem with multithreaded use of ssl or libraries that depend on it (libcurl).");
View file
_service:download_files:master.tar.gz/xbmc/utils/SystemInfo.cpp
Changed
@@ -1308,8 +1308,7 @@ static const int major = (__FreeBSD_version / 100000) % 100; static const int minor = (__FreeBSD_version / 1000) % 100; static const int Rxx = __FreeBSD_version % 1000; - if ((major < 9 && Rxx == 0) || - __FreeBSD_version == 900044 || __FreeBSD_version == 901000) + if ((major < 9 && Rxx == 0)) return StringUtils::Format("version %d.%d-RELEASE", major, minor); if (Rxx >= 500) return StringUtils::Format("version %d.%d-STABLE", major, minor);
View file
_service:download_files:master.tar.gz/xbmc/windows/GUIMediaWindow.cpp
Changed
@@ -847,7 +847,8 @@ pItem->SetLabel(strLabel); pItem->SetLabelPreformatted(true); pItem->m_bIsFolder = true; - pItem->SetSpecialSort(SortSpecialOnBottom); + pItem->SetSpecialSort(g_advancedSettings.m_addSourceOnTop ? + SortSpecialOnTop : SortSpecialOnBottom); m_vecItems->Add(pItem); } m_iLastControl = GetFocusedControlID();
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.