diff options
134 files changed, 1382 insertions, 781 deletions
diff --git a/.gitignore b/.gitignore index 19c200efe5..4fb64a22fe 100644 --- a/.gitignore +++ b/.gitignore @@ -288,7 +288,6 @@ cmake_install.cmake /tools/darwin/packaging/darwin_embedded/mkdeb-darwin_embedded.sh /tools/darwin/packaging/osx/mkdmg-osx.sh /tools/darwin/packaging/osx/VolumeIcon.icns -/tools/darwin/packaging/darwin_embedded/migrate_to_kodi.sh /tools/darwin/packaging/seatbeltunlock/mkdeb-seatbeltunlock.sh /tools/darwin/runtime/XBMCHelper diff --git a/addons/metadata.local/addon.xml b/addons/metadata.local/addon.xml index 897277b662..546fe134a7 100755 --- a/addons/metadata.local/addon.xml +++ b/addons/metadata.local/addon.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <addon id="metadata.local" name="Local information only" - version="1.0.0" + version="1.0.1" provider-name="Team Kodi"> <requires> <import addon="xbmc.metadata" version="1.0"/> @@ -22,8 +22,12 @@ language="multi" library="local.xml"/> <extension point="xbmc.addon.metadata"> - <summary lang="en">Local Infomation only pseudo-scraper</summary> - <description lang="en">Use local information only</description> + <summary lang="en_GB">Local Infomation only pseudo-scraper</summary> + <description lang="en_GB">Use local information only</description> <platform>all</platform> + <license>GPL-2.0-only</license> + <assets> + <icon>icon.png</icon> + </assets> </extension> </addon> diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index 0bca1a33b1..0ce12b7d56 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -20569,7 +20569,19 @@ msgctxt "#36556" msgid "Tone mapping parameter" msgstr "" -#empty strings from id 36557 to 36559 +#. label of a setting, tone mapping method +#: xbmc/video/dialogs/GUIDialogVideoSettings.cpp +msgctxt "#36557" +msgid "ACES Filmic" +msgstr "" + +#. label of a setting, tone mapping method +#: xbmc/video/dialogs/GUIDialogVideoSettings.cpp +msgctxt "#36558" +msgid "Hable" +msgstr "" + +#empty string with id 36559 #: system/settings/settings.xml msgctxt "#36560" diff --git a/cmake/scripts/darwin_embedded/Install.cmake b/cmake/scripts/darwin_embedded/Install.cmake index af18277a5e..02464eef9f 100644 --- a/cmake/scripts/darwin_embedded/Install.cmake +++ b/cmake/scripts/darwin_embedded/Install.cmake @@ -122,11 +122,6 @@ endif() set(DEPENDS_ROOT_FOR_XCODE ${NATIVEPREFIX}/..) configure_file(${CMAKE_SOURCE_DIR}/tools/darwin/packaging/darwin_embedded/mkdeb-darwin_embedded.sh.in ${CMAKE_BINARY_DIR}/tools/darwin/packaging/darwin_embedded/mkdeb-darwin_embedded.sh @ONLY) - -if(CORE_PLATFORM_NAME_LC STREQUAL ios) - configure_file(${CMAKE_SOURCE_DIR}/tools/darwin/packaging/darwin_embedded/migrate_to_kodi.sh.in - ${CMAKE_BINARY_DIR}/tools/darwin/packaging/darwin_embedded/migrate_to_kodi.sh @ONLY) -endif() add_custom_target(deb COMMAND sh ./mkdeb-darwin_embedded.sh ${CORE_BUILD_CONFIG} diff --git a/system/keymaps/keyboard.xml b/system/keymaps/keyboard.xml index 5cb986f1b6..694b6b10cc 100644 --- a/system/keymaps/keyboard.xml +++ b/system/keymaps/keyboard.xml @@ -398,6 +398,7 @@ <minus mod="ctrl">VolAmpDown</minus> <b mod="ctrl">CreateBookmark</b> <b mod="alt">CreateEpisodeBookmark</b> + <f11 mod="alt">CycleToneMapMethod</f11> </keyboard> </FullscreenVideo> <FullscreenGame> diff --git a/system/shaders/output_d3d.fx b/system/shaders/output_d3d.fx index 06233b692f..9e4f250850 100644 --- a/system/shaders/output_d3d.fx +++ b/system/shaders/output_d3d.fx @@ -41,58 +41,111 @@ SamplerState DitherSampler : IMMUTABLE Filter = MIN_MAG_MIP_POINT; }; #endif -#if defined(KODI_TONE_MAPPING) +#if (defined(KODI_TONE_MAPPING_ACES) || defined(KODI_TONE_MAPPING_HABLE) || defined(KODI_HLG_TO_PQ)) +static const float ST2084_m1 = 2610.0f / (4096.0f * 4.0f); +static const float ST2084_m2 = (2523.0f / 4096.0f) * 128.0f; +static const float ST2084_c1 = 3424.0f / 4096.0f; +static const float ST2084_c2 = (2413.0f / 4096.0f) * 32.0f; +static const float ST2084_c3 = (2392.0f / 4096.0f) * 32.0f; +#endif +#if defined(KODI_TONE_MAPPING_REINHARD) float g_toneP1; float3 g_coefsDst; -float tonemap(float val) +float reinhard(float x) +{ + return x * (1.0f + x / (g_toneP1 * g_toneP1)) / (1.0f + x); +} +#endif +#if defined(KODI_TONE_MAPPING_ACES) +float g_luminance; +float g_toneP1; + +float3 aces(float3 x) { - return val * (1 + val/(g_toneP1*g_toneP1))/(1 + val); + const float A = 2.51f; + const float B = 0.03f; + const float C = 2.43f; + const float D = 0.59f; + const float E = 0.14f; + return (x * (A * x + B)) / (x * (C * x + D) + E); +} +#endif +#if defined(KODI_TONE_MAPPING_HABLE) +float g_toneP1; +float g_toneP2; + +float3 hable(float3 x) +{ + const float A = 0.15f; + const float B = 0.5f; + const float C = 0.1f; + const float D = 0.2f; + const float E = 0.02f; + const float F = 0.3f; + return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F; +} +#endif +#if (defined(KODI_TONE_MAPPING_ACES) || defined(KODI_TONE_MAPPING_HABLE)) +float3 inversePQ(float3 x) +{ + x = pow(max(x, 0.0f), 1.0f / ST2084_m2); + x = max(x - ST2084_c1, 0.0f) / (ST2084_c2 - ST2084_c3 * x); + x = pow(x, 1.0f / ST2084_m1); + return x; } #endif #if defined(KODI_HLG_TO_PQ) float inverseHLG(float x) { - const float B67_a = 0.17883277; - const float B67_b = 0.28466892; - const float B67_c = 0.55991073; - const float B67_inv_r2 = 4.0; - if (x <= 0.5) + const float B67_a = 0.17883277f; + const float B67_b = 0.28466892f; + const float B67_c = 0.55991073f; + const float B67_inv_r2 = 4.0f; + if (x <= 0.5f) x = x * x * B67_inv_r2; else x = exp((x - B67_c) / B67_a) + B67_b; return x; } -float4 tranferPQ(float4 color) +float3 tranferPQ(float3 x) { - const float ST2084_m1 = 2610.0 / (4096.0 * 4.0); - const float ST2084_m2 = (2523.0 / 4096.0) * 128.0; - const float ST2084_c1 = 3424.0 / 4096.0; - const float ST2084_c2 = (2413.0 / 4096.0) * 32.0; - const float ST2084_c3 = (2392.0 / 4096.0) * 32.0; - color = pow(color / 1000.0, ST2084_m1); - color = (ST2084_c1 + ST2084_c2 * color) / (1 + ST2084_c3 * color); - color = pow(color, ST2084_m2); - return color; + x = pow(x / 1000.0f, ST2084_m1); + x = (ST2084_c1 + ST2084_c2 * x) / (1.0f + ST2084_c3 * x); + x = pow(x, ST2084_m2); + return x; } #endif float4 output4(float4 color, float2 uv) { -#if defined(KODI_TONE_MAPPING) +#if defined(KODI_TONE_MAPPING_REINHARD) float luma = dot(color.rgb, g_coefsDst); - color.rgb *= tonemap(luma) / luma; + color.rgb *= reinhard(luma) / luma; +#endif +#if defined(KODI_TONE_MAPPING_ACES) + color.rgb = inversePQ(color.rgb); + color.rgb *= (10000.0f / g_luminance) * (2.0f / g_toneP1); + color.rgb = aces(color.rgb); + color.rgb *= (1.24f / g_toneP1); + color.rgb = pow(color.rgb, 0.27f); +#endif +#if defined(KODI_TONE_MAPPING_HABLE) + color.rgb = inversePQ(color.rgb); + color.rgb *= g_toneP1; + color.rgb = hable(color.rgb * g_toneP2) / hable(g_toneP2); + color.rgb = pow(color.rgb, 1.0f / 2.2f); #endif #if defined(KODI_HLG_TO_PQ) color.r = inverseHLG(color.r); color.g = inverseHLG(color.g); color.b = inverseHLG(color.b); - float3 ootf_2020 = float3(0.2627, 0.6780, 0.0593); - float ootf_ys = 2000.0 * dot(ootf_2020, color); - color = color * pow(ootf_ys, 0.200); - color = tranferPQ(color); + float3 ootf_2020 = float3(0.2627f, 0.6780f, 0.0593f); + float ootf_ys = 2000.0f * dot(ootf_2020, color.rgb); + color.rgb *= pow(ootf_ys, 0.2f); + color.rgb = tranferPQ(color.rgb); #endif #if defined(KODI_3DLUT) half3 scale = m_LUTParams.x; diff --git a/tools/Linux/kodi.sh.in b/tools/Linux/kodi.sh.in index 6899a47c1e..aaf2f4ff7f 100644 --- a/tools/Linux/kodi.sh.in +++ b/tools/Linux/kodi.sh.in @@ -59,18 +59,6 @@ fi APPORT_CORE="/var/crash/$(echo -n ${KODI_BINARY}|tr / _).$(id -u).crash" -migrate_home() -{ - [ "$(basename $0)" = "xbmc" ] && echo "WARNING: Running ${bin_name} as "xbmc" is deprecated and will be removed in later versions, please switch to using the ${bin_name} binary" - - #check if data migration is needed - if [ -d "${HOME}/.xbmc" ] && [ ! -d "${KODI_DATA}" ]; then - echo "INFO: migrating userdata folder. Renaming ${HOME}/.xbmc to $KODI_DATA" - mv ${HOME}/.xbmc $KODI_DATA - touch ${KODI_DATA}/.kodi_data_was_migrated - fi -} - command_exists() { command -pv $1 >/dev/null 2>&1 @@ -172,8 +160,6 @@ propagate_sigterm() { trap propagate_sigterm TERM -migrate_home - if command_exists gdb; then # Output warning in case ulimit is unsupported by shell eval ulimit -c unlimited diff --git a/tools/android/packaging/xbmc/src/Splash.java.in b/tools/android/packaging/xbmc/src/Splash.java.in index 4cbe9ca6a7..66dca26f24 100644 --- a/tools/android/packaging/xbmc/src/Splash.java.in +++ b/tools/android/packaging/xbmc/src/Splash.java.in @@ -196,7 +196,6 @@ public class Splash extends Activity else { SetupEnvironment(); - MigrateUserData(); if (mState == InError) { @@ -626,55 +625,6 @@ public class Splash extends Activity } } - private void MigrateUserData() - { - String sOldUserDir; - File fOldUserDir; - try - { - sOldUserDir = getExternalFilesDir(null).getParentFile().getParentFile() + "/org.xbmc.xbmc/files/.xbmc"; - fOldUserDir = new File(sOldUserDir); - if (!fOldUserDir.exists()) - return; - } - catch (Exception e) - { - return; - } - - File fNewUserDir = new File(getExternalFilesDir(null), ".@APP_NAME_LC@"); - String s@APP_NAME@Migrated = fNewUserDir.getAbsolutePath() + "/.@APP_NAME_LC@_data_was_migrated"; - File f@APP_NAME@Migrated = new File(s@APP_NAME@Migrated); - - Log.d(TAG, "External_dir = " + fOldUserDir); - if (fOldUserDir.exists() && !fNewUserDir.exists()) - { - Log.d(TAG, "XBMC user data detected at " + fOldUserDir.getAbsolutePath() + ", migrating to " + fNewUserDir.getAbsolutePath()); - if (!fNewUserDir.getParentFile().exists() && !fNewUserDir.getParentFile().mkdirs()) - { - Log.d(TAG, "Error creating " + fNewUserDir.getParentFile().getAbsolutePath()); - return; - } - if (fOldUserDir.renameTo(fNewUserDir)) - { - try - { - new FileOutputStream(f@APP_NAME@Migrated).close(); - } - catch (IOException e1) - { - e1.printStackTrace(); - } - Log.d(TAG, "XBMC user data migrated to @APP_NAME@ successfully"); - } - else - { - Log.d(TAG, "Error migrating XBMC user data"); - } - } - } - - private boolean ParseCpuFeature() { ProcessBuilder cmd; @@ -951,7 +901,6 @@ public class Splash extends Activity mState = ChecksDone; SetupEnvironment(); - MigrateUserData(); if ((mState != DownloadingObb && mState != InError) && fXbmcHome.exists() && fXbmcHome.lastModified() >= fPackagePath.lastModified() && !mInstallLibs) { diff --git a/tools/android/packaging/xbmc/src/XBMCJsonRPC.java.in b/tools/android/packaging/xbmc/src/XBMCJsonRPC.java.in index 9e3efa983e..93bb84314b 100644 --- a/tools/android/packaging/xbmc/src/XBMCJsonRPC.java.in +++ b/tools/android/packaging/xbmc/src/XBMCJsonRPC.java.in @@ -75,50 +75,50 @@ public class XBMCJsonRPC "{\"jsonrpc\": \"2.0\", \"method\": \"VideoLibrary.GetMovies\", " + "\"params\": { \"filter\": {\"field\": \"playcount\", \"operator\": \"is\", \"value\": \"0\"}, " + "\"limits\": { \"start\" : 0, \"end\": 10}, " - + "\"properties\" : [\"imdbnumber\", \"title\", \"tagline\", \"thumbnail\", \"fanart\", \"year\", \"runtime\", \"file\", \"plot\"], " + + "\"properties\" : [\"imdbnumber\", \"title\", \"tagline\", \"art\", \"year\", \"runtime\", \"file\", \"plot\"], " + "\"sort\": { \"order\": \"descending\", \"method\": \"random\", \"ignorearticle\": true } }, " + "\"id\": \"1\"}"; private String RECOMMENDATIONS_SHOWS_JSON = - "{\"jsonrpc\":\"2.0\",\"method\":\"VideoLibrary.GetTVShows\",\"params\":{\"filter\":{\"and\":[{\"field\":\"playcount\",\"operator\":\"is\",\"value\":\"0\"},{\"field\":\"plot\",\"operator\":\"isnot\",\"value\":\"\"}]},\"limits\":{\"start\":0,\"end\":10},\"properties\":[\"imdbnumber\",\"title\",\"plot\",\"thumbnail\",\"fanart\", \"studio\"],\"sort\":{\"order\":\"descending\",\"method\":\"lastplayed\",\"ignorearticle\":true}},\"id\":\"1\"}"; + "{\"jsonrpc\":\"2.0\",\"method\":\"VideoLibrary.GetTVShows\",\"params\":{\"filter\":{\"and\":[{\"field\":\"playcount\",\"operator\":\"is\",\"value\":\"0\"},{\"field\":\"plot\",\"operator\":\"isnot\",\"value\":\"\"}]},\"limits\":{\"start\":0,\"end\":10},\"properties\":[\"imdbnumber\",\"title\",\"plot\",\"art\",\"studio\"],\"sort\":{\"order\":\"descending\",\"method\":\"lastplayed\",\"ignorearticle\":true}},\"id\":\"1\"}"; private String RECOMMENDATIONS_ALBUMS_JSON = - "{\"jsonrpc\": \"2.0\", \"method\": \"AudioLibrary.GetAlbums\", \"params\": { \"limits\": { \"start\" : 0, \"end\": 3}, \"properties\" : [\"title\", \"displayartist\", \"thumbnail\", \"fanart\"], \"sort\": { \"order\": \"descending\", \"method\": \"random\", \"ignorearticle\": true } }, \"id\": \"1\"}"; + "{\"jsonrpc\": \"2.0\", \"method\": \"AudioLibrary.GetAlbums\", \"params\": { \"limits\": { \"start\" : 0, \"end\": 3}, \"properties\" : [\"title\", \"displayartist\", \"art\"], \"sort\": { \"order\": \"descending\", \"method\": \"random\", \"ignorearticle\": true } }, \"id\": \"1\"}"; private String SEARCH_MOVIES_JSON = "{\"jsonrpc\": \"2.0\", \"method\": \"VideoLibrary.GetMovies\", " + "\"params\": { \"filter\": {%s}, " + "\"limits\": { \"start\" : 0, \"end\": 10}, " - + "\"properties\" : [\"imdbnumber\", \"title\", \"tagline\", \"thumbnail\", \"fanart\", \"year\", \"runtime\"], " + + "\"properties\" : [\"imdbnumber\", \"title\", \"tagline\", \"art\", \"year\", \"runtime\"], " + "\"sort\": { \"order\": \"ascending\", \"method\": \"title\", \"ignorearticle\": true } }, " + "\"id\": \"%s\"}"; private String SEARCH_SHOWS_JSON = - "{\"jsonrpc\":\"2.0\",\"method\":\"VideoLibrary.GetTVShows\",\"params\":{\"filter\":{%s},\"limits\":{\"start\":0,\"end\":10},\"properties\":[\"imdbnumber\",\"title\",\"plot\",\"thumbnail\",\"fanart\",\"year\"],\"sort\":{\"order\":\"descending\",\"method\":\"lastplayed\",\"ignorearticle\":true}},\"id\":\"%s\"}"; + "{\"jsonrpc\":\"2.0\",\"method\":\"VideoLibrary.GetTVShows\",\"params\":{\"filter\":{%s},\"limits\":{\"start\":0,\"end\":10},\"properties\":[\"imdbnumber\",\"title\",\"plot\",\"art\",\"year\"],\"sort\":{\"order\":\"descending\",\"method\":\"lastplayed\",\"ignorearticle\":true}},\"id\":\"%s\"}"; private String SEARCH_ALBUMS_JSON = - "{\"jsonrpc\": \"2.0\", \"method\": \"AudioLibrary.GetAlbums\", \"params\": {\"filter\":{%s},\"limits\": { \"start\" : 0, \"end\": 10}, \"properties\" : [\"title\", \"displayartist\", \"thumbnail\", \"fanart\"], \"sort\": { \"order\": \"descending\", \"method\": \"dateadded\", \"ignorearticle\": true } }, \"id\": \"%s\"}"; + "{\"jsonrpc\": \"2.0\", \"method\": \"AudioLibrary.GetAlbums\", \"params\": {\"filter\":{%s},\"limits\": { \"start\" : 0, \"end\": 10}, \"properties\" : [\"title\", \"displayartist\", \"art\"], \"sort\": { \"order\": \"descending\", \"method\": \"dateadded\", \"ignorearticle\": true } }, \"id\": \"%s\"}"; private String SEARCH_ARTISTS_JSON = - "{\"jsonrpc\": \"2.0\", \"method\": \"AudioLibrary.GetArtists\", \"params\": {\"filter\":{%s},\"limits\": { \"start\" : 0, \"end\": 10}, \"properties\" : [\"description\", \"thumbnail\", \"fanart\"], \"sort\": { \"order\": \"descending\", \"method\": \"dateadded\", \"ignorearticle\": true } }, \"id\": \"%s\"}"; + "{\"jsonrpc\": \"2.0\", \"method\": \"AudioLibrary.GetArtists\", \"params\": {\"filter\":{%s},\"limits\": { \"start\" : 0, \"end\": 10}, \"properties\" : [\"description\", \"art\"], \"sort\": { \"order\": \"descending\", \"method\": \"dateadded\", \"ignorearticle\": true } }, \"id\": \"%s\"}"; private String RETRIEVE_MOVIE_DETAILS = - "{ \"jsonrpc\": \"2.0\", \"method\": \"VideoLibrary.GetMovieDetails\", \"params\": { \"movieid\" : %s, \"properties\" : [\"imdbnumber\", \"title\", \"tagline\", \"thumbnail\", \"fanart\", \"year\", \"runtime\", \"file\", \"plot\", \"trailer\", \"rating\"] }, \"id\": \"%s\" }"; + "{ \"jsonrpc\": \"2.0\", \"method\": \"VideoLibrary.GetMovieDetails\", \"params\": { \"movieid\" : %s, \"properties\" : [\"imdbnumber\", \"title\", \"tagline\", \"art\", \"year\", \"runtime\", \"file\", \"plot\", \"trailer\", \"rating\"] }, \"id\": \"%s\" }"; private String RETRIEVE_EPISODE_DETAILS = - "{ \"jsonrpc\": \"2.0\", \"method\": \"VideoLibrary.GetEpisodeDetails\", \"params\": { \"episodeid\" : %s, \"properties\" : [\"title\", \"tvshowid\", \"showtitle\", \"season\", \"episode\", \"thumbnail\", \"fanart\", \"file\", \"plot\", \"rating\", \"runtime\", \"firstaired\"] }, \"id\": \"%s\" }"; + "{ \"jsonrpc\": \"2.0\", \"method\": \"VideoLibrary.GetEpisodeDetails\", \"params\": { \"episodeid\" : %s, \"properties\" : [\"title\", \"tvshowid\", \"showtitle\", \"season\", \"episode\", \"art\", \"file\", \"plot\", \"rating\", \"runtime\", \"firstaired\"] }, \"id\": \"%s\" }"; private String RETRIEVE_TVSHOW_DETAILS = - "{ \"jsonrpc\": \"2.0\", \"method\": \"VideoLibrary.GetTVShowDetails\", \"params\": { \"tvshowid\" : %s, \"properties\" : [\"title\", \"studio\", \"thumbnail\", \"fanart\", \"plot\", \"year\", \"rating\"] }, \"id\": \"%s\" }"; + "{ \"jsonrpc\": \"2.0\", \"method\": \"VideoLibrary.GetTVShowDetails\", \"params\": { \"tvshowid\" : %s, \"properties\" : [\"title\", \"studio\", \"art\", \"plot\", \"year\", \"rating\"] }, \"id\": \"%s\" }"; private String RETRIEVE_ALBUM_DETAILS = - "{ \"jsonrpc\": \"2.0\", \"method\": \"AudioLibrary.GetAlbumDetails\", \"params\": { \"albumid\" : %s, \"properties\" : [\"title\", \"displayartist\", \"thumbnail\", \"fanart\", \"artistid\"] }, \"id\": \"%s\" }"; + "{ \"jsonrpc\": \"2.0\", \"method\": \"AudioLibrary.GetAlbumDetails\", \"params\": { \"albumid\" : %s, \"properties\" : [\"title\", \"displayartist\", \"art\", \"artistid\"] }, \"id\": \"%s\" }"; private String RETRIEVE_SONG_DETAILS = - "{ \"jsonrpc\": \"2.0\", \"method\": \"AudioLibrary.GetSongDetails\", \"params\": { \"songid\" : %s, \"properties\" : [\"title\", \"displayartist\", \"thumbnail\", \"fanart\", \"albumid\", \"artistid\", \"file\"] }, \"id\": \"%s\" }"; + "{ \"jsonrpc\": \"2.0\", \"method\": \"AudioLibrary.GetSongDetails\", \"params\": { \"songid\" : %s, \"properties\" : [\"title\", \"displayartist\", \"art\", \"albumid\", \"artistid\", \"file\"] }, \"id\": \"%s\" }"; private String RETRIEVE_MUSICVIDEO_DETAILS = - "{ \"jsonrpc\": \"2.0\", \"method\": \"VideoLibrary.GetMusicVideoDetails\", \"params\": { \"musicvideoid\" : %s, \"properties\" : [\"title\", \"artist\", \"thumbnail\", \"fanart\", \"file\"] }, \"id\": \"%s\" }"; + "{ \"jsonrpc\": \"2.0\", \"method\": \"VideoLibrary.GetMusicVideoDetails\", \"params\": { \"musicvideoid\" : %s, \"properties\" : [\"title\", \"artist\", \"art\", \"file\"] }, \"id\": \"%s\" }"; private String RETRIEVE_FILE_ITEMS = "{ \"jsonrpc\": \"2.0\", \"method\": \"Files.GetDirectory\", \"params\": { \"directory\" : \"%s\" }, \"id\": \"%s\" }"; @@ -259,7 +259,18 @@ public class XBMCJsonRPC for (int i = 0; i < movies.size(); ++i) { JsonObject movie = movies.get(i).getAsJsonObject(); - mc.addRow(new Object[]{movie.get("movieid"), movie.get("title"), movie.get("tagline"), movie.get("thumbnail"), movie.get("fanart")}); + + String poster = extractKeyFromArtMap(movie, "poster"); + String thumb = extractKeyFromArtMap(movie, "thumb"); + String fanart = extractKeyFromArtMap(movie, "fanart"); + + mc.addRow(new Object[]{ + movie.get("movieid"), + movie.get("title"), + movie.get("tagline"), + poster != null && !poster.isEmpty() ? poster : thumb != null && !thumb.isEmpty() ? thumb : "", + fanart != null && !fanart.isEmpty() ? fanart : "" + }); } } catch (Exception e) { @@ -284,7 +295,18 @@ public class XBMCJsonRPC for (int i = 0; i < tvshows.size(); ++i) { JsonObject tvshow = tvshows.get(i).getAsJsonObject(); - mc.addRow(new Object[]{tvshow.get("movieid"), tvshow.get("title"), tvshow.get("plot"), tvshow.get("thumbnail"), tvshow.get("fanart")}); + + String poster = extractKeyFromArtMap(tvshow, "poster"); + String thumb = extractKeyFromArtMap(tvshow, "thumb"); + String fanart = extractKeyFromArtMap(tvshow, "fanart"); + + mc.addRow(new Object[]{ + tvshow.get("movieid"), + tvshow.get("title"), + tvshow.get("plot"), + poster != null && !poster.isEmpty() ? poster : thumb != null && !thumb.isEmpty() ? thumb : "", + fanart != null && !fanart.isEmpty() ? fanart : "" + }); } } catch (Exception e) { @@ -387,6 +409,9 @@ public class XBMCJsonRPC { JsonObject movie = movies.get(i).getAsJsonObject(); + String poster = extractKeyFromArtMap(movie, "poster"); + String thumb = extractKeyFromArtMap(movie, "thumb"); + int rYear = 0; long rDur = 0; try @@ -403,8 +428,12 @@ public class XBMCJsonRPC movie.get("movieid").getAsString(), movie.get("title").getAsString(), movie.get("tagline").getAsString(), - XBMCFileContentProvider.buildUri(getDownloadUrl(movie.get("thumbnail").getAsString())).toString(), - XBMCFileContentProvider.buildUri(getDownloadUrl(movie.get("thumbnail").getAsString())).toString(), + XBMCFileContentProvider.buildUri(getDownloadUrl( + poster != null && !poster.isEmpty() ? poster : thumb != null && !thumb.isEmpty() ? thumb : "" + )).toString(), + XBMCFileContentProvider.buildUri(getDownloadUrl( + poster != null && !poster.isEmpty() ? poster : thumb != null && !thumb.isEmpty() ? thumb : "" + )).toString(), Intent.ACTION_GET_CONTENT, Uri.parse("videodb://movies/titles/" + movie.get("movieid").getAsString() + "?showinfo=true"), 0, @@ -436,6 +465,9 @@ public class XBMCJsonRPC { JsonObject tvshow = tvshows.get(i).getAsJsonObject(); + String poster = extractKeyFromArtMap(tvshow, "poster"); + String thumb = extractKeyFromArtMap(tvshow, "thumb"); + int rYear = 0; long rDur = 0; try @@ -451,8 +483,12 @@ public class XBMCJsonRPC tvshow.get("tvshowid").getAsString(), tvshow.get("title").getAsString(), tvshow.get("plot").getAsString(), - XBMCFileContentProvider.buildUri(getDownloadUrl(tvshow.get("thumbnail").getAsString())).toString(), - XBMCFileContentProvider.buildUri(getDownloadUrl(tvshow.get("thumbnail").getAsString())).toString(), + XBMCFileContentProvider.buildUri(getDownloadUrl( + poster != null && !poster.isEmpty() ? poster : thumb != null && !thumb.isEmpty() ? thumb : "" + )).toString(), + XBMCFileContentProvider.buildUri(getDownloadUrl( + poster != null && !poster.isEmpty() ? poster : thumb != null && !thumb.isEmpty() ? thumb : "" + )).toString(), Intent.ACTION_GET_CONTENT, Uri.parse("videodb://tvshows/titles/" + tvshow.get("tvshowid").getAsString() + "?showinfo=true"), 0, @@ -484,13 +520,15 @@ public class XBMCJsonRPC for (int i = 0; i < albums.size() && totCount < limit; ++i) { JsonObject album = albums.get(i).getAsJsonObject(); + String thumb = extractKeyFromArtMap(album, "thumb"); + mc.addRow(new Object[] { album.get("albumid").getAsString(), album.get("title").getAsString(), album.get("displayartist").getAsString(), - XBMCFileContentProvider.buildUri(getDownloadUrl(album.get("thumbnail").getAsString())).toString(), - XBMCFileContentProvider.buildUri(getDownloadUrl(album.get("thumbnail").getAsString())).toString(), + XBMCFileContentProvider.buildUri(getDownloadUrl(thumb != null && !thumb.isEmpty() ? thumb : "" )).toString(), + XBMCFileContentProvider.buildUri(getDownloadUrl(thumb != null && !thumb.isEmpty() ? thumb : "" )).toString(), Intent.ACTION_GET_CONTENT, Uri.parse("musicdb://albums/" + album.get("albumid").getAsString() + "/"), 0, @@ -520,13 +558,15 @@ public class XBMCJsonRPC for (int i = 0; i < artists.size() && totCount < limit; ++i) { JsonObject artist = artists.get(i).getAsJsonObject(); + String thumb = extractKeyFromArtMap(artist, "thumb"); + mc.addRow(new Object[] { artist.get("artistid").getAsString(), artist.get("artist").getAsString(), artist.get("description").getAsString(), - XBMCFileContentProvider.buildUri(getDownloadUrl(artist.get("thumbnail").getAsString())).toString(), - XBMCFileContentProvider.buildUri(getDownloadUrl(artist.get("thumbnail").getAsString())).toString(), + XBMCFileContentProvider.buildUri(getDownloadUrl(thumb != null && !thumb.isEmpty() ? thumb : "" )).toString(), + XBMCFileContentProvider.buildUri(getDownloadUrl(thumb != null && !thumb.isEmpty() ? thumb : "" )).toString(), Intent.ACTION_GET_CONTENT, Uri.parse("musicdb://artists/" + artist.get("artistid").getAsString() + "/"), 0, @@ -573,6 +613,10 @@ public class XBMCJsonRPC JsonObject movie = movies.get(i).getAsJsonObject(); int id = movie.get("movieid").getAsInt() + 1000000; + String poster = extractKeyFromArtMap(movie, "poster"); + String thumb = extractKeyFromArtMap(movie, "thumb"); + String fanart = extractKeyFromArtMap(movie, "fanart"); + final XBMCRecommendationBuilder notificationBuilder = new XBMCRecommendationBuilder() .setContext(ctx) .setSmallIcon(R.drawable.notif_icon) @@ -581,14 +625,23 @@ public class XBMCJsonRPC .setDescription(movie.get("tagline").getAsString()) .setIntent(buildPendingMovieIntent(ctx, movie)); - if (movie.has("fanart") && !movie.get("fanart").getAsString().isEmpty()) + if (fanart != null && !fanart.isEmpty()) + { notificationBuilder.setBackground(XBMCFileContentProvider.buildUri( - getDownloadUrl(movie.get("fanart").getAsString())).toString()); - if (movie.has("thumbnail") && !movie.get("thumbnail").getAsString().isEmpty()) + getDownloadUrl(fanart)).toString()); + } + + if (poster != null && !poster.isEmpty()) + { + Bitmap bitmap = getBitmap(ctx, poster); + notificationBuilder.setBitmap(bitmap); + } + else if (thumb != null && !thumb.isEmpty()) { - Bitmap bitmap = getBitmap(ctx, movie.get("thumbnail").getAsString()); + Bitmap bitmap = getBitmap(ctx, thumb); notificationBuilder.setBitmap(bitmap); } + Notification notification = notificationBuilder.build(); mNotificationManager.notify(id, notification); mRecomendationIds.add(id); @@ -620,6 +673,10 @@ public class XBMCJsonRPC JsonObject tvshow = tvshows.get(i).getAsJsonObject(); int id = tvshow.get("tvshowid").getAsInt() + 2000000; + String poster = extractKeyFromArtMap(tvshow, "poster"); + String thumb = extractKeyFromArtMap(tvshow, "thumb"); + String fanart = extractKeyFromArtMap(tvshow, "fanart"); + final XBMCRecommendationBuilder notificationBuilder = new XBMCRecommendationBuilder() .setContext(ctx) .setSmallIcon(R.drawable.notif_icon) @@ -628,14 +685,23 @@ public class XBMCJsonRPC .setDescription(tvshow.get("plot").getAsString()) .setIntent(buildPendingShowIntent(ctx, tvshow)); - if (tvshow.has("fanart") && !tvshow.get("fanart").getAsString().isEmpty()) + if (fanart != null && !fanart.isEmpty()) + { notificationBuilder.setBackground(XBMCFileContentProvider.buildUri( - getDownloadUrl(tvshow.get("fanart").getAsString())).toString()); - if (tvshow.has("thumbnail") && !tvshow.get("thumbnail").getAsString().isEmpty()) + getDownloadUrl(fanart)).toString()); + } + + if (poster != null && !poster.isEmpty()) + { + Bitmap bitmap = getBitmap(ctx, poster); + notificationBuilder.setBitmap(bitmap); + } + else if (thumb != null && !thumb.isEmpty()) { - Bitmap bitmap = getBitmap(ctx, tvshow.get("thumbnail").getAsString()); + Bitmap bitmap = getBitmap(ctx, thumb); notificationBuilder.setBitmap(bitmap); } + Notification notification = notificationBuilder.build(); mNotificationManager.notify(id, notification); mRecomendationIds.add(id); @@ -668,6 +734,9 @@ public class XBMCJsonRPC JsonObject album = albums.get(i).getAsJsonObject(); int id = album.get("albumid").getAsInt() + 3000000; + String thumb = extractKeyFromArtMap(album, "thumb"); + String fanart = extractKeyFromArtMap(album, "fanart"); + final XBMCRecommendationBuilder notificationBuilder = new XBMCRecommendationBuilder() .setContext(ctx) .setSmallIcon(R.drawable.notif_icon) @@ -676,14 +745,17 @@ public class XBMCJsonRPC .setDescription(album.get("displayartist").getAsString()) .setIntent(buildPendingAlbumIntent(ctx, album)); - if (album.has("fanart") && !album.get("fanart").getAsString().isEmpty()) + if (fanart != null && !fanart.isEmpty()) + { notificationBuilder.setBackground(XBMCFileContentProvider.buildUri( - getDownloadUrl(album.get("fanart").getAsString())).toString()); - if (album.has("thumbnail") && !album.get("thumbnail").getAsString().isEmpty()) + getDownloadUrl(fanart)).toString()); + } + if (thumb != null && !thumb.isEmpty()) { - Bitmap bitmap = getBitmap(ctx, album.get("thumbnail").getAsString()); + Bitmap bitmap = getBitmap(ctx, thumb); notificationBuilder.setBitmap(bitmap); } + Notification notification = notificationBuilder.build(); mNotificationManager.notify(id, notification); mRecomendationIds.add(id); @@ -797,19 +869,30 @@ public class XBMCJsonRPC med.setId(details.get("movieid").getAsInt()); med.setTitle(details.get("title").getAsString()); med.setDescription(details.get("plot").getAsString()); - if (details.has("thumbnail") && !details.get("thumbnail").getAsString().isEmpty()) + // poster + String poster = extractKeyFromArtMap(details, "poster"); + if (poster != null && !poster.isEmpty()) + { + med.setCardImageUrl(XBMCFileContentProvider.buildUri(poster).toString()); + med.setCardImageAspectRatio("2:3"); + } + // fallback to thumb + else { - String url = getDownloadUrl(details.get("thumbnail").getAsString()); - if (url != null && !url.isEmpty()) - med.setCardImageUrl(XBMCFileContentProvider.buildUri(url).toString()); + poster = extractKeyFromArtMap(details, "thumb"); + if (poster != null && !poster.isEmpty()) + { + med.setCardImageUrl(XBMCFileContentProvider.buildUri(poster).toString()); + med.setCardImageAspectRatio("16:9"); + } } - med.setCardImageAspectRatio("2:3"); - if (details.has("fanart") && !details.get("fanart").getAsString().isEmpty()) + // fanart + String fanart = extractKeyFromArtMap(details, "fanart"); + if (fanart != null && !fanart.isEmpty()) { - String url = getDownloadUrl(details.get("fanart").getAsString()); - if (url != null && !url.isEmpty()) - med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(url).toString()); + med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(fanart).toString()); } + med.setXbmcUrl("videodb://movies/titles/" + details.get("movieid").getAsString() + "?showinfo=true"); /* @@ -856,18 +939,29 @@ public class XBMCJsonRPC med.setId(details.get("tvshowid").getAsInt()); med.setTitle(details.get("title").getAsString()); med.setDescription(details.get("plot").getAsString()); - if (details.has("thumbnail") && !details.get("thumbnail").getAsString().isEmpty()) + + // poster + String poster = extractKeyFromArtMap(details, "poster"); + if (poster != null && !poster.isEmpty()) + { + med.setCardImageUrl(XBMCFileContentProvider.buildUri(poster).toString()); + med.setCardImageAspectRatio("2:3"); + } + // fallback to thumb + else { - String url = getDownloadUrl(details.get("thumbnail").getAsString()); - if (url != null && !url.isEmpty()) - med.setCardImageUrl(XBMCFileContentProvider.buildUri(url).toString()); + poster = extractKeyFromArtMap(details, "thumb"); + if (poster != null && !poster.isEmpty()) + { + med.setCardImageUrl(XBMCFileContentProvider.buildUri(poster).toString()); + med.setCardImageAspectRatio("16:9"); + } } - med.setCardImageAspectRatio("2:3"); - if (details.has("fanart") && !details.get("fanart").getAsString().isEmpty()) + // fanart + String fanart = extractKeyFromArtMap(details, "fanart"); + if (fanart != null && !fanart.isEmpty()) { - String url = getDownloadUrl(details.get("fanart").getAsString()); - if (url != null && !url.isEmpty()) - med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(url).toString()); + med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(fanart).toString()); } med.setXbmcUrl("videodb://tvshows/titles/" + details.get("tvshowid").getAsInt() + "/"); med.setCategory(Media.MEDIA_TYPE_TVSHOW); @@ -892,19 +986,21 @@ public class XBMCJsonRPC med.setId(details.get("episodeid").getAsInt()); med.setTitle(details.get("title").getAsString()); med.setDescription(details.get("plot").getAsString()); - if (details.has("thumbnail") && !details.get("thumbnail").getAsString().isEmpty()) + + // thumb + String thumb = extractKeyFromArtMap(details, "thumb"); + if (thumb != null && !thumb.isEmpty()) { - String url = getDownloadUrl(details.get("thumbnail").getAsString()); - if (url != null && !url.isEmpty()) - med.setCardImageUrl(XBMCFileContentProvider.buildUri(url).toString()); + med.setCardImageUrl(XBMCFileContentProvider.buildUri(thumb).toString()); + med.setCardImageAspectRatio("16:9"); } - med.setCardImageAspectRatio("16:9"); - if (details.has("fanart") && !details.get("fanart").getAsString().isEmpty()) + // fanart + String fanart = extractKeyFromArtMap(details, "fanart"); + if (fanart != null && !fanart.isEmpty()) { - String url = getDownloadUrl(details.get("fanart").getAsString()); - if (url != null && !url.isEmpty()) - med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(url).toString()); + med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(fanart).toString()); } + med.setXbmcUrl("videodb://tvshows/titles/" + details.get("tvshowid").getAsInt() + "/" + details.get("episodeid").getAsInt() + "?showinfo=true"); /* String url = getDownloadUrl(details.get("file").getAsString()); @@ -937,19 +1033,21 @@ public class XBMCJsonRPC med.setId(details.get("albumid").getAsInt()); med.setTitle(details.get("title").getAsString()); med.setDescription(details.get("displayartist").getAsString()); - if (details.has("thumbnail") && !details.get("thumbnail").getAsString().isEmpty()) + + // thumb + String thumb = extractKeyFromArtMap(details, "thumb"); + if (thumb != null && !thumb.isEmpty()) { - String url = getDownloadUrl(details.get("thumbnail").getAsString()); - if (url != null && !url.isEmpty()) - med.setCardImageUrl(XBMCFileContentProvider.buildUri(url).toString()); + med.setCardImageUrl(XBMCFileContentProvider.buildUri(thumb).toString()); + med.setCardImageAspectRatio("1:1"); } - med.setCardImageAspectRatio("1:1"); - if (details.has("fanart") && !details.get("fanart").getAsString().isEmpty()) + // fanart + String fanart = extractKeyFromArtMap(details, "fanart"); + if (fanart != null && !fanart.isEmpty()) { - String url = getDownloadUrl(details.get("fanart").getAsString()); - if (url != null && !url.isEmpty()) - med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(url).toString()); + med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(fanart).toString()); } + med.setXbmcUrl("musicdb://albums/" + details.get("albumid").getAsString() + "/"); med.setCategory(Media.MEDIA_TYPE_ALBUM); } @@ -970,18 +1068,47 @@ public class XBMCJsonRPC med.setId(details.get("songid").getAsInt()); med.setTitle(details.get("title").getAsString()); med.setDescription(details.get("displayartist").getAsString()); - if (details.has("thumbnail") && !details.get("thumbnail").getAsString().isEmpty()) + + // album thumb + String thumb = extractKeyFromArtMap(details, "album.thumb"); + if (thumb != null && !thumb.isEmpty()) + { + med.setCardImageUrl(XBMCFileContentProvider.buildUri(thumb).toString()); + med.setCardImageAspectRatio("1:1"); + } + // fallback to albumartist.thumb + else + { + thumb = extractKeyFromArtMap(details, "albumartist.thumb"); + if (thumb != null && !thumb.isEmpty()) + { + med.setCardImageUrl(XBMCFileContentProvider.buildUri(thumb).toString()); + med.setCardImageAspectRatio("1:1"); + } + else + { + // fallback to artist.thumb + thumb = extractKeyFromArtMap(details, "artist.thumb"); + if (thumb != null && !thumb.isEmpty()) + { + med.setCardImageUrl(XBMCFileContentProvider.buildUri(thumb).toString()); + med.setCardImageAspectRatio("1:1"); + } + } + } + // fanart + String fanart = extractKeyFromArtMap(details, "albumartist.fanart"); + if (fanart != null && !fanart.isEmpty()) { - String url = getDownloadUrl(details.get("thumbnail").getAsString()); - if (url != null && !url.isEmpty()) - med.setCardImageUrl(XBMCFileContentProvider.buildUri(url).toString()); + med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(fanart).toString()); } - med.setCardImageAspectRatio("1:1"); - if (details.has("fanart") && !details.get("fanart").getAsString().isEmpty()) + else { - String url = getDownloadUrl(details.get("fanart").getAsString()); - if (url != null && !url.isEmpty()) - med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(url).toString()); + fanart = extractKeyFromArtMap(details, "artist.fanart"); + if (fanart != null && !fanart.isEmpty()) + { + med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(fanart).toString()); + } } String extension = ""; @@ -1023,18 +1150,18 @@ public class XBMCJsonRPC JsonArray ja = details.get("artist").getAsJsonArray(); if (ja.size() > 0) med.setDescription(ja.get(0).getAsString()); - if (details.has("thumbnail") && !details.get("thumbnail").getAsString().isEmpty()) + // thumb + String thumb = extractKeyFromArtMap(details, "thumb"); + if (thumb != null && !thumb.isEmpty()) { - String url = getDownloadUrl(details.get("thumbnail").getAsString()); - if (url != null && !url.isEmpty()) - med.setCardImageUrl(XBMCFileContentProvider.buildUri(url).toString()); + med.setCardImageUrl(XBMCFileContentProvider.buildUri(thumb).toString()); + med.setCardImageAspectRatio("1:1"); } - med.setCardImageAspectRatio("1:1"); - if (details.has("fanart") && !details.get("fanart").getAsString().isEmpty()) + // fanart + String fanart = extractKeyFromArtMap(details, "fanart"); + if (fanart != null && !fanart.isEmpty()) { - String url = getDownloadUrl(details.get("fanart").getAsString()); - if (url != null && !url.isEmpty()) - med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(url).toString()); + med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(fanart).toString()); } med.setXbmcUrl("videodb://musicvideos/titles/" + details.get("musicvideoid").getAsInt()); @@ -1266,11 +1393,22 @@ public class XBMCJsonRPC return medias; } + private String extractKeyFromArtMap(JsonObject details, String key) + { + if (details.has("art") && !details.get("art").getAsJsonObject().isJsonNull() && + details.get("art").getAsJsonObject().has(key) && + !details.get("art").getAsJsonObject().get(key).getAsString().isEmpty()) + { + return getDownloadUrl(details.get("art").getAsJsonObject().get(key).getAsString()); + } + return null; + } + private String convertRating(Double rating) { if(rating == null || rating.doubleValue() <= 0.0) return null; - + return String.valueOf(rating / 2.0); } diff --git a/tools/darwin/packaging/darwin_embedded/migrate_to_kodi.sh.in b/tools/darwin/packaging/darwin_embedded/migrate_to_kodi.sh.in deleted file mode 100644 index be9155fa8c..0000000000 --- a/tools/darwin/packaging/darwin_embedded/migrate_to_kodi.sh.in +++ /dev/null @@ -1,30 +0,0 @@ -APP_NAME=@APP_NAME@ -XBMC_HOME="/var/mobile/Library/Preferences/XBMC" -APP_HOME="/var/mobile/Library/Preferences/@APP_NAME@" - - -function needs_kodi_migration () { - #check if there is an old XBMC folder to migrate - if test -d "$XBMC_HOME" && test ! -d "$APP_HOME" - then - return "1"; - else - return "0"; - fi -} - -function migrate_to_kodi () { - echo "moving settings from $XBMC_HOME to $APP_HOME" - mv $XBMC_HOME $APP_HOME - chown -R mobile.mobile $APP_HOME - echo "Migration complete" - touch $APP_HOME/.kodi_data_was_migrated -} - -needs_kodi_migration -NEEDS_MIGRATION=$? -if [ "$NEEDS_MIGRATION" == "1" ] -then - echo "This is the first time you install @APP_NAME@ and we detected that you have an old XBMC configuration. Your XBMC configuration will now be migrated to @APP_NAME@ by moving the settings folder. If you ever want to go back to XBMC please backup /var/mobile/Library/Preferences/@APP_NAME@ after this installation has finished and rename it to XBMC in case you downgrade to XBMC." - migrate_to_kodi -fi diff --git a/tools/darwin/packaging/darwin_embedded/mkdeb-darwin_embedded.sh.in b/tools/darwin/packaging/darwin_embedded/mkdeb-darwin_embedded.sh.in index 78cb87aada..0d318be595 100644 --- a/tools/darwin/packaging/darwin_embedded/mkdeb-darwin_embedded.sh.in +++ b/tools/darwin/packaging/darwin_embedded/mkdeb-darwin_embedded.sh.in @@ -96,9 +96,6 @@ chmod +x $DIRNAME/$PACKAGE/DEBIAN/prerm # postinst: nothing for now. echo "#!/bin/sh" > $DIRNAME/$PACKAGE/DEBIAN/postinst echo "chown -R mobile:mobile /Applications/@APP_NAME@.app" >> $DIRNAME/$PACKAGE/DEBIAN/postinst -if [ "@PLATFORM@" != "appletvos" ]; then - cat $DIRNAME/migrate_to_kodi.sh >> $DIRNAME/$PACKAGE/DEBIAN/postinst -fi echo "/usr/bin/uicache" >> $DIRNAME/$PACKAGE/DEBIAN/postinst echo "echo 'finish:respringing ...'" >> $DIRNAME/$PACKAGE/DEBIAN/postinst chmod +x $DIRNAME/$PACKAGE/DEBIAN/postinst diff --git a/tools/darwin/runtime/preflight b/tools/darwin/runtime/preflight index e30336630a..d9311f5d1e 100755 --- a/tools/darwin/runtime/preflight +++ b/tools/darwin/runtime/preflight @@ -16,19 +16,6 @@ sub get_extras { return; } -sub get_xbmc_home { - my $os = get_os(); - my $home = get_home(); - return if !defined $home; - if ( $os eq "osx" ) { - return $home."/Library/Application Support/XBMC"; - } - elsif ( $os eq "linux" ) { - return $home."/.xbmc"; - } - return; -} - sub get_app_home { my $os = get_os(); my $home = get_home(); @@ -161,16 +148,6 @@ sub first_app_version_run() { return; } -sub needs_kodi_migration() { - my $xbmchome = get_xbmc_home(); - my $apphome = get_app_home(); - #check if there is an old XBMC folder to migrate - if ( -d "$xbmchome" && ! -d "$apphome" ) { - return 1; - } - return; -} - sub setup_default_app() { my $extras = get_extras(); my $apphome = get_app_home(); @@ -196,19 +173,6 @@ sub setup_version_app() { #TODO } -#migration from XBMC to Kodi -sub migrate_to_kodi() { - my $xbmchome = get_xbmc_home(); - my $apphome = get_app_home(); - print "mv $xbmchome $apphome"; - `mv "$xbmchome" "$apphome"`; - `touch -f "$apphome/.kodi_data_was_migrated"`; -} - -if (needs_kodi_migration()) { - migrate_to_kodi(); -} - if (first_app_run()) { setup_default_app(); } diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index f14d1c3627..fb4978c27c 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -1659,6 +1659,19 @@ bool CApplication::OnAction(const CAction &action) } return true; } + // Tone Mapping : switch to next tone map method + if (action.GetID() == ACTION_CYCLE_TONEMAP_METHOD) + { + if (m_appPlayer.IsPlayingVideo()) + { + CVideoSettings vs = m_appPlayer.GetVideoSettings(); + vs.m_ToneMapMethod++; + if (vs.m_ToneMapMethod >= VS_TONEMAPMETHOD_MAX) + vs.m_ToneMapMethod = VS_TONEMAPMETHOD_OFF + 1; + m_appPlayer.SetVideoSettings(vs); + } + return true; + } // built in functions : execute the built-in if (action.GetID() == ACTION_BUILT_IN_FUNCTION) { diff --git a/xbmc/FileItem.cpp b/xbmc/FileItem.cpp index 3266a8abfa..4f8539e304 100644 --- a/xbmc/FileItem.cpp +++ b/xbmc/FileItem.cpp @@ -1647,6 +1647,54 @@ void CFileItem::UpdateInfo(const CFileItem &item, bool replaceLabels /*=true*/) AppendProperties(item); } +void CFileItem::MergeInfo(const CFileItem& item) +{ + // TODO: Currently merge the metadata/art info is implemented for video case only + if (item.HasVideoInfoTag()) + { + if (item.m_videoInfoTag) + { + if (m_videoInfoTag) + m_videoInfoTag->Merge(*item.m_videoInfoTag); + else + m_videoInfoTag = new CVideoInfoTag(*item.m_videoInfoTag); + } + + m_pvrRecordingInfoTag = item.m_pvrRecordingInfoTag; + + SetOverlayImage(ICON_OVERLAY_UNWATCHED, GetVideoInfoTag()->GetPlayCount() > 0); + SetInvalid(); + } + if (item.HasMusicInfoTag()) + { + *GetMusicInfoTag() = *item.GetMusicInfoTag(); + SetInvalid(); + } + if (item.HasPictureInfoTag()) + { + *GetPictureInfoTag() = *item.GetPictureInfoTag(); + SetInvalid(); + } + if (item.HasGameInfoTag()) + { + *GetGameInfoTag() = *item.GetGameInfoTag(); + SetInvalid(); + } + SetDynPath(item.GetDynPath()); + if (!item.GetLabel().empty()) + SetLabel(item.GetLabel()); + if (!item.GetLabel2().empty()) + SetLabel2(item.GetLabel2()); + if (!item.GetArt().empty()) + { + if (item.IsVideo()) + AppendArt(item.GetArt()); + else + SetArt(item.GetArt()); + } + AppendProperties(item); +} + void CFileItem::SetFromVideoInfoTag(const CVideoInfoTag &video) { if (!video.m_strTitle.empty()) @@ -2275,7 +2323,7 @@ bool CFileItemList::IsEmpty() const return m_items.empty(); } -void CFileItemList::Reserve(int iCount) +void CFileItemList::Reserve(size_t iCount) { CSingleLock lock(m_lock); m_items.reserve(iCount); diff --git a/xbmc/FileItem.h b/xbmc/FileItem.h index 305db92632..8a6ba4d7e7 100644 --- a/xbmc/FileItem.h +++ b/xbmc/FileItem.h @@ -510,6 +510,14 @@ public: */ void UpdateInfo(const CFileItem &item, bool replaceLabels = true); + /*! \brief Merge an item with information from another item + We take metadata/art information from the given item and supplement the current + item with that info. If tags exist in the new item we only merge the missing + tag information. Properties are appended, and labels are updated if non-empty + in the given item. + */ + void MergeInfo(const CFileItem &item); + bool IsSamePath(const CFileItem *item) const; bool IsAlbum() const; @@ -675,7 +683,7 @@ public: void Append(const CFileItemList& itemlist); void Assign(const CFileItemList& itemlist, bool append = false); bool Copy (const CFileItemList& item, bool copyItems = true); - void Reserve(int iCount); + void Reserve(size_t iCount); void Sort(SortBy sortBy, SortOrder sortOrder, SortAttribute sortAttributes = SortAttributeNone); /* \brief Sorts the items based on the given sorting options diff --git a/xbmc/addons/Addon.h b/xbmc/addons/Addon.h index 06ba3d3e46..9715387588 100644 --- a/xbmc/addons/Addon.h +++ b/xbmc/addons/Addon.h @@ -62,6 +62,16 @@ public: bool HasType(TYPE type) const override { return m_addonInfo->HasType(type); } /** + * @brief To check complete addon (not only this) has a specific type + * defined in its first extension point including the provided subcontent + * e.g. video or audio + * + * @param[in] type Type identifier to be checked + * @return true in case the wanted type is the main type, false if not + */ + bool HasMainType(TYPE type) const override { return m_addonInfo->HasType(type, true); } + + /** * @brief The get for given addon type information and extension data * * @param[in] type The wanted type data diff --git a/xbmc/addons/AddonInstaller.cpp b/xbmc/addons/AddonInstaller.cpp index 30a584e28c..7fdd8c66c8 100644 --- a/xbmc/addons/AddonInstaller.cpp +++ b/xbmc/addons/AddonInstaller.cpp @@ -675,7 +675,7 @@ bool CAddonInstallJob::DoWork() { origin = ORIGIN_SYSTEM; // keep system add-on origin as ORIGIN_SYSTEM } - else if (m_addon->HasType(ADDON_REPOSITORY)) + else if (m_addon->HasMainType(ADDON_REPOSITORY)) { origin = m_addon->ID(); // use own id as origin if repository if (m_isUpdate) diff --git a/xbmc/addons/IAddon.h b/xbmc/addons/IAddon.h index ae69e67902..c56faf1af2 100644 --- a/xbmc/addons/IAddon.h +++ b/xbmc/addons/IAddon.h @@ -36,6 +36,7 @@ namespace ADDON virtual TYPE MainType() const = 0; virtual TYPE Type() const =0; virtual bool HasType(TYPE type) const = 0; + virtual bool HasMainType(TYPE type) const = 0; virtual std::string ID() const =0; virtual std::string Name() const =0; virtual bool IsInUse() const =0; diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream.h index b291c2f87f..1b3a735564 100644 --- a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream.h +++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/inputstream.h @@ -19,7 +19,7 @@ #include <time.h> // Increment this level always if you add features which can lead to compile failures in the addon -#define INPUTSTREAM_VERSION_LEVEL 3 +#define INPUTSTREAM_VERSION_LEVEL 4 #define INPUTSTREAM_MAX_INFO_COUNT 8 #define INPUTSTREAM_MAX_STREAM_COUNT 256 @@ -219,34 +219,34 @@ extern "C" enum INPUTSTREAM_FLAGS { /// @brief **0000 0000 0000 0000 :** Empty to set if nothing is used - INPUTSTREAM_FLAG_NONE = (1 << 0), + INPUTSTREAM_FLAG_NONE = 0, /// @brief **0000 0000 0000 0001 :** Default - INPUTSTREAM_FLAG_DEFAULT = (1 << 1), + INPUTSTREAM_FLAG_DEFAULT = (1 << 0), /// @brief **0000 0000 0000 0010 :** Dub - INPUTSTREAM_FLAG_DUB = (1 << 2), + INPUTSTREAM_FLAG_DUB = (1 << 1), /// @brief **0000 0000 0000 0100 :** Original - INPUTSTREAM_FLAG_ORIGINAL = (1 << 3), + INPUTSTREAM_FLAG_ORIGINAL = (1 << 2), /// @brief **0000 0000 0000 1000 :** Comment - INPUTSTREAM_FLAG_COMMENT = (1 << 4), + INPUTSTREAM_FLAG_COMMENT = (1 << 3), /// @brief **0000 0000 0001 0000 :** Lyrics - INPUTSTREAM_FLAG_LYRICS = (1 << 5), + INPUTSTREAM_FLAG_LYRICS = (1 << 4), /// @brief **0000 0000 0010 0000 :** Karaoke - INPUTSTREAM_FLAG_KARAOKE = (1 << 6), + INPUTSTREAM_FLAG_KARAOKE = (1 << 5), /// @brief **0000 0000 0100 0000 :** Forced - INPUTSTREAM_FLAG_FORCED = (1 << 7), + INPUTSTREAM_FLAG_FORCED = (1 << 6), /// @brief **0000 0000 1000 0000 :** Hearing impaired - INPUTSTREAM_FLAG_HEARING_IMPAIRED = (1 << 8), + INPUTSTREAM_FLAG_HEARING_IMPAIRED = (1 << 7), /// @brief **0000 0001 0000 0000 :** Visual impaired - INPUTSTREAM_FLAG_VISUAL_IMPAIRED = (1 << 9), + INPUTSTREAM_FLAG_VISUAL_IMPAIRED = (1 << 8), }; ///@} //---------------------------------------------------------------------------- diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/versions.h b/xbmc/addons/kodi-dev-kit/include/kodi/versions.h index e5c52d78fb..5808e1ab38 100644 --- a/xbmc/addons/kodi-dev-kit/include/kodi/versions.h +++ b/xbmc/addons/kodi-dev-kit/include/kodi/versions.h @@ -107,8 +107,8 @@ #define ADDON_INSTANCE_VERSION_IMAGEDECODER_XML_ID "kodi.binary.instance.imagedecoder" #define ADDON_INSTANCE_VERSION_IMAGEDECODER_DEPENDS "addon-instance/ImageDecoder.h" -#define ADDON_INSTANCE_VERSION_INPUTSTREAM "3.0.0" -#define ADDON_INSTANCE_VERSION_INPUTSTREAM_MIN "3.0.0" +#define ADDON_INSTANCE_VERSION_INPUTSTREAM "3.0.1" +#define ADDON_INSTANCE_VERSION_INPUTSTREAM_MIN "3.0.1" #define ADDON_INSTANCE_VERSION_INPUTSTREAM_XML_ID "kodi.binary.instance.inputstream" #define ADDON_INSTANCE_VERSION_INPUTSTREAM_DEPENDS "c-api/addon-instance/inputstream.h" \ "c-api/addon-instance/inputstream/demux_packet.h" \ @@ -172,8 +172,8 @@ #define ADDON_INSTANCE_VERSION_VISUALIZATION_DEPENDS "addon-instance/Visualization.h" \ "c-api/addon-instance/visualization.h" -#define ADDON_INSTANCE_VERSION_VIDEOCODEC "2.0.0" -#define ADDON_INSTANCE_VERSION_VIDEOCODEC_MIN "2.0.0" +#define ADDON_INSTANCE_VERSION_VIDEOCODEC "2.0.1" +#define ADDON_INSTANCE_VERSION_VIDEOCODEC_MIN "2.0.1" #define ADDON_INSTANCE_VERSION_VIDEOCODEC_XML_ID "kodi.binary.instance.videocodec" #define ADDON_INSTANCE_VERSION_VIDEOCODEC_DEPENDS "c-api/addon-instance/video_codec.h" \ "c-api/addon-instance/inputstream/stream_codec.h" \ diff --git a/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererGuiTexture.cpp b/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererGuiTexture.cpp index 7747832890..815186821f 100644 --- a/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererGuiTexture.cpp +++ b/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererGuiTexture.cpp @@ -29,8 +29,6 @@ using namespace DirectX; using namespace KODI; using namespace RETRO; -#define BUFFER_OFFSET(i) (static_cast<char*>(NULL) + (i)) - // --- CRendererFactoryGuiTexture ---------------------------------------------- std::string CRendererFactoryGuiTexture::RenderSystemName() const @@ -190,9 +188,9 @@ void CRPRendererGuiTexture::RenderInternal(bool clear, uint8_t alpha) glBufferData(GL_ARRAY_BUFFER, sizeof(PackedVertex) * 4, &vertex[0], GL_STATIC_DRAW); glVertexAttribPointer(posLoc, 3, GL_FLOAT, 0, sizeof(PackedVertex), - BUFFER_OFFSET(offsetof(PackedVertex, x))); + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, x))); glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, 0, sizeof(PackedVertex), - BUFFER_OFFSET(offsetof(PackedVertex, u1))); + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, u1))); glEnableVertexAttribArray(posLoc); glEnableVertexAttribArray(tex0Loc); diff --git a/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGL.cpp b/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGL.cpp index c1cd909933..bfeb62612d 100644 --- a/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGL.cpp +++ b/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGL.cpp @@ -13,8 +13,6 @@ #include "cores/RetroPlayer/rendering/RenderContext.h" #include "utils/log.h" -#define BUFFER_OFFSET(i) (static_cast<char*>(NULL) + (i)) - using namespace KODI; using namespace RETRO; @@ -64,10 +62,10 @@ CRPRendererOpenGL::CRPRendererOpenGL(const CRenderSettings& renderSettings, glBindBuffer(GL_ARRAY_BUFFER, m_mainVertexVBO); glEnableVertexAttribArray(vertLoc); glVertexAttribPointer(vertLoc, 3, GL_FLOAT, 0, sizeof(PackedVertex), - BUFFER_OFFSET(offsetof(PackedVertex, x))); + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, x))); glEnableVertexAttribArray(loc); glVertexAttribPointer(loc, 2, GL_FLOAT, 0, sizeof(PackedVertex), - BUFFER_OFFSET(offsetof(PackedVertex, u1))); + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, u1))); // Set up black bars VAO/VBO glGenVertexArrays(1, &m_blackbarsVAO); diff --git a/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGLES.cpp b/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGLES.cpp index 03427da6bd..0c4476fa7c 100644 --- a/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGLES.cpp +++ b/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGLES.cpp @@ -18,8 +18,6 @@ #include <cstring> #include <stddef.h> -#define BUFFER_OFFSET(i) ((char*)NULL + (i)) - using namespace KODI; using namespace RETRO; @@ -295,9 +293,9 @@ void CRPRendererOpenGLES::Render(uint8_t alpha) glBufferData(GL_ARRAY_BUFFER, sizeof(PackedVertex) * 4, &vertex[0], GL_STATIC_DRAW); glVertexAttribPointer(vertLoc, 3, GL_FLOAT, 0, sizeof(PackedVertex), - BUFFER_OFFSET(offsetof(PackedVertex, x))); + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, x))); glVertexAttribPointer(loc, 2, GL_FLOAT, 0, sizeof(PackedVertex), - BUFFER_OFFSET(offsetof(PackedVertex, u1))); + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, u1))); glEnableVertexAttribArray(vertLoc); glEnableVertexAttribArray(loc); diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp index 5d505adb07..5141635350 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp +++ b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp @@ -49,8 +49,6 @@ //! is a multiple of 128 and deinterlacing is on #define PBO_OFFSET 16 -#define BUFFER_OFFSET(i) ((char *)NULL + (i)) - using namespace Shaders; static const GLubyte stipple_weave[] = { @@ -1152,11 +1150,15 @@ void CLinuxRendererGL::RenderSinglePass(int index, int field) glBindBuffer(GL_ARRAY_BUFFER, vertexVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(PackedVertex)*4, &vertex[0], GL_STATIC_DRAW); - glVertexAttribPointer(vertLoc, 3, GL_FLOAT, 0, sizeof(PackedVertex), BUFFER_OFFSET(offsetof(PackedVertex, x))); - glVertexAttribPointer(Yloc, 2, GL_FLOAT, 0, sizeof(PackedVertex), BUFFER_OFFSET(offsetof(PackedVertex, u1))); - glVertexAttribPointer(Uloc, 2, GL_FLOAT, 0, sizeof(PackedVertex), BUFFER_OFFSET(offsetof(PackedVertex, u2))); + glVertexAttribPointer(vertLoc, 3, GL_FLOAT, 0, sizeof(PackedVertex), + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, x))); + glVertexAttribPointer(Yloc, 2, GL_FLOAT, 0, sizeof(PackedVertex), + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, u1))); + glVertexAttribPointer(Uloc, 2, GL_FLOAT, 0, sizeof(PackedVertex), + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, u2))); if (Vloc != -1) - glVertexAttribPointer(Vloc, 2, GL_FLOAT, 0, sizeof(PackedVertex), BUFFER_OFFSET(offsetof(PackedVertex, u3))); + glVertexAttribPointer(Vloc, 2, GL_FLOAT, 0, sizeof(PackedVertex), + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, u3))); glEnableVertexAttribArray(vertLoc); glEnableVertexAttribArray(Yloc); @@ -1377,11 +1379,15 @@ void CLinuxRendererGL::RenderToFBO(int index, int field, bool weave /*= false*/) glBindBuffer(GL_ARRAY_BUFFER, vertexVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(PackedVertex)*4, &vertex[0], GL_STATIC_DRAW); - glVertexAttribPointer(vertLoc, 3, GL_FLOAT, 0, sizeof(PackedVertex), BUFFER_OFFSET(offsetof(PackedVertex, x))); - glVertexAttribPointer(Yloc, 2, GL_FLOAT, 0, sizeof(PackedVertex), BUFFER_OFFSET(offsetof(PackedVertex, u1))); - glVertexAttribPointer(Uloc, 2, GL_FLOAT, 0, sizeof(PackedVertex), BUFFER_OFFSET(offsetof(PackedVertex, u2))); + glVertexAttribPointer(vertLoc, 3, GL_FLOAT, 0, sizeof(PackedVertex), + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, x))); + glVertexAttribPointer(Yloc, 2, GL_FLOAT, 0, sizeof(PackedVertex), + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, u1))); + glVertexAttribPointer(Uloc, 2, GL_FLOAT, 0, sizeof(PackedVertex), + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, u2))); if (Vloc != -1) - glVertexAttribPointer(Vloc, 2, GL_FLOAT, 0, sizeof(PackedVertex), BUFFER_OFFSET(offsetof(PackedVertex, u3))); + glVertexAttribPointer(Vloc, 2, GL_FLOAT, 0, sizeof(PackedVertex), + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, u3))); glEnableVertexAttribArray(vertLoc); glEnableVertexAttribArray(Yloc); @@ -1502,8 +1508,10 @@ void CLinuxRendererGL::RenderFromFBO() glBindBuffer(GL_ARRAY_BUFFER, vertexVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(PackedVertex)*4, &vertex[0], GL_STATIC_DRAW); - glVertexAttribPointer(vertLoc, 3, GL_FLOAT, 0, sizeof(PackedVertex), BUFFER_OFFSET(offsetof(PackedVertex, x))); - glVertexAttribPointer(loc, 2, GL_FLOAT, 0, sizeof(PackedVertex), BUFFER_OFFSET(offsetof(PackedVertex, u1))); + glVertexAttribPointer(vertLoc, 3, GL_FLOAT, 0, sizeof(PackedVertex), + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, x))); + glVertexAttribPointer(loc, 2, GL_FLOAT, 0, sizeof(PackedVertex), + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, u1))); glEnableVertexAttribArray(vertLoc); glEnableVertexAttribArray(loc); @@ -1639,8 +1647,10 @@ void CLinuxRendererGL::RenderRGB(int index, int field) glBindBuffer(GL_ARRAY_BUFFER, vertexVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(PackedVertex)*4, &vertex[0], GL_STATIC_DRAW); - glVertexAttribPointer(vertLoc, 3, GL_FLOAT, 0, sizeof(PackedVertex), BUFFER_OFFSET(offsetof(PackedVertex, x))); - glVertexAttribPointer(loc, 2, GL_FLOAT, 0, sizeof(PackedVertex), BUFFER_OFFSET(offsetof(PackedVertex, u1))); + glVertexAttribPointer(vertLoc, 3, GL_FLOAT, 0, sizeof(PackedVertex), + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, x))); + glVertexAttribPointer(loc, 2, GL_FLOAT, 0, sizeof(PackedVertex), + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, u1))); glEnableVertexAttribArray(vertLoc); glEnableVertexAttribArray(loc); diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererGL.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererGL.cpp index a75db3ca05..787a5a1d42 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererGL.cpp +++ b/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererGL.cpp @@ -35,8 +35,6 @@ #define USE_PREMULTIPLIED_ALPHA 1 -#define BUFFER_OFFSET(i) ((char *)NULL + (i)) - using namespace OVERLAY; static void LoadTexture(GLenum target @@ -408,9 +406,12 @@ void COverlayGlyphGL::Render(SRenderState& state) glBindBuffer(GL_ARRAY_BUFFER, VertexVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(VERTEX)*vecVertices.size(), &vecVertices[0], GL_STATIC_DRAW); - glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(VERTEX), BUFFER_OFFSET(offsetof(VERTEX, x))); - glVertexAttribPointer(colLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VERTEX), BUFFER_OFFSET(offsetof(VERTEX, r))); - glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, GL_FALSE, sizeof(VERTEX), BUFFER_OFFSET(offsetof(VERTEX, u))); + glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(VERTEX), + reinterpret_cast<const GLvoid*>(offsetof(VERTEX, x))); + glVertexAttribPointer(colLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VERTEX), + reinterpret_cast<const GLvoid*>(offsetof(VERTEX, r))); + glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, GL_FALSE, sizeof(VERTEX), + reinterpret_cast<const GLvoid*>(offsetof(VERTEX, u))); glEnableVertexAttribArray(posLoc); glEnableVertexAttribArray(colLoc); @@ -568,8 +569,10 @@ void COverlayTextureGL::Render(SRenderState& state) glBindBuffer(GL_ARRAY_BUFFER, vertexVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(PackedVertex)*4, &vertex[0], GL_STATIC_DRAW); - glVertexAttribPointer(posLoc, 2, GL_FLOAT, 0, sizeof(PackedVertex), BUFFER_OFFSET(offsetof(PackedVertex, x))); - glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, 0, sizeof(PackedVertex), BUFFER_OFFSET(offsetof(PackedVertex, u1))); + glVertexAttribPointer(posLoc, 2, GL_FLOAT, 0, sizeof(PackedVertex), + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, x))); + glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, 0, sizeof(PackedVertex), + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, u1))); glEnableVertexAttribArray(posLoc); glEnableVertexAttribArray(tex0Loc); diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp index fa3651c66e..3b8a906bc5 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp +++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp @@ -185,17 +185,20 @@ void COutputShader::ApplyEffectParameters(CD3DEffect &effect, unsigned sourceWid effect.SetResources("m_ditherMatrix", m_pDitherView.GetAddressOf(), 1); effect.SetFloatArray("m_ditherParams", ditherParams, 3); } - if (m_toneMapping) + if (m_toneMapping && m_toneMappingMethod == VS_TONEMAPMETHOD_REINHARD) { - float param = 0.7; + const float def_param = log10(100.0f) / log10(600.0f); // 600 nits --> 0.72 + float param = def_param; + if (m_hasLightMetadata) - param = log10(100) / log10(m_lightMetadata.MaxCLL); + param = static_cast<float>(log10(100) / log10(m_lightMetadata.MaxCLL)); else if (m_hasDisplayMetadata && m_displayMetadata.has_luminance) - param = log10(100) / log10(m_displayMetadata.max_luminance.num / m_displayMetadata.max_luminance.den); + param = static_cast<float>(log10(100) / log10(m_displayMetadata.max_luminance.num / + m_displayMetadata.max_luminance.den)); // Sanity check if (param < 0.1f || param > 5.0f) - param = 0.7f; + param = def_param; param *= m_toneMappingParam; @@ -205,6 +208,50 @@ void COutputShader::ApplyEffectParameters(CD3DEffect &effect, unsigned sourceWid effect.SetScalar("g_toneP1", param); effect.SetFloatArray("g_coefsDst", coefs, 3); } + else if (m_toneMapping && m_toneMappingMethod == VS_TONEMAPMETHOD_ACES) + { + effect.SetScalar("g_luminance", GetLuminanceValue()); + effect.SetScalar("g_toneP1", m_toneMappingParam); + } + else if (m_toneMapping && m_toneMappingMethod == VS_TONEMAPMETHOD_HABLE) + { + float lumin = GetLuminanceValue(); + float lumin_factor = (10000.0f / lumin) * (2.0f / m_toneMappingParam); + float lumin_div100 = lumin / (100.0f * m_toneMappingParam); + effect.SetScalar("g_toneP1", lumin_factor); + effect.SetScalar("g_toneP2", lumin_div100); + } +} + +float COutputShader::GetLuminanceValue() const +{ + float lum1 = 400.0f; // default for bad quality HDR-PQ sources (with no metadata) + float lum2 = lum1; + float lum3 = lum1; + + if (m_hasLightMetadata) + { + uint16_t lum = m_displayMetadata.max_luminance.num / m_displayMetadata.max_luminance.den; + if (m_lightMetadata.MaxCLL >= lum) + { + lum1 = static_cast<float>(lum); + lum2 = static_cast<float>(m_lightMetadata.MaxCLL); + } + else + { + lum1 = static_cast<float>(m_lightMetadata.MaxCLL); + lum2 = static_cast<float>(lum); + } + lum3 = static_cast<float>(m_lightMetadata.MaxFALL); + lum1 = (lum1 * 0.5f) + (lum2 * 0.2f) + (lum3 * 0.3f); + } + else if (m_hasDisplayMetadata && m_displayMetadata.has_luminance) + { + uint16_t lum = m_displayMetadata.max_luminance.num / m_displayMetadata.max_luminance.den; + lum1 = static_cast<float>(lum); + } + + return lum1; } void COutputShader::GetDefines(DefinesMap& map) const @@ -217,9 +264,17 @@ void COutputShader::GetDefines(DefinesMap& map) const { map["KODI_DITHER"] = ""; } - if (m_toneMapping) + if (m_toneMapping && m_toneMappingMethod == VS_TONEMAPMETHOD_REINHARD) { - map["KODI_TONE_MAPPING"] = ""; + map["KODI_TONE_MAPPING_REINHARD"] = ""; + } + else if (m_toneMapping && m_toneMappingMethod == VS_TONEMAPMETHOD_ACES) + { + map["KODI_TONE_MAPPING_ACES"] = ""; + } + else if (m_toneMapping && m_toneMappingMethod == VS_TONEMAPMETHOD_HABLE) + { + map["KODI_TONE_MAPPING_HABLE"] = ""; } if (m_useHLGtoPQ) { @@ -227,12 +282,14 @@ void COutputShader::GetDefines(DefinesMap& map) const } } -bool COutputShader::Create(bool useLUT, bool useDithering, int ditherDepth, bool toneMapping, bool HLGtoPQ) +bool COutputShader::Create( + bool useLUT, bool useDithering, int ditherDepth, bool toneMapping, int toneMethod, bool HLGtoPQ) { m_useLut = useLUT; m_ditherDepth = ditherDepth; - m_toneMapping = toneMapping && !DX::Windowing()->IsHDROutput(); + m_toneMapping = toneMapping; m_useHLGtoPQ = HLGtoPQ; + m_toneMappingMethod = toneMethod; CWinShader::CreateVertexBuffer(4, sizeof(Vertex)); @@ -295,6 +352,12 @@ void COutputShader::SetDisplayMetadata(bool hasDisplayMetadata, AVMasteringDispl m_lightMetadata = lightMetadata; } +void COutputShader::SetToneMapParam(int method, float param) +{ + m_toneMappingMethod = method; + m_toneMappingParam = param; +} + bool COutputShader::CreateLUTView(int lutSize, uint16_t* lutData, bool isRGB, ID3D11ShaderResourceView** ppLUTView) { if (!lutSize || !lutData) diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.h b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.h index 5ab850aafa..647f5ffbe6 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.h +++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.h @@ -60,7 +60,7 @@ public: void ApplyEffectParameters(CD3DEffect &effect, unsigned sourceWidth, unsigned sourceHeight); void GetDefines(DefinesMap &map) const; - bool Create(bool useLUT, bool useDithering, int ditherDepth, bool toneMapping, bool HLGtoPQ); + bool Create(bool useLUT, bool useDithering, int ditherDepth, bool toneMapping, int toneMethod, bool HLGtoPQ); void Render(CD3DTexture& sourceTexture, CRect sourceRect, const CPoint points[4] , CD3DTexture& target, unsigned range = 0, float contrast = 0.5f, float brightness = 0.5f); void Render(CD3DTexture& sourceTexture, CRect sourceRect, CRect destRect @@ -68,7 +68,7 @@ public: void SetLUT(int lutSize, ID3D11ShaderResourceView *pLUTView); void SetDisplayMetadata(bool hasDisplayMetadata, AVMasteringDisplayMetadata displayMetadata, bool hasLightMetadata, AVContentLightMetadata lightMetadata); - void SetToneMapParam(float param) { m_toneMappingParam = param; } + void SetToneMapParam(int method, float param); static bool CreateLUTView(int lutSize, uint16_t* lutData, bool isRGB, ID3D11ShaderResourceView** ppLUTView); @@ -83,6 +83,7 @@ private: void PrepareParameters(unsigned sourceWidth, unsigned sourceHeight, CRect sourceRect, const CPoint points[4]); void SetShaderParameters(CD3DTexture &sourceTexture, unsigned range, float contrast, float brightness); void CreateDitherView(); + float GetLuminanceValue() const; bool m_useLut = false; bool m_useDithering = false; @@ -95,6 +96,7 @@ private: unsigned m_sourceHeight = 0; int m_lutSize = 0; int m_ditherDepth = 0; + int m_toneMappingMethod = 0; float m_toneMappingParam = 1.0f; CRect m_sourceRect = {}; diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.cpp index 1713758773..b888859b43 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.cpp +++ b/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.cpp @@ -247,7 +247,7 @@ void CRendererBase::Render(CD3DTexture& target, const CRect& sourceRect, const C if (UseToneMapping()) { m_outputShader->SetDisplayMetadata(buf->hasDisplayMetadata, buf->displayMetadata, buf->hasLightMetadata, buf->lightMetadata); - m_outputShader->SetToneMapParam(m_videoSettings.m_ToneMapParam); + m_outputShader->SetToneMapParam(m_toneMapMethod, m_videoSettings.m_ToneMapParam); } FinalOutput(m_IntermediateTarget, target, source, dest); @@ -407,7 +407,8 @@ void CRendererBase::UpdateVideoFilters() if (!m_outputShader) { m_outputShader = std::make_shared<COutputShader>(); - if (!m_outputShader->Create(m_cmsOn, m_useDithering, m_ditherDepth, UseToneMapping(), m_useHLGtoPQ)) + if (!m_outputShader->Create(m_cmsOn, m_useDithering, m_ditherDepth, m_toneMapping, + m_toneMapMethod, m_useHLGtoPQ)) { CLog::LogF(LOGDEBUG, "unable to create output shader."); m_outputShader.reset(); @@ -422,20 +423,21 @@ void CRendererBase::UpdateVideoFilters() void CRendererBase::CheckVideoParameters() { CRenderBuffer* buf = m_renderBuffers[m_iBufferIndex]; + int method = m_videoSettings.m_ToneMapMethod; + + bool isHDRPQ = (buf->color_transfer == AVCOL_TRC_SMPTE2084 && buf->primaries == AVCOL_PRI_BT2020); + + bool toneMap = (isHDRPQ && m_HdrType == HDR_TYPE::HDR_NONE_SDR && method != VS_TONEMAPMETHOD_OFF); - bool toneMap = false; - if (m_videoSettings.m_ToneMapMethod != VS_TONEMAPMETHOD_OFF && !DX::Windowing()->IsHDROutput()) - { - if (buf->hasLightMetadata || buf->hasDisplayMetadata && buf->displayMetadata.has_luminance) - toneMap = true; - } bool hlg = (m_HdrType == HDR_TYPE::HDR_HLG); - if (toneMap != m_toneMapping || m_cmsOn != m_colorManager->IsEnabled() || hlg != m_useHLGtoPQ) + if (toneMap != m_toneMapping || m_cmsOn != m_colorManager->IsEnabled() || hlg != m_useHLGtoPQ || + method != m_toneMapMethod) { m_toneMapping = toneMap; m_cmsOn = m_colorManager->IsEnabled(); m_useHLGtoPQ = hlg; + m_toneMapMethod = method; m_outputShader.reset(); OnOutputReset(); diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.h b/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.h index 3dc074c385..c7a1ff8ac2 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.h +++ b/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.h @@ -158,6 +158,7 @@ protected: bool m_cmsOn = false; bool m_clutLoaded = false; bool m_useHLGtoPQ = false; + int m_toneMapMethod = 0; int m_iBufferIndex = 0; int m_iNumBuffers = 0; diff --git a/xbmc/cores/VideoSettings.cpp b/xbmc/cores/VideoSettings.cpp index 9f18508c31..20b287a5c6 100644 --- a/xbmc/cores/VideoSettings.cpp +++ b/xbmc/cores/VideoSettings.cpp @@ -36,6 +36,10 @@ CVideoSettings::CVideoSettings() m_StereoMode = 0; m_StereoInvert = false; m_VideoStream = -1; + m_ToneMapMethod = VS_TONEMAPMETHOD_REINHARD; + m_ToneMapParam = 1.0f; + m_Orientation = 0; + m_CenterMixLevel = 0; } bool CVideoSettings::operator!=(const CVideoSettings &right) const diff --git a/xbmc/cores/VideoSettings.h b/xbmc/cores/VideoSettings.h index 687c84a530..4e2007a8a6 100644 --- a/xbmc/cores/VideoSettings.h +++ b/xbmc/cores/VideoSettings.h @@ -60,8 +60,10 @@ enum ESCALINGMETHOD enum ETONEMAPMETHOD { - VS_TONEMAPMETHOD_OFF=0, - VS_TONEMAPMETHOD_REINHARD, + VS_TONEMAPMETHOD_OFF = 0, + VS_TONEMAPMETHOD_REINHARD = 1, + VS_TONEMAPMETHOD_ACES = 2, + VS_TONEMAPMETHOD_HABLE = 3, VS_TONEMAPMETHOD_MAX }; @@ -88,8 +90,8 @@ public: bool operator!=(const CVideoSettings &right) const; EINTERLACEMETHOD m_InterlaceMethod; - ESCALINGMETHOD m_ScalingMethod; - int m_ViewMode; // current view mode + ESCALINGMETHOD m_ScalingMethod; + int m_ViewMode; // current view mode float m_CustomZoomAmount; // custom setting zoom amount float m_CustomPixelRatio; // custom setting pixel ratio float m_CustomVerticalShift; // custom setting vertical shift @@ -111,10 +113,10 @@ public: int m_StereoMode; bool m_StereoInvert; int m_VideoStream; - int m_ToneMapMethod = VS_TONEMAPMETHOD_REINHARD; - float m_ToneMapParam = 1.0; - int m_Orientation = 0; - int m_CenterMixLevel = 0; // relative to metadata or default + int m_ToneMapMethod; + float m_ToneMapParam; + int m_Orientation; + int m_CenterMixLevel; // relative to metadata or default }; class CCriticalSection; diff --git a/xbmc/dbwrappers/Database.cpp b/xbmc/dbwrappers/Database.cpp index a3d2c0602b..90c02c2bc8 100644 --- a/xbmc/dbwrappers/Database.cpp +++ b/xbmc/dbwrappers/Database.cpp @@ -299,6 +299,40 @@ std::string CDatabase::GetSingleValue(const std::string &query) return GetSingleValue(query, m_pDS); } +int CDatabase::GetSingleValueInt(const std::string& query, std::unique_ptr<Dataset>& ds) +{ + int ret = 0; + try + { + if (!m_pDB || !ds) + return ret; + + if (ds->query(query) && ds->num_rows() > 0) + ret = ds->fv(0).get_asInt(); + + ds->close(); + } + catch (...) + { + CLog::Log(LOGERROR, "%s - failed on query '%s'", __FUNCTION__, query.c_str()); + } + return ret; +} + +int CDatabase::GetSingleValueInt(const std::string& strTable, + const std::string& strColumn, + const std::string& strWhereClause /* = std::string() */, + const std::string& strOrderBy /* = std::string() */) +{ + std::string strResult = GetSingleValue(strTable, strColumn, strWhereClause, strOrderBy); + return static_cast<int>(strtol(strResult.c_str(), NULL, 10)); +} + +int CDatabase::GetSingleValueInt(const std::string& query) +{ + return GetSingleValueInt(query, m_pDS); +} + bool CDatabase::DeleteValues(const std::string &strTable, const Filter &filter /* = Filter() */) { std::string strQuery; diff --git a/xbmc/dbwrappers/Database.h b/xbmc/dbwrappers/Database.h index 54f905fafd..523a13a882 100644 --- a/xbmc/dbwrappers/Database.h +++ b/xbmc/dbwrappers/Database.h @@ -130,6 +130,28 @@ public: std::string GetSingleValue(const std::string &query, std::unique_ptr<dbiplus::Dataset> &ds); /*! + * @brief Get a single integer value from a table. + * @remarks The values of the strWhereClause and strOrderBy parameters have to be FormatSQL'ed when used. + * @param strTable The table to get the value from. + * @param strColumn The column to get. + * @param strWhereClause If set, use this WHERE clause. + * @param strOrderBy If set, use this ORDER BY clause. + * @return The requested value or 0 if it wasn't found. + */ + int GetSingleValueInt(const std::string& strTable, + const std::string& strColumn, + const std::string& strWhereClause = std::string(), + const std::string& strOrderBy = std::string()); + int GetSingleValueInt(const std::string& query); + + /*! \brief Get a single integer value from a query on a dataset. + \param query the query in question. + \param ds the dataset to use for the query. + \return the value from the query, 0 on failure. + */ + int GetSingleValueInt(const std::string& query, std::unique_ptr<dbiplus::Dataset>& ds); + + /*! * @brief Delete values from a table. * @param strTable The table to delete the values from. * @param filter The Filter to apply to this query. diff --git a/xbmc/favourites/FavouritesService.cpp b/xbmc/favourites/FavouritesService.cpp index 650284373e..764f1113b9 100644 --- a/xbmc/favourites/FavouritesService.cpp +++ b/xbmc/favourites/FavouritesService.cpp @@ -16,6 +16,7 @@ #include "music/tags/MusicInfoTag.h" #include "settings/AdvancedSettings.h" #include "settings/SettingsComponent.h" +#include "utils/ContentUtils.h" #include "utils/StringUtils.h" #include "utils/URIUtils.h" #include "utils/XBMCTinyXML.h" @@ -156,7 +157,7 @@ bool CFavouritesService::AddOrRemove(const CFileItem& item, int contextWindow) const CFileItemPtr favourite(std::make_shared<CFileItem>(item.GetLabel())); if (item.GetLabel().empty()) favourite->SetLabel(CUtil::GetTitleFromPath(item.GetPath(), item.m_bIsFolder)); - favourite->SetArt("thumb", item.GetArt("thumb")); + favourite->SetArt("thumb", ContentUtils::GetPreferredArtImage(item)); favourite->SetPath(favUrl); m_favourites.Add(favourite); } diff --git a/xbmc/filesystem/MusicDatabaseDirectory/QueryParams.cpp b/xbmc/filesystem/MusicDatabaseDirectory/QueryParams.cpp index 54dbbcf287..3353631275 100644 --- a/xbmc/filesystem/MusicDatabaseDirectory/QueryParams.cpp +++ b/xbmc/filesystem/MusicDatabaseDirectory/QueryParams.cpp @@ -24,7 +24,7 @@ CQueryParams::CQueryParams() void CQueryParams::SetQueryParam(NODE_TYPE NodeType, const std::string& strNodeName) { - long idDb=atol(strNodeName.c_str()); + int idDb = atoi(strNodeName.c_str()); switch (NodeType) { diff --git a/xbmc/filesystem/MusicDatabaseDirectory/QueryParams.h b/xbmc/filesystem/MusicDatabaseDirectory/QueryParams.h index 47fcd6fde2..abfbdeaad8 100644 --- a/xbmc/filesystem/MusicDatabaseDirectory/QueryParams.h +++ b/xbmc/filesystem/MusicDatabaseDirectory/QueryParams.h @@ -18,24 +18,24 @@ namespace XFILE { public: CQueryParams(); - long GetArtistId() { return m_idArtist; } - long GetAlbumId() { return m_idAlbum; } - long GetGenreId() { return m_idGenre; } - long GetSongId() { return m_idSong; } - long GetYear() { return m_year; } - long GetDisc() { return m_disc; } + int GetArtistId() { return m_idArtist; } + int GetAlbumId() { return m_idAlbum; } + int GetGenreId() { return m_idGenre; } + int GetSongId() { return m_idSong; } + int GetYear() { return m_year; } + int GetDisc() { return m_disc; } protected: void SetQueryParam(NODE_TYPE NodeType, const std::string& strNodeName); friend class CDirectoryNode; private: - long m_idArtist; - long m_idAlbum; - long m_idGenre; - long m_idSong; - long m_year; - long m_disc; + int m_idArtist; + int m_idAlbum; + int m_idGenre; + int m_idSong; + int m_year; + int m_disc; }; } } diff --git a/xbmc/filesystem/MusicDatabaseFile.cpp b/xbmc/filesystem/MusicDatabaseFile.cpp index 766a50f84f..0e41ad4835 100644 --- a/xbmc/filesystem/MusicDatabaseFile.cpp +++ b/xbmc/filesystem/MusicDatabaseFile.cpp @@ -35,7 +35,7 @@ std::string CMusicDatabaseFile::TranslateUrl(const CURL& url) if (!StringUtils::IsNaturalNumber(strFileName)) return ""; - long idSong=atol(strFileName.c_str()); + int idSong = atoi(strFileName.c_str()); CSong song; if (!musicDatabase.GetSong(idSong, song)) diff --git a/xbmc/filesystem/PluginDirectory.cpp b/xbmc/filesystem/PluginDirectory.cpp index ab3d4bb6f4..16c1188900 100644 --- a/xbmc/filesystem/PluginDirectory.cpp +++ b/xbmc/filesystem/PluginDirectory.cpp @@ -197,7 +197,7 @@ bool CPluginDirectory::GetPluginResult(const std::string& strPath, CFileItem &re resultItem.SetDynPath(newDir.m_fileResult->GetPath()); resultItem.SetMimeType(newDir.m_fileResult->GetMimeType()); resultItem.SetContentLookup(newDir.m_fileResult->ContentLookup()); - resultItem.UpdateInfo(*newDir.m_fileResult); + resultItem.MergeInfo(*newDir.m_fileResult); if (newDir.m_fileResult->HasVideoInfoTag() && newDir.m_fileResult->GetVideoInfoTag()->GetResumePoint().IsSet()) resultItem.m_lStartOffset = STARTOFFSET_RESUME; // resume point set in the resume item, so force resume } diff --git a/xbmc/guilib/GUIFontTTFGL.cpp b/xbmc/guilib/GUIFontTTFGL.cpp index d0c4219e2c..a242366385 100644 --- a/xbmc/guilib/GUIFontTTFGL.cpp +++ b/xbmc/guilib/GUIFontTTFGL.cpp @@ -32,7 +32,6 @@ #include FT_OUTLINE_H #define ELEMENT_ARRAY_MAX_CHAR_INDEX (1000) -#define BUFFER_OFFSET(i) ((char *)NULL + (i)) CGUIFontTTF* CGUIFontTTF::CreateGUIFontTTF(const std::string& fileName) { @@ -159,9 +158,12 @@ void CGUIFontTTFGL::LastEnd() glBindBuffer(GL_ARRAY_BUFFER, VertexVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(SVertex)*vecVertices.size(), &vecVertices[0], GL_STATIC_DRAW); - glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(SVertex), BUFFER_OFFSET(offsetof(SVertex, x))); - glVertexAttribPointer(colLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(SVertex), BUFFER_OFFSET(offsetof(SVertex, r))); - glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex), BUFFER_OFFSET(offsetof(SVertex, u))); + glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(SVertex), + reinterpret_cast<const GLvoid*>(offsetof(SVertex, x))); + glVertexAttribPointer(colLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(SVertex), + reinterpret_cast<const GLvoid*>(offsetof(SVertex, r))); + glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex), + reinterpret_cast<const GLvoid*>(offsetof(SVertex, u))); glDrawArrays(GL_TRIANGLES, 0, vecVertices.size()); diff --git a/xbmc/guilib/GUITextureGL.cpp b/xbmc/guilib/GUITextureGL.cpp index 5e98d07c4e..d04e12cde5 100644 --- a/xbmc/guilib/GUITextureGL.cpp +++ b/xbmc/guilib/GUITextureGL.cpp @@ -16,8 +16,6 @@ #include "utils/log.h" #include "windowing/WinSystem.h" -#define BUFFER_OFFSET(i) ((char *)NULL + (i)) - CGUITexture* CGUITexture::CreateTexture( float posX, float posY, float width, float height, const CTextureInfo& texture) { @@ -116,13 +114,16 @@ void CGUITextureGL::End() if (m_diffuse.size()) { - glVertexAttribPointer(tex1Loc, 2, GL_FLOAT, 0, sizeof(PackedVertex), BUFFER_OFFSET(offsetof(PackedVertex, u2))); + glVertexAttribPointer(tex1Loc, 2, GL_FLOAT, 0, sizeof(PackedVertex), + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, u2))); glEnableVertexAttribArray(tex1Loc); } - glVertexAttribPointer(posLoc, 3, GL_FLOAT, 0, sizeof(PackedVertex), BUFFER_OFFSET(offsetof(PackedVertex, x))); + glVertexAttribPointer(posLoc, 3, GL_FLOAT, 0, sizeof(PackedVertex), + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, x))); glEnableVertexAttribArray(posLoc); - glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, 0, sizeof(PackedVertex), BUFFER_OFFSET(offsetof(PackedVertex, u1))); + glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, 0, sizeof(PackedVertex), + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, u1))); glEnableVertexAttribArray(tex0Loc); glGenBuffers(1, &IndexVBO); @@ -320,12 +321,14 @@ void CGUITexture::DrawQuad(const CRect& rect, glBindBuffer(GL_ARRAY_BUFFER, vertexVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(PackedVertex)*4, &vertex[0], GL_STATIC_DRAW); - glVertexAttribPointer(posLoc, 3, GL_FLOAT, 0, sizeof(PackedVertex), BUFFER_OFFSET(offsetof(PackedVertex, x))); + glVertexAttribPointer(posLoc, 3, GL_FLOAT, 0, sizeof(PackedVertex), + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, x))); glEnableVertexAttribArray(posLoc); if (texture) { - glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, 0, sizeof(PackedVertex), BUFFER_OFFSET(offsetof(PackedVertex, u1))); + glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, 0, sizeof(PackedVertex), + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, u1))); glEnableVertexAttribArray(tex0Loc); } diff --git a/xbmc/input/actions/ActionIDs.h b/xbmc/input/actions/ActionIDs.h index 0a3ffd37cf..01233668f9 100644 --- a/xbmc/input/actions/ActionIDs.h +++ b/xbmc/input/actions/ActionIDs.h @@ -430,6 +430,8 @@ #define ACTION_HDR_TOGGLE 260 //!< Toggle display HDR on/off +#define ACTION_CYCLE_TONEMAP_METHOD 261 //!< Switch to next tonemap method + // Voice actions #define ACTION_VOICE_RECOGNIZE 300 diff --git a/xbmc/input/actions/ActionTranslator.cpp b/xbmc/input/actions/ActionTranslator.cpp index 877bd3b9ab..774d225d6e 100644 --- a/xbmc/input/actions/ActionTranslator.cpp +++ b/xbmc/input/actions/ActionTranslator.cpp @@ -204,6 +204,9 @@ static const std::map<ActionName, ActionID> ActionMappings = { // HDR display support {"hdrtoggle", ACTION_HDR_TOGGLE}, + // Tone mapping + {"cycletonemapmethod", ACTION_CYCLE_TONEMAP_METHOD}, + // PVR actions {"channelup", ACTION_CHANNEL_UP}, {"channeldown", ACTION_CHANNEL_DOWN}, diff --git a/xbmc/interfaces/json-rpc/AudioLibrary.cpp b/xbmc/interfaces/json-rpc/AudioLibrary.cpp index 194838150e..77ee116f86 100644 --- a/xbmc/interfaces/json-rpc/AudioLibrary.cpp +++ b/xbmc/interfaces/json-rpc/AudioLibrary.cpp @@ -277,7 +277,7 @@ JSONRPC_STATUS CAudioLibrary::GetAlbums(const std::string &method, ITransportLay for (unsigned int index = 0; index < result["albums"].size(); index++) { CFileItem item; - item.GetMusicInfoTag()->SetDatabaseId(result["albums"][index]["albumid"].asInteger(), MediaTypeAlbum); + item.GetMusicInfoTag()->SetDatabaseId(result["albums"][index]["albumid"].asInteger32(), MediaTypeAlbum); // Could use FillDetails, but it does unnecessary serialization of empty MusiInfoTag // CFileItemPtr itemptr(new CFileItem(item)); @@ -432,9 +432,9 @@ JSONRPC_STATUS CAudioLibrary::GetSongs(const std::string &method, ITransportLaye CFileItem item; // Only needs song and album id (if we have it) set to get art // Getting art is quicker if "albumid" has been fetched - item.GetMusicInfoTag()->SetDatabaseId(result["songs"][index]["songid"].asInteger(), MediaTypeSong); + item.GetMusicInfoTag()->SetDatabaseId(result["songs"][index]["songid"].asInteger32(), MediaTypeSong); if (result["songs"][index].isMember("albumid")) - item.GetMusicInfoTag()->SetAlbumId(result["songs"][index]["albumid"].asInteger()); + item.GetMusicInfoTag()->SetAlbumId(result["songs"][index]["albumid"].asInteger32()); else item.GetMusicInfoTag()->SetAlbumId(-1); @@ -796,9 +796,9 @@ JSONRPC_STATUS CAudioLibrary::SetAlbumDetails(const std::string &method, ITransp if (ParameterNotNull(parameterObject, "rating")) album.fRating = parameterObject["rating"].asFloat(); if (ParameterNotNull(parameterObject, "userrating")) - album.iUserrating = parameterObject["userrating"].asInteger(); + album.iUserrating = static_cast<int>(parameterObject["userrating"].asInteger()); if (ParameterNotNull(parameterObject, "votes")) - album.iVotes = parameterObject["votes"].asInteger(); + album.iVotes = static_cast<int>(parameterObject["votes"].asInteger()); if (ParameterNotNull(parameterObject, "year")) album.strReleaseDate = parameterObject["year"].asString(); if (ParameterNotNull(parameterObject, "musicbrainzalbumid")) @@ -891,7 +891,7 @@ JSONRPC_STATUS CAudioLibrary::SetSongDetails(const std::string &method, ITranspo if (ParameterNotNull(parameterObject, "rating")) song.rating = parameterObject["rating"].asFloat(); if (ParameterNotNull(parameterObject, "userrating")) - song.userrating = parameterObject["userrating"].asInteger(); + song.userrating = static_cast<int>(parameterObject["userrating"].asInteger()); if (ParameterNotNull(parameterObject, "track")) song.iTrack = (song.iTrack & 0xffff0000) | ((int)parameterObject["track"].asInteger() & 0xffff); if (ParameterNotNull(parameterObject, "disc")) diff --git a/xbmc/interfaces/json-rpc/JSONServiceDescription.cpp b/xbmc/interfaces/json-rpc/JSONServiceDescription.cpp index f052d53aa8..2848bfe1d9 100644 --- a/xbmc/interfaces/json-rpc/JSONServiceDescription.cpp +++ b/xbmc/interfaces/json-rpc/JSONServiceDescription.cpp @@ -957,7 +957,7 @@ JSONRPC_STATUS JSONSchemaTypeDefinition::Check(const CVariant& value, // If we have a string, we need to check the length if (HasType(type, StringValue) && value.isString()) { - int size = value.asString().size(); + int size = static_cast<int>(value.asString().size()); if (size < minLength) { CLog::Log(LOGDEBUG, "JSONRPC: Value does not meet minLength requirements in type %s", name.c_str()); @@ -1225,7 +1225,7 @@ JSONSchemaTypeDefinition::CJsonSchemaPropertiesMap::JSONSchemaPropertiesIterator unsigned int JSONSchemaTypeDefinition::CJsonSchemaPropertiesMap::size() const { - return m_propertiesmap.size(); + return static_cast<unsigned int>(m_propertiesmap.size()); } JsonRpcMethod::JsonRpcMethod() diff --git a/xbmc/interfaces/json-rpc/schema/version.txt b/xbmc/interfaces/json-rpc/schema/version.txt index 86885f3d04..651cf58459 100644 --- a/xbmc/interfaces/json-rpc/schema/version.txt +++ b/xbmc/interfaces/json-rpc/schema/version.txt @@ -1 +1 @@ -JSONRPC_VERSION 11.19.0 +JSONRPC_VERSION 11.19.1 diff --git a/xbmc/interfaces/legacy/ListItem.cpp b/xbmc/interfaces/legacy/ListItem.cpp index b5089e23b8..530d1cc9ce 100644 --- a/xbmc/interfaces/legacy/ListItem.cpp +++ b/xbmc/interfaces/legacy/ListItem.cpp @@ -497,7 +497,7 @@ namespace XBMCAddon //! @todo add the rest of the infolabels if (key == "dbid" && !type.empty()) - musictag.SetDatabaseId(strtol(value.c_str(), NULL, 10), type); + musictag.SetDatabaseId(static_cast<int>(strtol(value.c_str(), NULL, 10)), type); else if (key == "tracknumber") musictag.SetTrackNumber(strtol(value.c_str(), NULL, 10)); else if (key == "discnumber") diff --git a/xbmc/music/Album.h b/xbmc/music/Album.h index 5b81fc95c1..18a08b725d 100644 --- a/xbmc/music/Album.h +++ b/xbmc/music/Album.h @@ -141,7 +141,7 @@ public: bool Load(const TiXmlElement *element, bool append = false, bool prioritise = false); bool Save(TiXmlNode *node, const std::string &tag, const std::string& strPath); - long idAlbum = -1; + int idAlbum = -1; std::string strAlbum; std::string strMusicBrainzAlbumID; std::string strReleaseGroupMBID; diff --git a/xbmc/music/Artist.h b/xbmc/music/Artist.h index 37864b61ea..2ec77a8254 100644 --- a/xbmc/music/Artist.h +++ b/xbmc/music/Artist.h @@ -32,7 +32,7 @@ public: class CArtist { public: - long idArtist = -1; + int idArtist = -1; bool operator<(const CArtist& a) const { if (strMusicBrainzArtistID.empty() && a.strMusicBrainzArtistID.empty()) @@ -164,7 +164,7 @@ public: void SetScrapedMBID(bool scrapedMBID) { this->m_bScrapedMBID = scrapedMBID; } private: - long idArtist = -1; + int idArtist = -1; std::string m_strArtist; std::string m_strSortName; std::string m_strMusicBrainzArtistID; @@ -176,7 +176,7 @@ typedef std::vector<CArtistCredit> VECARTISTCREDITS; const std::string BLANKARTIST_FAKEMUSICBRAINZID = "Artist Tag Missing"; const std::string BLANKARTIST_NAME = "[Missing Tag]"; -const long BLANKARTIST_ID = 1; +const int BLANKARTIST_ID = 1; const std::string VARIOUSARTISTS_MBID = "89ad4ac3-39f7-470e-963a-56509c546377"; #define ROLE_ARTIST 1 //Default role @@ -189,7 +189,7 @@ public: : idRole(-1), m_strRole(std::move(strRole)), m_strArtist(std::move(strArtist)), idArtist(-1) { } - CMusicRole(int role, std::string strRole, std::string strArtist, long ArtistId) + CMusicRole(int role, std::string strRole, std::string strArtist, int ArtistId) : idRole(role), m_strRole(std::move(strRole)), m_strArtist(std::move(strArtist)), @@ -199,8 +199,8 @@ public: std::string GetArtist() const { return m_strArtist; } std::string GetRoleDesc() const { return m_strRole; } int GetRoleId() const { return idRole; } - long GetArtistId() const { return idArtist; } - void SetArtistId(long iArtistId) { idArtist = iArtistId; } + int GetArtistId() const { return idArtist; } + void SetArtistId(int iArtistId) { idArtist = iArtistId; } bool operator==(const CMusicRole& a) const { @@ -213,7 +213,7 @@ private: int idRole; std::string m_strRole; std::string m_strArtist; - long idArtist; + int idArtist; }; typedef std::vector<CMusicRole> VECMUSICROLES; diff --git a/xbmc/music/MusicDatabase.cpp b/xbmc/music/MusicDatabase.cpp index 16b9cf4e7a..7623ca447b 100644 --- a/xbmc/music/MusicDatabase.cpp +++ b/xbmc/music/MusicDatabase.cpp @@ -685,7 +685,7 @@ bool CMusicDatabase::AddAlbum(CAlbum& album, int idSource) AddAlbumArtist(artistCredit->idArtist, album.idAlbum, artistCredit->GetArtist(), - std::distance(album.artistCredits.begin(), artistCredit)); + static_cast<int>(std::distance(album.artistCredits.begin(), artistCredit))); } for (auto song = album.songs.begin(); song != album.songs.end(); ++song) @@ -724,7 +724,7 @@ bool CMusicDatabase::AddAlbum(CAlbum& album, int idSource) song->idSong, ROLE_ARTIST, artistCredit->GetArtist(), // we don't have song artist breakdowns from scrapers, yet - std::distance(song->artistCredits.begin(), artistCredit)); + static_cast<int>(std::distance(song->artistCredits.begin(), artistCredit))); } // Having added artist credits (maybe with MBID) add the other contributing artists (no MBID) // and use COMPOSERSORT tag data to provide sort names for artists that are composers @@ -735,7 +735,7 @@ bool CMusicDatabase::AddAlbum(CAlbum& album, int idSource) // Folder layout may mean AddAlbum call has added more songs to an existing album std::string strSQL; strSQL = PrepareSQL("SELECT SUM(iDuration) FROM song WHERE idAlbum = %i", album.idAlbum); - int albumDuration = static_cast<int>(strtol(GetSingleValue(strSQL).c_str(), nullptr, 10)); + int albumDuration = GetSingleValueInt(strSQL); m_pDS->exec(PrepareSQL("UPDATE album SET iAlbumDuration = %i WHERE idAlbum = %i", albumDuration, album.idAlbum)); @@ -762,7 +762,7 @@ bool CMusicDatabase::AddAlbum(CAlbum& album, int idSource) std::string strSQL; strSQL = PrepareSQL("SELECT COUNT(DISTINCT strDiscSubtitle) FROM song WHERE song.idAlbum = %i", album.idAlbum); - int numTitles = static_cast<int>(strtol(GetSingleValue(strSQL).c_str(), nullptr, 10)); + int numTitles = GetSingleValueInt(strSQL); if (numTitles >=3) { strSQL = PrepareSQL("UPDATE album SET bBoxedSet=1 WHERE album.idAlbum=%i", album.idAlbum); @@ -816,7 +816,7 @@ bool CMusicDatabase::UpdateAlbum(CAlbum& album) { // not a boxset already so make sure we have enough discs & they all have titles std::string strSQL; strSQL = PrepareSQL("SELECT iDiscTotal FROM album WHERE idAlbum = %i", album.idAlbum); - int numDiscs = static_cast<int>(strtol(GetSingleValue(strSQL).c_str(), nullptr, 10)); + int numDiscs = GetSingleValueInt(strSQL); if (numDiscs >= 2) { canBeBoxset = true; @@ -883,7 +883,7 @@ bool CMusicDatabase::UpdateAlbum(CAlbum& album) AddAlbumArtist(artistCredit->idArtist, album.idAlbum, artistCredit->GetArtist(), - std::distance(album.artistCredits.begin(), artistCredit)); + static_cast<int>(std::distance(album.artistCredits.begin(), artistCredit))); } /* Replace the songs with those scraped or imported, but if new songs is empty (such as when called from JSON) do not remove the original ones @@ -1169,7 +1169,7 @@ bool CMusicDatabase::UpdateSong(CSong& song, song.idSong, ROLE_ARTIST, artistCredit->GetArtist(), - std::distance(song.artistCredits.begin(), artistCredit)); + static_cast<int>(std::distance(song.artistCredits.begin(), artistCredit))); } // Having added artist credits (maybe with MBID) add the other contributing artists (MBID unknown) // and use COMPOSERSORT tag data to provide sort names for artists that are composers @@ -2673,7 +2673,7 @@ bool CMusicDatabase::GetIsAlbumArtist(int idArtist, CFileItem* item) { try { - int countalbum = strtol(GetSingleValue("album_artist", "count(idArtist)", PrepareSQL("idArtist=%i", idArtist)).c_str(), NULL, 10); + int countalbum = GetSingleValueInt("album_artist", "count(idArtist)", PrepareSQL("idArtist=%i", idArtist)); CVariant IsAlbumArtistObj(CVariant::VariantTypeBoolean); IsAlbumArtistObj = (countalbum > 0); item->SetProperty("isalbumartist", IsAlbumArtistObj); @@ -3007,7 +3007,7 @@ bool CMusicDatabase::GetSongByFileName(const std::string& strFileNameAndPath, CS { std::string strFile = URIUtils::GetFileName(strFileNameAndPath); URIUtils::RemoveExtension(strFile); - return GetSong(atol(strFile.c_str()), song); + return GetSong(atoi(strFile.c_str()), song); } if (nullptr == m_pDB) @@ -3025,7 +3025,7 @@ bool CMusicDatabase::GetSongByFileName(const std::string& strFileNameAndPath, CS if (startOffset) strSQL += PrepareSQL(" AND iStartOffset=%" PRIi64, startOffset); - int idSong = (int)strtol(GetSingleValue(strSQL).c_str(), NULL, 10); + int idSong = GetSingleValueInt(strSQL); if (idSong > 0) return GetSong(idSong, song); @@ -3807,7 +3807,7 @@ bool CMusicDatabase::CleanupSongs(CGUIDialogProgress* progressDialog /*= nullptr { int total; // Count total number of songs - total = (int)strtol(GetSingleValue("SELECT COUNT(1) FROM song", m_pDS).c_str(), nullptr, 10); + total = GetSingleValueInt("SELECT COUNT(1) FROM song", m_pDS); // No songs to clean if (total == 0) return true; @@ -4999,7 +4999,6 @@ bool CMusicDatabase::GetArtistsByWhere(const std::string& strBaseDir, const Filt // Count done in full query fetch when unlimited if (countOnly || limitedInSQL) { - std::string strValue; if (extended) { // Count distinct without group by @@ -5008,12 +5007,11 @@ bool CMusicDatabase::GetArtistsByWhere(const std::string& strBaseDir, const Filt std::string strSQLWhere; if (!BuildSQL(strSQLWhere, countFilter, strSQLWhere)) return false; - strValue = GetSingleValue( - "SELECT COUNT(DISTINCT artistview.idArtist) FROM artistview " + strSQLWhere, m_pDS); + total = GetSingleValueInt( + "SELECT COUNT(DISTINCT artistview.idArtist) FROM artistview " + strSQLWhere, m_pDS); } else - strValue = GetSingleValue("SELECT COUNT(1) FROM artistview " + strSQLExtra, m_pDS); - total = static_cast<int>(strtol(strValue.c_str(), NULL, 10)); + total = GetSingleValueInt("SELECT COUNT(1) FROM artistview " + strSQLExtra, m_pDS); } if (countOnly) { @@ -5210,7 +5208,6 @@ bool CMusicDatabase::GetAlbumsByWhere(const std::string &baseDir, const Filter & // Count done in full query fetch when unlimited if (countOnly || limitedInSQL) { - std::string strValue; if (extended) { // Count distinct without group by @@ -5219,12 +5216,11 @@ bool CMusicDatabase::GetAlbumsByWhere(const std::string &baseDir, const Filter & std::string strSQLWhere; if (!BuildSQL(strSQLWhere, countFilter, strSQLWhere)) return false; - strValue = GetSingleValue( + total = GetSingleValueInt( "SELECT COUNT(DISTINCT albumview.idAlbum) FROM albumview " + strSQLWhere, m_pDS); } else - strValue = GetSingleValue("SELECT COUNT(1) FROM albumview " + strSQLExtra, m_pDS); - total = static_cast<int>(strtol(strValue.c_str(), NULL, 10)); + total = GetSingleValueInt("SELECT COUNT(1) FROM albumview " + strSQLExtra, m_pDS); } if (countOnly) { @@ -5414,7 +5410,7 @@ bool CMusicDatabase::GetDiscsByWhere(CMusicDbUrl& musicUrl, "albumview.idAlbum " + strSQLExtra; strSQL = "SELECT COUNT(1) FROM (" + strSQL + ") AS albumdisc "; - total = static_cast<int>(strtol(GetSingleValue(strSQL, m_pDS).c_str(), nullptr, 10)); + total = GetSingleValueInt(strSQL, m_pDS); } if (countOnly) { @@ -5552,7 +5548,7 @@ int CMusicDatabase::GetDiscsCount(const std::string& baseDir, const Filter& filt int iDiscTotal = -1; CFileItemList itemscount; if (GetDiscsByWhere(baseDir, filter, itemscount, SortDescription(), true)) - iDiscTotal = itemscount.GetProperty("total").asInteger(); + iDiscTotal = itemscount.GetProperty("total").asInteger32(); return iDiscTotal; } @@ -5592,20 +5588,18 @@ bool CMusicDatabase::GetSongsFullByWhere(const std::string &baseDir, const Filte // Count (without group by) number of songs that satisfy selection criteria // Much quicker to use song table, not songview, when filtering only on song fields - std::string strValue; if (extended || (!extFilter.where.empty() && (extFilter.where.find("strAlbum") != std::string::npos || extFilter.where.find("strPath") != std::string::npos || extFilter.where.find("bCompilation") != std::string::npos || extFilter.where.find("bBoxedset") != std::string::npos))) - strValue = GetSingleValue("SELECT COUNT(1) FROM songview " + strSQLExtra, m_pDS); + total = GetSingleValueInt("SELECT COUNT(1) FROM songview " + strSQLExtra, m_pDS); else { std::string strSQLsong = strSQLExtra; StringUtils::Replace(strSQLsong, "songview", "song"); - strValue = GetSingleValue("SELECT COUNT(1) FROM song " + strSQLsong, m_pDS); + total = GetSingleValueInt("SELECT COUNT(1) FROM song " + strSQLsong, m_pDS); } - total = static_cast<int>(strtol(strValue.c_str(), NULL, 10)); if (extended) extFilter.AppendGroup("songview.idSong"); @@ -5828,7 +5822,7 @@ bool CMusicDatabase::GetSongsByWhere(const std::string &baseDir, const Filter &f sorting.sortBy == SortByNone && (sorting.limitStart > 0 || sorting.limitEnd > 0)) { - total = (int)strtol(GetSingleValue(PrepareSQL(strSQL, "COUNT(1)") + strSQLExtra, m_pDS).c_str(), NULL, 10); + total = GetSingleValueInt(PrepareSQL(strSQL, "COUNT(1)") + strSQLExtra, m_pDS); strSQLExtra += DatabaseUtils::BuildLimitClause(sorting.limitEnd, sorting.limitStart); } @@ -6017,7 +6011,7 @@ bool CMusicDatabase::GetArtistsByWhereJSON(const std::set<std::string>& fields, // Count number of artists that satisfy selection criteria //(includes xsp limits from filter, but not sort limits) - total = static_cast<int>(strtol(GetSingleValue("SELECT COUNT(1) FROM artist " + strSQLExtra, m_pDS).c_str(), NULL, 10)); + total = GetSingleValueInt("SELECT COUNT(1) FROM artist " + strSQLExtra, m_pDS); resultcount = static_cast<size_t>(total); // Process albumartistsonly option @@ -6312,7 +6306,7 @@ bool CMusicDatabase::GetArtistsByWhereJSON(const std::set<std::string>& fields, // Adjust where in the results record the join fields are allowing for the // inline view fields (Quicker than finding field by name every time) // idArtist + other artist fields - joinLayout.AdjustRecordNumbers(1 + dbfieldindex.size()); + joinLayout.AdjustRecordNumbers(static_cast<int>(1 + dbfieldindex.size())); // Build full query // When have multiple value joins e.g. song genres, use inline view @@ -6700,7 +6694,7 @@ bool CMusicDatabase::GetAlbumsByWhereJSON(const std::set<std::string>& fields, c // Count number of albums that satisfy selection criteria // (includes xsp limits from filter, but not sort limits) // Use albumview as filter rules in where clause may use scalar query fields - total = static_cast<int>(strtol(GetSingleValue("SELECT COUNT(1) FROM albumview " + strSQLExtra, m_pDS).c_str(), nullptr, 10)); + total = GetSingleValueInt("SELECT COUNT(1) FROM albumview " + strSQLExtra, m_pDS); resultcount = static_cast<size_t>(total); // Get order by (and any scalar query artist fields @@ -6834,7 +6828,7 @@ bool CMusicDatabase::GetAlbumsByWhereJSON(const std::set<std::string>& fields, c // Adjust where in the results record the join fields are allowing for the // inline view fields (Quicker than finding field by name every time) // idAlbum + other album fields - joinLayout.AdjustRecordNumbers(1 + dbfieldindex.size()); + joinLayout.AdjustRecordNumbers(static_cast<int>(1 + dbfieldindex.size())); // Build full query // When have multiple value joins (artists or song genres) use inline view @@ -7125,8 +7119,7 @@ bool CMusicDatabase::GetSongsByWhereJSON(const std::set<std::string>& fields, co // Count number of songs that satisfy selection criteria // (includes xsp limits from filter, but not sort limits) - total = static_cast<int>(strtol( - GetSingleValue("SELECT COUNT(1) FROM song " + strSQLExtra, m_pDS).c_str(), nullptr, 10)); + total = GetSingleValueInt("SELECT COUNT(1) FROM song " + strSQLExtra, m_pDS); resultcount = static_cast<size_t>(total); int iAddedFields = GetOrderFilter(MediaTypeSong, sortDescription, extFilter); @@ -7398,7 +7391,7 @@ bool CMusicDatabase::GetSongsByWhereJSON(const std::set<std::string>& fields, co // Adjust where in the results record the join fields are allowing for the // inline view fields (Quicker than finding field by name every time) // idSong + other song fields - joinLayout.AdjustRecordNumbers(1 + dbfieldindex.size()); + joinLayout.AdjustRecordNumbers(static_cast<int>(1 + dbfieldindex.size())); // Build full query // When have multiple value joins use inline view @@ -8148,7 +8141,7 @@ void CMusicDatabase::UpdateTables(int version) strSQL = "SELECT count(idSong) FROM song " "WHERE NOT EXISTS(SELECT idSong FROM song_artist " "WHERE song_artist.idsong = song.idsong AND song_artist.idRole = 1)"; - int numsongs = strtol(GetSingleValue(strSQL).c_str(), NULL, 10); + int numsongs = GetSingleValueInt(strSQL); if (numsongs > 0) { CLog::Log(LOGDEBUG, "%i songs have no artist, setting artist to [Missing]", numsongs); @@ -8172,7 +8165,7 @@ void CMusicDatabase::UpdateTables(int version) strSQL = "SELECT count(idAlbum) FROM album " "WHERE NOT EXISTS(SELECT idAlbum FROM album_artist " "WHERE album_artist.idAlbum = album.idAlbum)"; - int numalbums = strtol(GetSingleValue(strSQL).c_str(), NULL, 10); + int numalbums = GetSingleValueInt(strSQL); if (numalbums > 0) { CLog::Log(LOGDEBUG, "%i albums have no artist, setting artist to [Missing]", numalbums); @@ -8796,7 +8789,7 @@ unsigned int CMusicDatabase::GetRandomSongIDs(const Filter &filter, std::vector< m_pDS->next(); } // cleanup m_pDS->close(); - return songIDs.size(); + return static_cast<unsigned int>(songIDs.size()); } catch (...) { @@ -9409,7 +9402,7 @@ bool CMusicDatabase::CheckSources(VECSOURCES& sources) } // Check number of entries matches - size_t total = static_cast<size_t>(strtol(GetSingleValue("SELECT COUNT(1) FROM source").c_str(), NULL, 10)); + size_t total = static_cast<size_t>(GetSingleValueInt("SELECT COUNT(1) FROM source")); if (total != sources.size()) return false; @@ -9916,7 +9909,7 @@ bool CMusicDatabase::IsSongAlbumArtist(int idSong, int idArtist) bool CMusicDatabase::IsAlbumBoxset(int idAlbum) { std::string strSQL = PrepareSQL("SELECT bBoxedSet FROM album WHERE idAlbum = %i", idAlbum); - int isBoxSet = strtol(GetSingleValue(strSQL).c_str(), nullptr, 10); + int isBoxSet = GetSingleValueInt(strSQL); return (isBoxSet == 1 ? true : false); } @@ -10317,18 +10310,18 @@ std::string CMusicDatabase::GetAlbumDiscTitle(int idAlbum, int idDisc) int CMusicDatabase::GetBoxsetsCount() { - return strtol(GetSingleValue("album", "count(idAlbum)", "bBoxedSet = 1").c_str(), nullptr, 10); + return GetSingleValueInt("album", "count(idAlbum)", "bBoxedSet = 1"); } int CMusicDatabase::GetAlbumDiscsCount(int idAlbum) { std::string strSQL = PrepareSQL("SELECT iDiscTotal FROM album WHERE album.idAlbum = %i", idAlbum); - return strtol(GetSingleValue(strSQL).c_str(), nullptr, 10); + return GetSingleValueInt(strSQL); } int CMusicDatabase::GetCompilationAlbumsCount() { - return strtol(GetSingleValue("album", "count(idAlbum)", "bCompilation = 1").c_str(), NULL, 10); + return GetSingleValueInt("album", "count(idAlbum)", "bCompilation = 1"); } int CMusicDatabase::GetSinglesCount() @@ -10340,13 +10333,13 @@ int CMusicDatabase::GetSinglesCount() int CMusicDatabase::GetArtistCountForRole(int role) { std::string strSQL = PrepareSQL("SELECT COUNT(DISTINCT idartist) FROM song_artist WHERE song_artist.idRole = %i", role); - return strtol(GetSingleValue(strSQL).c_str(), NULL, 10); + return GetSingleValueInt(strSQL); } int CMusicDatabase::GetArtistCountForRole(const std::string& strRole) { std::string strSQL = PrepareSQL("SELECT COUNT(DISTINCT idartist) FROM song_artist JOIN role ON song_artist.idRole = role.idRole WHERE role.strRole LIKE '%s'", strRole.c_str()); - return strtol(GetSingleValue(strSQL).c_str(), NULL, 10); + return GetSingleValueInt(strSQL); } bool CMusicDatabase::SetPathHash(const std::string &path, const std::string &hash) @@ -10489,7 +10482,7 @@ bool CMusicDatabase::RemoveSongsFromPath(const std::string &path1, MAPSONGS& son void CMusicDatabase::CheckArtistLinksChanged() { std::string strSQL = "SELECT COUNT(1) FROM removed_link "; - int iLinks = static_cast<int>(strtol(GetSingleValue(strSQL, m_pDS).c_str(), nullptr, 10)); + int iLinks = GetSingleValueInt(strSQL, m_pDS); if (iLinks > 0) { SetArtistLinksUpdated(); // Store datetime artist links last updated @@ -10630,7 +10623,7 @@ int CMusicDatabase::GetSongIDFromPath(const std::string &filePath) { std::string strFile=URIUtils::GetFileName(filePath); URIUtils::RemoveExtension(strFile); - return atol(strFile.c_str()); + return atoi(strFile.c_str()); } // hit the db try @@ -11725,7 +11718,7 @@ bool CMusicDatabase::ImportSongHistory(const std::string& xmlFile, const int tot m_pDS->exec("CREATE INDEX idxHistSong ON HistSong(idSong)"); // Log how many songs matched - int unmatched = static_cast<int>(strtol(GetSingleValue("SELECT COUNT(1) FROM HistSong WHERE idSong < 0", m_pDS).c_str(), nullptr, 10)); + int unmatched = GetSingleValueInt("SELECT COUNT(1) FROM HistSong WHERE idSong < 0", m_pDS); CLog::Log(LOGINFO, "{0}: Importing song history {1} of {2} songs matched", __FUNCTION__, total - unmatched, total); if (progressDialog) @@ -11879,7 +11872,7 @@ void CMusicDatabase::SetPropertiesForFileItem(CFileItem& item) if (item.HasProperty("artistid") && item.GetProperty("artistid").isArray()) { CVariant::const_iterator_array varid = item.GetProperty("artistid").begin_array(); - idArtist = varid->asInteger(); + idArtist = static_cast<int>(varid->asInteger()); } else idArtist = GetArtistByName(item.GetMusicInfoTag()->GetArtistString()); @@ -11901,6 +11894,36 @@ void CMusicDatabase::SetPropertiesForFileItem(CFileItem& item) } } +void CMusicDatabase::SetItemUpdated(int mediaId, const std::string& mediaType) +{ + std::string strSQL; + try + { + if (mediaType != MediaTypeArtist && mediaType != MediaTypeAlbum && mediaType != MediaTypeSong) + return; + if (nullptr == m_pDB) + return; + if (nullptr == m_pDS) + return; + + // Fire AFTER UPDATE db trigger on artist, album or song table to set datemodified field + // e.g. when artwork for item is changed from info dialog but not item details. + // Use SQL UPDATE that does not change record data. + if (mediaType == MediaTypeArtist) + strSQL = PrepareSQL("UPDATE artist SET strArtist = strArtist WHERE idArtist = %i", mediaId); + else if (mediaType == MediaTypeAlbum) + strSQL = PrepareSQL("UPDATE album SET strAlbum = strAlbum WHERE idAlbum = %i", mediaId); + else // MediaTypeSong + strSQL = PrepareSQL("UPDATE song SET strTitle = strTitle WHERE idSong = %i", mediaId); + m_pDS->exec(strSQL); + } + catch (...) + { + CLog::Log(LOGERROR, "CMusicDatabase::{0} ({1}, {2}) - failed to execute {3}", __FUNCTION__, + mediaId, mediaType.c_str(), strSQL.c_str()); + } +} + void CMusicDatabase::SetArtForItem(int mediaId, const std::string &mediaType, const std::map<std::string, std::string> &art) { for (const auto &i : art) diff --git a/xbmc/music/MusicDatabase.h b/xbmc/music/MusicDatabase.h index c7ab3328ae..191dc983d1 100644 --- a/xbmc/music/MusicDatabase.h +++ b/xbmc/music/MusicDatabase.h @@ -571,6 +571,7 @@ public: void SetPropertiesForFileItem(CFileItem& item); static void SetPropertiesFromArtist(CFileItem& item, const CArtist& artist); static void SetPropertiesFromAlbum(CFileItem& item, const CAlbum& album); + void SetItemUpdated(int mediaId, const std::string& mediaType); ///////////////////////////////////////////////// // Art diff --git a/xbmc/music/MusicInfoLoader.cpp b/xbmc/music/MusicInfoLoader.cpp index 67a8247df3..4869b0c8e3 100644 --- a/xbmc/music/MusicInfoLoader.cpp +++ b/xbmc/music/MusicInfoLoader.cpp @@ -98,7 +98,7 @@ bool CMusicInfoLoader::LoadAdditionalTagInfo(CFileItem* pItem) if (pItem->HasProperty("artistid") && pItem->GetProperty("artistid").isArray()) { CVariant::const_iterator_array varid = pItem->GetProperty("artistid").begin_array(); - int idArtist = varid->asInteger(); + int idArtist = static_cast<int>(varid->asInteger()); artistfound = database.GetArtist(idArtist, artist, false); } else diff --git a/xbmc/music/MusicUtils.cpp b/xbmc/music/MusicUtils.cpp index 0a15b6f1b8..c813c5267d 100644 --- a/xbmc/music/MusicUtils.cpp +++ b/xbmc/music/MusicUtils.cpp @@ -65,7 +65,7 @@ namespace MUSIC_UTILS for (CVariant::const_iterator_array varid = pSongItem->GetProperty("artistid").begin_array(); varid != pSongItem->GetProperty("artistid").end_array(); varid++) { - int idArtist = varid->asInteger(); + int idArtist = static_cast<int>(varid->asInteger()); result = (itemID == idArtist); if (result) break; @@ -100,6 +100,8 @@ namespace MUSIC_UTILS db.SetArtForItem(itemID, type, m_artType, m_newArt); else db.RemoveArtForItem(itemID, type, m_artType); + // Artwork changed so set datemodified field for artist, album or song + db.SetItemUpdated(itemID, type); /* Update the art of the songs of the current music playlist. Song thumb is often a fallback from the album and fanart is from the artist(s). diff --git a/xbmc/music/Song.cpp b/xbmc/music/Song.cpp index 313a67c987..c20bb10052 100644 --- a/xbmc/music/Song.cpp +++ b/xbmc/music/Song.cpp @@ -66,8 +66,8 @@ CSong::CSong(CFileItem& item) dateAdded = tag.GetDateAdded(); replayGain = tag.GetReplayGain(); strThumb = item.GetUserMusicThumb(true); - iStartOffset = item.m_lStartOffset; - iEndOffset = item.m_lEndOffset; + iStartOffset = static_cast<int>(item.m_lStartOffset); + iEndOffset = static_cast<int>(item.m_lEndOffset); idSong = -1; iTimesPlayed = 0; idAlbum = -1; diff --git a/xbmc/music/Song.h b/xbmc/music/Song.h index 2f2df6eb15..a744669d43 100644 --- a/xbmc/music/Song.h +++ b/xbmc/music/Song.h @@ -34,7 +34,7 @@ class CVariant; class CGenre { public: - long idGenre; + int idGenre; std::string strGenre; }; @@ -157,7 +157,7 @@ public: void SetArtistCredits(const std::vector<std::string>& names, const std::vector<std::string>& hints, const std::vector<std::string>& mbids); - long idSong; + int idSong; int idAlbum; std::string strFileName; std::string strTitle; diff --git a/xbmc/music/dialogs/GUIDialogMusicInfo.cpp b/xbmc/music/dialogs/GUIDialogMusicInfo.cpp index 94b641ec44..2a863f50ec 100644 --- a/xbmc/music/dialogs/GUIDialogMusicInfo.cpp +++ b/xbmc/music/dialogs/GUIDialogMusicInfo.cpp @@ -979,12 +979,12 @@ void CGUIDialogMusicInfo::ShowFor(CFileItem* pItem) } else if (pItem->HasProperty("artist_musicid")) { - musicitem.GetMusicInfoTag()->SetDatabaseId(pItem->GetProperty("artist_musicid").asInteger(), + musicitem.GetMusicInfoTag()->SetDatabaseId(pItem->GetProperty("artist_musicid").asInteger32(), MediaTypeArtist); } else if (pItem->HasProperty("album_musicid")) { - musicitem.GetMusicInfoTag()->SetDatabaseId(pItem->GetProperty("album_musicid").asInteger(), + musicitem.GetMusicInfoTag()->SetDatabaseId(pItem->GetProperty("album_musicid").asInteger32(), MediaTypeAlbum); } else diff --git a/xbmc/music/infoscanner/MusicInfoScanner.cpp b/xbmc/music/infoscanner/MusicInfoScanner.cpp index 7e1088fcc4..b8eafbb1ef 100644 --- a/xbmc/music/infoscanner/MusicInfoScanner.cpp +++ b/xbmc/music/infoscanner/MusicInfoScanner.cpp @@ -945,7 +945,7 @@ int CMusicInfoScanner::RetrieveMusicInfo(const std::string& strDirectory, CFileI m_musicDatabase.AddAlbum(album, m_idSourcePath); m_albumsAdded.insert(album.idAlbum); - numAdded += album.songs.size(); + numAdded += static_cast<int>(album.songs.size()); } return numAdded; } @@ -999,7 +999,7 @@ void MUSIC_INFO::CMusicInfoScanner::ScrapeInfoAddedAlbums() if (m_handle) { m_handle->SetText(album.GetAlbumArtistString() + " - " + album.strAlbum); - m_handle->SetProgress(i, m_albumsAdded.size()); + m_handle->SetProgress(i, static_cast<int>(m_albumsAdded.size())); } // Fetch any artist mbids for album artist(s) and song artists when scraping those too. @@ -1168,7 +1168,7 @@ void MUSIC_INFO::CMusicInfoScanner::RetrieveLocalArt() if (m_handle) { m_handle->SetText(album.GetAlbumArtistString() + " - " + album.strAlbum); - m_handle->SetProgress(count, m_albumsAdded.size()); + m_handle->SetProgress(count, static_cast<int>(m_albumsAdded.size())); } /* @@ -1931,7 +1931,7 @@ void CMusicInfoScanner::ScannerWait(unsigned int milliseconds) m_StopEvent.WaitMSec(milliseconds); } else - XbmcThreads::ThreadSleep(milliseconds); + std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds)); } bool CMusicInfoScanner::AddArtistArtwork(CArtist& artist, const std::string& artfolder) diff --git a/xbmc/music/tags/MusicInfoTag.cpp b/xbmc/music/tags/MusicInfoTag.cpp index 9b2293c352..0c3f541b9a 100644 --- a/xbmc/music/tags/MusicInfoTag.cpp +++ b/xbmc/music/tags/MusicInfoTag.cpp @@ -442,7 +442,7 @@ void CMusicInfoTag::SetYear(int year) m_strReleaseDate.clear(); } -void CMusicInfoTag::SetDatabaseId(long id, const std::string &type) +void CMusicInfoTag::SetDatabaseId(int id, const std::string &type) { m_iDbId = id; m_type = type; @@ -1107,7 +1107,7 @@ void CMusicInfoTag::Archive(CArchive& ar) for (int i = 0; i < iMusicRolesSize; ++i) { int idRole; - long idArtist; + int idArtist; std::string strArtist; std::string strRole; ar >> idRole; diff --git a/xbmc/music/tags/MusicInfoTag.h b/xbmc/music/tags/MusicInfoTag.h index a0261a382c..3c1b994425 100644 --- a/xbmc/music/tags/MusicInfoTag.h +++ b/xbmc/music/tags/MusicInfoTag.h @@ -107,7 +107,7 @@ public: void SetYear(int year); void SetOriginalDate(const std::string& strOriginalDate); void SetReleaseDate(const std::string& strReleaseDate); - void SetDatabaseId(long id, const std::string &type); + void SetDatabaseId(int id, const std::string &type); void SetTrackNumber(int iTrack); void SetDiscNumber(int iDiscNumber); void SetTrackAndDiscNumber(int iTrackAndDisc); diff --git a/xbmc/music/tags/MusicInfoTagLoaderFFmpeg.cpp b/xbmc/music/tags/MusicInfoTagLoaderFFmpeg.cpp index c2a25fd3ed..9bb2cdc09b 100644 --- a/xbmc/music/tags/MusicInfoTagLoaderFFmpeg.cpp +++ b/xbmc/music/tags/MusicInfoTagLoaderFFmpeg.cpp @@ -100,9 +100,11 @@ bool CMusicInfoTagLoaderFFmpeg::Load(const std::string& strFileName, CMusicInfoT tag.SetGenre(avtag->value); else if (StringUtils::CompareNoCase(avtag->key, "part_number") == 0 || StringUtils::CompareNoCase(avtag->key, "track") == 0) - tag.SetTrackNumber(strtol(avtag->value, nullptr, 10)); + tag.SetTrackNumber( + static_cast<int>(strtol(avtag->value, nullptr, 10))); else if (StringUtils::CompareNoCase(avtag->key, "disc") == 0) - tag.SetDiscNumber(strtol(avtag->value, nullptr, 10)); + tag.SetDiscNumber( + static_cast<int>(strtol(avtag->value, nullptr, 10))); else if (StringUtils::CompareNoCase(avtag->key, "date") == 0) tag.SetReleaseDate(avtag->value); else if (StringUtils::CompareNoCase(avtag->key, "compilation") == 0) @@ -131,7 +133,7 @@ bool CMusicInfoTagLoaderFFmpeg::Load(const std::string& strFileName, CMusicInfoT else if (StringUtils::CompareNoCase(avtag->key, "TYER") == 0) tag.AddReleaseDate(avtag->value); // YYYY part else if (StringUtils::CompareNoCase(avtag->key, "TBPM") == 0) - tag.SetBPM(strtol(avtag->value, nullptr, 10)); + tag.SetBPM(static_cast<int>(strtol(avtag->value, nullptr, 10))); else if (StringUtils::CompareNoCase(avtag->key, "TDTG") == 0) {} // Tagging time else if (StringUtils::CompareNoCase(avtag->key, "language") == 0 || StringUtils::CompareNoCase(avtag->key, "TLAN") == 0) {} // Languages diff --git a/xbmc/music/tags/TagLoaderTagLib.cpp b/xbmc/music/tags/TagLoaderTagLib.cpp index d5bb2e422e..113863b49d 100644 --- a/xbmc/music/tags/TagLoaderTagLib.cpp +++ b/xbmc/music/tags/TagLoaderTagLib.cpp @@ -298,8 +298,12 @@ bool CTagLoaderTagLib::ParseTag(ID3v2::Tag *id3v2, EmbeddedArt *art, MUSIC_INFO: else if (it->first == "TSOC") SetComposerSort(tag, GetID3v2StringList(it->second)); else if (it->first == "TIT2") tag.SetTitle(it->second.front()->toString().to8Bit(true)); else if (it->first == "TCON") SetGenre(tag, GetID3v2StringList(it->second)); - else if (it->first == "TRCK") tag.SetTrackNumber(strtol(it->second.front()->toString().toCString(true), nullptr, 10)); - else if (it->first == "TPOS") tag.SetDiscNumber(strtol(it->second.front()->toString().toCString(true), nullptr, 10)); + else if (it->first == "TRCK") + tag.SetTrackNumber( + static_cast<int>(strtol(it->second.front()->toString().toCString(true), nullptr, 10))); + else if (it->first == "TPOS") + tag.SetDiscNumber( + static_cast<int>(strtol(it->second.front()->toString().toCString(true), nullptr, 10))); else if (it->first == "TDOR" || it->first == "TORY") // TDOR - ID3v2.4, TORY - ID3v2.3 tag.SetOriginalDate(it->second.front()->toString().to8Bit(true)); else if (it->first == "TDAT") {} // empty as taglib has moved the value to TDRC @@ -320,7 +324,8 @@ bool CTagLoaderTagLib::ParseTag(ID3v2::Tag *id3v2, EmbeddedArt *art, MUSIC_INFO: else if (it->first == "TSST") tag.SetDiscSubtitle(it->second.front()->toString().to8Bit(true)); else if (it->first == "TBPM") - tag.SetBPM(strtol(it->second.front()->toString().toCString(true), nullptr, 10)); + tag.SetBPM( + static_cast<int>(strtol(it->second.front()->toString().toCString(true), nullptr, 10))); else if (it->first == "USLT") // Loop through any lyrics frames. Could there be multiple frames, how to choose? for (ID3v2::FrameList::ConstIterator lt = it->second.begin(); lt != it->second.end(); ++lt) diff --git a/xbmc/music/windows/GUIWindowMusicBase.cpp b/xbmc/music/windows/GUIWindowMusicBase.cpp index ef91ac9374..fd1d8a5706 100644 --- a/xbmc/music/windows/GUIWindowMusicBase.cpp +++ b/xbmc/music/windows/GUIWindowMusicBase.cpp @@ -1051,7 +1051,7 @@ bool CGUIWindowMusicBase::OnSelect(int iItem) if (choice == MUSIC_SELECT_ACTION_RESUME) { (*itemIt)->SetProperty("audiobook_bookmark", bookmark); - return CGUIMediaWindow::OnSelect(itemIt - m_vecItems->cbegin()); + return CGUIMediaWindow::OnSelect(static_cast<int>(itemIt - m_vecItems->cbegin())); } else if (choice < 0) return true; diff --git a/xbmc/music/windows/GUIWindowMusicNav.cpp b/xbmc/music/windows/GUIWindowMusicNav.cpp index a0b5533410..fb11c2c5b9 100644 --- a/xbmc/music/windows/GUIWindowMusicNav.cpp +++ b/xbmc/music/windows/GUIWindowMusicNav.cpp @@ -668,7 +668,7 @@ bool CGUIWindowMusicNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button) // music videos - artists if (StringUtils::StartsWithNoCase(item->GetPath(), "videodb://musicvideos/artists/")) { - long idArtist = m_musicdatabase.GetArtistByName(item->GetLabel()); + int idArtist = m_musicdatabase.GetArtistByName(item->GetLabel()); if (idArtist == -1) return false; std::string path = StringUtils::Format("musicdb://artists/%ld/", idArtist); @@ -685,7 +685,7 @@ bool CGUIWindowMusicNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button) // music videos - albums if (StringUtils::StartsWithNoCase(item->GetPath(), "videodb://musicvideos/albums/")) { - long idAlbum = m_musicdatabase.GetAlbumByName(item->GetLabel()); + int idAlbum = m_musicdatabase.GetAlbumByName(item->GetLabel()); if (idAlbum == -1) return false; std::string path = StringUtils::Format("musicdb://albums/%ld/", idAlbum); diff --git a/xbmc/network/upnp/UPnPInternal.cpp b/xbmc/network/upnp/UPnPInternal.cpp index 7fef33cda1..652ff364b1 100644 --- a/xbmc/network/upnp/UPnPInternal.cpp +++ b/xbmc/network/upnp/UPnPInternal.cpp @@ -24,6 +24,7 @@ #include "settings/AdvancedSettings.h" #include "settings/Settings.h" #include "settings/SettingsComponent.h" +#include "utils/ContentUtils.h" #include "utils/LangCodeExpander.h" #include "utils/StringUtils.h" #include "utils/URIUtils.h" @@ -579,13 +580,9 @@ BuildObject(CFileItem& item, if (!thumb_loader.IsNull()) thumb_loader->LoadItem(&item); - // finally apply the found artwork - // note: movies should use poster as the preferred "thumb" image - if (item.HasVideoInfoTag() && item.GetVideoInfoTag()->m_type == MediaTypeMovie && - item.HasArt("poster")) - thumb = item.GetArt("poster"); - else - thumb = item.GetArt("thumb"); + // we have to decide the best art type to serve to the client - use ContentUtils + // to get it since it depends on the mediatype of the item being served + thumb = ContentUtils::GetPreferredArtImage(item); if (!thumb.empty()) { PLT_AlbumArtInfo art; diff --git a/xbmc/pictures/SlideShowPicture.cpp b/xbmc/pictures/SlideShowPicture.cpp index cbd8ee25d2..f97c79ed15 100644 --- a/xbmc/pictures/SlideShowPicture.cpp +++ b/xbmc/pictures/SlideShowPicture.cpp @@ -45,8 +45,6 @@ using namespace Microsoft::WRL; #define FPS 25 -#define BUFFER_OFFSET(i) ((char *)NULL + (i)) - static float zoomamount[10] = { 1.0f, 1.2f, 1.5f, 2.0f, 2.8f, 4.0f, 6.0f, 9.0f, 13.5f, 20.0f }; CSlideShowPic::CSlideShowPic() @@ -909,8 +907,10 @@ void CSlideShowPic::Render(float* x, float* y, CTexture* pTexture, UTILS::Color glBindBuffer(GL_ARRAY_BUFFER, vertexVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(PackedVertex)*4, &vertex[0], GL_STATIC_DRAW); - glVertexAttribPointer(posLoc, 3, GL_FLOAT, 0, sizeof(PackedVertex), BUFFER_OFFSET(offsetof(PackedVertex, x))); - glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, 0, sizeof(PackedVertex), BUFFER_OFFSET(offsetof(PackedVertex, u1))); + glVertexAttribPointer(posLoc, 3, GL_FLOAT, 0, sizeof(PackedVertex), + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, x))); + glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, 0, sizeof(PackedVertex), + reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, u1))); glEnableVertexAttribArray(posLoc); glEnableVertexAttribArray(tex0Loc); diff --git a/xbmc/platform/CMakeLists.txt b/xbmc/platform/CMakeLists.txt index 5a9be9d212..63029e1c24 100644 --- a/xbmc/platform/CMakeLists.txt +++ b/xbmc/platform/CMakeLists.txt @@ -1,20 +1,11 @@ -file(GLOB OVERRIDES_CPP overrides/${CORE_SYSTEM_NAME}/*.cpp) -file(GLOB OVERRIDES_H overrides/${CORE_SYSTEM_NAME}/*.h) - set(SOURCES Environment.cpp Platform.cpp - xbmc.cpp - ${OVERRIDES_CPP}) + xbmc.cpp) set(HEADERS Environment.h Filesystem.h MessagePrinter.h Platform.h - xbmc.h - ${OVERRIDES_H}) + xbmc.h) core_add_library(platform_common) - -if(OVERRIDES_CPP) - target_compile_definitions(${CORE_LIBRARY} PRIVATE -DPLATFORM_OVERRIDE) -endif() diff --git a/xbmc/platform/Platform.cpp b/xbmc/platform/Platform.cpp index 5b90611d74..7c7f1e7dd6 100644 --- a/xbmc/platform/Platform.cpp +++ b/xbmc/platform/Platform.cpp @@ -10,18 +10,6 @@ #include "ServiceBroker.h" -// Override for platform ports -#if !defined(PLATFORM_OVERRIDE) - -CPlatform* CPlatform::CreateInstance() -{ - return new CPlatform(); -} - -#endif - -// base class definitions - CPlatform::CPlatform() = default; CPlatform::~CPlatform() = default; diff --git a/xbmc/platform/android/CMakeLists.txt b/xbmc/platform/android/CMakeLists.txt index 68cd68a5c4..200729cb9a 100644 --- a/xbmc/platform/android/CMakeLists.txt +++ b/xbmc/platform/android/CMakeLists.txt @@ -1,6 +1,8 @@ set(SOURCES CPUInfoAndroid.cpp - MemUtils.cpp) + MemUtils.cpp + PlatformAndroid.cpp) -set(HEADERS CPUInfoAndroid.h) +set(HEADERS CPUInfoAndroid.h + PlatformAndroid.h) core_add_library(androidsupport) diff --git a/xbmc/platform/overrides/android/PlatformAndroid.cpp b/xbmc/platform/android/PlatformAndroid.cpp index f27e3db141..f27e3db141 100644 --- a/xbmc/platform/overrides/android/PlatformAndroid.cpp +++ b/xbmc/platform/android/PlatformAndroid.cpp diff --git a/xbmc/platform/overrides/android/PlatformAndroid.h b/xbmc/platform/android/PlatformAndroid.h index c88c5411ce..c88c5411ce 100644 --- a/xbmc/platform/overrides/android/PlatformAndroid.h +++ b/xbmc/platform/android/PlatformAndroid.h diff --git a/xbmc/platform/darwin/ios-common/CMakeLists.txt b/xbmc/platform/darwin/ios-common/CMakeLists.txt index 94987b576f..9a95136da4 100644 --- a/xbmc/platform/darwin/ios-common/CMakeLists.txt +++ b/xbmc/platform/darwin/ios-common/CMakeLists.txt @@ -4,7 +4,8 @@ set(SOURCES AnnounceReceiver.mm DarwinEmbedKeyboardView.mm DarwinEmbedNowPlayingInfoManager.mm DarwinEmbedUtils.mm - NSData+GZIP.m) + NSData+GZIP.m + PlatformDarwinEmbedded.cpp) set(HEADERS AnnounceReceiver.h CPUInfoDarwinEmbed.h @@ -12,6 +13,7 @@ set(HEADERS AnnounceReceiver.h DarwinEmbedKeyboardView.h DarwinEmbedNowPlayingInfoManager.h DarwinEmbedUtils.h - NSData+GZIP.h) + NSData+GZIP.h + PlatformDarwinEmbedded.h) core_add_library(platform_ios-common) diff --git a/xbmc/platform/overrides/darwin_embedded/PlatformDarwinEmbedded.cpp b/xbmc/platform/darwin/ios-common/PlatformDarwinEmbedded.cpp index 09fe5dd899..09fe5dd899 100644 --- a/xbmc/platform/overrides/darwin_embedded/PlatformDarwinEmbedded.cpp +++ b/xbmc/platform/darwin/ios-common/PlatformDarwinEmbedded.cpp diff --git a/xbmc/platform/overrides/darwin_embedded/PlatformDarwinEmbedded.h b/xbmc/platform/darwin/ios-common/PlatformDarwinEmbedded.h index 665dd61b7e..665dd61b7e 100644 --- a/xbmc/platform/overrides/darwin_embedded/PlatformDarwinEmbedded.h +++ b/xbmc/platform/darwin/ios-common/PlatformDarwinEmbedded.h diff --git a/xbmc/platform/darwin/ios-common/peripherals/Input_Gamecontroller.mm b/xbmc/platform/darwin/ios-common/peripherals/Input_Gamecontroller.mm index 1075ab52c1..282712ac08 100644 --- a/xbmc/platform/darwin/ios-common/peripherals/Input_Gamecontroller.mm +++ b/xbmc/platform/darwin/ios-common/peripherals/Input_Gamecontroller.mm @@ -395,7 +395,7 @@ struct PlayerControllerState withAxis:GCCONTROLLER_EXTENDED_GAMEPAD_AXIS::RIGHT withplayerIndex:playerIndex]; } - if (@available(iOS 12.1, *)) + if (@available(iOS 12.1, tvOS 12.1, *)) { // Left Thumbstick Button if (gamepad.leftThumbstickButton == element) @@ -566,7 +566,7 @@ struct PlayerControllerState [controller.extendedGamepad performSelector:@selector(buttonOptions)] != nil) ++optionalButtonCount; - if (@available(iOS 12.1, *)) + if (@available(iOS 12.1, tvOS 12.1, *)) { if (controller.extendedGamepad.leftThumbstickButton) ++optionalButtonCount; diff --git a/xbmc/platform/darwin/osx/CMakeLists.txt b/xbmc/platform/darwin/osx/CMakeLists.txt index 9759e303c4..3ef7dc54d6 100644 --- a/xbmc/platform/darwin/osx/CMakeLists.txt +++ b/xbmc/platform/darwin/osx/CMakeLists.txt @@ -2,6 +2,7 @@ set(SOURCES CocoaInterface.mm CPUInfoOsx.cpp HotKeyController.m OSXTextInputResponder.mm + PlatformDarwinOSX.cpp smc.c XBMCHelper.cpp) @@ -9,6 +10,7 @@ set(HEADERS CocoaInterface.h CPUInfoOsx.h HotKeyController.h OSXTextInputResponder.h + PlatformDarwinOSX.h smc.h XBMCHelper.h) diff --git a/xbmc/platform/overrides/osx/PlatformDarwinOSX.cpp b/xbmc/platform/darwin/osx/PlatformDarwinOSX.cpp index 076d4939bd..076d4939bd 100644 --- a/xbmc/platform/overrides/osx/PlatformDarwinOSX.cpp +++ b/xbmc/platform/darwin/osx/PlatformDarwinOSX.cpp diff --git a/xbmc/platform/overrides/osx/PlatformDarwinOSX.h b/xbmc/platform/darwin/osx/PlatformDarwinOSX.h index ca2c331c97..ca2c331c97 100644 --- a/xbmc/platform/overrides/osx/PlatformDarwinOSX.h +++ b/xbmc/platform/darwin/osx/PlatformDarwinOSX.h diff --git a/xbmc/platform/freebsd/CMakeLists.txt b/xbmc/platform/freebsd/CMakeLists.txt index c80f4858b4..5e77b017f3 100644 --- a/xbmc/platform/freebsd/CMakeLists.txt +++ b/xbmc/platform/freebsd/CMakeLists.txt @@ -2,12 +2,14 @@ set(SOURCES CPUInfoFreebsd.cpp OptionalsReg.cpp ../linux/OptionalsReg.cpp ../linux/TimeUtils.cpp - MemUtils.cpp) + MemUtils.cpp + PlatformFreebsd.cpp) set(HEADERS CPUInfoFreebsd.h OptionalsReg.h ../linux/OptionalsReg.h - ../linux/TimeUtils.h) + ../linux/TimeUtils.h + PlatformFreebsd.h) if(ALSA_FOUND) list(APPEND SOURCES ../linux/FDEventMonitor.cpp) diff --git a/xbmc/platform/overrides/freebsd/PlatformFreebsd.cpp b/xbmc/platform/freebsd/PlatformFreebsd.cpp index e56e54f817..17829a9a99 100644 --- a/xbmc/platform/overrides/freebsd/PlatformFreebsd.cpp +++ b/xbmc/platform/freebsd/PlatformFreebsd.cpp @@ -8,6 +8,9 @@ #include "PlatformFreebsd.h" +#include "utils/StringUtils.h" + +#include "platform/freebsd/OptionalsReg.h" #include "platform/linux/powermanagement/LinuxPowerSyscall.h" // clang-format off @@ -76,5 +79,46 @@ bool CPlatformFreebsd::Init() CLinuxPowerSyscall::Register(); + std::string envSink; + if (getenv("KODI_AE_SINK")) + envSink = getenv("KODI_AE_SINK"); + + if (StringUtils::EqualsNoCase(envSink, "ALSA")) + { + OPTIONALS::ALSARegister(); + } + else if (StringUtils::EqualsNoCase(envSink, "PULSE")) + { + OPTIONALS::PulseAudioRegister(); + } + else if (StringUtils::EqualsNoCase(envSink, "OSS")) + { + OPTIONALS::OSSRegister(); + } + else if (StringUtils::EqualsNoCase(envSink, "SNDIO")) + { + OPTIONALS::SndioRegister(); + } + else if (StringUtils::EqualsNoCase(envSink, "ALSA+PULSE")) + { + OPTIONALS::ALSARegister(); + OPTIONALS::PulseAudioRegister(); + } + else + { + if (!OPTIONALS::PulseAudioRegister()) + { + if (!OPTIONALS::ALSARegister()) + { + if (!OPTIONALS::SndioRegister()) + { + OPTIONALS::OSSRegister(); + } + } + } + } + + m_lirc.reset(OPTIONALS::LircRegister()); + return true; } diff --git a/xbmc/platform/overrides/freebsd/PlatformFreebsd.h b/xbmc/platform/freebsd/PlatformFreebsd.h index c98be81999..6538c047a0 100644 --- a/xbmc/platform/overrides/freebsd/PlatformFreebsd.h +++ b/xbmc/platform/freebsd/PlatformFreebsd.h @@ -8,8 +8,11 @@ #pragma once +#include "platform/linux/OptionalsReg.h" #include "platform/posix/PlatformPosix.h" +#include <memory> + class CPlatformFreebsd : public CPlatformPosix { public: @@ -17,4 +20,7 @@ public: ~CPlatformFreebsd() override = default; bool Init() override; + +private: + std::unique_ptr<OPTIONALS::CLircContainer, OPTIONALS::delete_CLircContainer> m_lirc; }; diff --git a/xbmc/platform/linux/CMakeLists.txt b/xbmc/platform/linux/CMakeLists.txt index 3f851f521f..179604c560 100644 --- a/xbmc/platform/linux/CMakeLists.txt +++ b/xbmc/platform/linux/CMakeLists.txt @@ -1,11 +1,13 @@ set(SOURCES CPUInfoLinux.cpp MemUtils.cpp OptionalsReg.cpp + PlatformLinux.cpp SysfsPath.cpp TimeUtils.cpp) set(HEADERS CPUInfoLinux.h OptionalsReg.h + PlatformLinux.h SysfsPath.h TimeUtils.h) diff --git a/xbmc/platform/linux/OptionalsReg.cpp b/xbmc/platform/linux/OptionalsReg.cpp index 1e376b33c7..5af22c38a1 100644 --- a/xbmc/platform/linux/OptionalsReg.cpp +++ b/xbmc/platform/linux/OptionalsReg.cpp @@ -28,17 +28,6 @@ bool OPTIONALS::ALSARegister() #endif //----------------------------------------------------------------------------- -// OSS -//----------------------------------------------------------------------------- - -#ifdef TARGET_LINUX -bool OPTIONALS::OSSRegister() -{ - return false; -} -#endif - -//----------------------------------------------------------------------------- // PulseAudio //----------------------------------------------------------------------------- diff --git a/xbmc/platform/linux/OptionalsReg.h b/xbmc/platform/linux/OptionalsReg.h index 9d537ef4a4..662c20d5c9 100644 --- a/xbmc/platform/linux/OptionalsReg.h +++ b/xbmc/platform/linux/OptionalsReg.h @@ -27,17 +27,6 @@ bool PulseAudioRegister(); } //----------------------------------------------------------------------------- -// OSS -//----------------------------------------------------------------------------- - -#ifdef TARGET_LINUX -namespace OPTIONALS -{ -bool OSSRegister(); -} -#endif - -//----------------------------------------------------------------------------- // sndio //----------------------------------------------------------------------------- diff --git a/xbmc/platform/overrides/linux/PlatformLinux.cpp b/xbmc/platform/linux/PlatformLinux.cpp index 8f34287b10..3f66962112 100644 --- a/xbmc/platform/overrides/linux/PlatformLinux.cpp +++ b/xbmc/platform/linux/PlatformLinux.cpp @@ -8,6 +8,8 @@ #include "PlatformLinux.h" +#include "utils/StringUtils.h" + #include "platform/linux/powermanagement/LinuxPowerSyscall.h" // clang-format off @@ -76,5 +78,39 @@ bool CPlatformLinux::Init() CLinuxPowerSyscall::Register(); + std::string envSink; + if (getenv("KODI_AE_SINK")) + envSink = getenv("KODI_AE_SINK"); + + if (StringUtils::EqualsNoCase(envSink, "ALSA")) + { + OPTIONALS::ALSARegister(); + } + else if (StringUtils::EqualsNoCase(envSink, "PULSE")) + { + OPTIONALS::PulseAudioRegister(); + } + else if (StringUtils::EqualsNoCase(envSink, "SNDIO")) + { + OPTIONALS::SndioRegister(); + } + else if (StringUtils::EqualsNoCase(envSink, "ALSA+PULSE")) + { + OPTIONALS::ALSARegister(); + OPTIONALS::PulseAudioRegister(); + } + else + { + if (!OPTIONALS::PulseAudioRegister()) + { + if (!OPTIONALS::ALSARegister()) + { + OPTIONALS::SndioRegister(); + } + } + } + + m_lirc.reset(OPTIONALS::LircRegister()); + return true; } diff --git a/xbmc/platform/overrides/linux/PlatformLinux.h b/xbmc/platform/linux/PlatformLinux.h index 1f9af158cc..9a872a5f55 100644 --- a/xbmc/platform/overrides/linux/PlatformLinux.h +++ b/xbmc/platform/linux/PlatformLinux.h @@ -8,8 +8,11 @@ #pragma once +#include "platform/linux/OptionalsReg.h" #include "platform/posix/PlatformPosix.h" +#include <memory> + class CPlatformLinux : public CPlatformPosix { public: @@ -18,4 +21,7 @@ public: ~CPlatformLinux() override = default; bool Init() override; + +private: + std::unique_ptr<OPTIONALS::CLircContainer, OPTIONALS::delete_CLircContainer> m_lirc; }; diff --git a/xbmc/platform/win10/CMakeLists.txt b/xbmc/platform/win10/CMakeLists.txt index 2101870906..6ddf3c8df7 100644 --- a/xbmc/platform/win10/CMakeLists.txt +++ b/xbmc/platform/win10/CMakeLists.txt @@ -3,6 +3,7 @@ set(SOURCES CPUInfoWin10.cpp Environment.cpp Win10App.cpp MessagePrinter.cpp + PlatformWin10.cpp ../win32/CharsetConverter.cpp ../win32/dxerr.cpp ../win32/Filesystem.cpp @@ -15,6 +16,7 @@ set(HEADERS AsyncHelpers.h CPUInfoWin10.h input/RemoteControlXbox.h Win10App.h + PlatformWin10.h ../win32/CharsetConverter.h ../win32/dirent.h ../win32/dxerr.h diff --git a/xbmc/platform/overrides/windowsstore/PlatformWin10.cpp b/xbmc/platform/win10/PlatformWin10.cpp index 0d0aa73862..0d0aa73862 100644 --- a/xbmc/platform/overrides/windowsstore/PlatformWin10.cpp +++ b/xbmc/platform/win10/PlatformWin10.cpp diff --git a/xbmc/platform/overrides/windowsstore/PlatformWin10.h b/xbmc/platform/win10/PlatformWin10.h index 62abfda4ba..62abfda4ba 100644 --- a/xbmc/platform/overrides/windowsstore/PlatformWin10.h +++ b/xbmc/platform/win10/PlatformWin10.h diff --git a/xbmc/platform/win32/CMakeLists.txt b/xbmc/platform/win32/CMakeLists.txt index 5d048c9322..57afab0e41 100644 --- a/xbmc/platform/win32/CMakeLists.txt +++ b/xbmc/platform/win32/CMakeLists.txt @@ -6,6 +6,7 @@ set(SOURCES CharsetConverter.cpp dxerr.cpp Filesystem.cpp pch.cpp + PlatformWin32.cpp WIN32Util.cpp WindowHelper.cpp XTimeUtils.cpp) @@ -20,6 +21,7 @@ set(HEADERS CharsetConverter.h netdb.h pch.h PlatformDefs.h + PlatformWin32.h resource.h unistd.h WIN32Util.h diff --git a/xbmc/platform/overrides/windows/PlatformWin32.cpp b/xbmc/platform/win32/PlatformWin32.cpp index 6cdaab3dce..6cdaab3dce 100644 --- a/xbmc/platform/overrides/windows/PlatformWin32.cpp +++ b/xbmc/platform/win32/PlatformWin32.cpp diff --git a/xbmc/platform/overrides/windows/PlatformWin32.h b/xbmc/platform/win32/PlatformWin32.h index c2685c187f..c2685c187f 100644 --- a/xbmc/platform/overrides/windows/PlatformWin32.h +++ b/xbmc/platform/win32/PlatformWin32.h diff --git a/xbmc/pvr/PVRDatabase.cpp b/xbmc/pvr/PVRDatabase.cpp index afba3956b5..77895e4e4e 100644 --- a/xbmc/pvr/PVRDatabase.cpp +++ b/xbmc/pvr/PVRDatabase.cpp @@ -75,6 +75,16 @@ void CPVRDatabase::Close() CDatabase::Close(); } +void CPVRDatabase::Lock() +{ + m_critSection.lock(); +} + +void CPVRDatabase::Unlock() +{ + m_critSection.unlock(); +} + void CPVRDatabase::CreateTables() { CSingleLock lock(m_critSection); @@ -289,19 +299,21 @@ bool CPVRDatabase::DeleteChannels() return DeleteValues("channels"); } -bool CPVRDatabase::Delete(const CPVRChannel& channel) +bool CPVRDatabase::QueueDeleteQuery(const CPVRChannel& channel) { /* invalid channel */ if (channel.ChannelID() <= 0) return false; - CLog::LogFC(LOGDEBUG, LOGPVR, "Deleting channel '{}' from the database", channel.ChannelName()); + CLog::LogFC(LOGDEBUG, LOGPVR, "Queueing delete for channel '{}' from the database", + channel.ChannelName()); Filter filter; filter.AppendWhere(PrepareSQL("idChannel = %u", channel.ChannelID())); - CSingleLock lock(m_critSection); - return DeleteValues("channels", filter); + std::string strQuery; + BuildSQL(PrepareSQL("DELETE FROM %s ", "channels"), filter, strQuery); + return CDatabase::QueueDeleteQuery(strQuery); } int CPVRDatabase::Get(CPVRChannelGroup& results, bool bCompressDB) diff --git a/xbmc/pvr/PVRDatabase.h b/xbmc/pvr/PVRDatabase.h index d0cb5cc879..f5d23db0a6 100644 --- a/xbmc/pvr/PVRDatabase.h +++ b/xbmc/pvr/PVRDatabase.h @@ -25,6 +25,8 @@ namespace PVR /** The PVR database */ + static constexpr int CHANNEL_COMMIT_QUERY_COUNT_LIMIT = 10000; + class CPVRDatabase : public CDatabase { public: @@ -46,6 +48,16 @@ namespace PVR void Close() override; /*! + * @brief Lock the database. + */ + void Lock(); + + /*! + * @brief Unlock the database. + */ + void Unlock(); + + /*! * @brief Get the minimal database version that is required to operate correctly. * @return The minimal database version. */ @@ -109,7 +121,7 @@ namespace PVR * @param channel The channel to remove. * @return True if the channel was removed, false otherwise. */ - bool Delete(const CPVRChannel& channel); + bool QueueDeleteQuery(const CPVRChannel& channel); /*! * @brief Get the list of channels from the database diff --git a/xbmc/pvr/addons/PVRClientMenuHooks.cpp b/xbmc/pvr/addons/PVRClientMenuHooks.cpp index b1297d5a19..1763d9197c 100644 --- a/xbmc/pvr/addons/PVRClientMenuHooks.cpp +++ b/xbmc/pvr/addons/PVRClientMenuHooks.cpp @@ -26,7 +26,7 @@ CPVRClientMenuHook::CPVRClientMenuHook(const std::string& addonId, const PVR_MEN hook.category != PVR_MENUHOOK_TIMER && hook.category != PVR_MENUHOOK_EPG && hook.category != PVR_MENUHOOK_RECORDING && - hook.category != PVR_MENUHOOK_RECORDING && + hook.category != PVR_MENUHOOK_DELETED_RECORDING && hook.category != PVR_MENUHOOK_SETTING) CLog::LogF(LOGERROR, "Unknown PVR_MENUHOOK_CAT value: {}", hook.category); } diff --git a/xbmc/pvr/addons/PVRClients.cpp b/xbmc/pvr/addons/PVRClients.cpp index ebebe76b03..04e054db44 100644 --- a/xbmc/pvr/addons/PVRClients.cpp +++ b/xbmc/pvr/addons/PVRClients.cpp @@ -510,11 +510,16 @@ PVR_ERROR CPVRClients::GetTimerTypes(std::vector<std::shared_ptr<CPVRTimerType>> }); } -PVR_ERROR CPVRClients::GetRecordings(CPVRRecordings* recordings, bool deleted) -{ - return ForCreatedClients(__FUNCTION__, [recordings, deleted](const std::shared_ptr<CPVRClient>& client) { - return client->GetRecordings(recordings, deleted); - }); +PVR_ERROR CPVRClients::GetRecordings(CPVRRecordings* recordings, + bool deleted, + std::vector<int>& failedClients) +{ + return ForCreatedClients( + __FUNCTION__, + [recordings, deleted](const std::shared_ptr<CPVRClient>& client) { + return client->GetRecordings(recordings, deleted); + }, + failedClients); } PVR_ERROR CPVRClients::DeleteAllRecordingsFromTrash() diff --git a/xbmc/pvr/addons/PVRClients.h b/xbmc/pvr/addons/PVRClients.h index e7b7c0b338..560cd0dc54 100644 --- a/xbmc/pvr/addons/PVRClients.h +++ b/xbmc/pvr/addons/PVRClients.h @@ -200,9 +200,12 @@ namespace PVR * @brief Get all recordings from clients * @param recordings Store the recordings in this container. * @param deleted If true, return deleted recordings, return not deleted recordings otherwise. + * @param failedClients in case of errors will contain the ids of the clients for which the recordings could not be obtained. * @return PVR_ERROR_NO_ERROR if the operation succeeded, the respective PVR_ERROR value otherwise. */ - PVR_ERROR GetRecordings(CPVRRecordings* recordings, bool deleted); + PVR_ERROR GetRecordings(CPVRRecordings* recordings, + bool deleted, + std::vector<int>& failedClients); /*! * @brief Delete all "soft" deleted recordings permanently on the backend. diff --git a/xbmc/pvr/channels/PVRChannel.cpp b/xbmc/pvr/channels/PVRChannel.cpp index 5187b1647d..7798653929 100644 --- a/xbmc/pvr/channels/PVRChannel.cpp +++ b/xbmc/pvr/channels/PVRChannel.cpp @@ -101,7 +101,7 @@ void CPVRChannel::Serialize(CVariant& value) const /********** XBMC related channel methods **********/ -bool CPVRChannel::Delete() +bool CPVRChannel::QueueDelete() { bool bReturn = false; const std::shared_ptr<CPVRDatabase> database = CServiceBroker::GetPVRManager().GetTVDatabase(); @@ -111,13 +111,13 @@ bool CPVRChannel::Delete() const std::shared_ptr<CPVREpg> epg = GetEPG(); if (epg) { - CServiceBroker::GetPVRManager().EpgContainer().DeleteEpg(epg); + CServiceBroker::GetPVRManager().EpgContainer().QueueDeleteEpg(epg); CSingleLock lock(m_critSection); m_epg.reset(); } - bReturn = database->Delete(*this); + bReturn = database->QueueDeleteQuery(*this); return bReturn; } diff --git a/xbmc/pvr/channels/PVRChannel.h b/xbmc/pvr/channels/PVRChannel.h index f678ed4661..ff489197f6 100644 --- a/xbmc/pvr/channels/PVRChannel.h +++ b/xbmc/pvr/channels/PVRChannel.h @@ -50,7 +50,7 @@ namespace PVR * @brief Delete this channel from the database and delete the corresponding EPG table if it exists. * @return True if it was deleted successfully, false otherwise. */ - bool Delete(); + bool QueueDelete(); /*! * @brief Update this channel tag with the data of the given channel tag. diff --git a/xbmc/pvr/channels/PVRChannelGroupInternal.cpp b/xbmc/pvr/channels/PVRChannelGroupInternal.cpp index 96e065d9dd..fe21c30975 100644 --- a/xbmc/pvr/channels/PVRChannelGroupInternal.cpp +++ b/xbmc/pvr/channels/PVRChannelGroupInternal.cpp @@ -17,6 +17,7 @@ #include "pvr/addons/PVRClients.h" #include "pvr/channels/PVRChannel.h" #include "pvr/epg/EpgContainer.h" +#include "pvr/epg/EpgDatabase.h" #include "utils/Variant.h" #include "utils/log.h" @@ -282,10 +283,43 @@ std::vector<std::shared_ptr<CPVRChannel>> CPVRChannelGroupInternal::RemoveDelete { std::vector<std::shared_ptr<CPVRChannel>> removedChannels = CPVRChannelGroup::RemoveDeletedChannels(channels); - for (const auto& channel : removedChannels) + bool channelsDeleted = false; + + const std::shared_ptr<CPVRDatabase> database = CServiceBroker::GetPVRManager().GetTVDatabase(); + const std::shared_ptr<CPVREpgDatabase> epgDatabase = + CServiceBroker::GetPVRManager().EpgContainer().GetEpgDatabase(); + if (!database || !epgDatabase) + { + CLog::LogF(LOGERROR, "No TV or EPG database"); + } + else { - // since channel was not found in the internal group, it was deleted from the backend - channel->Delete(); + // Note: We must lock the dbs the whole time, otherwise races may occur. + database->Lock(); + epgDatabase->Lock(); + + for (const auto& channel : removedChannels) + { + // since channel was not found in the internal group, it was deleted from the backend + channelsDeleted |= channel->QueueDelete(); + + size_t queryCount = epgDatabase->GetDeleteQueriesCount(); + if (queryCount > EPG_COMMIT_QUERY_COUNT_LIMIT) + epgDatabase->CommitDeleteQueries(); + + queryCount = database->GetDeleteQueriesCount(); + if (queryCount > CHANNEL_COMMIT_QUERY_COUNT_LIMIT) + database->CommitDeleteQueries(); + } + + if (channelsDeleted) + { + epgDatabase->CommitDeleteQueries(); + database->CommitDeleteQueries(); + } + + epgDatabase->Unlock(); + database->Unlock(); } return removedChannels; diff --git a/xbmc/pvr/epg/Epg.cpp b/xbmc/pvr/epg/Epg.cpp index 8fce752b2c..1c8972994c 100644 --- a/xbmc/pvr/epg/Epg.cpp +++ b/xbmc/pvr/epg/Epg.cpp @@ -330,7 +330,7 @@ bool CPVREpg::QueuePersistQuery(const std::shared_ptr<CPVREpgDatabase>& database return true; } -bool CPVREpg::Delete(const std::shared_ptr<CPVREpgDatabase>& database) +bool CPVREpg::QueueDeleteQueries(const std::shared_ptr<CPVREpgDatabase>& database) { if (!database) { @@ -339,10 +339,10 @@ bool CPVREpg::Delete(const std::shared_ptr<CPVREpgDatabase>& database) } // delete own epg db entry - database->Delete(*this); + database->QueueDeleteEpgQuery(*this); // delete all tags for this epg from db - m_tags.Delete(); + m_tags.QueueDelete(); Clear(); diff --git a/xbmc/pvr/epg/Epg.h b/xbmc/pvr/epg/Epg.h index 09577c378f..6b3f18da64 100644 --- a/xbmc/pvr/epg/Epg.h +++ b/xbmc/pvr/epg/Epg.h @@ -217,11 +217,11 @@ namespace PVR bool QueuePersistQuery(const std::shared_ptr<CPVREpgDatabase>& database); /*! - * @brief Delete this table from the given database + * @brief Write the delete queries into the given database's queue * @param database The database. - * @return True if the table was deleted, false otherwise. + * @return True on success, false otherwise. */ - bool Delete(const std::shared_ptr<CPVREpgDatabase>& database); + bool QueueDeleteQueries(const std::shared_ptr<CPVREpgDatabase>& database); /*! * @brief Get the start time of the first entry in this table. diff --git a/xbmc/pvr/epg/EpgContainer.cpp b/xbmc/pvr/epg/EpgContainer.cpp index 5aff3f3df3..2ffac5b268 100644 --- a/xbmc/pvr/epg/EpgContainer.cpp +++ b/xbmc/pvr/epg/EpgContainer.cpp @@ -319,7 +319,7 @@ bool CPVREpgContainer::PersistAll(unsigned int iMaxTimeslice) const bReturn &= epg->QueuePersistQuery(database); size_t queryCount = database->GetInsertQueriesCount() + database->GetDeleteQueriesCount(); - if (queryCount > 10000) + if (queryCount > EPG_COMMIT_QUERY_COUNT_LIMIT) { CLog::LogFC(LOGDEBUG, LOGEPG, "EPG Container: committing {} queries in loop.", queryCount); @@ -626,11 +626,18 @@ bool CPVREpgContainer::RemoveOldEntries() return true; } -bool CPVREpgContainer::DeleteEpg(const std::shared_ptr<CPVREpg>& epg) +bool CPVREpgContainer::QueueDeleteEpg(const std::shared_ptr<CPVREpg>& epg) { if (!epg || epg->EpgID() < 0) return false; + const std::shared_ptr<CPVREpgDatabase> database = GetEpgDatabase(); + if (!database) + { + CLog::LogF(LOGERROR, "No EPG database"); + return false; + } + std::shared_ptr<CPVREpg> epgToDelete; { CSingleLock lock(m_critSection); @@ -645,8 +652,7 @@ bool CPVREpgContainer::DeleteEpg(const std::shared_ptr<CPVREpg>& epg) m_channelUidToEpgMap.erase(epgEntry1); CLog::LogFC(LOGDEBUG, LOGEPG, "Deleting EPG table {} ({})", epg->Name(), epg->EpgID()); - - epgEntry->second->Delete(GetEpgDatabase()); + epgEntry->second->QueueDeleteQueries(database); epgToDelete = epgEntry->second; m_epgIdToEpgMap.erase(epgEntry); @@ -749,8 +755,17 @@ bool CPVREpgContainer::UpdateEPG(bool bOnlyPending /* = false */) if (bShowProgress && !bOnlyPending) progressHandler->DestroyProgress(); + database->Lock(); for (const auto& epg : invalidTables) - DeleteEpg(epg); + { + QueueDeleteEpg(epg); + + size_t queryCount = database->GetDeleteQueriesCount(); + if (queryCount > EPG_COMMIT_QUERY_COUNT_LIMIT) + database->CommitDeleteQueries(); + } + database->CommitDeleteQueries(); + database->Unlock(); if (bInterrupted) { diff --git a/xbmc/pvr/epg/EpgContainer.h b/xbmc/pvr/epg/EpgContainer.h index edfc48c4e6..c997b963ce 100644 --- a/xbmc/pvr/epg/EpgContainer.h +++ b/xbmc/pvr/epg/EpgContainer.h @@ -86,11 +86,11 @@ namespace PVR bool IsStarted() const; /*! - * @brief Delete an EPG table from this container. + * @brief Queue the deletion of an EPG table from this container. * @param epg The table to delete. * @return True on success, false otherwise. */ - bool DeleteEpg(const std::shared_ptr<CPVREpg>& epg); + bool QueueDeleteEpg(const std::shared_ptr<CPVREpg>& epg); /*! * @brief CEventStream callback for PVR events. diff --git a/xbmc/pvr/epg/EpgDatabase.cpp b/xbmc/pvr/epg/EpgDatabase.cpp index 383872d6a1..9fb62c5020 100644 --- a/xbmc/pvr/epg/EpgDatabase.cpp +++ b/xbmc/pvr/epg/EpgDatabase.cpp @@ -274,7 +274,7 @@ bool CPVREpgDatabase::DeleteEpg() return bReturn; } -bool CPVREpgDatabase::Delete(const CPVREpg& table) +bool CPVREpgDatabase::QueueDeleteEpgQuery(const CPVREpg& table) { /* invalid channel */ if (table.EpgID() <= 0) @@ -287,7 +287,10 @@ bool CPVREpgDatabase::Delete(const CPVREpg& table) CSingleLock lock(m_critSection); filter.AppendWhere(PrepareSQL("idEpg = %u", table.EpgID())); - return DeleteValues("epg", filter); + + std::string strQuery; + BuildSQL(PrepareSQL("DELETE FROM %s ", "epg"), filter, strQuery); + return QueueDeleteQuery(strQuery); } bool CPVREpgDatabase::QueueDeleteTagQuery(const CPVREpgInfoTag& tag) @@ -1052,6 +1055,18 @@ bool CPVREpgDatabase::DeleteEpgTags(int iEpgId) return DeleteValues("epgtags", filter); } +bool CPVREpgDatabase::QueueDeleteEpgTags(int iEpgId) +{ + Filter filter; + + CSingleLock lock(m_critSection); + filter.AppendWhere(PrepareSQL("idEpg = %u", iEpgId)); + + std::string strQuery; + BuildSQL(PrepareSQL("DELETE FROM %s ", "epg"), filter, strQuery); + return QueueDeleteQuery(strQuery); +} + bool CPVREpgDatabase::QueuePersistQuery(const CPVREpgInfoTag& tag) { if (tag.EpgID() <= 0) diff --git a/xbmc/pvr/epg/EpgDatabase.h b/xbmc/pvr/epg/EpgDatabase.h index 1e02e6f90b..a0ab972d59 100644 --- a/xbmc/pvr/epg/EpgDatabase.h +++ b/xbmc/pvr/epg/EpgDatabase.h @@ -25,6 +25,8 @@ namespace PVR /** The EPG database */ + static constexpr int EPG_COMMIT_QUERY_COUNT_LIMIT = 10000; + class CPVREpgDatabase : public CDatabase, public std::enable_shared_from_this<CPVREpgDatabase> { public: @@ -81,11 +83,11 @@ namespace PVR bool DeleteEpg(); /*! - * @brief Delete an EPG table. - * @param table The table to remove. - * @return True if the table was removed successfully, false otherwise. + * @brief Queue deletionof an EPG table. + * @param tag The table to queue for deletion. + * @return True on success, false otherwise. */ - bool Delete(const CPVREpg& table); + bool QueueDeleteEpgQuery(const CPVREpg& table); /*! * @brief Write the query to delete the given EPG tag to db query queue. @@ -258,6 +260,13 @@ namespace PVR bool DeleteEpgTags(int iEpgId); /*! + * @brief Queue the erase all EPG tags with the given epg ID. + * @param iEpgId The ID of the EPG. + * @return True if the entries were queued successfully, false otherwise. + */ + bool QueueDeleteEpgTags(int iEpgId); + + /*! * @brief Write the query to persist the given EPG tag to db query queue. * @param tag The tag to persist. * @return True on success, false otherwise. diff --git a/xbmc/pvr/epg/EpgTagsContainer.cpp b/xbmc/pvr/epg/EpgTagsContainer.cpp index 797f0c10c7..c1a8123959 100644 --- a/xbmc/pvr/epg/EpgTagsContainer.cpp +++ b/xbmc/pvr/epg/EpgTagsContainer.cpp @@ -643,10 +643,10 @@ void CPVREpgTagsContainer::QueuePersistQuery() } } -void CPVREpgTagsContainer::Delete() +void CPVREpgTagsContainer::QueueDelete() { if (m_database) - m_database->DeleteEpgTags(m_iEpgID); + m_database->QueueDeleteEpgTags(m_iEpgID); Clear(); } diff --git a/xbmc/pvr/epg/EpgTagsContainer.h b/xbmc/pvr/epg/EpgTagsContainer.h index 75ed5029b9..99b06b946f 100644 --- a/xbmc/pvr/epg/EpgTagsContainer.h +++ b/xbmc/pvr/epg/EpgTagsContainer.h @@ -171,9 +171,9 @@ public: void QueuePersistQuery(); /*! - * @brief Delete this container from its database. + * @brief Queue the deletion of this container from its database. */ - void Delete(); + void QueueDelete(); private: /*! diff --git a/xbmc/pvr/recordings/PVRRecordings.cpp b/xbmc/pvr/recordings/PVRRecordings.cpp index 6f4fb21864..385b12ab74 100644 --- a/xbmc/pvr/recordings/PVRRecordings.cpp +++ b/xbmc/pvr/recordings/PVRRecordings.cpp @@ -40,13 +40,15 @@ void CPVRRecordings::UpdateFromClients() for (const auto& recording : m_recordings) recording.second->SetDirty(true); - CServiceBroker::GetPVRManager().Clients()->GetRecordings(this, false); - CServiceBroker::GetPVRManager().Clients()->GetRecordings(this, true); + std::vector<int> failedClients; + CServiceBroker::GetPVRManager().Clients()->GetRecordings(this, false, failedClients); + CServiceBroker::GetPVRManager().Clients()->GetRecordings(this, true, failedClients); // remove recordings that were deleted at the backend for (auto it = m_recordings.begin(); it != m_recordings.end();) { - if ((*it).second->IsDirty()) + if ((*it).second->IsDirty() && std::find(failedClients.begin(), failedClients.end(), + (*it).second->ClientID()) == failedClients.end()) it = m_recordings.erase(it); else ++it; diff --git a/xbmc/settings/MediaSettings.cpp b/xbmc/settings/MediaSettings.cpp index 27c5ac7bea..37d653e999 100644 --- a/xbmc/settings/MediaSettings.cpp +++ b/xbmc/settings/MediaSettings.cpp @@ -114,10 +114,11 @@ bool CMediaSettings::Load(const TiXmlNode *settings) m_defaultVideoSettings.m_StereoMode = 0; if (!XMLUtils::GetInt(pElement, "centermixlevel", m_defaultVideoSettings.m_CenterMixLevel)) m_defaultVideoSettings.m_CenterMixLevel = 0; - - m_defaultVideoSettings.m_ToneMapMethod = 1; - m_defaultVideoSettings.m_ToneMapParam = 1.0f; m_defaultVideoSettings.m_SubtitleCached = false; + if (!XMLUtils::GetInt(pElement, "tonemapmethod", m_defaultVideoSettings.m_ToneMapMethod)) + m_defaultVideoSettings.m_ToneMapMethod = VS_TONEMAPMETHOD_REINHARD; + if (!XMLUtils::GetFloat(pElement, "tonemapparam", m_defaultVideoSettings.m_ToneMapParam, 0.1f, 5.0f)) + m_defaultVideoSettings.m_ToneMapParam = 1.0f; } m_defaultGameSettings.Reset(); @@ -220,6 +221,8 @@ bool CMediaSettings::Save(TiXmlNode *settings) const XMLUtils::SetBoolean(pNode, "nonlinstretch", m_defaultVideoSettings.m_CustomNonLinStretch); XMLUtils::SetInt(pNode, "stereomode", m_defaultVideoSettings.m_StereoMode); XMLUtils::SetInt(pNode, "centermixlevel", m_defaultVideoSettings.m_CenterMixLevel); + XMLUtils::SetInt(pNode, "tonemapmethod", m_defaultVideoSettings.m_ToneMapMethod); + XMLUtils::SetFloat(pNode, "tonemapparam", m_defaultVideoSettings.m_ToneMapParam); // default audio settings for dsp addons TiXmlElement audioSettingsNode("defaultaudiosettings"); diff --git a/xbmc/settings/dialogs/GUIDialogLibExportSettings.cpp b/xbmc/settings/dialogs/GUIDialogLibExportSettings.cpp index 432413a077..8ed9a7d79f 100644 --- a/xbmc/settings/dialogs/GUIDialogLibExportSettings.cpp +++ b/xbmc/settings/dialogs/GUIDialogLibExportSettings.cpp @@ -444,7 +444,7 @@ int CGUIDialogLibExportSettings::GetExportItemsFromSetting(const SettingConstPtr CLog::Log(LOGERROR, "CGUIDialogLibExportSettings::%s - wrong items value type", __FUNCTION__); return 0; } - exportitems += value.asInteger(); + exportitems += static_cast<int>(value.asInteger()); } return exportitems; } diff --git a/xbmc/threads/SystemClock.h b/xbmc/threads/SystemClock.h index d38f2326eb..5db7657deb 100644 --- a/xbmc/threads/SystemClock.h +++ b/xbmc/threads/SystemClock.h @@ -59,9 +59,4 @@ namespace XbmcThreads inline unsigned int GetInitialTimeoutValue(void) const { return totalWaitTime; } inline unsigned int GetStartTime(void) const { return startTime; } }; - - inline void ThreadSleep(unsigned int millis) - { - std::this_thread::sleep_for(std::chrono::microseconds(millis)); - } } diff --git a/xbmc/threads/test/CMakeLists.txt b/xbmc/threads/test/CMakeLists.txt index 0c9b07a489..136e972223 100644 --- a/xbmc/threads/test/CMakeLists.txt +++ b/xbmc/threads/test/CMakeLists.txt @@ -1,5 +1,6 @@ set(SOURCES TestEvent.cpp - TestSharedSection.cpp) + TestSharedSection.cpp + TestEndTime.cpp) set(HEADERS TestHelpers.h) diff --git a/xbmc/threads/test/TestEndTime.cpp b/xbmc/threads/test/TestEndTime.cpp new file mode 100644 index 0000000000..daa13b37b7 --- /dev/null +++ b/xbmc/threads/test/TestEndTime.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2005-2020 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "threads/SystemClock.h" + +#include <gtest/gtest.h> + +namespace +{ + +void CommonTests(XbmcThreads::EndTime& endTime) +{ + EXPECT_EQ(static_cast<unsigned int>(100), endTime.GetInitialTimeoutValue()); + EXPECT_LE(static_cast<unsigned int>(0), endTime.GetStartTime()); + + EXPECT_FALSE(endTime.IsTimePast()); + EXPECT_LT(static_cast<unsigned int>(0), endTime.MillisLeft()); + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + EXPECT_TRUE(endTime.IsTimePast()); + EXPECT_EQ(static_cast<unsigned int>(0), endTime.MillisLeft()); + + endTime.SetInfinite(); + EXPECT_EQ(std::numeric_limits<unsigned int>::max(), endTime.GetInitialTimeoutValue()); + endTime.SetExpired(); + EXPECT_EQ(static_cast<unsigned int>(0), endTime.GetInitialTimeoutValue()); +} + +} // namespace + +TEST(TestEndTime, DefaultConstructor) +{ + XbmcThreads::EndTime endTime; + endTime.Set(static_cast<unsigned int>(100)); + + CommonTests(endTime); +} + +TEST(TestEndTime, ExplicitConstructor) +{ + XbmcThreads::EndTime endTime(static_cast<unsigned int>(100)); + + CommonTests(endTime); +} diff --git a/xbmc/threads/test/TestHelpers.h b/xbmc/threads/test/TestHelpers.h index 760e4d594e..9cd88bc8ec 100644 --- a/xbmc/threads/test/TestHelpers.h +++ b/xbmc/threads/test/TestHelpers.h @@ -14,7 +14,10 @@ #define MILLIS(x) x -inline static void SleepMillis(unsigned int millis) { XbmcThreads::ThreadSleep(millis); } +inline static void SleepMillis(unsigned int millis) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(millis)); +} template<class E> inline static bool waitForWaiters(E& event, int numWaiters, int milliseconds) { diff --git a/xbmc/utils/CMakeLists.txt b/xbmc/utils/CMakeLists.txt index 4e46c05b2f..05c008d17c 100644 --- a/xbmc/utils/CMakeLists.txt +++ b/xbmc/utils/CMakeLists.txt @@ -12,6 +12,7 @@ set(SOURCES ActorProtocol.cpp CharsetConverter.cpp CharsetDetection.cpp ColorUtils.cpp + ContentUtils.cpp CPUInfo.cpp Crc32.cpp CryptThreading.cpp @@ -89,6 +90,7 @@ set(HEADERS ActorProtocol.h CPUInfo.h Color.h ColorUtils.h + ContentUtils.h Crc32.h CryptThreading.h DatabaseUtils.h diff --git a/xbmc/utils/ContentUtils.cpp b/xbmc/utils/ContentUtils.cpp new file mode 100644 index 0000000000..87737de44c --- /dev/null +++ b/xbmc/utils/ContentUtils.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2005-2020 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "ContentUtils.h" + +#include "FileItem.h" +#include "video/VideoInfoTag.h" + +namespace +{ +const bool HasPreferredArtType(const CFileItem& item) +{ + return item.HasVideoInfoTag() && (item.GetVideoInfoTag()->m_type == MediaTypeMovie || + item.GetVideoInfoTag()->m_type == MediaTypeTvShow || + item.GetVideoInfoTag()->m_type == MediaTypeSeason || + item.GetVideoInfoTag()->m_type == MediaTypeVideoCollection); +} + +const std::string GetPreferredArtType(MediaType type) +{ + if (type == MediaTypeMovie || type == MediaTypeTvShow || type == MediaTypeSeason || + type == MediaTypeVideoCollection) + { + return "poster"; + } + return "thumb"; +} +} // namespace + +const std::string ContentUtils::GetPreferredArtImage(const CFileItem& item) +{ + if (HasPreferredArtType(item)) + { + auto preferredArtType = GetPreferredArtType(item.GetVideoInfoTag()->m_type); + if (item.HasArt(preferredArtType)) + { + return item.GetArt(preferredArtType); + } + } + return item.GetArt("thumb"); +} diff --git a/xbmc/utils/ContentUtils.h b/xbmc/utils/ContentUtils.h new file mode 100644 index 0000000000..a1e4d3f345 --- /dev/null +++ b/xbmc/utils/ContentUtils.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2005-2020 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#pragma once + +#include "media/MediaType.h" + +#include <string> + +class CFileItem; + +class ContentUtils +{ +public: + /*! \brief Gets the preferred art image for a given item (depending on its media type). Provided a CFileItem + with many art types on its art map, this method will return a default preferred image (content dependent) for situations where the + the client expects a single image to represent the item. For instance, for movies and shows this will return the poster, while for + episodes it will return the thumb. + \param item The CFileItem to process + \return the preferred art image + */ + static const std::string GetPreferredArtImage(const CFileItem& item); +}; diff --git a/xbmc/utils/RecentlyAddedJob.cpp b/xbmc/utils/RecentlyAddedJob.cpp index 80093a3859..b4060a84c8 100644 --- a/xbmc/utils/RecentlyAddedJob.cpp +++ b/xbmc/utils/RecentlyAddedJob.cpp @@ -212,7 +212,7 @@ bool CRecentlyAddedJob::UpdateMusic() if (musicdatabase.GetRecentlyAddedAlbumSongs("musicdb://songs/", musicItems, NUM_ITEMS)) { - long idAlbum = -1; + int idAlbum = -1; std::string strAlbumThumb; std::string strAlbumFanart; for (; i < musicItems.Size(); ++i) @@ -340,7 +340,7 @@ bool CRecentlyAddedJob::UpdateTotal() musicdatabase.GetArtistsByWhere(musicUrl.ToString(), filter, items, SortDescription(), true); int MusArtistTotals = 0; if (items.Size() == 1 && items.Get(0)->HasProperty("total")) - MusArtistTotals = items.Get(0)->GetProperty("total").asInteger(); + MusArtistTotals = static_cast<int>(items.Get(0)->GetProperty("total").asInteger()); int MusSongTotals = atoi(musicdatabase.GetSingleValue("songview" , "count(1)").c_str()); int MusAlbumTotals = atoi(musicdatabase.GetSingleValue("songview" , "count(distinct strAlbum)").c_str()); diff --git a/xbmc/utils/StringUtils.cpp b/xbmc/utils/StringUtils.cpp index 5a93035012..c19d285bba 100644 --- a/xbmc/utils/StringUtils.cpp +++ b/xbmc/utils/StringUtils.cpp @@ -702,7 +702,9 @@ std::vector<std::string> StringUtils::Split(const std::string& input, const std: return result; } -std::vector<std::string> StringUtils::SplitMulti(const std::vector<std::string> &input, const std::vector<std::string> &delimiters, unsigned int iMaxStrings /* = 0 */) +std::vector<std::string> StringUtils::SplitMulti(const std::vector<std::string>& input, + const std::vector<std::string>& delimiters, + size_t iMaxStrings /* = 0 */) { if (input.empty()) return std::vector<std::string>(); @@ -731,7 +733,7 @@ std::vector<std::string> StringUtils::SplitMulti(const std::vector<std::string> // Control the number of strings input is split into, keeping the original strings. // Note iMaxStrings > input.size() - int iNew = iMaxStrings - results.size(); + int64_t iNew = iMaxStrings - results.size(); for (size_t di = 0; di < delimiters.size(); di++) { for (size_t i = 0; i < results.size(); i++) @@ -1236,7 +1238,7 @@ int StringUtils::AlphaNumericCollation(int nKey1, const void* pKey1, int nKey2, // do we have numbers? if (lnum != rnum) { // yes - and they're different! - return lnum - rnum; + return static_cast<int>(lnum - rnum); } // Advance to after digits i = ld; diff --git a/xbmc/utils/StringUtils.h b/xbmc/utils/StringUtils.h index dd0b107f82..c3c93c0357 100644 --- a/xbmc/utils/StringUtils.h +++ b/xbmc/utils/StringUtils.h @@ -242,7 +242,9 @@ public: \param delimiters Delimiter strings to be used to split the input strings \param iMaxStrings (optional) Maximum number of resulting split strings */ - static std::vector<std::string> SplitMulti(const std::vector<std::string> &input, const std::vector<std::string> &delimiters, unsigned int iMaxStrings = 0); + static std::vector<std::string> SplitMulti(const std::vector<std::string>& input, + const std::vector<std::string>& delimiters, + size_t iMaxStrings = 0); static int FindNumber(const std::string& strInput, const std::string &strFind); static int64_t AlphaNumericCompare(const wchar_t *left, const wchar_t *right); static int AlphaNumericCollation(int nKey1, const void* pKey1, int nKey2, const void* pKey2); diff --git a/xbmc/video/ContextMenus.cpp b/xbmc/video/ContextMenus.cpp index f9684d1b96..4f7c3f40cf 100644 --- a/xbmc/video/ContextMenus.cpp +++ b/xbmc/video/ContextMenus.cpp @@ -318,6 +318,12 @@ bool CPlay::IsVisible(const CFileItem& itemIn) const if (IsActiveRecordingsFolder(item)) return true; + // Music nav window has own "Play" context menu button, do not show this one. Playlist files + // like .m3u and .strm return IsVideo() true but from music nav window play with paplayer. + const int currentWindow = CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow(); + if (currentWindow == WINDOW_MUSIC_NAV) + return false; + if (item.m_bIsFolder) return false; //! @todo implement diff --git a/xbmc/video/VideoDatabase.cpp b/xbmc/video/VideoDatabase.cpp index bed0426c1d..862b4874e2 100644 --- a/xbmc/video/VideoDatabase.cpp +++ b/xbmc/video/VideoDatabase.cpp @@ -4469,12 +4469,6 @@ bool CVideoDatabase::GetVideoSettings(int idFile, CVideoSettings &settings) settings.m_Orientation = m_pDS->fv("Orientation").get_asInt(); settings.m_CenterMixLevel = m_pDS->fv("CenterMixLevel").get_asInt(); m_pDS->close(); - - if (settings.m_ToneMapParam == 0.0) - { - settings.m_ToneMapMethod = VS_TONEMAPMETHOD_REINHARD; - settings.m_ToneMapParam = 1.0; - } return true; } m_pDS->close(); diff --git a/xbmc/video/VideoInfoTag.cpp b/xbmc/video/VideoInfoTag.cpp index bab6ce7c46..53ca075498 100644 --- a/xbmc/video/VideoInfoTag.cpp +++ b/xbmc/video/VideoInfoTag.cpp @@ -322,6 +322,152 @@ bool CVideoInfoTag::Load(const TiXmlElement *element, bool append, bool prioriti return true; } +void CVideoInfoTag::Merge(CVideoInfoTag& other) +{ + if (m_director.empty()) + m_director = other.m_director; + if (m_writingCredits.empty()) + m_writingCredits = other.m_writingCredits; + if (m_genre.empty()) + m_genre = other.m_genre; + if (m_country.empty()) + m_country = other.m_country; + if (m_strTagLine.empty()) + m_strTagLine = other.m_strTagLine; + if (m_strPlotOutline.empty()) + m_strPlotOutline = other.m_strPlotOutline; + if (m_strPlot.empty()) + m_strPlot = other.m_strPlot; + if (!m_strPictureURL.HasData()) + m_strPictureURL = other.m_strPictureURL; + if (m_strTitle.empty()) + m_strTitle = other.m_strTitle; + if (m_strShowTitle.empty()) + m_strShowTitle = other.m_strShowTitle; + if (m_strOriginalTitle.empty()) + m_strOriginalTitle = other.m_strOriginalTitle; + if (m_strSortTitle.empty()) + m_strSortTitle = other.m_strSortTitle; + if (!m_cast.size()) + m_cast = other.m_cast; + + if (m_set.title.empty()) + m_set.title = other.m_set.title; + if (!m_set.id) + m_set.id = other.m_set.id; + if (m_set.overview.empty()) + m_set.overview = other.m_set.overview; + if (m_tags.empty()) + m_tags = other.m_tags; + + if (m_strFile.empty()) + m_strFile = other.m_strFile; + if (m_strPath.empty()) + m_strPath = other.m_strPath; + + if (m_strMPAARating.empty()) + m_strMPAARating = other.m_strMPAARating; + if (m_strFileNameAndPath.empty()) + m_strFileNameAndPath = other.m_strFileNameAndPath; + + if (!m_premiered.IsValid() && other.m_premiered.IsValid()) + SetPremiered(other.GetPremiered()); + + if (m_strStatus.empty()) + m_strStatus = other.m_strStatus; + if (m_strProductionCode.empty()) + m_strProductionCode = other.m_strProductionCode; + + if (!m_firstAired.IsValid()) + m_firstAired = other.m_firstAired; + if (m_studio.empty()) + m_studio = other.m_studio; + if (m_strAlbum.empty()) + m_strAlbum = other.m_strAlbum; + if (m_artist.empty()) + m_artist = other.m_artist; + if (m_strTrailer.empty()) + m_strTrailer = other.m_strTrailer; + if (!m_iTop250) + m_iTop250 = other.m_iTop250; + if (m_iSeason == -1) + m_iSeason = other.m_iSeason; + if (m_iEpisode == -1) + m_iEpisode = other.m_iEpisode; + + if (m_iIdUniqueID == -1) + m_iIdUniqueID = other.m_iIdUniqueID; + if (!m_uniqueIDs.size() && other.m_uniqueIDs.size()) + { + m_uniqueIDs = other.m_uniqueIDs; + m_strDefaultUniqueID = other.m_strDefaultUniqueID; + }; + if (m_iSpecialSortSeason == -1) + m_iSpecialSortSeason = other.m_iSpecialSortSeason; + if (m_iSpecialSortEpisode == -1) + m_iSpecialSortEpisode = other.m_iSpecialSortEpisode; + + if (m_ratings.empty() && !other.m_ratings.empty()) + { + m_ratings = other.m_ratings; + m_strDefaultRating = other.m_strDefaultRating; + }; + if (m_iIdRating == -1) + m_iIdRating = other.m_iIdRating; + if (!m_iUserRating) + m_iUserRating = other.m_iUserRating; + + if (m_iDbId == -1) + m_iDbId = other.m_iDbId; + if (m_iFileId == -1) + m_iFileId = other.m_iFileId; + if (m_iBookmarkId == -1) + m_iBookmarkId = other.m_iBookmarkId; + if (m_iTrack == -1) + m_iTrack = other.m_iTrack; + + if (!m_fanart.GetNumFanarts()) + m_fanart = other.m_fanart; + + if (!m_duration) + m_duration = other.m_duration; + if (!m_lastPlayed.IsValid()) + m_lastPlayed = other.m_lastPlayed; + + if (m_showLink.empty()) + m_showLink = other.m_showLink; + if (!m_namedSeasons.size()) + m_namedSeasons = other.m_namedSeasons; + if (!m_streamDetails.HasItems()) + m_streamDetails = other.m_streamDetails; + if (!IsPlayCountSet() && other.IsPlayCountSet()) + SetPlayCount(other.GetPlayCount()); + + if (!m_EpBookmark.IsSet() && other.m_EpBookmark.IsSet()) + m_EpBookmark = other.m_EpBookmark; + + if (m_basePath.empty()) + m_basePath = other.m_basePath; + if (m_parentPathID == -1) + m_parentPathID = other.m_parentPathID; + if (!GetResumePoint().IsSet() && other.GetResumePoint().IsSet()) + SetResumePoint(other.GetResumePoint()); + if (m_iIdShow == -1) + m_iIdShow = other.m_iIdShow; + if (m_iIdSeason == -1) + m_iIdSeason = other.m_iIdSeason; + + if (!m_dateAdded.IsValid()) + m_dateAdded = other.m_dateAdded; + // m_type + if (m_relevance == -1) + m_relevance = other.m_relevance; + if (!m_parsedDetails) + m_parsedDetails = other.m_parsedDetails; + if (!m_coverArt.size()) + m_coverArt = other.m_coverArt; +} + void CVideoInfoTag::Archive(CArchive& ar) { if (ar.IsStoring()) diff --git a/xbmc/video/VideoInfoTag.h b/xbmc/video/VideoInfoTag.h index 810bef1020..a1968a4b29 100644 --- a/xbmc/video/VideoInfoTag.h +++ b/xbmc/video/VideoInfoTag.h @@ -71,6 +71,7 @@ public: */ bool Load(const TiXmlElement *element, bool append = false, bool prioritise = false); bool Save(TiXmlNode *node, const std::string &tag, bool savePathInfo = true, const TiXmlElement *additionalNode = NULL); + void Merge(CVideoInfoTag& other); void Archive(CArchive& ar) override; void Serialize(CVariant& value) const override; void ToSortable(SortItem& sortable, Field field) const override; diff --git a/xbmc/video/dialogs/GUIDialogVideoSettings.cpp b/xbmc/video/dialogs/GUIDialogVideoSettings.cpp index 759358b420..e3f99a54d4 100644 --- a/xbmc/video/dialogs/GUIDialogVideoSettings.cpp +++ b/xbmc/video/dialogs/GUIDialogVideoSettings.cpp @@ -406,11 +406,20 @@ void CGUIDialogVideoSettings::InitializeSettings() // tone mapping if (g_application.GetAppPlayer().Supports(RENDERFEATURE_TONEMAP)) { + bool visible = !(CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool( + CServiceBroker::GetWinSystem()->SETTING_WINSYSTEM_IS_HDR_DISPLAY) && + CServiceBroker::GetWinSystem()->IsHDRDisplay()); entries.clear(); entries.push_back(TranslatableIntegerSettingOption(36554, VS_TONEMAPMETHOD_OFF)); entries.push_back(TranslatableIntegerSettingOption(36555, VS_TONEMAPMETHOD_REINHARD)); - AddSpinner(groupVideo, SETTING_VIDEO_TONEMAP_METHOD, 36553, SettingLevel::Basic, videoSettings.m_ToneMapMethod, entries); - AddSlider(groupVideo, SETTING_VIDEO_TONEMAP_PARAM, 36556, SettingLevel::Basic, videoSettings.m_ToneMapParam, "%2.2f", 0.1f, 0.1f, 5.0f, 36556, usePopup); + entries.push_back(TranslatableIntegerSettingOption(36557, VS_TONEMAPMETHOD_ACES)); + entries.push_back(TranslatableIntegerSettingOption(36558, VS_TONEMAPMETHOD_HABLE)); + + AddSpinner(groupVideo, SETTING_VIDEO_TONEMAP_METHOD, 36553, SettingLevel::Basic, + videoSettings.m_ToneMapMethod, entries, false, visible); + AddSlider(groupVideo, SETTING_VIDEO_TONEMAP_PARAM, 36556, SettingLevel::Basic, + videoSettings.m_ToneMapParam, "%2.2f", 0.1f, 0.1f, 5.0f, 36556, usePopup, false, + visible); } // stereoscopic settings diff --git a/xbmc/video/windows/VideoFileItemListModifier.cpp b/xbmc/video/windows/VideoFileItemListModifier.cpp index d1677682ca..099cbc1d2e 100644 --- a/xbmc/video/windows/VideoFileItemListModifier.cpp +++ b/xbmc/video/windows/VideoFileItemListModifier.cpp @@ -81,9 +81,13 @@ void CVideoFileItemListModifier::AddQueuingFolder(CFileItemList& items) pItem->SetProperty("numepisodes", watched + unwatched); // will be changed later to reflect watchmode setting pItem->SetProperty("watchedepisodes", watched); pItem->SetProperty("unwatchedepisodes", unwatched); - if (items.Size() && items[0]->GetVideoInfoTag()) + + // @note: the items list contains the (..) upper directory navigation fileitem plus all the + // season directory fileitems for a given show. We want to assign the "All Seasons" listitem + // the infotag of the tv show - so do not use the first item in the list! + if (items.Size() && items[items.Size() - 1]->GetVideoInfoTag()) { - *pItem->GetVideoInfoTag() = *items[0]->GetVideoInfoTag(); + *pItem->GetVideoInfoTag() = *items[items.Size() - 1]->GetVideoInfoTag(); pItem->GetVideoInfoTag()->m_iSeason = -1; } pItem->GetVideoInfoTag()->m_strTitle = strLabel; diff --git a/xbmc/windowing/X11/WinSystemX11GLContext.cpp b/xbmc/windowing/X11/WinSystemX11GLContext.cpp index 6f09ef58cf..09e397970e 100644 --- a/xbmc/windowing/X11/WinSystemX11GLContext.cpp +++ b/xbmc/windowing/X11/WinSystemX11GLContext.cpp @@ -27,9 +27,6 @@ #include "windowing/GraphicContext.h" #include "windowing/WindowSystemFactory.h" -#include "platform/freebsd/OptionalsReg.h" -#include "platform/linux/OptionalsReg.h" - #include <vector> #include <X11/Xlib.h> @@ -49,49 +46,6 @@ std::unique_ptr<CWinSystemBase> CWinSystemX11GLContext::CreateWinSystem() return std::make_unique<CWinSystemX11GLContext>(); } -CWinSystemX11GLContext::CWinSystemX11GLContext() -{ - std::string envSink; - if (getenv("KODI_AE_SINK")) - envSink = getenv("KODI_AE_SINK"); - if (StringUtils::EqualsNoCase(envSink, "ALSA")) - { - OPTIONALS::ALSARegister(); - } - else if (StringUtils::EqualsNoCase(envSink, "PULSE")) - { - OPTIONALS::PulseAudioRegister(); - } - else if (StringUtils::EqualsNoCase(envSink, "OSS")) - { - OPTIONALS::OSSRegister(); - } - else if (StringUtils::EqualsNoCase(envSink, "SNDIO")) - { - OPTIONALS::SndioRegister(); - } - else if (StringUtils::EqualsNoCase(envSink, "ALSA+PULSE")) - { - OPTIONALS::ALSARegister(); - OPTIONALS::PulseAudioRegister(); - } - else - { - if (!OPTIONALS::PulseAudioRegister()) - { - if (!OPTIONALS::ALSARegister()) - { - if (!OPTIONALS::SndioRegister()) - { - OPTIONALS::OSSRegister(); - } - } - } - } - - m_lirc.reset(OPTIONALS::LircRegister()); -} - CWinSystemX11GLContext::~CWinSystemX11GLContext() { delete m_pGLContext; diff --git a/xbmc/windowing/X11/WinSystemX11GLContext.h b/xbmc/windowing/X11/WinSystemX11GLContext.h index ce5fae21fa..7d227b2cf3 100644 --- a/xbmc/windowing/X11/WinSystemX11GLContext.h +++ b/xbmc/windowing/X11/WinSystemX11GLContext.h @@ -12,9 +12,6 @@ #include "rendering/gl/RenderSystemGL.h" #include "system_egl.h" -#include "platform/freebsd/OptionalsReg.h" -#include "platform/linux/OptionalsReg.h" - #include <memory> class CGLContext; @@ -31,7 +28,7 @@ class CVaapiProxy; class CWinSystemX11GLContext : public CWinSystemX11, public CRenderSystemGL { public: - CWinSystemX11GLContext(); + CWinSystemX11GLContext() = default; ~CWinSystemX11GLContext() override; static void Register(); @@ -75,8 +72,6 @@ protected: void operator()(CVaapiProxy *p) const; }; std::unique_ptr<CVaapiProxy, delete_CVaapiProxy> m_vaapiProxy; - - std::unique_ptr<OPTIONALS::CLircContainer, OPTIONALS::delete_CLircContainer> m_lirc; }; } diff --git a/xbmc/windowing/X11/WinSystemX11GLESContext.cpp b/xbmc/windowing/X11/WinSystemX11GLESContext.cpp index 86c8b435e5..d4b4f32af0 100644 --- a/xbmc/windowing/X11/WinSystemX11GLESContext.cpp +++ b/xbmc/windowing/X11/WinSystemX11GLESContext.cpp @@ -25,8 +25,6 @@ #include "windowing/GraphicContext.h" #include "windowing/WindowSystemFactory.h" -#include "platform/linux/OptionalsReg.h" - using namespace KODI; using namespace KODI::WINDOWING::X11; @@ -40,44 +38,6 @@ std::unique_ptr<CWinSystemBase> CWinSystemX11GLESContext::CreateWinSystem() return std::make_unique<CWinSystemX11GLESContext>(); } -CWinSystemX11GLESContext::CWinSystemX11GLESContext() -{ - std::string envSink; - if (getenv("KODI_AE_SINK")) - envSink = getenv("KODI_AE_SINK"); - if (StringUtils::EqualsNoCase(envSink, "ALSA")) - { - OPTIONALS::ALSARegister(); - } - else if (StringUtils::EqualsNoCase(envSink, "PULSE")) - { - OPTIONALS::PulseAudioRegister(); - } - else if (StringUtils::EqualsNoCase(envSink, "OSS")) - { - OPTIONALS::OSSRegister(); - } - else if (StringUtils::EqualsNoCase(envSink, "SNDIO")) - { - OPTIONALS::SndioRegister(); - } - else - { - if (!OPTIONALS::PulseAudioRegister()) - { - if (!OPTIONALS::ALSARegister()) - { - if (!OPTIONALS::SndioRegister()) - { - OPTIONALS::OSSRegister(); - } - } - } - } - - m_lirc.reset(OPTIONALS::LircRegister()); -} - CWinSystemX11GLESContext::~CWinSystemX11GLESContext() { delete m_pGLContext; diff --git a/xbmc/windowing/X11/WinSystemX11GLESContext.h b/xbmc/windowing/X11/WinSystemX11GLESContext.h index 02caf60917..cdb1cc4f8e 100644 --- a/xbmc/windowing/X11/WinSystemX11GLESContext.h +++ b/xbmc/windowing/X11/WinSystemX11GLESContext.h @@ -12,10 +12,6 @@ #include "WinSystemX11.h" #include "rendering/gles/RenderSystemGLES.h" -#include "platform/linux/OptionalsReg.h" - -#include <memory> - class CGLContextEGL; namespace KODI @@ -28,8 +24,8 @@ namespace X11 class CWinSystemX11GLESContext : public CWinSystemX11, public CRenderSystemGLES { public: - CWinSystemX11GLESContext(); - virtual ~CWinSystemX11GLESContext(); + CWinSystemX11GLESContext() = default; + virtual ~CWinSystemX11GLESContext() override; static void Register(); static std::unique_ptr<CWinSystemBase> CreateWinSystem(); @@ -59,8 +55,6 @@ protected: CGLContextEGL* m_pGLContext = nullptr; bool m_newGlContext; - - std::unique_ptr<OPTIONALS::CLircContainer, OPTIONALS::delete_CLircContainer> m_lirc; }; } // namespace X11 diff --git a/xbmc/windowing/gbm/WinSystemGbm.cpp b/xbmc/windowing/gbm/WinSystemGbm.cpp index 21c6e77411..fbc7299ea0 100644 --- a/xbmc/windowing/gbm/WinSystemGbm.cpp +++ b/xbmc/windowing/gbm/WinSystemGbm.cpp @@ -23,9 +23,6 @@ #include "utils/log.h" #include "windowing/GraphicContext.h" -#include "platform/freebsd/OptionalsReg.h" -#include "platform/linux/OptionalsReg.h" - #include <string.h> using namespace KODI::WINDOWING::GBM; @@ -35,46 +32,7 @@ CWinSystemGbm::CWinSystemGbm() : m_GBM(new CGBMUtils), m_libinput(new CLibInputHandler) { - std::string envSink; - if (getenv("KODI_AE_SINK")) - envSink = getenv("KODI_AE_SINK"); - if (StringUtils::EqualsNoCase(envSink, "ALSA")) - { - OPTIONALS::ALSARegister(); - } - else if (StringUtils::EqualsNoCase(envSink, "PULSE")) - { - OPTIONALS::PulseAudioRegister(); - } - else if (StringUtils::EqualsNoCase(envSink, "OSS")) - { - OPTIONALS::OSSRegister(); - } - else if (StringUtils::EqualsNoCase(envSink, "SNDIO")) - { - OPTIONALS::SndioRegister(); - } - else if (StringUtils::EqualsNoCase(envSink, "ALSA+PULSE")) - { - OPTIONALS::ALSARegister(); - OPTIONALS::PulseAudioRegister(); - } - else - { - if (!OPTIONALS::PulseAudioRegister()) - { - if (!OPTIONALS::ALSARegister()) - { - if (!OPTIONALS::SndioRegister()) - { - OPTIONALS::OSSRegister(); - } - } - } - } - m_dpms = std::make_shared<CGBMDPMSSupport>(); - m_lirc.reset(OPTIONALS::LircRegister()); m_libinput->Start(); } diff --git a/xbmc/windowing/gbm/WinSystemGbm.h b/xbmc/windowing/gbm/WinSystemGbm.h index 3087ea52c5..6ec6f47cd1 100644 --- a/xbmc/windowing/gbm/WinSystemGbm.h +++ b/xbmc/windowing/gbm/WinSystemGbm.h @@ -13,8 +13,6 @@ #include "threads/CriticalSection.h" #include "windowing/WinSystem.h" -#include "platform/freebsd/OptionalsReg.h" -#include "platform/linux/OptionalsReg.h" #include "platform/linux/input/LibInputHandler.h" #include <utility> @@ -79,7 +77,6 @@ protected: bool m_dispReset = false; XbmcThreads::EndTime m_dispResetTimer; - std::unique_ptr<OPTIONALS::CLircContainer, OPTIONALS::delete_CLircContainer> m_lirc; std::unique_ptr<CLibInputHandler> m_libinput; }; diff --git a/xbmc/windowing/wayland/OptionalsReg.cpp b/xbmc/windowing/wayland/OptionalsReg.cpp index 9774a2e9f7..c314a0fa83 100644 --- a/xbmc/windowing/wayland/OptionalsReg.cpp +++ b/xbmc/windowing/wayland/OptionalsReg.cpp @@ -11,7 +11,7 @@ //----------------------------------------------------------------------------- // VAAPI //----------------------------------------------------------------------------- -#if defined (HAVE_LIBVA) && defined(HAVE_EGL) +#if defined(HAVE_LIBVA) && defined(HAS_EGL) #include <va/va_wayland.h> #include "cores/VideoPlayer/DVDCodecs/Video/VAAPI.h" #include "cores/VideoPlayer/VideoRenderers/HwDecRender/RendererVAAPIGL.h" diff --git a/xbmc/windowing/wayland/WinSystemWayland.cpp b/xbmc/windowing/wayland/WinSystemWayland.cpp index 450876a40e..6d07197bc7 100644 --- a/xbmc/windowing/wayland/WinSystemWayland.cpp +++ b/xbmc/windowing/wayland/WinSystemWayland.cpp @@ -43,8 +43,6 @@ #include "utils/log.h" #include "windowing/linux/OSScreenSaverFreedesktop.h" -#include "platform/freebsd/OptionalsReg.h" -#include "platform/linux/OptionalsReg.h" #include "platform/linux/TimeUtils.h" #include <algorithm> @@ -139,45 +137,7 @@ struct MsgBufferScale CWinSystemWayland::CWinSystemWayland() : CWinSystemBase{}, m_protocol{"WinSystemWaylandInternal"} { - std::string envSink; - if (getenv("KODI_AE_SINK")) - envSink = getenv("KODI_AE_SINK"); - if (StringUtils::EqualsNoCase(envSink, "ALSA")) - { - OPTIONALS::ALSARegister(); - } - else if (StringUtils::EqualsNoCase(envSink, "PULSE")) - { - OPTIONALS::PulseAudioRegister(); - } - else if (StringUtils::EqualsNoCase(envSink, "OSS")) - { - OPTIONALS::OSSRegister(); - } - else if (StringUtils::EqualsNoCase(envSink, "SNDIO")) - { - OPTIONALS::SndioRegister(); - } - else if (StringUtils::EqualsNoCase(envSink, "ALSA+PULSE")) - { - OPTIONALS::ALSARegister(); - OPTIONALS::PulseAudioRegister(); - } - else - { - if (!OPTIONALS::PulseAudioRegister()) - { - if (!OPTIONALS::ALSARegister()) - { - if (!OPTIONALS::SndioRegister()) - { - OPTIONALS::OSSRegister(); - } - } - } - } m_winEvents.reset(new CWinEventsWayland()); - m_lirc.reset(OPTIONALS::LircRegister()); } CWinSystemWayland::~CWinSystemWayland() noexcept diff --git a/xbmc/windowing/wayland/WinSystemWayland.h b/xbmc/windowing/wayland/WinSystemWayland.h index 26952c33ef..9f93d4bd46 100644 --- a/xbmc/windowing/wayland/WinSystemWayland.h +++ b/xbmc/windowing/wayland/WinSystemWayland.h @@ -20,9 +20,6 @@ #include "utils/ActorProtocol.h" #include "windowing/WinSystem.h" -#include "platform/freebsd/OptionalsReg.h" -#include "platform/linux/OptionalsReg.h" - #include <atomic> #include <ctime> #include <list> @@ -294,8 +291,6 @@ private: std::uint32_t m_lastAckedSerial{0u}; /// Whether this is the first call to SetFullScreen bool m_isInitialSetFullScreen{true}; - - std::unique_ptr<OPTIONALS::CLircContainer, OPTIONALS::delete_CLircContainer> m_lirc; }; |