diff -Nru kodi-18.2+git20190422.1151-final/addons/resource.language.en_gb/resources/strings.po kodi-18.3+git20190621.1610-final/addons/resource.language.en_gb/resources/strings.po --- kodi-18.2+git20190422.1151-final/addons/resource.language.en_gb/resources/strings.po 2019-04-22 09:51:05.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/resource.language.en_gb/resources/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -5097,6 +5097,7 @@ #empty string with id 10121 #: xbmc/guilib/WindowIDs.h +#: xbmc/music/dialogs/GUIDialogVisualisationPresetList.cpp msgctxt "#10122" msgid "Visualization preset list" msgstr "" @@ -6879,8 +6880,9 @@ msgid "Preset" msgstr "" +#: xbmc/music/dialogs/GUIDialogVisualisationPresetList.cpp msgctxt "#13389" -msgid "There are no presets available\nfor this visualisation" +msgid "There are no presets available for this visualisation" msgstr "" msgctxt "#13390" @@ -6970,6 +6972,7 @@ msgid "Picture information" msgstr "" +#: xbmc/music/dialogs/GUIDialogVisualisationPresetList.cpp msgctxt "#13407" msgid "{0:s} presets" msgstr "" @@ -21253,7 +21256,7 @@ msgid "Output information to NFO files" msgstr "" -#. See #38309 when NFO and art export disabled so only artist folders +#. See #38309 when NFO and art export disabled so only artist folders #: xbmc/settings/dialogs/GUIDialogLibExportSettings.cpp msgctxt "#38310" msgid "Output information to NFO files (currently exporting artist folders only)" diff -Nru kodi-18.2+git20190422.1151-final/addons/screensaver.xbmc.builtin.dim/addon.xml kodi-18.3+git20190621.1610-final/addons/screensaver.xbmc.builtin.dim/addon.xml --- kodi-18.2+git20190422.1151-final/addons/screensaver.xbmc.builtin.dim/addon.xml 2019-04-22 09:51:05.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/screensaver.xbmc.builtin.dim/addon.xml 2019-06-21 14:09:24.000000000 +0000 @@ -1,7 +1,7 @@ diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/addon.xml kodi-18.3+git20190621.1610-final/addons/skin.estouchy/addon.xml --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/addon.xml 2019-04-22 09:51:05.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/addon.xml 2019-06-21 14:09:24.000000000 +0000 @@ -1,5 +1,5 @@ - + diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.af_za/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.af_za/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.af_za/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.af_za/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -96,6 +96,10 @@ msgid "Updated:" msgstr "Opgedateer:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "GEPOUSEER" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "VORENTOE SPOEL" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.am_et/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.am_et/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.am_et/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.am_et/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -72,6 +72,10 @@ msgid "Updated:" msgstr "ተሻሽሏል:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "ማቆሚያ" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "ወደ ፊት ማሳለፊያ" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.ar_sa/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.ar_sa/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.ar_sa/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.ar_sa/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -68,6 +68,10 @@ msgid "Login" msgstr "تسجيل الدخول" +msgctxt "#31043" +msgid "PAUSED" +msgstr "متوقف" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "تقديم سريع" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.be_by/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.be_by/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.be_by/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.be_by/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -76,6 +76,10 @@ msgid "Login" msgstr "Login" +msgctxt "#31043" +msgid "PAUSED" +msgstr "ПРЫПЫНЕНА" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "FAST FORWARD" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.bg_bg/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.bg_bg/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.bg_bg/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.bg_bg/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -56,6 +56,10 @@ msgid "Episodes" msgstr "Епизоди" +msgctxt "#31015" +msgid "Player info" +msgstr "Информация за плейъра" + msgctxt "#31016" msgid "Albums" msgstr "Албуми" @@ -96,6 +100,10 @@ msgid "Updated:" msgstr "Обновено:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "НА ПАУЗА" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "ПРЕВЪРТАНЕ НАПРЕД" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.ca_es/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.ca_es/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.ca_es/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.ca_es/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -96,6 +96,10 @@ msgid "Updated:" msgstr "Actualització:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "PAUSA" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "AVANÇA DE PRESSA" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.cs_cz/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.cs_cz/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.cs_cz/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.cs_cz/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -56,6 +56,10 @@ msgid "Episodes" msgstr "Epizody" +msgctxt "#31015" +msgid "Player info" +msgstr "Informace o hráči" + msgctxt "#31016" msgid "Albums" msgstr "Alba" @@ -96,6 +100,10 @@ msgid "Updated:" msgstr "Aktualizované:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "POZASTAVENO" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "PŘETÁČÍ SE VPŘED" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.cy_gb/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.cy_gb/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.cy_gb/strings.po 2019-04-22 09:51:05.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.cy_gb/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -64,6 +64,10 @@ msgid "Login" msgstr "Mewngofnodi" +msgctxt "#31043" +msgid "PAUSED" +msgstr "OEDWYD" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "YMLAEN CYFLYM" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.da_dk/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.da_dk/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.da_dk/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.da_dk/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -96,6 +96,10 @@ msgid "Updated:" msgstr "Opdateret:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "PAUSE" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "SPOL FREM" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.de_de/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.de_de/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.de_de/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.de_de/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -96,6 +96,10 @@ msgid "Updated:" msgstr "Aktualisiert:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "PAUSE" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "SCHNELL VORSPULEN" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.el_gr/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.el_gr/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.el_gr/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.el_gr/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -96,6 +96,10 @@ msgid "Updated:" msgstr "Ενημερωμένο:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "ΠΑΥΣΗ" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "ΠΡΟΩΘΗΣΗ" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.en_au/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.en_au/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.en_au/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.en_au/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -68,6 +68,10 @@ msgid "Login" msgstr "Login" +msgctxt "#31043" +msgid "PAUSED" +msgstr "PAUSED" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "FAST FORWARD" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.en_nz/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.en_nz/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.en_nz/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.en_nz/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -56,6 +56,10 @@ msgid "Episodes" msgstr "Episodes" +msgctxt "#31015" +msgid "Player info" +msgstr "Player info" + msgctxt "#31016" msgid "Albums" msgstr "Albums" @@ -96,6 +100,10 @@ msgid "Updated:" msgstr "Updated:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "PAUSED" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "FAST FORWARD" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.en_us/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.en_us/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.en_us/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.en_us/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -96,6 +96,10 @@ msgid "Updated:" msgstr "Updated:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "PAUSED" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "FAST FORWARD" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.es_ar/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.es_ar/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.es_ar/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.es_ar/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -88,6 +88,10 @@ msgid "Login" msgstr "Ingresar" +msgctxt "#31043" +msgid "PAUSED" +msgstr "PAUSADO" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "AVANCE RAPIDO" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.es_es/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.es_es/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.es_es/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.es_es/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -56,6 +56,10 @@ msgid "Episodes" msgstr "Episodios" +msgctxt "#31015" +msgid "Player info" +msgstr "Info reproductor" + msgctxt "#31016" msgid "Albums" msgstr "Álbumes" @@ -96,6 +100,10 @@ msgid "Updated:" msgstr "Actualizado:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "PAUSA" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "AVANZAR" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.es_mx/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.es_mx/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.es_mx/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.es_mx/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -96,6 +96,10 @@ msgid "Updated:" msgstr "Actualizado:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "PAUSA" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "AVANCE RAPIDO" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.et_ee/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.et_ee/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.et_ee/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.et_ee/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -68,6 +68,10 @@ msgid "Login" msgstr "Logi sisse" +msgctxt "#31043" +msgid "PAUSED" +msgstr "PAUSIS" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "KIIRELT EDASI" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.eu_es/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.eu_es/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.eu_es/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.eu_es/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -96,6 +96,10 @@ msgid "Updated:" msgstr "Eguneratua: " +msgctxt "#31043" +msgid "PAUSED" +msgstr "PAUSATUA" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "BIZKOR AURRERATU" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.fa_ir/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.fa_ir/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.fa_ir/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.fa_ir/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -40,6 +40,10 @@ msgid "Login" msgstr "ورود" +msgctxt "#31043" +msgid "PAUSED" +msgstr "مکث شده" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "حرکت سریع به جلو" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.fi_fi/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.fi_fi/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.fi_fi/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.fi_fi/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -56,6 +56,10 @@ msgid "Episodes" msgstr "Jaksot" +msgctxt "#31015" +msgid "Player info" +msgstr "Soittimen tiedot" + msgctxt "#31016" msgid "Albums" msgstr "Albumit" @@ -96,6 +100,10 @@ msgid "Updated:" msgstr "Päivitetty:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "TAUKO" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "KELAUS ETEENPÄIN" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.fo_fo/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.fo_fo/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.fo_fo/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.fo_fo/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -36,6 +36,10 @@ msgid "Page" msgstr "Síða" +msgctxt "#31043" +msgid "PAUSED" +msgstr "STEÐGUR" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "SKJÓTT FRAMM" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.fr_ca/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.fr_ca/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.fr_ca/strings.po 2018-12-03 16:49:55.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.fr_ca/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -56,6 +56,10 @@ msgid "Episodes" msgstr "Épisodes" +msgctxt "#31015" +msgid "Player info" +msgstr "Informations sur le lecteur" + msgctxt "#31016" msgid "Albums" msgstr "Albums" @@ -96,6 +100,10 @@ msgid "Updated:" msgstr "Mis à jour :" +msgctxt "#31043" +msgid "PAUSED" +msgstr "EN PAUSE" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "AVANCE RAPIDE" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.fr_fr/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.fr_fr/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.fr_fr/strings.po 2019-01-28 18:34:06.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.fr_fr/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -56,6 +56,10 @@ msgid "Episodes" msgstr "Épisodes" +msgctxt "#31015" +msgid "Player info" +msgstr "Infos du lecteur" + msgctxt "#31016" msgid "Albums" msgstr "Albums " @@ -96,6 +100,10 @@ msgid "Updated:" msgstr "Mis à jour :" +msgctxt "#31043" +msgid "PAUSED" +msgstr "EN PAUSE" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "AVANCE RAPIDE" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.gl_es/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.gl_es/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.gl_es/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.gl_es/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -56,6 +56,10 @@ msgid "Episodes" msgstr "Episodios" +msgctxt "#31015" +msgid "Player info" +msgstr "Información do xogador" + msgctxt "#31016" msgid "Albums" msgstr "Álbumes" @@ -66,7 +70,7 @@ msgctxt "#31018" msgid "Player process info" -msgstr "Información do procesado da Xogadora" +msgstr "Información do proceso do reprodutor" msgctxt "#31019" msgid "Video decoder" @@ -96,6 +100,10 @@ msgid "Updated:" msgstr "Actualizado:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "EN PAUSA" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "ADIANTE" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.he_il/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.he_il/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.he_il/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.he_il/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -96,6 +96,10 @@ msgid "Updated:" msgstr ":עודכן" +msgctxt "#31043" +msgid "PAUSED" +msgstr "מושהה" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "הרצה קדימה" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.hr_hr/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.hr_hr/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.hr_hr/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.hr_hr/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -56,6 +56,10 @@ msgid "Episodes" msgstr "Epizode" +msgctxt "#31015" +msgid "Player info" +msgstr "Informacije reproduktora" + msgctxt "#31016" msgid "Albums" msgstr "Albumi" @@ -96,6 +100,10 @@ msgid "Updated:" msgstr "Nadopunjeno:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "PAUZIRANO" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "PREMOTAVANJE UNAPRIJED" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.hu_hu/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.hu_hu/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.hu_hu/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.hu_hu/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -56,6 +56,10 @@ msgid "Episodes" msgstr "Epizódok" +msgctxt "#31015" +msgid "Player info" +msgstr "Lejátszó info" + msgctxt "#31016" msgid "Albums" msgstr "Albumok" @@ -96,6 +100,10 @@ msgid "Updated:" msgstr "Frissítve:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "MEGÁLLÍTVA" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "ELŐRETEKERÉS" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.hy_am/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.hy_am/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.hy_am/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.hy_am/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -36,6 +36,10 @@ msgid "Login" msgstr "Մուտք" +msgctxt "#31043" +msgid "PAUSED" +msgstr "ԴԱԴԱՐ" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "ԱՌԱՋ" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.id_id/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.id_id/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.id_id/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.id_id/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -72,6 +72,10 @@ msgid "Login" msgstr "Masuk" +msgctxt "#31043" +msgid "PAUSED" +msgstr "JEDA" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "MAJU CEPAT" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.is_is/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.is_is/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.is_is/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.is_is/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -56,6 +56,10 @@ msgid "Episodes" msgstr "Þættir" +msgctxt "#31015" +msgid "Player info" +msgstr "Upplýsingar um spilara" + msgctxt "#31016" msgid "Albums" msgstr "Hljómplötur" @@ -96,6 +100,10 @@ msgid "Updated:" msgstr "Uppfært:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "Í BIÐ" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "HRATT ÁFRAM" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.it_it/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.it_it/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.it_it/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.it_it/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -96,6 +96,10 @@ msgid "Updated:" msgstr "Aggiornato:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "IN PAUSA" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "AVANZ. VELOCE" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.ja_jp/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.ja_jp/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.ja_jp/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.ja_jp/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -68,6 +68,10 @@ msgid "Login" msgstr "ログイン" +msgctxt "#31043" +msgid "PAUSED" +msgstr "静止中" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "早送り" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.ko_kr/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.ko_kr/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.ko_kr/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.ko_kr/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -56,6 +56,10 @@ msgid "Episodes" msgstr "에피소드" +msgctxt "#31015" +msgid "Player info" +msgstr "플레이어 정보" + msgctxt "#31016" msgid "Albums" msgstr "앨범" @@ -96,6 +100,10 @@ msgid "Updated:" msgstr "업데이트:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "일시 중지" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "빠르게" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.lt_lt/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.lt_lt/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.lt_lt/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.lt_lt/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -56,6 +56,10 @@ msgid "Episodes" msgstr "Epizodai" +msgctxt "#31015" +msgid "Player info" +msgstr "Grotuvo informacija" + msgctxt "#31016" msgid "Albums" msgstr "Albumai" @@ -96,6 +100,10 @@ msgid "Updated:" msgstr "Atnaujinta:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "PAUZĖ" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "PRASUKTI PIRMYN" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.lv_lv/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.lv_lv/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.lv_lv/strings.po 2019-01-28 18:34:06.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.lv_lv/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -84,6 +84,10 @@ msgid "Login" msgstr "Pieteikšanās" +msgctxt "#31043" +msgid "PAUSED" +msgstr "IEPAUZĒTS" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "TĪT UZ PRIEKŠU" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.mk_mk/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.mk_mk/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.mk_mk/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.mk_mk/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -72,6 +72,10 @@ msgid "Login" msgstr "Најави се" +msgctxt "#31043" +msgid "PAUSED" +msgstr "ПАУЗИРАНО" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "ПРЕМОТУВАЊЕ НАНАПРЕД" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.mn_mn/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.mn_mn/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.mn_mn/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.mn_mn/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -28,6 +28,10 @@ msgid "Page" msgstr "Хуудас" +msgctxt "#31043" +msgid "PAUSED" +msgstr "ТҮР ЗОГСООСОН" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "УРАГШ ГҮЙЛГЭХ" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.ms_my/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.ms_my/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.ms_my/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.ms_my/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -56,6 +56,10 @@ msgid "Episodes" msgstr "Episod" +msgctxt "#31015" +msgid "Player info" +msgstr "Maklumat pemain" + msgctxt "#31016" msgid "Albums" msgstr "Album" @@ -96,6 +100,10 @@ msgid "Updated:" msgstr "Dikemaskini:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "TERHENTI SEJENAK" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "MAJU PANTAS" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.mt_mt/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.mt_mt/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.mt_mt/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.mt_mt/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -36,6 +36,10 @@ msgid "Page" msgstr "Paġna" +msgctxt "#31043" +msgid "PAUSED" +msgstr "IPPAWŻAT" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "GĦAĠĠEL QUDDIEM" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.my_mm/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.my_mm/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.my_mm/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.my_mm/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -40,6 +40,10 @@ msgid "Login" msgstr "ဝင်ရန်" +msgctxt "#31043" +msgid "PAUSED" +msgstr "ခဏရပ်မည်" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "အရှေ့သို့အနည်းငယ်ရစ်မည်" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.nb_no/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.nb_no/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.nb_no/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.nb_no/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -96,6 +96,10 @@ msgid "Updated:" msgstr "Oppdatert:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "PAUSE" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "Spol framover" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.nl_nl/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.nl_nl/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.nl_nl/strings.po 2018-12-29 14:31:08.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.nl_nl/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -96,6 +96,10 @@ msgid "Updated:" msgstr "Geüpdated:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "PAUZE" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "VOORUITSPOELEN" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.pl_pl/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.pl_pl/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.pl_pl/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.pl_pl/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -96,6 +96,10 @@ msgid "Updated:" msgstr "Zaktualizowano:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "PAUZA" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "DO PRZODU" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.pt_br/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.pt_br/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.pt_br/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.pt_br/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -96,6 +96,10 @@ msgid "Updated:" msgstr "Atualizado:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "PAUSADO" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "Avanço Rápido" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.pt_pt/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.pt_pt/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.pt_pt/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.pt_pt/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -96,6 +96,10 @@ msgid "Updated:" msgstr "Última atualização:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "EM PAUSA" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "AVANÇAR" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.ro_ro/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.ro_ro/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.ro_ro/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.ro_ro/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -96,6 +96,10 @@ msgid "Updated:" msgstr "Actualizat:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "ÎN PAUZĂ" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "ÎNAINTE" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.ru_ru/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.ru_ru/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.ru_ru/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.ru_ru/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -56,6 +56,10 @@ msgid "Episodes" msgstr "Серии" +msgctxt "#31015" +msgid "Player info" +msgstr "Информация об игроке" + msgctxt "#31016" msgid "Albums" msgstr "Альбомы" @@ -96,6 +100,10 @@ msgid "Updated:" msgstr "Обновлено:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "ПАУЗА" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "ПЕРЕМОТКА ВПЕРЕД" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.sk_sk/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.sk_sk/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.sk_sk/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.sk_sk/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -56,6 +56,10 @@ msgid "Episodes" msgstr "Epizódy" +msgctxt "#31015" +msgid "Player info" +msgstr "Informácie o prehrávači" + msgctxt "#31016" msgid "Albums" msgstr "Albumy" @@ -96,6 +100,10 @@ msgid "Updated:" msgstr "Aktualizované:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "PAUZA" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "RÝCHLO VPRED" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.sl_si/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.sl_si/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.sl_si/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.sl_si/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -68,6 +68,10 @@ msgid "Login" msgstr "Prijava" +msgctxt "#31043" +msgid "PAUSED" +msgstr "PREKINITEV" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "PREVIJANJE NAPREJ" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.sq_al/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.sq_al/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.sq_al/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.sq_al/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -64,6 +64,10 @@ msgid "Info List" msgstr "Lista Info" +msgctxt "#31043" +msgid "PAUSED" +msgstr "PAUZUAR" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "PËRSHPEJTO" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.sr_rs/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.sr_rs/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.sr_rs/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.sr_rs/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -96,6 +96,10 @@ msgid "Updated:" msgstr "Ажурирано:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "ПАУЗИРАНО" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "ПРЕМОТАВАЊЕ УНАПРЕД" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.sr_rs@latin/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.sr_rs@latin/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.sr_rs@latin/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.sr_rs@latin/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -96,6 +96,10 @@ msgid "Updated:" msgstr "Ažurirano:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "PAUZIRANO" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "PREMOTAVANjE UNAPRED" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.sv_se/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.sv_se/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.sv_se/strings.po 2018-12-03 16:49:55.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.sv_se/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -56,6 +56,10 @@ msgid "Episodes" msgstr "Avsnitt" +msgctxt "#31015" +msgid "Player info" +msgstr "Spelarinfo" + msgctxt "#31016" msgid "Albums" msgstr "Album" @@ -96,6 +100,10 @@ msgid "Updated:" msgstr "Uppdaterad:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "PAUSAD" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "SPOLA FRAMÅT" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.szl/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.szl/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.szl/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.szl/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -92,6 +92,10 @@ msgid "Updated:" msgstr "Zaktualizowano było:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "PAUZA" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "DO PRZODKU" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.ta_in/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.ta_in/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.ta_in/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.ta_in/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -68,6 +68,10 @@ msgid "Login" msgstr "புகுபதிகை" +msgctxt "#31043" +msgid "PAUSED" +msgstr "இடைநிறுத்தம்" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "முன்சுற்று" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.tg_tj/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.tg_tj/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.tg_tj/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.tg_tj/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -40,6 +40,10 @@ msgid "Login" msgstr "Вуруд" +msgctxt "#31043" +msgid "PAUSED" +msgstr "ТАВАҚҚУФШУДА" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "БАСУРЪАТ БА ПЕШ ГАРДОНИДАНИ РОҲЧА" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.th_th/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.th_th/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.th_th/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.th_th/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -96,6 +96,10 @@ msgid "Updated:" msgstr "อัพเดต:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "หยุดชั่วขณะ" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "ไปหน้าแบบเร็ว" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.tr_tr/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.tr_tr/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.tr_tr/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.tr_tr/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -56,6 +56,10 @@ msgid "Episodes" msgstr "Bölümler" +msgctxt "#31015" +msgid "Player info" +msgstr "Yürütücü bilgisi" + msgctxt "#31016" msgid "Albums" msgstr "Albümler" @@ -96,6 +100,10 @@ msgid "Updated:" msgstr "Güncellendi" +msgctxt "#31043" +msgid "PAUSED" +msgstr "DURAKLATILDI" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "İLERİ SAR" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.uk_ua/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.uk_ua/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.uk_ua/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.uk_ua/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -96,6 +96,10 @@ msgid "Updated:" msgstr "Оновлено:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "ПАУЗА" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "ПЕРЕМОТКА ВПЕРЕД" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.vi_vn/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.vi_vn/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.vi_vn/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.vi_vn/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -64,6 +64,10 @@ msgid "Login" msgstr "Đăng nhập" +msgctxt "#31043" +msgid "PAUSED" +msgstr "Tạm dừng" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "TUA NHANH" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.zh_cn/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.zh_cn/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.zh_cn/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.zh_cn/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -56,6 +56,10 @@ msgid "Episodes" msgstr "集" +msgctxt "#31015" +msgid "Player info" +msgstr "播放信息" + msgctxt "#31016" msgid "Albums" msgstr "专辑" @@ -96,6 +100,10 @@ msgid "Updated:" msgstr "已更新:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "暂停" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "快进" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.zh_tw/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.zh_tw/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estouchy/language/resource.language.zh_tw/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estouchy/language/resource.language.zh_tw/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -96,6 +96,10 @@ msgid "Updated:" msgstr "已更新:" +msgctxt "#31043" +msgid "PAUSED" +msgstr "已暫停" + msgctxt "#31044" msgid "FAST FORWARD" msgstr "快轉" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estuary/addon.xml kodi-18.3+git20190621.1610-final/addons/skin.estuary/addon.xml --- kodi-18.2+git20190422.1151-final/addons/skin.estuary/addon.xml 2019-04-22 09:51:05.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estuary/addon.xml 2019-06-21 14:09:24.000000000 +0000 @@ -1,5 +1,5 @@ - + diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estuary/language/resource.language.de_de/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estuary/language/resource.language.de_de/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estuary/language/resource.language.de_de/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estuary/language/resource.language.de_de/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -454,7 +454,7 @@ msgctxt "#31134" msgid "Remaining" -msgstr "Verbleibend" +msgstr "Restzeit" msgctxt "#31136" msgid "Click here to see latest changes..." @@ -571,3 +571,7 @@ msgctxt "#31166" msgid "Profile avatar" msgstr "Profil-Avatar" + +msgctxt "#31167" +msgid "Animate background" +msgstr "Hintergrund animieren" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estuary/language/resource.language.en_nz/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estuary/language/resource.language.en_nz/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estuary/language/resource.language.en_nz/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estuary/language/resource.language.en_nz/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -444,6 +444,14 @@ msgid "Choose skin fanart pack" msgstr "Choose skin fanart pack" +msgctxt "#31132" +msgid "Select Program" +msgstr "Select Program" + +msgctxt "#31133" +msgid "Select Resolution" +msgstr "Select Resolution" + msgctxt "#31134" msgid "Remaining" msgstr "Remaining" @@ -552,6 +560,18 @@ msgid "Show Fanart background" msgstr "Show Fanart background" +msgctxt "#31164" +msgid "Choose kind of profile identification" +msgstr "Choose kind of profile identification" + msgctxt "#31165" msgid "Profile name" msgstr "Profile name" + +msgctxt "#31166" +msgid "Profile avatar" +msgstr "Profile avatar" + +msgctxt "#31167" +msgid "Animate background" +msgstr "Animate background" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estuary/language/resource.language.eu_es/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estuary/language/resource.language.eu_es/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estuary/language/resource.language.eu_es/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estuary/language/resource.language.eu_es/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -274,7 +274,7 @@ msgctxt "#31080" msgid "Ends at" -msgstr "Amaiera ordua:" +msgstr "Amaiera ordua" msgctxt "#31082" msgid "Lyrics add-on" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estuary/language/resource.language.gl_es/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estuary/language/resource.language.gl_es/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estuary/language/resource.language.gl_es/strings.po 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estuary/language/resource.language.gl_es/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -448,6 +448,10 @@ msgid "Select Program" msgstr "Seleccionar programa" +msgctxt "#31133" +msgid "Select Resolution" +msgstr "Seleccionar resolución" + msgctxt "#31134" msgid "Remaining" msgstr "Restante" @@ -556,6 +560,18 @@ msgid "Show Fanart background" msgstr "Amosar Fanart como fondo" +msgctxt "#31164" +msgid "Choose kind of profile identification" +msgstr "Seleccionar o tipo de identificación do perfil" + msgctxt "#31165" msgid "Profile name" msgstr "Nome do perfíl" + +msgctxt "#31166" +msgid "Profile avatar" +msgstr "Avatar do perfil" + +msgctxt "#31167" +msgid "Animate background" +msgstr "Animar o fondo" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estuary/language/resource.language.ko_kr/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estuary/language/resource.language.ko_kr/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estuary/language/resource.language.ko_kr/strings.po 2019-01-13 07:51:35.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estuary/language/resource.language.ko_kr/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -274,7 +274,7 @@ msgctxt "#31080" msgid "Ends at" -msgstr "종료:" +msgstr "종료" msgctxt "#31082" msgid "Lyrics add-on" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estuary/language/resource.language.tr_tr/strings.po kodi-18.3+git20190621.1610-final/addons/skin.estuary/language/resource.language.tr_tr/strings.po --- kodi-18.2+git20190422.1151-final/addons/skin.estuary/language/resource.language.tr_tr/strings.po 2019-04-22 09:51:05.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estuary/language/resource.language.tr_tr/strings.po 2019-06-21 14:09:24.000000000 +0000 @@ -450,7 +450,7 @@ msgctxt "#31133" msgid "Select Resolution" -msgstr "Çözünürlük seç" +msgstr "Çözünürlük Seç" msgctxt "#31134" msgid "Remaining" @@ -562,7 +562,7 @@ msgctxt "#31164" msgid "Choose kind of profile identification" -msgstr "Profil kimliği türünü seçin" +msgstr "Profil kimliğini görüntüleme türünü seçin" msgctxt "#31165" msgid "Profile name" diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estuary/xml/DialogAddonSettings.xml kodi-18.3+git20190621.1610-final/addons/skin.estuary/xml/DialogAddonSettings.xml --- kodi-18.2+git20190422.1151-final/addons/skin.estuary/xml/DialogAddonSettings.xml 2019-04-22 09:51:05.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estuary/xml/DialogAddonSettings.xml 2019-06-21 14:09:24.000000000 +0000 @@ -19,7 +19,7 @@ 29 80 400 - 685 + 690 -25 vertical 9000 diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estuary/xml/Home.xml kodi-18.3+git20190621.1610-final/addons/skin.estuary/xml/Home.xml --- kodi-18.2+git20190422.1151-final/addons/skin.estuary/xml/Home.xml 2019-01-13 07:51:35.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estuary/xml/Home.xml 2019-06-21 14:09:24.000000000 +0000 @@ -527,7 +527,7 @@ vertical 14010 Integer.IsGreater(Container(14100).NumItems,0) | Container(14100).IsUpdating - + 130 @@ -536,7 +536,7 @@ - + DepthContentPopout 130 diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estuary/xml/Includes_MediaMenu.xml kodi-18.3+git20190621.1610-final/addons/skin.estuary/xml/Includes_MediaMenu.xml --- kodi-18.2+git20190422.1151-final/addons/skin.estuary/xml/Includes_MediaMenu.xml 2018-07-31 18:47:37.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estuary/xml/Includes_MediaMenu.xml 2019-06-21 14:09:24.000000000 +0000 @@ -365,11 +365,12 @@ Control.IsEnabled(4) SendClick(4) + MediaMenuSearchButton Container.CanFilter + !Container.CanFilterAdvanced MediaMenuItemsCommon right - + Container.CanFilterAdvanced @@ -380,6 +381,12 @@ + + + MediaMenuItemsCommon + + + diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estuary/xml/Includes.xml kodi-18.3+git20190621.1610-final/addons/skin.estuary/xml/Includes.xml --- kodi-18.2+git20190422.1151-final/addons/skin.estuary/xml/Includes.xml 2019-04-22 09:48:14.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estuary/xml/Includes.xml 2019-06-21 14:09:24.000000000 +0000 @@ -57,7 +57,6 @@ Hidden conditional Control.IsVisible(52) | Control.IsVisible(500) | Control.IsVisible(55) | Control.IsVisible(501) | Control.IsVisible(54) - diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estuary/xml/SkinSettings.xml kodi-18.3+git20190621.1610-final/addons/skin.estuary/xml/SkinSettings.xml --- kodi-18.2+git20190422.1151-final/addons/skin.estuary/xml/SkinSettings.xml 2018-07-31 18:47:37.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estuary/xml/SkinSettings.xml 2019-06-21 14:09:24.000000000 +0000 @@ -328,8 +328,8 @@ vertical conditional - 5 - 5 + 1000 + 1000 Visible Hidden WindowOpen diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estuary/xml/Variables.xml kodi-18.3+git20190621.1610-final/addons/skin.estuary/xml/Variables.xml --- kodi-18.2+git20190422.1151-final/addons/skin.estuary/xml/Variables.xml 2019-04-22 09:51:05.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estuary/xml/Variables.xml 2019-06-21 14:09:24.000000000 +0000 @@ -256,6 +256,7 @@ [COLOR grey]$INFO[ListItem.Year, (,)][/COLOR] + $INFO[ListItem.TVShowTitle]$INFO[ListItem.Year, ([COLOR grey],[/COLOR])] $INFO[ListItem.Title]$INFO[ListItem.Year, ([COLOR grey],[/COLOR])] $INFO[ListItem.Label]$INFO[ListItem.Year, ([COLOR grey],[/COLOR])] @@ -264,7 +265,7 @@ $LOCALIZE[208] - $INFO[ListItem.Season]$INFO[ListItem.Episode,[COLOR grey]x[/COLOR],: ]$INFO[ListItem.TVShowTitle] + $INFO[ListItem.Season]$INFO[ListItem.Episode,[COLOR grey]x[/COLOR],: ]$INFO[ListItem.Title] $INFO[ListItem.Tagline,[I],[/I]] $INFO[ListItem.Genre] diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estuary/xml/View_500_Wall.xml kodi-18.3+git20190621.1610-final/addons/skin.estuary/xml/View_500_Wall.xml --- kodi-18.2+git20190422.1151-final/addons/skin.estuary/xml/View_500_Wall.xml 2018-07-31 18:47:37.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estuary/xml/View_500_Wall.xml 2019-06-21 14:09:24.000000000 +0000 @@ -39,7 +39,7 @@ - + 110 @@ -48,7 +48,7 @@ - + DepthContentPopout Focus @@ -79,7 +79,7 @@ - + 150 @@ -87,7 +87,7 @@ - + DepthContentPopout 150 @@ -99,7 +99,7 @@ - + 150 @@ -107,7 +107,7 @@ - + DepthContentPopout 150 diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estuary/xml/View_502_FanArt.xml kodi-18.3+git20190621.1610-final/addons/skin.estuary/xml/View_502_FanArt.xml --- kodi-18.2+git20190422.1151-final/addons/skin.estuary/xml/View_502_FanArt.xml 2018-11-04 08:12:28.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estuary/xml/View_502_FanArt.xml 2019-06-21 14:09:24.000000000 +0000 @@ -57,7 +57,6 @@ 502 vertical conditional - 40 diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estuary/xml/View_50_List.xml kodi-18.3+git20190621.1610-final/addons/skin.estuary/xml/View_50_List.xml --- kodi-18.2+git20190422.1151-final/addons/skin.estuary/xml/View_50_List.xml 2018-12-03 16:49:55.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estuary/xml/View_50_List.xml 2019-06-21 14:09:24.000000000 +0000 @@ -31,7 +31,6 @@ 50 vertical conditional - DepthContentPopout diff -Nru kodi-18.2+git20190422.1151-final/addons/skin.estuary/xml/View_54_InfoWall.xml kodi-18.3+git20190621.1610-final/addons/skin.estuary/xml/View_54_InfoWall.xml --- kodi-18.2+git20190422.1151-final/addons/skin.estuary/xml/View_54_InfoWall.xml 2018-11-21 19:38:53.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/addons/skin.estuary/xml/View_54_InfoWall.xml 2019-06-21 14:09:24.000000000 +0000 @@ -400,7 +400,7 @@ - + 64 110 @@ -410,7 +410,7 @@ - + DepthContentPopout Focus @@ -442,14 +442,14 @@ - + 0 150 InfoWallPictureLayout - + DepthContentPopout 0 diff -Nru kodi-18.2+git20190422.1151-final/BUILDDATE kodi-18.3+git20190621.1610-final/BUILDDATE --- kodi-18.2+git20190422.1151-final/BUILDDATE 2019-04-22 09:51:54.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/BUILDDATE 2019-06-21 14:10:03.000000000 +0000 @@ -1 +1 @@ -20190422 +20190621 diff -Nru kodi-18.2+git20190422.1151-final/cmake/treedata/optional/common/gbm.txt kodi-18.3+git20190621.1610-final/cmake/treedata/optional/common/gbm.txt --- kodi-18.2+git20190422.1151-final/cmake/treedata/optional/common/gbm.txt 2019-04-22 09:48:14.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/cmake/treedata/optional/common/gbm.txt 2019-06-21 14:09:24.000000000 +0000 @@ -1,2 +1,3 @@ xbmc/cores/RetroPlayer/process/gbm cores/RetroPlayer/process/gbm # GBM +xbmc/cores/VideoPlayer/Process/gbm cores/VideoPlayer/Process/gbm # GBM xbmc/windowing/gbm windowing/gbm # GBM \ No newline at end of file diff -Nru kodi-18.2+git20190422.1151-final/debian/changelog kodi-18.3+git20190621.1610-final/debian/changelog --- kodi-18.2+git20190422.1151-final/debian/changelog 2019-04-22 10:02:26.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/debian/changelog 2019-06-21 14:20:22.000000000 +0000 @@ -1,4 +1,176 @@ -kodi (2:18.2+git20190422.1151-final-0bionic) bionic; urgency=high +kodi (2:18.3+git20190621.1610-final-0bionic) bionic; urgency=high + + [Arne Morten Kvarving] + * bump for 18.3 final + + [smp79] + * replace payloadObj.release() with payloadObj.reset() in ActorProtocol.cpp + + [Lukas Rusak] + * CRendererDRMPRIMEGLES: add override methods for ERENDERFEATURE and ESCALINGMETHOD + + [Lukas Rusak] + * CRendererDRMPRIMEGLES: update VBO's to be similar to CLinuxRendererGL + + [Lukas Rusak] + * CRendererDRMPRIMEGLES: use CEGLFence to sync rendering + + [Lukas Rusak] + * CEGLFence: add class to help with EGL sync objects + + [Lukas Rusak] + * CDRMUtils: explicitly set the caps we want (atomic brings them in) + + [Jonas Karlman] + * DVDVideoCodecDRMPRIME: update process info in get format callback + + [Jonas Karlman] + * DVDVideoCodecDRMPRIME: GetPicture only works for DRM_PRIME pix fmt + + [Jonas Karlman] + * VideoBufferDRMPRIME: add Map/Unmap callbacks + + [Jonas Karlman] + * VideoBufferDRMPRIME: extract interface + + [Jonas Karlman] + * VideoBufferDRMPRIME: extract class + + [Jonas Karlman] + * GBM: override ProcessInfo and use Deinterlace Half by default on arm + + [Lukas Rusak] + * CDRMUtils: fallback to drmModeAddFB2 if drmModeAddFB2WithModifiers fails + + [Lukas Rusak] + * CDRMUtils: rework modifiers flag selection + + [Lukas Rusak] + * CWinSystemGbm: only lock the front buffer if something is rendered + + [wsnipex] + * fixed: webdav over http2 + + [gemedet] + * Use special sort order when selecting first unwatched + + [Matt Filetto] + * ActiveAE: Fix crash when song switches to 48khtz track and viz is on + + [arnova] + * changed: Increase buffer for Curl http response to 4k (fixes #16179) + + [arnova] + * fixed: DVD playback from http(s) sources (fixes #15694) + + [ronie] + * [Estuary] fix navigation in side menu + + [DaveTBlake] + * When choose art don't show thumb were not applicable and fix thumbnail listing + + [DaveTBlake] + * Fix getting first "thumb" type art URL from scraper available art results + + [Kai Sommerfeld] + * [interfaces] Fix crash on Kodi exit caused by double freed AsyncCallbackMessage. + + [Bas Rieter] + * [PlaylistPlayer] Resolve plugin paths to fill the item infotag + + [ronie] + * [Estuary] (Info)Wall fixes + + [Kai Sommerfeld] + * [PVR] Separate GUI from PVR core: remove CFileItem usage from core: step 1: directory listings. + + [Kai Sommerfeld] + * [video] Add support for HEVC to CDVDDemuxClient::GetStreamCodecName. + + [Kai Sommerfeld] + * [PVR] Prevent concurrent updates for all pvr windows. + + [ronie] + * [Estuary] fix search button on side menu + + [Darren-Hill] + * Blade menu and context menu exit + + [Darren-Hill] + * Blade menu access for touchscreens + + [Sam Nazarko] + * LibInputKeyboard: re-add support for KEY_STOP as we had in CLinuxInputDevices + + [DaVukovic] + * [Estuary] Fix order of TVShowTitle and Title + + [Kai Sommerfeld] + * [PVR] Fix group manager crash when adding a new group. Closes #16079. + + [ronie] + * [Estuary] fix scrollbar focus with mouse + + [ronie] + * [Estuary] fix scrollbar in skinsettings + + [ronie] + * [Estuary] addonsettings - fix list + + [DaveTBlake] + * Fix blank viz preset dialog when no viz or when viz not have presets + + [Attila Jakosa] + * [lang][skin.estouchy] updated language files from Transifex + + [Attila Jakosa] + * [lang][skin.estuary] updated language files from Transifex + + [Attila Jakosa] + * [lang][kodi.core] automatic syntax corrections for the en_GB language file + + [peak3d] + * Remove 3:2 pullback from current check + + [djp952] + * Create EPG when a PVR channel has been dynamically added at runtime + + [DaveTBlake] + * Fix display of blank dialog when X key hit and there is no visualisation + + [djp952] + * Fix problem with newly added channels causing EPG UI corruption + + [Kai Sommerfeld] + * [PVR] Fix CPVREpg::(Add + + [fritsch] + * MusicExtensions: Add dtshd as that extension is used for commercial dtshd audio files + + [fritsch] + * PAPlayer: Don't fallback to DTS too early + + [ronie] + * [Estuary] favourites widget would not scroll to end on 16:10 displays + + [arnova] + * fixed: Resume bookmark would clear on player start failure + + [linknetx] + * [FIX] - Kodi crashes with empty node in advanced settings file + + [peak3d] + * CGUIDialogMediaBrowser: Fix usage of wrong item index + + [Kai Sommerfeld] + * [settings] Fix media source path substitution. + + [fritsch] + * Version: Increase Leia version to 18.3-RC1 + + [kszaq] + * GL: fix HAS_FLOAT_TEXTURE usage + [fritsch] * Splash: Update to 18.2 Leia diff -Nru kodi-18.2+git20190422.1151-final/debian/changelog.tmp kodi-18.3+git20190621.1610-final/debian/changelog.tmp --- kodi-18.2+git20190422.1151-final/debian/changelog.tmp 2019-04-22 09:52:28.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/debian/changelog.tmp 2019-06-21 14:10:33.000000000 +0000 @@ -1,4 +1,176 @@ -kodi (2:18.2+git20190422.1151-final-0dist) dist; urgency=high +kodi (2:18.3+git20190621.1610-final-0dist) dist; urgency=high + + [Arne Morten Kvarving] + * bump for 18.3 final + + [smp79] + * replace payloadObj.release() with payloadObj.reset() in ActorProtocol.cpp + + [Lukas Rusak] + * CRendererDRMPRIMEGLES: add override methods for ERENDERFEATURE and ESCALINGMETHOD + + [Lukas Rusak] + * CRendererDRMPRIMEGLES: update VBO's to be similar to CLinuxRendererGL + + [Lukas Rusak] + * CRendererDRMPRIMEGLES: use CEGLFence to sync rendering + + [Lukas Rusak] + * CEGLFence: add class to help with EGL sync objects + + [Lukas Rusak] + * CDRMUtils: explicitly set the caps we want (atomic brings them in) + + [Jonas Karlman] + * DVDVideoCodecDRMPRIME: update process info in get format callback + + [Jonas Karlman] + * DVDVideoCodecDRMPRIME: GetPicture only works for DRM_PRIME pix fmt + + [Jonas Karlman] + * VideoBufferDRMPRIME: add Map/Unmap callbacks + + [Jonas Karlman] + * VideoBufferDRMPRIME: extract interface + + [Jonas Karlman] + * VideoBufferDRMPRIME: extract class + + [Jonas Karlman] + * GBM: override ProcessInfo and use Deinterlace Half by default on arm + + [Lukas Rusak] + * CDRMUtils: fallback to drmModeAddFB2 if drmModeAddFB2WithModifiers fails + + [Lukas Rusak] + * CDRMUtils: rework modifiers flag selection + + [Lukas Rusak] + * CWinSystemGbm: only lock the front buffer if something is rendered + + [wsnipex] + * fixed: webdav over http2 + + [gemedet] + * Use special sort order when selecting first unwatched + + [Matt Filetto] + * ActiveAE: Fix crash when song switches to 48khtz track and viz is on + + [arnova] + * changed: Increase buffer for Curl http response to 4k (fixes #16179) + + [arnova] + * fixed: DVD playback from http(s) sources (fixes #15694) + + [ronie] + * [Estuary] fix navigation in side menu + + [DaveTBlake] + * When choose art don't show thumb were not applicable and fix thumbnail listing + + [DaveTBlake] + * Fix getting first "thumb" type art URL from scraper available art results + + [Kai Sommerfeld] + * [interfaces] Fix crash on Kodi exit caused by double freed AsyncCallbackMessage. + + [Bas Rieter] + * [PlaylistPlayer] Resolve plugin paths to fill the item infotag + + [ronie] + * [Estuary] (Info)Wall fixes + + [Kai Sommerfeld] + * [PVR] Separate GUI from PVR core: remove CFileItem usage from core: step 1: directory listings. + + [Kai Sommerfeld] + * [video] Add support for HEVC to CDVDDemuxClient::GetStreamCodecName. + + [Kai Sommerfeld] + * [PVR] Prevent concurrent updates for all pvr windows. + + [ronie] + * [Estuary] fix search button on side menu + + [Darren-Hill] + * Blade menu and context menu exit + + [Darren-Hill] + * Blade menu access for touchscreens + + [Sam Nazarko] + * LibInputKeyboard: re-add support for KEY_STOP as we had in CLinuxInputDevices + + [DaVukovic] + * [Estuary] Fix order of TVShowTitle and Title + + [Kai Sommerfeld] + * [PVR] Fix group manager crash when adding a new group. Closes #16079. + + [ronie] + * [Estuary] fix scrollbar focus with mouse + + [ronie] + * [Estuary] fix scrollbar in skinsettings + + [ronie] + * [Estuary] addonsettings - fix list + + [DaveTBlake] + * Fix blank viz preset dialog when no viz or when viz not have presets + + [Attila Jakosa] + * [lang][skin.estouchy] updated language files from Transifex + + [Attila Jakosa] + * [lang][skin.estuary] updated language files from Transifex + + [Attila Jakosa] + * [lang][kodi.core] automatic syntax corrections for the en_GB language file + + [peak3d] + * Remove 3:2 pullback from current check + + [djp952] + * Create EPG when a PVR channel has been dynamically added at runtime + + [DaveTBlake] + * Fix display of blank dialog when X key hit and there is no visualisation + + [djp952] + * Fix problem with newly added channels causing EPG UI corruption + + [Kai Sommerfeld] + * [PVR] Fix CPVREpg::(Add + + [fritsch] + * MusicExtensions: Add dtshd as that extension is used for commercial dtshd audio files + + [fritsch] + * PAPlayer: Don't fallback to DTS too early + + [ronie] + * [Estuary] favourites widget would not scroll to end on 16:10 displays + + [arnova] + * fixed: Resume bookmark would clear on player start failure + + [linknetx] + * [FIX] - Kodi crashes with empty node in advanced settings file + + [peak3d] + * CGUIDialogMediaBrowser: Fix usage of wrong item index + + [Kai Sommerfeld] + * [settings] Fix media source path substitution. + + [fritsch] + * Version: Increase Leia version to 18.3-RC1 + + [kszaq] + * GL: fix HAS_FLOAT_TEXTURE usage + [fritsch] * Splash: Update to 18.2 Leia diff -Nru kodi-18.2+git20190422.1151-final/debian/changelog.tmp.old kodi-18.3+git20190621.1610-final/debian/changelog.tmp.old --- kodi-18.2+git20190422.1151-final/debian/changelog.tmp.old 2019-04-22 09:51:54.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/debian/changelog.tmp.old 2019-06-21 14:10:03.000000000 +0000 @@ -1,5 +1,603 @@ kodi (2:18.0+git20180719.0202-3231481-0dist) dist; urgency=high + [fritsch] + * Splash: Update to 18.2 Leia + + [fritsch] + * Version: Bump to 18.2 + + [peak3d] + * Fix / secure 2 code places + + [Kai Sommerfeld] + * Leia: Changed repo-binary-addons branch to 'Leia'. + + [AkariDN] + * [VideoInfoScanner] don't call GetArtwork for plugin sources + + [Rechi] + * [addons] sync with repo + + [Rechi] + * [darwin][packaging] adjust minimum iOS version to 9.0 after 4020c8649d + + [djp952] + * Initialize timer info tag with first available timer type from client instead of manual one-shot + + [DaveTBlake] + * Fix log statement - remove { and } from format are not parsing + + [peak3d] + * [Android] Add colorMode to android:configChanges to avoid restarts + + [peak3d] + * Fix pixelstore usage + + [Lukas Rusak] + * CEGLImage: don't add modifiers if they are just linear + + [Lukas Rusak] + * CRenderBufferPoolGBM: use DRM_FORMAT_ARGB1555 for AV_PIX_FMT_RGB555 + + [peak3d] + * Find 3:2 pullback when searching for matching resolutions + + [Rechi] + * [cleanup] remove retroplayer leftovers after 3ed099ae0d + + [afl1] + * DVDVideoCodecAmlogic: fix div by 0 in FrameRateTracking + + [afl1] + * AMLCodec: update pts overflow for every frame + + [peak3d] + * [Android] Prevent modeswitch when native_window is invalid + + [kszaq] + * VideoSyncAML: Increase rendering thread prioroty + + [afl1] + * DVDVideoCodecAmlogic: InstanceGuard fix + + [Dmitry_L] + * AMLUtils: Default resolution change to 1080p + + [kszaq] + * AMLUtils: turn 3D off for resolution switch + + [fritsch] + * DVDDemuxFFmpeg: Do not discard stream indexes belonging to program + + [DaveTBlake] + * Fix singles node sort orders - include year, playcount and lastplayed to be consistent with songs (on albums) + + [DaveTBlake] + * Fix loader skipping music files that are in library but located on a server hence have dynpath starting "HTTP" and IsInternetStream returns true. + + [DaveTBlake] + * Import music library data on a separate thread from GUI. This allows cancel button on progress dialog to be clicked. + + [DaveTBlake] + * Export song playback history - playcount, last played and ratings to single xml file + + [Ryan Rector] + * Add available artwork to the video 'Choose art type' dialog + + [Rechi] + * [cleanup] remove ifdef conditions already handled by buildsystem + + [Rechi] + * [cleanup] remove ifdef include guards + + [ronie] + * [python] update WindowXML docs + + [Olaf Hering] + * [tests] use correct storage type for results from XFILE::CFile + + [Olaf Hering] + * [tests] use correct storage type for results from StringUtils + + [Olaf Hering] + * [peripherals] remove inclusion of android specific header + + [jjd-uk] + * Estuary Track Info Fix + + [afl1] + * [Application] - register Stereoscopicmanager for message target - workaround for #13878 for leia + + [ronie] + * [Estouchy] add missing 15th addon shortcut on homescreen + + [James Hutchinson] + * [AMLCodec] dont poll decoder rate when seeking + + [Philipp Kerling] + * [vaapi] Remove unused code + + [Philipp Kerling] + * [vaapi] Always deinterlace when an interlaced frame was encountered once + + [Philipp Kerling] + * [vaapi] Support running progressive frames through the vpp deinterlacer + + [Philipp Kerling] + * [vaapi] Remove filter_flags setting in vpp + + [Philipp Kerling] + * [vaapi] Remove superfluous logic from ffmpeg postproc + + [Philipp Kerling] + * [vaapi] Include name of failed function in error messages + + [Philipp Kerling] + * [vaapi] Remove texture bit guessing + + [kszaq] + * [DVDVideoCodec] Properly reset color_primaries + + [Arne Morten Kvarving] + * oh noes, i used bad words. + + [DaveTBlake] + * Add facility to export artist folders only, no NFO or art. Show full description of where export is going when not picking folder explicitly. Simplify display by hiding non-applicable controls depending on export type. + + [Olaf Hering] + * [cmake] update minimum version of libdrm + + [Olaf Hering] + * restore compatibility with sqlite3 v3.8 + + [Ryan Rector] + * Include user config and available artwork in music "Choose art type" dialog + + [James Hutchinson] + * [AMLCodec] use decoder fps rate to accurately calculate video_rate + + [ronie] + * addon settings - inherit settings level + + [fritsch] + * CThreads: Reacquire Lock after WaitForThreadExit has finished + + [ronie] + * [skins] addon settings - add help text + + [Alwin Esch] + * [cmake] partly revert #15642 to have wayland and GBM working + + [DaveTBlake] + * Export all art types for albums and artists, not just thumb and fanart + + [Philipp Kerling] + * [wayland] Fix raw pointer comparison + + [Rechi] + * [depends] binary-addons: fix libGL.so location + + [Olaf Hering] + * [wayland] fix compilation with C++17 + + [DaveTBlake] + * On refresh of album or artist from info dialog, prompt to ignore NFO file and fetch metadata and art from remote sites + + [Alwin Esch] + * [cmake] fix set of APP_RENDER_SYSTEM on KodiConfig.cmake + + [kszaq] + * GL: Don't use SM_TEXTURE_LIM for GLSL < 1.5 + + [enen92] + * [pydocs] Add warning to ControlList().reset() regarding ListItem destruction + + [Rechi] + * [fix] installing binary addons from zip (and repo) + + [linknetx] + * [PVR] Timers context menu 'Find similar' missing + + [Philipp Kerling] + * [curl] Move libcurl symbols out of namespace + + [DaveTBlake] + * Show artist disambiguation text to help user select which artist they are scraping by when no mbid and scraper has found more than one artist with that name. Add disambiguation, gender and type to Python scraper artist processing. + + [Philipp Kerling] + * [posix] Quit instead of shutdown on signals + + [Matthias Reichl] + * AESinkALSA: fix enumeration of cards without front devices + + [Rechi] + * [windows] remove pragma lib + + [Rechi] + * [cmake] handle D3DX11Effects with PLATFORM_REQUIRED_DEPS + + [Rechi] + * [cmake] require zlib for all platforms + + [Rechi] + * [cmake] zip for android is already handled via PLATFORM_REQUIRED_DEPS + + [Philipp Kerling] + * Reword roadmap item template to make its intent clearer + + [Rechi] + * use angle-bracket include form for FFmpeg headers + + [peak3d] + * Decoderfilter implementation + + [enen92] + * [Docs] Use docs.kodi.tv instead of the codedocs url + + [Maven85] + * [estuary] fix title for non episodes + + [pkerling] + * Delete ProBot triage config + + [enen92] + * [Doxygen] Include github markdown file for code guidelines + + [enen92] + * [GUIControllerWindow] Correctly subscribe to RepositoryUpdated events + + [enen92] + * [PVR] Only trigger CPVRUpdateAddonsJob if the AddonEvent is a PVR client + + [fritsch] + * GLContextEGL: Fix wraparounds on 32 bit system + + [Kai Sommerfeld] + * [PVR] Fix PVR inter component dependencies: changes after code review. + + [Kai Sommerfeld] + * [PVR] Fix PVR inter component dependencies: Rework epg database dependencies. + + [Kai Sommerfeld] + * [PVR] Fix PVR inter component dependencies: epg,epgcontainer must not depend on epgsearchfilter. + + [Kai Sommerfeld] + * [PVR] Fix PVR inter component dependencies: epg must not depend on epgcontainer. + + [Kai Sommerfeld] + * [PVR] Fix PVR inter component dependencies: epgtag must not depend on epg. + + [Kai Sommerfeld] + * [PVR] Fix PVR inter component dependencies: timer must not depend on timers. + + [Kai Sommerfeld] + * [PVR] Fix PVR inter component dependencies: remove CFileItem and CFileList from PVR core. Those are GUI classes using global graphics mutex, which easily can lead to deadlocks when used inside PVR core. + + [Kai Sommerfeld] + * [PVR] Fix PVR inter component dependencies: channelgroup must not depend on channelgroups. + + [Kai Sommerfeld] + * [PVR] Fix PVR inter component dependencies: channel must not depend on channelgroup. + + [Kai Sommerfeld] + * [PVR] Fix PVR inter component dependencies: timers must not depend on recordings. + + [Kai Sommerfeld] + * [PVR] Refactor: Get rid off some CFileItems where CPVRTimerInfoTags are sufficient. + + [Kai Sommerfeld] + * [PVR] Fix PVR inter component dependencies: channels must not depend on timers. + + [Kai Sommerfeld] + * [PVR] PVR inter component dependencies: channel can hold epg member; no expensive lookups needed to obtain epg for a channel. + + [Kai Sommerfeld] + * [PVR] Fix PVR inter component dependencies: epg must not depend on channels. + + [Kai Sommerfeld] + * [PVR] CEpgInfoTag cosmetics. + + [Kai Sommerfeld] + * [PVR] Fix PVR inter component dependencies: epg must not depend on timers. + + [Kai Sommerfeld] + * [PVR] Fix PVR inter component dependencies: epg must not depend on recordings. + + [ronie] + * [estuary] fix reversed episode / tvshow title + + [Kai Sommerfeld] + * [PVR] Guide window: On first open, trigger immediate fetching of real data, not delayed. + + [Arne Morten Kvarving] + * fixed: obtaining movie name for stacks + + [peak3d] + * [Android] Yet another refreshrate switch enhancement + + [Philipp Kerling] + * [posix] Handle signals by setting atomic flag instead of pop-up thread + + [pkerling] + * Enable ProBot triage bot + + [pkerling] + * Add ProBot triage bot configuration + + [peak3d] + * [VideoPlayer] Ensure queue is not in intermediate state when flushing + + [peak3d] + * [Android] Don't signal END_OF_STREAM if dropping packets + + [Kai Sommerfeld] + * [PVR] Fix 'any channel' timer rules children not displayed. + + [Memphiz] + * GUIWindowManager - wait for the closing animation to finish when closing a window sync only when GUI is rendered + + [JimmyS83] + * Fixed error "Unexpected [standby_pc_on_tv_standby] setting value message" when using "Ignore" for standby_pc_on_tv_standby. https://github.com/xbmc/xbmc/issues/15698 + + [fritsch] + * FFMPEG: Bump to 4.0.3-Leia-18.2 + + [ronie] + * [pyton] update docs for artwork functions + + [Kai Sommerfeld] + * [PVR] Speedup first open of Guide window. + + [DaveTBlake] + * Player.GetItem add "mediapath" and "dynpath" properties + + [DaveTBlake] + * GetArtist - always fetch scraped art URLs from dataset. Ensure discography is imported and exported for artist. + + [Kai Sommerfeld] + * [PVR] Fix all datetime gui labels to return empty string if datetime is invalid. + + [Kai Sommerfeld] + * [PVR] Guide window: Fix wrong information shown for gap tags. + + [phunkyfish] + * Don't include timer in active or recording lists if timer state is PVR_TIMER_STATE_ERROR + + [phunkyfish] + * Don't display enabled toggle in timer settings dialog if timer state is PVR_TIMER_STATE_ERROR + + [phunkyfish] + * Don't display Activate/Deactivate in timer context menu if timer state is PVR_TIMER_STATE_ERROR + + [kszaq] + * [AddonVideoCodec] Initialize color_primaries to AVCOL_PRI_UNSPECIFIED + + [ronie] + * [Estouchy] fix missing weather temps + + [Kai Sommerfeld] + * [PVR] Speedup close of Guide window. + + [peak3d] + * Minor log changes + + [peak3d] + * [Android] implement MediaSession::onMediaButtonEvent + + [Michael Brehm] + * Use audio stream to determine start time of MPEG-TS programs with no video streams + + [kszaq] + * [GLES] Check for UNPACK_ROW_LENGTH support on renderer instantiation, not on every LoadPlane call + + [peak3d] + * [Android] Prevent HDMI_AUDIO_PLUG intent on TV + + [Rechi] + * [cmake] microhttpd: only link with libraries + + [Rechi] + * [depends] microhttpd: remove build & install hacks + + [peak3d] + * [Android] generate keypress if mediasession action arrives and kodi has focus + + [Memphiz] + * [ios/cmake] - ensure that CURRENT_ARCH is set by cmake when calling Codesing.command + + [DaveTBlake] + * Stop excluding artist with name that matches the current localised string for "Various artists". + + [Memphiz] + * [ios/windowing] - cache internal touch screen resolution because when going from external to internal screen - display settings want to know these before actually switching to internal. As we rely on eaglbounds we can't tell the internal resolution before switching - so we have to give back the cached results. - fixes touch screen issues due to wrong resolution for older ios9 32bit devices like ipad2 - while still maintaining the fix for external screens + + [ronie] + * [music] format album rating + + [Craig Andrews] + * In Repository, don't set content encoding to gzip explicitly + + [Craig Andrews] + * In ScraperUrl, don't set content encoding to gzip explicitly + + [Craig Andrews] + * [curl] Use the response header to determine if content is encoded + + [peak3d] + * [Android] Fix monoscopic/2D viewrect calcuation + + [Memphiz] + * Revert "[ios/WinSystem] - instead of using the eaglbounds for determining the size of the internal screen - simply use the scerensize from UIScreen and exchange width with height (because the screen is installed 90° rotated). This fixes traversing back from external to internal screen which resulted in getting the eaglbounds from the external screen BUILDDATE CMakeLists.txt LICENSE.md LICENSES README.md VERSION addons appveyor.yml cmake debian docs lib media privacy-policy.txt project system tools userdata version.txt xbmc xbmc-xrandr.c screenscale from the internal (and lead to non-working touch input)" + + [Memphiz] + * [ios/signing] - added old ldid for 32bit for fixing fake signing for 32 bit builds + + [Rechi] + * [cleanup] remove include guards + + [Craig Andrews] + * [curl] Accept all supported content encodings by default + + [Memphiz] + * [GraphicsContext] - add a setting to adjust refreshrate/resolution only on playback start + + [peak3d] + * [Android] Don't flip GLES if window was destroyed + + [Kai Sommerfeld] + * [PVR] Fix crash on channel switch when no pvr client is enabled. + + [linknetx] + * [PVR] - Recording edit context menu still visible when not supported by backend + + [Arne Morten Kvarving] + * fixed: put add-on instance creation/destruction in a critical section + + [Arne Morten Kvarving] + * fixed: do not try to list empty directory in directory provider + + [Arne Morten Kvarving] + * various uninited variable usage + + [peak3d] + * [Android] send BUFFER_EOF to MediaCdec if EOF was detected + + [DaveTBlake] + * Fix album artist name and Musicbrainz id tag matching fallback processing when ALBUMARTISTS tag not provided + + [peak3d] + * [Android] SignalEndOfStream / start with I-Frame for h264 / h256 + + [fritsch] + * AESinkAudioTrack: Trace flush on deinitialize + + [Rechi] + * [fix] guard windows specific include + + [peak3d] + * [Android] Check if ActiveAE is available if HEAD_PLUGGED intent arrives + + [Kai Sommerfeld] + * [PVR][guiinfo] Fix/add support for ListItem.ParentalRating, VideoPlayer.Premiered, ListItem.Rating, VideoPlayer.Rating for PVR items. + + [arnova] + * fixed: We should always update stream details from player (fixes #15584) + + [peak3d] + * Fix refclock calculation + + [DaveTBlake] + * Fix TCP buffer parsing to find JSON statements to correctly ignore escaped quotes, and brackets when inside quote pairs. + + [Tyler Szabo] + * [database] Verify date parsing when querying videos by year + + [Ryan Rector] + * [videodb]fix: Return empty InfoTag when looking up non-existent musicvideo + + [Attila Jakosa] + * [lang][skin.estouchy] updated language files from Transifex + + [Attila Jakosa] + * [lang][skin.estuary] updated language files from Transifex + + [Hugh N. Greenberg] + * Fixes a crash when a file's embedded art is invalid + + [Rechi] + * [cleanup] remove yajl leftovers after 15017d865b + + [Rechi] + * silence dangling else warnings + + [Ryan Rector] + * Set NFO thumb without aspect as poster + + [Rikard Falkeborn] + * [audioengine] Const correct Sinks + + [Rikard Falkeborn] + * [audioengine] Const correct ActiveAE + + [Rikard Falkeborn] + * [audioengine] Const correct Utils + + [DaveTBlake] + * Stop playing current file when playlist player has stopped. Playlistplayer sends a GUI_MSG_PLAYLISTPLAYER_STOPPED message when aborting playback when next from last item in list, or repeat one and song is invalid. This ensures that the player stops too. + + [peak3d] + * Allow speedadjust for half frame situations (e.g. 3:2 pullback) + + [peak3d] + * [Android] Post instead SendMessage to stop playing on SCREEN_OFF + + [Kai Sommerfeld] + * [PVR] Fix LISTITEM_DURATION for timers. + + [DaveTBlake] + * Fix delay of playback on switching song in party mode regression. + + [peak3d] + * [Android] Implement MediaDRM provisioning + + [peak3d] + * [Android] change intent management in java::main + + [Joost van den Broek] + * TestUtil: Added ValidatePath Test + + [Philipp Kerling] + * [docs] Update style guidelines + + [Michael Brehm] + * GetStreamProperties() is only called when bHandlesDemuxing is true + + [Memphiz] + * [JSON]Add Player.SetViewMode and Player.GetViewMode methods + + [Ryan Rector] + * [skins] prefer poster over thumb to match design + + [kszaq] + * [GLES] OverlayRendererGL: add support for BGRA extensions for GLES + + [ronie] + * [skins] improvement & cosmetics + + [Martijn Kaijser] + * bump to 18.2rc1 + + [peak3d] + * [Windowing] Prefix output name to all RESOLUTIONS, includeing RES_DESKTOP + + [DaVukovic] + * [docs/README.Fedora] fixes and updates + + [Joost van den Broek] + * CUtil::ValidatePath fix stripping double (back)slash chars + + [Michael Brehm] + * Document implict call to CloseXXXStream() before OpenXXXStream() + + [Peter Vicman] + * wake on access: fix crash on startup When Kodi starts there is no GUI yet. log file: http://ix.io/1Af1 + + [Kai Sommerfeld] + * [estuary] Fix visual glitch when PVR info dialog activated from PVR channels OSD. + + [ronie] + * [python] fix usage of line-breaks in ok dialog + + [wsnipex] + * [curl] enable HTTP2 support + + [wsnipex] + * [depends] add http2 support to curl via nghttp2 + + [Rainer Hochecker] + * VideoPlayer: set demuxer speed other than pause and normal + + [Rechi] * [addons] sync with repo Binary files /tmp/tmpT_tRne/jPIbC9iaes/kodi-18.2+git20190422.1151-final/media/splash.jpg and /tmp/tmpT_tRne/5qNbkVtCae/kodi-18.3+git20190621.1610-final/media/splash.jpg differ diff -Nru kodi-18.2+git20190422.1151-final/system/keymaps/joystick.xml kodi-18.3+git20190621.1610-final/system/keymaps/joystick.xml --- kodi-18.2+git20190422.1151-final/system/keymaps/joystick.xml 2019-01-28 18:34:07.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/system/keymaps/joystick.xml 2019-06-21 14:09:24.000000000 +0000 @@ -229,7 +229,7 @@ Pause Stop - ActivateWindow(AddonSettings) + Addon.Default.OpenSettings(xbmc.player.musicviz) ActivateWindow(VisualisationPresetList) Info ActivateWindow(MusicOSD) diff -Nru kodi-18.2+git20190422.1151-final/system/keymaps/mouse.xml kodi-18.3+git20190621.1610-final/system/keymaps/mouse.xml --- kodi-18.2+git20190422.1151-final/system/keymaps/mouse.xml 2018-05-01 00:00:13.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/system/keymaps/mouse.xml 2019-06-21 14:09:24.000000000 +0000 @@ -34,6 +34,7 @@ middleclick doubleclick contextmenu + Menu wheeldown wheelup mousedrag @@ -58,4 +59,9 @@ Info + + + back + + diff -Nru kodi-18.2+git20190422.1151-final/system/keymaps/touchscreen.xml kodi-18.3+git20190621.1610-final/system/keymaps/touchscreen.xml --- kodi-18.2+git20190422.1151-final/system/keymaps/touchscreen.xml 2018-05-01 00:00:13.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/system/keymaps/touchscreen.xml 2019-06-21 14:09:24.000000000 +0000 @@ -30,6 +30,7 @@ SwipeLeft Back SwipeRight + Menu SwipeUp SwipeDown SwitchPlayer diff -Nru kodi-18.2+git20190422.1151-final/system/shaders/GL/1.2/gl_convolution-4x4.glsl kodi-18.3+git20190621.1610-final/system/shaders/GL/1.2/gl_convolution-4x4.glsl --- kodi-18.2+git20190422.1151-final/system/shaders/GL/1.2/gl_convolution-4x4.glsl 2018-05-01 00:00:13.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/system/shaders/GL/1.2/gl_convolution-4x4.glsl 2019-06-21 14:09:24.000000000 +0000 @@ -35,7 +35,7 @@ half4 weight(float pos) { -#if (HAS_FLOAT_TEXTURE) +#if defined(HAS_FLOAT_TEXTURE) return texture1D(kernelTex, pos); #else return texture1D(kernelTex, pos) * 2.0 - 1.0; diff -Nru kodi-18.2+git20190422.1151-final/system/shaders/GL/1.2/gl_convolution-6x6.glsl kodi-18.3+git20190621.1610-final/system/shaders/GL/1.2/gl_convolution-6x6.glsl --- kodi-18.2+git20190422.1151-final/system/shaders/GL/1.2/gl_convolution-6x6.glsl 2018-05-01 00:00:13.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/system/shaders/GL/1.2/gl_convolution-6x6.glsl 2019-06-21 14:09:24.000000000 +0000 @@ -35,7 +35,7 @@ half3 weight(float pos) { -#if (HAS_FLOAT_TEXTURE) +#if defined(HAS_FLOAT_TEXTURE) return texture1D(kernelTex, pos).rgb; #else return texture1D(kernelTex, pos).rgb * 2.0 - 1.0; diff -Nru kodi-18.2+git20190422.1151-final/system/shaders/GL/1.5/gl_convolution-4x4.glsl kodi-18.3+git20190621.1610-final/system/shaders/GL/1.5/gl_convolution-4x4.glsl --- kodi-18.2+git20190422.1151-final/system/shaders/GL/1.5/gl_convolution-4x4.glsl 2018-05-01 00:00:13.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/system/shaders/GL/1.5/gl_convolution-4x4.glsl 2019-06-21 14:09:24.000000000 +0000 @@ -18,7 +18,7 @@ half4 weight(float pos) { -#if (HAS_FLOAT_TEXTURE) +#if defined(HAS_FLOAT_TEXTURE) return texture(kernelTex, pos); #else return texture(kernelTex, pos) * 2.0 - 1.0; diff -Nru kodi-18.2+git20190422.1151-final/system/shaders/GL/1.5/gl_convolution-6x6.glsl kodi-18.3+git20190621.1610-final/system/shaders/GL/1.5/gl_convolution-6x6.glsl --- kodi-18.2+git20190422.1151-final/system/shaders/GL/1.5/gl_convolution-6x6.glsl 2018-05-01 00:00:13.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/system/shaders/GL/1.5/gl_convolution-6x6.glsl 2019-06-21 14:09:24.000000000 +0000 @@ -18,7 +18,7 @@ half3 weight(float pos) { -#if (HAS_FLOAT_TEXTURE) +#if defined(HAS_FLOAT_TEXTURE) return texture(kernelTex, pos).rgb; #else return texture(kernelTex, pos).rgb * 2.0 - 1.0; diff -Nru kodi-18.2+git20190422.1151-final/VERSION kodi-18.3+git20190621.1610-final/VERSION --- kodi-18.2+git20190422.1151-final/VERSION 2019-04-22 09:51:54.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/VERSION 2019-06-21 14:10:03.000000000 +0000 @@ -1 +1 @@ -f264356 +89472b7 diff -Nru kodi-18.2+git20190422.1151-final/version.txt kodi-18.3+git20190621.1610-final/version.txt --- kodi-18.2+git20190422.1151-final/version.txt 2019-04-22 09:51:06.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/version.txt 2019-06-21 14:09:24.000000000 +0000 @@ -1,12 +1,12 @@ APP_NAME Kodi COMPANY_NAME XBMC Foundation -COPYRIGHT_YEARS 2005-2018 +COPYRIGHT_YEARS 2005-2019 WEBSITE http://kodi.tv VERSION_MAJOR 18 -VERSION_MINOR 2 +VERSION_MINOR 3 VERSION_TAG -VERSION_CODE 18.2.0 -ADDON_API 18.2.0 +VERSION_CODE 18.3.0 +ADDON_API 18.3.0 APP_PACKAGE org.xbmc.kodi PACKAGE_IDENTITY XBMCFoundation.Kodi PACKAGE_PUBLISHER C62BD90A-CDD8-477F-96C3-B25992247B97 diff -Nru kodi-18.2+git20190422.1151-final/xbmc/Application.cpp kodi-18.3+git20190621.1610-final/xbmc/Application.cpp --- kodi-18.2+git20190422.1151-final/xbmc/Application.cpp 2019-04-22 09:51:06.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/Application.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -3085,6 +3085,10 @@ bool playCountUpdate = false; float percent = 0.0f; + // Make sure we don't reset existing bookmark etc. on eg. player start failure + if (bookmark.timeInSeconds == 0.0f) + return; + if (m_stackHelper.GetRegisteredStack(fileItem) != nullptr && m_stackHelper.GetRegisteredStackTotalTimeMs(fileItem) > 0) { // regular stack case: we have to save the bookmark on the stack diff -Nru kodi-18.2+git20190422.1151-final/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp kodi-18.3+git20190621.1610-final/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp --- kodi-18.2+git20190422.1151-final/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp 2019-04-22 09:51:06.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -2191,7 +2191,7 @@ { // copy the samples into the viz input buffer CSampleBuffer *viz = m_vizBuffersInput->GetFreeBuffer(); - int samples = out->pkt->nb_samples; + int samples = std::min(out->pkt->nb_samples, viz->pkt->max_nb_samples); int bytes = samples * out->pkt->config.channels / out->pkt->planes * out->pkt->bytes_per_sample; for(int i= 0; i < out->pkt->planes; i++) { diff -Nru kodi-18.2+git20190422.1151-final/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp kodi-18.3+git20190621.1610-final/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp --- kodi-18.2+git20190422.1151-final/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp 2018-12-03 16:49:55.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -1601,9 +1601,6 @@ { if (!strnicmp(path, "shout://", 8)) // don't stat shoutcast return -1; - if (!strnicmp(path, "http://", 7) - || !strnicmp(path, "https://", 8)) // don't stat http - return -1; if (!strnicmp(path, "mms://", 6)) // don't stat mms return -1; @@ -1647,9 +1644,6 @@ { if (!strnicmp(path, "shout://", 8)) // don't stat shoutcast return -1; - if (!strnicmp(path, "http://", 7) - || !strnicmp(path, "https://", 8)) // don't stat http - return -1; if (!strnicmp(path, "mms://", 6)) // don't stat mms return -1; diff -Nru kodi-18.2+git20190422.1151-final/xbmc/cores/paplayer/VideoPlayerCodec.cpp kodi-18.3+git20190621.1610-final/xbmc/cores/paplayer/VideoPlayerCodec.cpp --- kodi-18.2+git20190422.1151-final/xbmc/cores/paplayer/VideoPlayerCodec.cpp 2018-08-26 13:40:15.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/cores/paplayer/VideoPlayerCodec.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -510,7 +510,7 @@ break; case AV_CODEC_ID_DTS: - format.m_streamInfo.m_type = CAEStreamInfo::STREAM_TYPE_DTSHD_CORE; + format.m_streamInfo.m_type = CAEStreamInfo::STREAM_TYPE_DTSHD; format.m_streamInfo.m_sampleRate = samplerate; break; @@ -520,6 +520,12 @@ bool supports = CServiceBroker::GetActiveAE()->SupportsRaw(format); + if (!supports && codecId == AV_CODEC_ID_DTS) + { + format.m_streamInfo.m_type = CAEStreamInfo::STREAM_TYPE_DTSHD_CORE; + supports = CServiceBroker::GetActiveAE()->SupportsRaw(format); + } + if (supports) return format.m_streamInfo.m_type; else diff -Nru kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp --- kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp 2019-04-22 09:51:06.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -10,6 +10,7 @@ #include "ServiceBroker.h" #include "cores/VideoPlayer/DVDCodecs/DVDFactoryCodec.h" +#include "cores/VideoPlayer/Process/gbm/VideoBufferDRMPRIME.h" #include "settings/Settings.h" #include "settings/SettingsComponent.h" #include "settings/lib/Setting.h" @@ -24,137 +25,6 @@ using namespace KODI::WINDOWING::GBM; -//------------------------------------------------------------------------------ -// Video Buffers -//------------------------------------------------------------------------------ - -CVideoBufferDRMPRIME::CVideoBufferDRMPRIME(IVideoBufferPool& pool, int id) - : CVideoBuffer(id) -{ - m_pFrame = av_frame_alloc(); -} - -CVideoBufferDRMPRIME::~CVideoBufferDRMPRIME() -{ - Unref(); - av_frame_free(&m_pFrame); -} - -void CVideoBufferDRMPRIME::SetRef(AVFrame* frame) -{ - av_frame_move_ref(m_pFrame, frame); -} - -void CVideoBufferDRMPRIME::Unref() -{ - av_frame_unref(m_pFrame); -} - -int CVideoBufferDRMPRIME::GetColorEncoding() const -{ - switch (m_pFrame->colorspace) - { - case AVCOL_SPC_BT2020_CL: - case AVCOL_SPC_BT2020_NCL: - return DRM_COLOR_YCBCR_BT2020; - case AVCOL_SPC_SMPTE170M: - case AVCOL_SPC_BT470BG: - case AVCOL_SPC_FCC: - return DRM_COLOR_YCBCR_BT601; - case AVCOL_SPC_BT709: - return DRM_COLOR_YCBCR_BT709; - case AVCOL_SPC_RESERVED: - case AVCOL_SPC_UNSPECIFIED: - default: - if (m_pFrame->width > 1024 || m_pFrame->height >= 600) - return DRM_COLOR_YCBCR_BT709; - else - return DRM_COLOR_YCBCR_BT601; - } -} - -int CVideoBufferDRMPRIME::GetColorRange() const -{ - switch (m_pFrame->color_range) - { - case AVCOL_RANGE_JPEG: - return DRM_COLOR_YCBCR_FULL_RANGE; - case AVCOL_RANGE_MPEG: - default: - return DRM_COLOR_YCBCR_LIMITED_RANGE; - } -} - -//------------------------------------------------------------------------------ - -class CVideoBufferPoolDRMPRIME - : public IVideoBufferPool -{ -public: - ~CVideoBufferPoolDRMPRIME(); - void Return(int id) override; - CVideoBuffer* Get() override; - -protected: - CCriticalSection m_critSection; - std::vector m_all; - std::deque m_used; - std::deque m_free; -}; - -CVideoBufferPoolDRMPRIME::~CVideoBufferPoolDRMPRIME() -{ - for (auto buf : m_all) - delete buf; -} - -CVideoBuffer* CVideoBufferPoolDRMPRIME::Get() -{ - CSingleLock lock(m_critSection); - - CVideoBufferDRMPRIME* buf = nullptr; - if (!m_free.empty()) - { - int idx = m_free.front(); - m_free.pop_front(); - m_used.push_back(idx); - buf = m_all[idx]; - } - else - { - int id = m_all.size(); - buf = new CVideoBufferDRMPRIME(*this, id); - m_all.push_back(buf); - m_used.push_back(id); - } - - buf->Acquire(GetPtr()); - return buf; -} - -void CVideoBufferPoolDRMPRIME::Return(int id) -{ - CSingleLock lock(m_critSection); - - m_all[id]->Unref(); - auto it = m_used.begin(); - while (it != m_used.end()) - { - if (*it == id) - { - m_used.erase(it); - break; - } - else - ++it; - } - m_free.push_back(id); -} - -//------------------------------------------------------------------------------ -// main class -//------------------------------------------------------------------------------ - CDVDVideoCodecDRMPRIME::CDVDVideoCodecDRMPRIME(CProcessInfo& processInfo) : CDVDVideoCodec(processInfo) { @@ -220,11 +90,17 @@ return nullptr; } -static enum AVPixelFormat GetFormat(struct AVCodecContext* avctx, const enum AVPixelFormat* fmt) +enum AVPixelFormat CDVDVideoCodecDRMPRIME::GetFormat(struct AVCodecContext* avctx, const enum AVPixelFormat* fmt) { for (int n = 0; fmt[n] != AV_PIX_FMT_NONE; n++) + { if (fmt[n] == AV_PIX_FMT_DRM_PRIME) + { + CDVDVideoCodecDRMPRIME* ctx = static_cast(avctx->opaque); + ctx->UpdateProcessInfo(avctx, fmt[n]); return fmt[n]; + } + } return AV_PIX_FMT_NONE; } @@ -259,6 +135,7 @@ } m_pCodecContext->pix_fmt = AV_PIX_FMT_DRM_PRIME; + m_pCodecContext->opaque = static_cast(this); m_pCodecContext->get_format = GetFormat; m_pCodecContext->codec_tag = hints.codec_tag; m_pCodecContext->coded_width = hints.width; @@ -281,27 +158,25 @@ return false; } - if (m_pCodecContext->pix_fmt != AV_PIX_FMT_DRM_PRIME) - { - CLog::Log(LOGNOTICE, "CDVDVideoCodecDRMPRIME::%s - unexpected pix fmt %s", __FUNCTION__, av_get_pix_fmt_name(m_pCodecContext->pix_fmt)); - avcodec_free_context(&m_pCodecContext); - return false; - } - - const char* pixFmtName = av_get_pix_fmt_name(m_pCodecContext->pix_fmt); - m_processInfo.SetVideoPixelFormat(pixFmtName ? pixFmtName : ""); - m_processInfo.SetVideoDimensions(hints.width, hints.height); + UpdateProcessInfo(m_pCodecContext, m_pCodecContext->pix_fmt); m_processInfo.SetVideoDeintMethod("none"); m_processInfo.SetVideoDAR(hints.aspect); - if (pCodec->name) - m_name = std::string("ff-") + pCodec->name; + return true; +} + +void CDVDVideoCodecDRMPRIME::UpdateProcessInfo(struct AVCodecContext* avctx, const enum AVPixelFormat pix_fmt) +{ + const char* pixFmtName = av_get_pix_fmt_name(pix_fmt); + m_processInfo.SetVideoPixelFormat(pixFmtName ? pixFmtName : ""); + m_processInfo.SetVideoDimensions(avctx->coded_width, avctx->coded_height); + + if (avctx->codec && avctx->codec->name) + m_name = std::string("ff-") + avctx->codec->name; else m_name = "ffmpeg"; - m_processInfo.SetVideoDecoderName(m_name, true); - - return true; + m_processInfo.SetVideoDecoderName(m_name, pix_fmt == AV_PIX_FMT_DRM_PRIME); } bool CDVDVideoCodecDRMPRIME::AddData(const DemuxPacket& packet) @@ -412,9 +287,18 @@ SetPictureParams(pVideoPicture); - CVideoBufferDRMPRIME* buffer = dynamic_cast(m_videoBufferPool->Get()); - buffer->SetRef(m_pFrame); - pVideoPicture->videoBuffer = buffer; + if (m_pFrame->format == AV_PIX_FMT_DRM_PRIME) + { + CVideoBufferDRMPRIME* buffer = dynamic_cast(m_videoBufferPool->Get()); + buffer->SetRef(m_pFrame); + pVideoPicture->videoBuffer = buffer; + } + + if (!pVideoPicture->videoBuffer) + { + CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::{} - videoBuffer:nullptr format:{}", __FUNCTION__, av_get_pix_fmt_name(static_cast(m_pFrame->format))); + return VC_ERROR; + } return VC_PICTURE; } diff -Nru kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h --- kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h 2019-04-22 09:51:06.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h 2019-06-21 14:09:24.000000000 +0000 @@ -13,45 +13,6 @@ #include "cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodec.h" #include "cores/VideoPlayer/Process/VideoBuffer.h" -extern "C" { -#include -#include -} - -// Color enums is copied from linux include/drm/drm_color_mgmt.h (strangely not part of uapi) -enum drm_color_encoding { - DRM_COLOR_YCBCR_BT601, - DRM_COLOR_YCBCR_BT709, - DRM_COLOR_YCBCR_BT2020, -}; -enum drm_color_range { - DRM_COLOR_YCBCR_LIMITED_RANGE, - DRM_COLOR_YCBCR_FULL_RANGE, -}; - -class CVideoBufferPoolDRMPRIME; - -class CVideoBufferDRMPRIME - : public CVideoBuffer -{ -public: - CVideoBufferDRMPRIME(IVideoBufferPool& pool, int id); - ~CVideoBufferDRMPRIME(); - void SetRef(AVFrame* frame); - void Unref(); - - uint32_t m_fb_id = 0; - uint32_t m_handles[AV_DRM_MAX_PLANES] = {0}; - - AVDRMFrameDescriptor* GetDescriptor() const { return reinterpret_cast(m_pFrame->data[0]); } - uint32_t GetWidth() const { return m_pFrame->width; } - uint32_t GetHeight() const { return m_pFrame->height; } - int GetColorEncoding() const; - int GetColorRange() const; -protected: - AVFrame* m_pFrame = nullptr; -}; - class CDVDVideoCodecDRMPRIME : public CDVDVideoCodec { @@ -73,10 +34,12 @@ protected: void Drain(); void SetPictureParams(VideoPicture* pVideoPicture); + void UpdateProcessInfo(struct AVCodecContext* avctx, const enum AVPixelFormat fmt); + static enum AVPixelFormat GetFormat(struct AVCodecContext* avctx, const enum AVPixelFormat* fmt); std::string m_name; int m_codecControlFlags = 0; AVCodecContext* m_pCodecContext = nullptr; AVFrame* m_pFrame = nullptr; - std::shared_ptr m_videoBufferPool; + std::shared_ptr m_videoBufferPool; }; diff -Nru kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp --- kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp 2019-02-11 10:31:27.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -608,6 +608,8 @@ strName = "vp8"; else if (stream->codec == AV_CODEC_ID_VP9) strName = "vp9"; + else if (stream->codec == AV_CODEC_ID_HEVC) + strName = "hevc"; } return strName; } diff -Nru kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/Process/gbm/CMakeLists.txt kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/Process/gbm/CMakeLists.txt --- kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/Process/gbm/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/Process/gbm/CMakeLists.txt 2019-06-21 14:09:24.000000000 +0000 @@ -0,0 +1,7 @@ +set(SOURCES ProcessInfoGBM.cpp + VideoBufferDRMPRIME.cpp) + +set(HEADERS ProcessInfoGBM.h + VideoBufferDRMPRIME.h) + +core_add_library(processGBM) diff -Nru kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/Process/gbm/ProcessInfoGBM.cpp kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/Process/gbm/ProcessInfoGBM.cpp --- kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/Process/gbm/ProcessInfoGBM.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/Process/gbm/ProcessInfoGBM.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2019 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 "ProcessInfoGBM.h" + +using namespace VIDEOPLAYER; + +CProcessInfo* CProcessInfoGBM::Create() +{ + return new CProcessInfoGBM(); +} + +void CProcessInfoGBM::Register() +{ + CProcessInfo::RegisterProcessControl("gbm", CProcessInfoGBM::Create); +} + +CProcessInfoGBM::CProcessInfoGBM() +{ +} + +EINTERLACEMETHOD CProcessInfoGBM::GetFallbackDeintMethod() +{ +#if defined(__arm__) + return EINTERLACEMETHOD::VS_INTERLACEMETHOD_DEINTERLACE_HALF; +#else + return CProcessInfo::GetFallbackDeintMethod(); +#endif +} diff -Nru kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/Process/gbm/ProcessInfoGBM.h kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/Process/gbm/ProcessInfoGBM.h --- kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/Process/gbm/ProcessInfoGBM.h 1970-01-01 00:00:00.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/Process/gbm/ProcessInfoGBM.h 2019-06-21 14:09:24.000000000 +0000 @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2019 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 "cores/IPlayer.h" +#include "cores/VideoPlayer/Process/ProcessInfo.h" + +namespace VIDEOPLAYER +{ + +class CProcessInfoGBM : public CProcessInfo +{ +public: + CProcessInfoGBM(); + static CProcessInfo* Create(); + static void Register(); + EINTERLACEMETHOD GetFallbackDeintMethod() override; +}; + +} // namespace VIDEOPLAYER diff -Nru kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/Process/gbm/VideoBufferDRMPRIME.cpp kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/Process/gbm/VideoBufferDRMPRIME.cpp --- kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/Process/gbm/VideoBufferDRMPRIME.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/Process/gbm/VideoBufferDRMPRIME.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2017-2018 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 "VideoBufferDRMPRIME.h" + +#include "threads/SingleLock.h" + +extern "C" +{ +#include +#include +} + +IVideoBufferDRMPRIME::IVideoBufferDRMPRIME(int id) + : CVideoBuffer(id) +{ +} + +CVideoBufferDRMPRIME::CVideoBufferDRMPRIME(IVideoBufferPool& pool, int id) + : IVideoBufferDRMPRIME(id) +{ + m_pFrame = av_frame_alloc(); +} + +CVideoBufferDRMPRIME::~CVideoBufferDRMPRIME() +{ + Unref(); + av_frame_free(&m_pFrame); +} + +void CVideoBufferDRMPRIME::SetRef(AVFrame* frame) +{ + av_frame_move_ref(m_pFrame, frame); +} + +void CVideoBufferDRMPRIME::Unref() +{ + av_frame_unref(m_pFrame); +} + +int CVideoBufferDRMPRIME::GetColorEncoding() const +{ + switch (m_pFrame->colorspace) + { + case AVCOL_SPC_BT2020_CL: + case AVCOL_SPC_BT2020_NCL: + return DRM_COLOR_YCBCR_BT2020; + case AVCOL_SPC_SMPTE170M: + case AVCOL_SPC_BT470BG: + case AVCOL_SPC_FCC: + return DRM_COLOR_YCBCR_BT601; + case AVCOL_SPC_BT709: + return DRM_COLOR_YCBCR_BT709; + case AVCOL_SPC_RESERVED: + case AVCOL_SPC_UNSPECIFIED: + default: + if (m_pFrame->width > 1024 || m_pFrame->height >= 600) + return DRM_COLOR_YCBCR_BT709; + else + return DRM_COLOR_YCBCR_BT601; + } +} + +int CVideoBufferDRMPRIME::GetColorRange() const +{ + switch (m_pFrame->color_range) + { + case AVCOL_RANGE_JPEG: + return DRM_COLOR_YCBCR_FULL_RANGE; + case AVCOL_RANGE_MPEG: + default: + return DRM_COLOR_YCBCR_LIMITED_RANGE; + } +} + +bool CVideoBufferDRMPRIME::IsValid() const +{ + AVDRMFrameDescriptor* descriptor = GetDescriptor(); + return descriptor && descriptor->nb_layers; +} + +CVideoBufferPoolDRMPRIME::~CVideoBufferPoolDRMPRIME() +{ + for (auto buf : m_all) + delete buf; +} + +CVideoBuffer* CVideoBufferPoolDRMPRIME::Get() +{ + CSingleLock lock(m_critSection); + + CVideoBufferDRMPRIME* buf = nullptr; + if (!m_free.empty()) + { + int idx = m_free.front(); + m_free.pop_front(); + m_used.push_back(idx); + buf = m_all[idx]; + } + else + { + int id = m_all.size(); + buf = new CVideoBufferDRMPRIME(*this, id); + m_all.push_back(buf); + m_used.push_back(id); + } + + buf->Acquire(GetPtr()); + return buf; +} + +void CVideoBufferPoolDRMPRIME::Return(int id) +{ + CSingleLock lock(m_critSection); + + m_all[id]->Unref(); + auto it = m_used.begin(); + while (it != m_used.end()) + { + if (*it == id) + { + m_used.erase(it); + break; + } + else + ++it; + } + m_free.push_back(id); +} diff -Nru kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/Process/gbm/VideoBufferDRMPRIME.h kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/Process/gbm/VideoBufferDRMPRIME.h --- kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/Process/gbm/VideoBufferDRMPRIME.h 1970-01-01 00:00:00.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/Process/gbm/VideoBufferDRMPRIME.h 2019-06-21 14:09:24.000000000 +0000 @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2017-2018 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 "cores/VideoPlayer/Process/VideoBuffer.h" + +extern "C" +{ +#include +#include +} + +// Color enums is copied from linux include/drm/drm_color_mgmt.h (strangely not part of uapi) +enum drm_color_encoding +{ + DRM_COLOR_YCBCR_BT601, + DRM_COLOR_YCBCR_BT709, + DRM_COLOR_YCBCR_BT2020, +}; +enum drm_color_range +{ + DRM_COLOR_YCBCR_LIMITED_RANGE, + DRM_COLOR_YCBCR_FULL_RANGE, +}; + +class IVideoBufferDRMPRIME : public CVideoBuffer +{ +public: + IVideoBufferDRMPRIME() = delete; + virtual ~IVideoBufferDRMPRIME() = default; + + virtual AVDRMFrameDescriptor* GetDescriptor() const = 0; + virtual uint32_t GetWidth() const = 0; + virtual uint32_t GetHeight() const = 0; + virtual int GetColorEncoding() const + { + return DRM_COLOR_YCBCR_BT709; + }; + virtual int GetColorRange() const + { + return DRM_COLOR_YCBCR_LIMITED_RANGE; + }; + + virtual bool IsValid() const + { + return true; + }; + virtual bool Map() + { + return true; + }; + virtual void Unmap() {}; + + uint32_t m_fb_id = 0; + uint32_t m_handles[AV_DRM_MAX_PLANES] = {}; + +protected: + explicit IVideoBufferDRMPRIME(int id); +}; + +class CVideoBufferDRMPRIME : public IVideoBufferDRMPRIME +{ +public: + CVideoBufferDRMPRIME(IVideoBufferPool& pool, int id); + ~CVideoBufferDRMPRIME(); + void SetRef(AVFrame* frame); + void Unref(); + + AVDRMFrameDescriptor* GetDescriptor() const override + { + return reinterpret_cast(m_pFrame->data[0]); + } + uint32_t GetWidth() const override + { + return m_pFrame->width; + } + uint32_t GetHeight() const override + { + return m_pFrame->height; + } + int GetColorEncoding() const override; + int GetColorRange() const override; + + bool IsValid() const override; + +protected: + AVFrame* m_pFrame = nullptr; +}; + +class CVideoBufferPoolDRMPRIME : public IVideoBufferPool +{ +public: + ~CVideoBufferPoolDRMPRIME(); + void Return(int id) override; + CVideoBuffer* Get() override; + +protected: + CCriticalSection m_critSection; + std::vector m_all; + std::deque m_used; + std::deque m_free; +}; diff -Nru kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DRMPRIMEEGL.cpp kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DRMPRIMEEGL.cpp --- kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DRMPRIMEEGL.cpp 2018-10-23 16:19:50.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DRMPRIMEEGL.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -15,11 +15,14 @@ m_eglImage.reset(new CEGLImage(eglDisplay)); } -bool CDRMPRIMETexture::Map(CVideoBufferDRMPRIME *buffer) +bool CDRMPRIMETexture::Map(IVideoBufferDRMPRIME* buffer) { if (m_primebuffer) return true; + if (!buffer->Map()) + return false; + m_texWidth = buffer->GetWidth(); m_texHeight = buffer->GetHeight(); @@ -74,6 +77,8 @@ glDeleteTextures(1, &m_texture); + m_primebuffer->Unmap(); + m_primebuffer->Release(); m_primebuffer = nullptr; } diff -Nru kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DRMPRIMEEGL.h kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DRMPRIMEEGL.h --- kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DRMPRIMEEGL.h 2018-10-23 16:19:50.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DRMPRIMEEGL.h 2019-06-21 14:09:24.000000000 +0000 @@ -8,15 +8,16 @@ #pragma once -#include "cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h" +#include "cores/VideoPlayer/Process/gbm/VideoBufferDRMPRIME.h" #include "utils/EGLImage.h" +#include "utils/Geometry.h" #include "system_gl.h" class CDRMPRIMETexture { public: - bool Map(CVideoBufferDRMPRIME *buffer); + bool Map(IVideoBufferDRMPRIME* buffer); void Unmap(); void Init(EGLDisplay eglDisplay); @@ -24,7 +25,7 @@ CSizeInt GetTextureSize() { return { m_texWidth, m_texHeight }; } protected: - CVideoBufferDRMPRIME *m_primebuffer{nullptr}; + IVideoBufferDRMPRIME* m_primebuffer{nullptr}; std::unique_ptr m_eglImage; const GLenum m_textureTarget{GL_TEXTURE_EXTERNAL_OES}; diff -Nru kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIME.cpp kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIME.cpp --- kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIME.cpp 2018-11-21 19:38:54.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIME.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -8,20 +8,21 @@ #include "RendererDRMPRIME.h" -#include "cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h" +#include "ServiceBroker.h" +#include "cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodec.h" +#include "cores/VideoPlayer/Process/gbm/VideoBufferDRMPRIME.h" #include "cores/VideoPlayer/VideoRenderers/HwDecRender/VideoLayerBridgeDRMPRIME.h" #include "cores/VideoPlayer/VideoRenderers/RenderCapture.h" #include "cores/VideoPlayer/VideoRenderers/RenderFactory.h" #include "cores/VideoPlayer/VideoRenderers/RenderFlags.h" -#include "settings/lib/Setting.h" #include "settings/DisplaySettings.h" #include "settings/Settings.h" #include "settings/SettingsComponent.h" +#include "settings/lib/Setting.h" #include "utils/log.h" +#include "windowing/GraphicContext.h" #include "windowing/gbm/DRMAtomic.h" #include "windowing/gbm/WinSystemGbm.h" -#include "windowing/GraphicContext.h" -#include "ServiceBroker.h" using namespace KODI::WINDOWING::GBM; @@ -34,7 +35,7 @@ CBaseRenderer* CRendererDRMPRIME::Create(CVideoBuffer* buffer) { - if (buffer && dynamic_cast(buffer) && + if (buffer && dynamic_cast(buffer) && CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(SETTING_VIDEOPLAYER_USEPRIMERENDERER) == 0) { CWinSystemGbm* winSystem = dynamic_cast(CServiceBroker::GetWinSystem()); @@ -132,7 +133,7 @@ if (m_iLastRenderBuffer == index) return true; - CVideoBufferDRMPRIME* buffer = dynamic_cast(m_buffers[index].videoBuffer); + IVideoBufferDRMPRIME* buffer = dynamic_cast(m_buffers[index].videoBuffer); if (buffer && buffer->m_fb_id) return true; @@ -162,12 +163,8 @@ return; } - CVideoBufferDRMPRIME* buffer = dynamic_cast(m_buffers[index].videoBuffer); - if (!buffer) - return; - - AVDRMFrameDescriptor* descriptor = buffer->GetDescriptor(); - if (!descriptor || !descriptor->nb_layers) + IVideoBufferDRMPRIME* buffer = dynamic_cast(m_buffers[index].videoBuffer); + if (!buffer || !buffer->IsValid()) return; if (!m_videoLayerBridge) diff -Nru kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.cpp kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.cpp --- kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.cpp 2019-04-22 09:48:17.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -10,10 +10,12 @@ #include "cores/VideoPlayer/VideoRenderers/RenderFactory.h" #include "ServiceBroker.h" +#include "utils/EGLFence.h" #include "utils/log.h" #include "windowing/gbm/WinSystemGbmGLESContext.h" using namespace KODI::WINDOWING::GBM; +using namespace KODI::UTILS::EGL; CRendererDRMPRIMEGLES::~CRendererDRMPRIMEGLES() { @@ -23,7 +25,7 @@ CBaseRenderer* CRendererDRMPRIMEGLES::Create(CVideoBuffer* buffer) { - if (buffer && dynamic_cast(buffer)) + if (buffer && dynamic_cast(buffer)) return new CRendererDRMPRIMEGLES(); return nullptr; @@ -43,15 +45,27 @@ for (auto &texture : m_DRMPRIMETextures) texture.Init(winSystem->GetEGLDisplay()); + for (auto& fence : m_fences) + { + fence.reset(new CEGLFence(winSystem->GetEGLDisplay())); + } + return CLinuxRendererGLES::Configure(picture, fps, orientation); } void CRendererDRMPRIMEGLES::ReleaseBuffer(int index) { + m_fences[index]->DestroyFence(); + m_DRMPRIMETextures[index].Unmap(); CLinuxRendererGLES::ReleaseBuffer(index); } +bool CRendererDRMPRIMEGLES::NeedBuffer(int index) +{ + return !m_fences[index]->IsSignaled(); +} + bool CRendererDRMPRIMEGLES::CreateTexture(int index) { CPictureBuffer &buf = m_buffers[index]; @@ -85,9 +99,9 @@ { CPictureBuffer &buf = m_buffers[index]; - CVideoBufferDRMPRIME *buffer = dynamic_cast(buf.videoBuffer); + IVideoBufferDRMPRIME* buffer = dynamic_cast(buf.videoBuffer); - if (!buffer) + if (!buffer || !buffer->IsValid()) { CLog::Log(LOGNOTICE, "CRendererDRMPRIMEGLES::%s - no buffer", __FUNCTION__); return false; @@ -139,28 +153,44 @@ { float x, y, z; float u1, v1; - } vertex[4]; + }; + + std::array vertex; GLint vertLoc = renderSystem->GUIShaderGetPos(); GLint loc = renderSystem->GUIShaderGetCoord0(); - for (unsigned int i = 0; i < 4; i++) - { - // Setup vertex position values - vertex[i].x = m_rotatedDestCoords[i].x; - vertex[i].y = m_rotatedDestCoords[i].y; - vertex[i].z = 0.0f; - } - - // Setup texture coordinates - vertex[0].u1 = vertex[3].u1 = plane.rect.x1; - vertex[0].v1 = vertex[1].v1 = plane.rect.y1; - vertex[1].u1 = vertex[2].u1 = plane.rect.x2; - vertex[2].v1 = vertex[3].v1 = plane.rect.y2; + // top left + vertex[0].x = m_rotatedDestCoords[0].x; + vertex[0].y = m_rotatedDestCoords[0].y; + vertex[0].z = 0.0f; + vertex[0].u1 = plane.rect.x1; + vertex[0].v1 = plane.rect.y1; + + // top right + vertex[1].x = m_rotatedDestCoords[1].x; + vertex[1].y = m_rotatedDestCoords[1].y; + vertex[1].z = 0.0f; + vertex[1].u1 = plane.rect.x2; + vertex[1].v1 = plane.rect.y1; + + // bottom right + vertex[2].x = m_rotatedDestCoords[2].x; + vertex[2].y = m_rotatedDestCoords[2].y; + vertex[2].z = 0.0f; + vertex[2].u1 = plane.rect.x2; + vertex[2].v1 = plane.rect.y2; + + // bottom left + vertex[3].x = m_rotatedDestCoords[3].x; + vertex[3].y = m_rotatedDestCoords[3].y; + vertex[3].z = 0.0f; + vertex[3].u1 = plane.rect.x1; + vertex[3].v1 = plane.rect.y2;; glGenBuffers(1, &vertexVBO); glBindBuffer(GL_ARRAY_BUFFER, vertexVBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(PackedVertex)*4, &vertex[0], GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, sizeof(PackedVertex) * vertex.size(), vertex.data(), GL_STATIC_DRAW); glVertexAttribPointer(vertLoc, 3, GL_FLOAT, 0, sizeof(PackedVertex), reinterpret_cast(offsetof(PackedVertex, x))); glVertexAttribPointer(loc, 2, GL_FLOAT, 0, sizeof(PackedVertex), reinterpret_cast(offsetof(PackedVertex, u1))); @@ -170,7 +200,7 @@ glGenBuffers(1, &indexVBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBO); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte)*4, idx, GL_STATIC_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte) * 4, idx, GL_STATIC_DRAW); glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, 0); @@ -188,3 +218,34 @@ return true; } + +void CRendererDRMPRIMEGLES::AfterRenderHook(int index) +{ + m_fences[index]->CreateFence(); +} + +bool CRendererDRMPRIMEGLES::Supports(ERENDERFEATURE feature) +{ + switch (feature) + { + case RENDERFEATURE_STRETCH: + case RENDERFEATURE_ZOOM: + case RENDERFEATURE_VERTICAL_SHIFT: + case RENDERFEATURE_PIXEL_RATIO: + case RENDERFEATURE_ROTATION: + return true; + default: + return false; + } +} + +bool CRendererDRMPRIMEGLES::Supports(ESCALINGMETHOD method) +{ + switch (method) + { + case VS_SCALINGMETHOD_LINEAR: + return true; + default: + return false; + } +} diff -Nru kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.h kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.h --- kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.h 2019-04-22 09:48:17.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.h 2019-06-21 14:09:24.000000000 +0000 @@ -11,6 +11,20 @@ #include "cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.h" #include "DRMPRIMEEGL.h" +#include +#include + +namespace KODI +{ +namespace UTILS +{ +namespace EGL +{ +class CEGLFence; +} +} +} + class CRendererDRMPRIMEGLES : public CLinuxRendererGLES { public: @@ -24,14 +38,20 @@ // CLinuxRendererGLES overrides bool Configure(const VideoPicture &picture, float fps, unsigned int orientation) override; void ReleaseBuffer(int index) override; + bool NeedBuffer(int index) override; + + bool Supports(ERENDERFEATURE feature) override; + bool Supports(ESCALINGMETHOD method) override; protected: // CLinuxRendererGLES overrides bool LoadShadersHook() override; bool RenderHook(int index) override; + void AfterRenderHook(int index) override; bool UploadTexture(int index) override; void DeleteTexture(int index) override; bool CreateTexture(int index) override; + std::array, NUM_BUFFERS> m_fences; CDRMPRIMETexture m_DRMPRIMETextures[NUM_BUFFERS]; }; diff -Nru kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/VideoLayerBridgeDRMPRIME.cpp kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/VideoLayerBridgeDRMPRIME.cpp --- kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/VideoLayerBridgeDRMPRIME.cpp 2018-12-03 16:49:55.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/VideoLayerBridgeDRMPRIME.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -8,7 +8,7 @@ #include "VideoLayerBridgeDRMPRIME.h" -#include "cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h" +#include "cores/VideoPlayer/Process/gbm/VideoBufferDRMPRIME.h" #include "utils/log.h" #include "windowing/gbm/DRMUtils.h" @@ -33,7 +33,7 @@ m_DRM->AddProperty(plane, "CRTC_ID", 0); } -void CVideoLayerBridgeDRMPRIME::Acquire(CVideoBufferDRMPRIME* buffer) +void CVideoLayerBridgeDRMPRIME::Acquire(IVideoBufferDRMPRIME* buffer) { // release the buffer that is no longer presented on screen Release(m_prev_buffer); @@ -46,7 +46,7 @@ m_buffer->Acquire(); } -void CVideoLayerBridgeDRMPRIME::Release(CVideoBufferDRMPRIME* buffer) +void CVideoLayerBridgeDRMPRIME::Release(IVideoBufferDRMPRIME* buffer) { if (!buffer) return; @@ -55,11 +55,14 @@ buffer->Release(); } -bool CVideoLayerBridgeDRMPRIME::Map(CVideoBufferDRMPRIME* buffer) +bool CVideoLayerBridgeDRMPRIME::Map(IVideoBufferDRMPRIME* buffer) { if (buffer->m_fb_id) return true; + if (!buffer->Map()) + return false; + AVDRMFrameDescriptor* descriptor = buffer->GetDescriptor(); uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0}, flags = 0; uint64_t modifier[4] = {0}; @@ -108,7 +111,7 @@ return true; } -void CVideoLayerBridgeDRMPRIME::Unmap(CVideoBufferDRMPRIME* buffer) +void CVideoLayerBridgeDRMPRIME::Unmap(IVideoBufferDRMPRIME* buffer) { if (buffer->m_fb_id) { @@ -125,9 +128,11 @@ buffer->m_handles[i] = 0; } } + + buffer->Unmap(); } -void CVideoLayerBridgeDRMPRIME::Configure(CVideoBufferDRMPRIME* buffer) +void CVideoLayerBridgeDRMPRIME::Configure(IVideoBufferDRMPRIME* buffer) { struct plane* plane = m_DRM->GetVideoPlane(); if (m_DRM->SupportsProperty(plane, "COLOR_ENCODING") && @@ -138,7 +143,7 @@ } } -void CVideoLayerBridgeDRMPRIME::SetVideoPlane(CVideoBufferDRMPRIME* buffer, const CRect& destRect) +void CVideoLayerBridgeDRMPRIME::SetVideoPlane(IVideoBufferDRMPRIME* buffer, const CRect& destRect) { if (!Map(buffer)) { diff -Nru kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/VideoLayerBridgeDRMPRIME.h kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/VideoLayerBridgeDRMPRIME.h --- kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/VideoLayerBridgeDRMPRIME.h 2018-10-23 16:19:50.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/VideoLayerBridgeDRMPRIME.h 2019-06-21 14:09:24.000000000 +0000 @@ -24,7 +24,7 @@ } } -class CVideoBufferDRMPRIME; +class IVideoBufferDRMPRIME; class CVideoLayerBridgeDRMPRIME : public KODI::WINDOWING::GBM::CVideoLayerBridge @@ -34,19 +34,19 @@ ~CVideoLayerBridgeDRMPRIME(); void Disable() override; - virtual void Configure(CVideoBufferDRMPRIME* buffer); - virtual void SetVideoPlane(CVideoBufferDRMPRIME* buffer, const CRect& destRect); + virtual void Configure(IVideoBufferDRMPRIME* buffer); + virtual void SetVideoPlane(IVideoBufferDRMPRIME* buffer, const CRect& destRect); virtual void UpdateVideoPlane(); protected: std::shared_ptr m_DRM; private: - void Acquire(CVideoBufferDRMPRIME* buffer); - void Release(CVideoBufferDRMPRIME* buffer); - bool Map(CVideoBufferDRMPRIME* buffer); - void Unmap(CVideoBufferDRMPRIME* buffer); + void Acquire(IVideoBufferDRMPRIME* buffer); + void Release(IVideoBufferDRMPRIME* buffer); + bool Map(IVideoBufferDRMPRIME* buffer); + void Unmap(IVideoBufferDRMPRIME* buffer); - CVideoBufferDRMPRIME* m_buffer = nullptr; - CVideoBufferDRMPRIME* m_prev_buffer = nullptr; + IVideoBufferDRMPRIME* m_buffer = nullptr; + IVideoBufferDRMPRIME* m_prev_buffer = nullptr; }; diff -Nru kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/VideoFilterShaderGL.cpp kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/VideoFilterShaderGL.cpp --- kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/VideoFilterShaderGL.cpp 2018-07-31 18:47:39.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/VideoFilterShaderGL.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -84,9 +84,7 @@ } if (m_floattex) - defines = "#define HAS_FLOAT_TEXTURE 1\n"; - else - defines = "#define HAS_FLOAT_TEXTURE 0\n"; + defines = "#define HAS_FLOAT_TEXTURE\n"; //don't compile in stretch support when it's not needed if (stretch) diff -Nru kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/VideoFilterShaderGLES.cpp kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/VideoFilterShaderGLES.cpp --- kodi-18.2+git20190422.1151-final/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/VideoFilterShaderGLES.cpp 2018-07-31 18:47:39.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/VideoFilterShaderGLES.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -99,12 +99,11 @@ if (m_floattex) { m_internalformat = GL_RGBA16F_EXT; - defines = "#define HAS_FLOAT_TEXTURE 1\n"; + defines = "#define HAS_FLOAT_TEXTURE\n"; } else { m_internalformat = GL_RGBA; - defines = "#define HAS_FLOAT_TEXTURE 0\n"; } CLog::Log(LOGDEBUG, "GL: ConvolutionFilterShader: using %s defines:\n%s", shadername.c_str(), defines.c_str()); diff -Nru kodi-18.2+git20190422.1151-final/xbmc/dialogs/GUIDialogMediaSource.cpp kodi-18.3+git20190621.1610-final/xbmc/dialogs/GUIDialogMediaSource.cpp --- kodi-18.2+git20190422.1151-final/xbmc/dialogs/GUIDialogMediaSource.cpp 2019-04-22 09:51:07.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/dialogs/GUIDialogMediaSource.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -229,15 +229,16 @@ void CGUIDialogMediaSource::OnPathBrowse(int item) { - if (item < 0 || item > m_paths->Size()) return; + if (item < 0 || item >= m_paths->Size()) return; // Browse is called. Open the filebrowser dialog. // Ignore current path is best at this stage?? - std::string path; + std::string path = m_paths->Get(item)->GetPath(); bool allowNetworkShares(m_type != "programs"); VECSOURCES extraShares; - if (m_name != CUtil::GetTitleFromPath(m_paths->Get(item)->GetPath())) + if (m_name != CUtil::GetTitleFromPath(path)) m_bNameChanged = true; + path.clear(); std::string strDevices = g_localizeStrings.Get(33040); //"% Devices" @@ -550,7 +551,7 @@ CGUIMessage message(GUI_MSG_ITEM_SELECTED, GetID(), CONTROL_PATH); OnMessage(message); int value = message.GetParam1(); - if (value < 0 || value > m_paths->Size()) return 0; + if (value < 0 || value >= m_paths->Size()) return 0; return value; } diff -Nru kodi-18.2+git20190422.1151-final/xbmc/filesystem/CurlFile.cpp kodi-18.3+git20190621.1610-final/xbmc/filesystem/CurlFile.cpp --- kodi-18.2+git20190422.1151-final/xbmc/filesystem/CurlFile.cpp 2019-04-22 09:51:07.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/filesystem/CurlFile.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -1011,8 +1011,8 @@ std::string error; if (m_httpresponse >= 400 && CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->CanLogComponent(LOGCURL)) { - error.resize(256); - ReadString(&error[0], 255); + error.resize(4096); + ReadString(&error[0], 4095); } CLog::Log(LOGERROR, "CCurlFile::Open failed with code %li for %s:\n%s", m_httpresponse, redactPath.c_str(), error.c_str()); diff -Nru kodi-18.2+git20190422.1151-final/xbmc/filesystem/DAVDirectory.cpp kodi-18.3+git20190621.1610-final/xbmc/filesystem/DAVDirectory.cpp --- kodi-18.2+git20190422.1151-final/xbmc/filesystem/DAVDirectory.cpp 2018-10-03 07:06:27.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/filesystem/DAVDirectory.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -47,7 +47,7 @@ else if (CDAVCommon::ValueWithoutNamespace(pResponseChild, "propstat")) { - if (CDAVCommon::GetStatusTag(pResponseChild->ToElement()) == "HTTP/1.1 200 OK") + if (CDAVCommon::GetStatusTag(pResponseChild->ToElement()).find("200 OK") != std::string::npos) { /* Iterate propstat children elements */ for (pPropstatChild = pResponseChild->FirstChild(); pPropstatChild != 0; pPropstatChild = pPropstatChild->NextSibling()) diff -Nru kodi-18.2+git20190422.1151-final/xbmc/filesystem/DAVFile.cpp kodi-18.3+git20190621.1610-final/xbmc/filesystem/DAVFile.cpp --- kodi-18.2+git20190422.1151-final/xbmc/filesystem/DAVFile.cpp 2018-07-31 18:47:39.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/filesystem/DAVFile.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -74,7 +74,7 @@ { std::string sRetCode = CDAVCommon::GetStatusTag(pChild->ToElement()); CRegExp rxCode; - rxCode.RegComp("HTTP/1\\.1\\s(\\d+)\\s.*"); + rxCode.RegComp("HTTP/.+\\s(\\d+)\\s.*"); if (rxCode.RegFind(sRetCode) >= 0) { if (rxCode.GetSubCount()) diff -Nru kodi-18.2+git20190422.1151-final/xbmc/filesystem/PVRDirectory.cpp kodi-18.3+git20190621.1610-final/xbmc/filesystem/PVRDirectory.cpp --- kodi-18.2+git20190422.1151-final/xbmc/filesystem/PVRDirectory.cpp 2018-07-31 18:47:39.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/filesystem/PVRDirectory.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -6,19 +6,9 @@ * See LICENSES/README.md for more information. */ -#include "FileItem.h" -#include "guilib/LocalizeStrings.h" #include "PVRDirectory.h" -#include "ServiceBroker.h" -#include "URL.h" -#include "utils/log.h" -#include "utils/StringUtils.h" -#include "utils/URIUtils.h" - -#include "pvr/PVRManager.h" -#include "pvr/channels/PVRChannelGroupsContainer.h" -#include "pvr/recordings/PVRRecordings.h" -#include "pvr/timers/PVRTimers.h" + +#include "pvr/PVRGUIDirectory.h" using namespace XFILE; using namespace PVR; @@ -29,115 +19,38 @@ bool CPVRDirectory::Exists(const CURL& url) { - if (!CServiceBroker::GetPVRManager().IsStarted()) - return false; - - return (url.IsProtocol("pvr") && StringUtils::StartsWith(url.GetFileName(), "recordings")); + const CPVRGUIDirectory dir(url); + return dir.Exists(); } bool CPVRDirectory::GetDirectory(const CURL& url, CFileItemList &items) { - std::string base(url.Get()); - URIUtils::RemoveSlashAtEnd(base); - - std::string fileName = url.GetFileName(); - URIUtils::RemoveSlashAtEnd(fileName); - CLog::Log(LOGDEBUG, "CPVRDirectory::GetDirectory(%s)", base.c_str()); - items.SetCacheToDisc(CFileItemList::CACHE_NEVER); - - if (fileName == "") - { - if (CServiceBroker::GetPVRManager().IsStarted()) - { - CFileItemPtr item; - - item.reset(new CFileItem(base + "channels/", true)); - item->SetLabel(g_localizeStrings.Get(19019)); - item->SetLabelPreformatted(true); - items.Add(item); - - item.reset(new CFileItem(base + "recordings/active/", true)); - item->SetLabel(g_localizeStrings.Get(19017)); // TV Recordings - item->SetLabelPreformatted(true); - items.Add(item); - - item.reset(new CFileItem(base + "recordings/deleted/", true)); - item->SetLabel(g_localizeStrings.Get(19108)); // Deleted TV Recordings - item->SetLabelPreformatted(true); - items.Add(item); - - // Sort by name only. Labels are preformatted. - items.AddSortMethod(SortByLabel, 551 /* Name */, LABEL_MASKS("%L", "", "%L", "")); - } - return true; - } - else if (StringUtils::StartsWith(fileName, "recordings")) - { - if (CServiceBroker::GetPVRManager().IsStarted()) - { - const std::string pathToUrl(url.Get()); - return CServiceBroker::GetPVRManager().Recordings()->GetDirectory(pathToUrl, items); - } - return true; - } - else if (StringUtils::StartsWith(fileName, "channels")) - { - if (CServiceBroker::GetPVRManager().ChannelGroups() && CServiceBroker::GetPVRManager().ChannelGroups()->Loaded()) - { - const std::string pathToUrl(url.Get()); - return CServiceBroker::GetPVRManager().ChannelGroups()->GetDirectory(pathToUrl, items); - } - return true; - } - else if (StringUtils::StartsWith(fileName, "timers")) - { - if (CServiceBroker::GetPVRManager().IsStarted()) - { - const std::string pathToUrl(url.Get()); - return CServiceBroker::GetPVRManager().Timers()->GetDirectory(pathToUrl, items); - } - return true; - } - - return false; + const CPVRGUIDirectory dir(url); + return dir.GetDirectory(items); } bool CPVRDirectory::SupportsWriteFileOperations(const std::string& strPath) { - CURL url(strPath); - std::string filename = url.GetFileName(); - - return URIUtils::IsPVRRecording(filename); -} - -bool CPVRDirectory::IsLiveTV(const std::string& strPath) -{ - CURL url(strPath); - std::string filename = url.GetFileName(); - - return URIUtils::IsLiveTV(filename); + const CPVRGUIDirectory dir(strPath); + return dir.SupportsWriteFileOperations(); } bool CPVRDirectory::HasTVRecordings() { - return CServiceBroker::GetPVRManager().IsStarted() ? - CServiceBroker::GetPVRManager().Recordings()->GetNumTVRecordings() > 0 : false; + return CPVRGUIDirectory::HasTVRecordings(); } bool CPVRDirectory::HasDeletedTVRecordings() { - return CServiceBroker::GetPVRManager().IsStarted() ? - CServiceBroker::GetPVRManager().Recordings()->HasDeletedTVRecordings() : false; + return CPVRGUIDirectory::HasDeletedTVRecordings(); } bool CPVRDirectory::HasRadioRecordings() { - return CServiceBroker::GetPVRManager().IsStarted() ? - CServiceBroker::GetPVRManager().Recordings()->GetNumRadioRecordings() > 0 : false; + return CPVRGUIDirectory::HasRadioRecordings(); } bool CPVRDirectory::HasDeletedRadioRecordings() { - return CServiceBroker::GetPVRManager().IsStarted() ? - CServiceBroker::GetPVRManager().Recordings()->HasDeletedRadioRecordings() : false; + return CPVRGUIDirectory::HasDeletedRadioRecordings(); } diff -Nru kodi-18.2+git20190422.1151-final/xbmc/filesystem/PVRDirectory.h kodi-18.3+git20190621.1610-final/xbmc/filesystem/PVRDirectory.h --- kodi-18.2+git20190422.1151-final/xbmc/filesystem/PVRDirectory.h 2018-07-31 18:47:39.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/filesystem/PVRDirectory.h 2019-06-21 14:09:24.000000000 +0000 @@ -10,8 +10,6 @@ #include "IDirectory.h" -class CPVRSession; - namespace XFILE { class CPVRDirectory @@ -27,7 +25,7 @@ bool Exists(const CURL& url) override; static bool SupportsWriteFileOperations(const std::string& strPath); - static bool IsLiveTV(const std::string& strPath); + static bool HasTVRecordings(); static bool HasDeletedTVRecordings(); static bool HasRadioRecordings(); diff -Nru kodi-18.2+git20190422.1151-final/xbmc/interfaces/json-rpc/PVROperations.cpp kodi-18.3+git20190621.1610-final/xbmc/interfaces/json-rpc/PVROperations.cpp --- kodi-18.2+git20190422.1151-final/xbmc/interfaces/json-rpc/PVROperations.cpp 2019-04-22 09:51:07.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/interfaces/json-rpc/PVROperations.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -113,8 +113,11 @@ return InvalidParams; CFileItemList channels; - if (channelGroup->GetMembers(channels) < 0) - return InvalidParams; + const std::vector groupMembers = channelGroup->GetMembers(CPVRChannelGroup::Include::ONLY_VISIBLE); + for (const auto& groupMember : groupMembers) + { + channels.Add(std::make_shared(groupMember.channel)); + } HandleFileItemList("channelid", false, "channels", channels, parameterObject, result, true); @@ -280,7 +283,12 @@ else { CFileItemList channels; - channelGroup->GetMembers(channels); + const std::vector groupMembers = channelGroup->GetMembers(CPVRChannelGroup::Include::ONLY_VISIBLE); + for (const auto& groupMember : groupMembers) + { + channels.Add(std::make_shared(groupMember.channel)); + } + object["channels"] = CVariant(CVariant::VariantTypeArray); HandleFileItemList("channelid", false, "channels", channels, parameterObject["channels"], object, false); @@ -298,7 +306,11 @@ return FailedToExecute; CFileItemList timerList; - timers->GetAll(timerList); + const std::vector> tags = timers->GetAll(); + for (const auto& timer : tags) + { + timerList.Add(std::make_shared(timer)); + } HandleFileItemList("timerid", false, "timers", timerList, parameterObject, result, true); @@ -413,7 +425,11 @@ return FailedToExecute; CFileItemList recordingsList; - recordings->GetAll(recordingsList); + const std::vector> recs = recordings->GetAll(); + for (const auto& recording : recs) + { + recordingsList.Add(std::make_shared(recording)); + } HandleFileItemList("recordingid", true, "recordings", recordingsList, parameterObject, result, true); diff -Nru kodi-18.2+git20190422.1151-final/xbmc/interfaces/legacy/CallbackHandler.cpp kodi-18.3+git20190621.1610-final/xbmc/interfaces/legacy/CallbackHandler.cpp --- kodi-18.2+git20190422.1151-final/xbmc/interfaces/legacy/CallbackHandler.cpp 2018-07-31 18:47:39.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/interfaces/legacy/CallbackHandler.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -49,16 +49,13 @@ CallbackQueue::iterator iter = g_callQueue.begin(); while (iter != g_callQueue.end()) { - AddonClass::Ref cur(*iter); + if ((*iter)->handler.get() == this) // then this message is because of me { - if (cur->handler.get() == this) // then this message is because of me - { - g_callQueue.erase(iter); - iter = g_callQueue.begin(); - } - else - ++iter; + g_callQueue.erase(iter); + iter = g_callQueue.begin(); } + else + ++iter; } } diff -Nru kodi-18.2+git20190422.1151-final/xbmc/music/dialogs/GUIDialogMusicInfo.cpp kodi-18.3+git20190621.1610-final/xbmc/music/dialogs/GUIDialogMusicInfo.cpp --- kodi-18.2+git20190422.1151-final/xbmc/music/dialogs/GUIDialogMusicInfo.cpp 2019-01-13 07:51:36.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/music/dialogs/GUIDialogMusicInfo.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -755,22 +755,6 @@ item->SetLabel(g_localizeStrings.Get(13512)); items.Add(item); } - else if (m_item->HasArt("thumb")) - { - // For missing art of that type add the thumb (when it exists and not a fallback) - CGUIListItem::ArtMap::const_iterator i = primeArt.find("thumb"); - if (i != primeArt.end()) - { - CFileItemPtr item(new CFileItem("thumb://Thumb", false)); - item->SetArt("thumb", m_item->GetArt("thumb")); - if (m_bArtistInfo) - item->SetIconImage("DefaultArtistCover.png"); - else - item->SetIconImage("DefaultAlbumCover.png"); - item->SetLabel(g_localizeStrings.Get(21371)); - items.Add(item); - } - } // Grab the thumbnails of this art type scraped from the web std::vector remotethumbs; diff -Nru kodi-18.2+git20190422.1151-final/xbmc/music/dialogs/GUIDialogVisualisationPresetList.cpp kodi-18.3+git20190621.1610-final/xbmc/music/dialogs/GUIDialogVisualisationPresetList.cpp --- kodi-18.2+git20190422.1151-final/xbmc/music/dialogs/GUIDialogVisualisationPresetList.cpp 2018-07-31 18:47:39.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/music/dialogs/GUIDialogVisualisationPresetList.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -29,7 +29,7 @@ switch (message.GetMessage()) { case GUI_MSG_VISUALISATION_UNLOADING: - SetVisualisation(nullptr); + ClearVisualisation(); break; } return CGUIDialogSelect::OnMessage(message); @@ -41,11 +41,23 @@ m_viz->SetPreset(idx); } +void CGUIDialogVisualisationPresetList::ClearVisualisation() +{ + m_viz = nullptr; + Reset(); +} + void CGUIDialogVisualisationPresetList::SetVisualisation(CGUIVisualisationControl* vis) { m_viz = vis; Reset(); - if (m_viz) + if (!m_viz) + { // No viz, but show something if this dialog activated + SetHeading(CVariant{ 10122 }); + CFileItem item(g_localizeStrings.Get(13389)); + Add(item); + } + else { SetUseDetails(false); SetMultiSelection(false); @@ -61,6 +73,12 @@ } SetSelected(m_viz->GetActivePreset()); } + else + { // Viz does not have any presets + // "There are no presets available for this visualisation" + CFileItem item(g_localizeStrings.Get(13389)); + Add(item); + } } } @@ -68,13 +86,12 @@ { CGUIMessage msg(GUI_MSG_GET_VISUALISATION, 0, 0); CServiceBroker::GetGUI()->GetWindowManager().SendMessage(msg); - if (msg.GetPointer()) - SetVisualisation(static_cast(msg.GetPointer())); + SetVisualisation(static_cast(msg.GetPointer())); CGUIDialogSelect::OnInitWindow(); } void CGUIDialogVisualisationPresetList::OnDeinitWindow(int nextWindowID) { - SetVisualisation(nullptr); + ClearVisualisation(); CGUIDialogSelect::OnDeinitWindow(nextWindowID); } diff -Nru kodi-18.2+git20190422.1151-final/xbmc/music/dialogs/GUIDialogVisualisationPresetList.h kodi-18.3+git20190621.1610-final/xbmc/music/dialogs/GUIDialogVisualisationPresetList.h --- kodi-18.2+git20190422.1151-final/xbmc/music/dialogs/GUIDialogVisualisationPresetList.h 2018-07-31 18:47:39.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/music/dialogs/GUIDialogVisualisationPresetList.h 2019-06-21 14:09:24.000000000 +0000 @@ -26,6 +26,7 @@ void OnSelect(int idx) override; private: + void ClearVisualisation(); void SetVisualisation(CGUIVisualisationControl *addon); CGUIVisualisationControl* m_viz = nullptr; }; diff -Nru kodi-18.2+git20190422.1151-final/xbmc/music/infoscanner/MusicInfoScanner.cpp kodi-18.3+git20190621.1610-final/xbmc/music/infoscanner/MusicInfoScanner.cpp --- kodi-18.2+git20190422.1151-final/xbmc/music/infoscanner/MusicInfoScanner.cpp 2019-04-22 09:51:07.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/music/infoscanner/MusicInfoScanner.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -1659,7 +1659,7 @@ (StringUtils::StartsWith(artURL, "image://") && CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_MUSICLIBRARY_PREFERONLINEALBUMART))) { - std::string thumb = CScraperUrl::GetThumbURL(album.thumbURL.GetFirstThumb()); + std::string thumb = CScraperUrl::GetThumbURL(album.thumbURL.GetFirstThumb("thumb")); if (!thumb.empty()) { CTextureCache::GetInstance().BackgroundCacheImage(thumb); @@ -1998,16 +1998,13 @@ } } } - // No local art, use first from scraped lists. + // No local art, use first of that type from scraped lists. // Fanart has own list. Art type is encoded into the scraper XML held in - // thumbURL as optional "aspect=" field. Type "thumb" or "" returns URLs for - // all types of art including those without aspect. Those URL without aspect - // are also returned for all other type values. + // thumbURL as optional "aspect=" field. Those URL without aspect are also + // returned for all other type values. if (strArt.empty()) { - if (type == "thumb") - strArt = CScraperUrl::GetThumbURL(artist.thumbURL.GetFirstThumb()); - else if (type == "fanart") + if (type == "fanart") strArt = artist.fanart.GetImageURL(); else strArt = CScraperUrl::GetThumbURL(artist.thumbURL.GetFirstThumb(type)); @@ -2091,19 +2088,15 @@ } } } - // No local art, use first from scraped list. - // Art type is encoded into the scraper XML held in thumbURL as optional - // "aspect=" field. Type "thumb" or "" returns URLs for all types of art - // including those without aspect. Those URL without aspect are also - // returned for all other type values. + // No local art, use first of that type from scraped list. + // Art type is encoded into the scraper XML held in thumbURL as + // optional "aspect=" field. Those URL without aspect are also returned for + // all other type values. // Historically albums do not have fanart, so there is no special handling // of scraper results for it (unlike artist). if (strArt.empty()) { - if (type == "thumb") - strArt = CScraperUrl::GetThumbURL(album.thumbURL.GetFirstThumb()); - else - strArt = CScraperUrl::GetThumbURL(album.thumbURL.GetFirstThumb(type)); + strArt = CScraperUrl::GetThumbURL(album.thumbURL.GetFirstThumb(type)); } // Add art to album and library if (!strArt.empty()) diff -Nru kodi-18.2+git20190422.1151-final/xbmc/platform/linux/input/LibInputKeyboard.cpp kodi-18.3+git20190621.1610-final/xbmc/platform/linux/input/LibInputKeyboard.cpp --- kodi-18.2+git20190422.1151-final/xbmc/platform/linux/input/LibInputKeyboard.cpp 2018-10-23 16:19:51.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/platform/linux/input/LibInputKeyboard.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -137,7 +137,7 @@ // Media keys { XKB_KEY_XF86Eject, XBMCK_EJECT }, - // XBMCK_STOP clashes with XBMCK_MEDIA_STOP + { XKB_KEY_Cancel, XBMCK_STOP }, { XKB_KEY_XF86AudioRecord, XBMCK_RECORD }, // XBMCK_REWIND clashes with XBMCK_MEDIA_REWIND { XKB_KEY_XF86Phone, XBMCK_PHONE }, diff -Nru kodi-18.2+git20190422.1151-final/xbmc/PlayListPlayer.cpp kodi-18.3+git20190621.1610-final/xbmc/PlayListPlayer.cpp --- kodi-18.2+git20190422.1151-final/xbmc/PlayListPlayer.cpp 2019-02-11 10:31:27.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/PlayListPlayer.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -25,8 +25,10 @@ #include "interfaces/AnnouncementManager.h" #include "input/Key.h" #include "URL.h" +#include "utils/URIUtils.h" #include "messaging/ApplicationMessenger.h" #include "filesystem/VideoDatabaseFile.h" +#include "filesystem/PluginDirectory.h" #include "messaging/helpers/DialogOKHelper.h" #include "ServiceBroker.h" @@ -892,6 +894,12 @@ if (list->Size() == 1 && !(*list)[0]->IsPlayList()) { CFileItemPtr item = (*list)[0]; + // if the item is a plugin we need to resolve the URL to ensure the infotags are filled. + // resolve only for a maximum of 5 times to avoid deadlocks (plugin:// paths can resolve to plugin:// paths) + for (int i = 0; URIUtils::IsPlugin(item->GetDynPath()) && i < 5; ++i) + { + XFILE::CPluginDirectory::GetPluginResult(item->GetDynPath(), *item, true); + } if (item->IsAudio() || item->IsVideo()) Play(item, pMsg->strParam); else diff -Nru kodi-18.2+git20190422.1151-final/xbmc/pvr/channels/PVRChannelGroup.cpp kodi-18.3+git20190621.1610-final/xbmc/pvr/channels/PVRChannelGroup.cpp --- kodi-18.2+git20190422.1151-final/xbmc/pvr/channels/PVRChannelGroup.cpp 2019-04-22 09:51:08.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/pvr/channels/PVRChannelGroup.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -34,13 +34,13 @@ using namespace PVR; -CPVRChannelGroup::CPVRChannelGroup(void) +CPVRChannelGroup::CPVRChannelGroup() { OnInit(); } CPVRChannelGroup::CPVRChannelGroup(bool bRadio, - unsigned int iGroupId, + int iGroupId, const std::string& strGroupName, const std::shared_ptr& allChannelsGroup) : m_bRadio(bRadio), @@ -490,17 +490,13 @@ return retval; } -PVR_CHANNEL_GROUP_SORTED_MEMBERS CPVRChannelGroup::GetMembers(void) const +std::vector CPVRChannelGroup::GetMembers(Include eFilter /* = Include::ALL */) const { CSingleLock lock(m_critSection); - return m_sortedMembers; -} - -int CPVRChannelGroup::GetMembers(CFileItemList &results, Include eFilter /* = Include::ONLY_VISIBLE */) const -{ - int iOrigSize = results.Size(); - CSingleLock lock(m_critSection); + if (eFilter == Include::ALL) + return m_sortedMembers; + std::vector members; for (const auto& member : m_sortedMembers) { switch (eFilter) @@ -517,10 +513,10 @@ break; } - results.Add(std::make_shared(member.channel)); + members.emplace_back(member); } - return results.Size() - iOrigSize; + return members; } void CPVRChannelGroup::GetChannelNumbers(std::vector& channelNumbers) const @@ -773,11 +769,11 @@ CSingleLock lock(m_critSection); /* only persist if the group has changes and is fully loaded or never has been saved before */ - if (!HasChanges() || (!m_bLoaded && m_iGroupId != -1)) + if (!HasChanges() || (!m_bLoaded && m_iGroupId != INVALID_GROUP_ID)) return bReturn; // Mark newly created groups as loaded so future updates will also be persisted... - if (m_iGroupId == -1) + if (m_iGroupId == INVALID_GROUP_ID) m_bLoaded = true; if (database) @@ -926,7 +922,7 @@ channel = (*it).channel; if (!channel->IsHidden()) { - bool bEmpty = false; + bool bEmpty = true; CPVREpgPtr epg = channel->GetEPG(); if (epg) diff -Nru kodi-18.2+git20190422.1151-final/xbmc/pvr/channels/PVRChannelGroup.h kodi-18.3+git20190621.1610-final/xbmc/pvr/channels/PVRChannelGroup.h --- kodi-18.2+git20190422.1151-final/xbmc/pvr/channels/PVRChannelGroup.h 2019-04-22 09:51:08.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/pvr/channels/PVRChannelGroup.h 2019-06-21 14:09:24.000000000 +0000 @@ -59,16 +59,16 @@ friend class CPVRDatabase; public: - CPVRChannelGroup(void); + static const int INVALID_GROUP_ID = -1; /*! * @brief Create a new channel group instance. * @param bRadio True if this group holds radio channels. - * @param iGroupId The database ID of this group. + * @param iGroupId The database ID of this group or INVALID_GROUP_ID if the group was not yet stored in the database. * @param strGroupName The name of this group. * @param allChannelsGroup The channel group containing all TV or radio channels. */ - CPVRChannelGroup(bool bRadio, unsigned int iGroupId, const std::string& strGroupName, const std::shared_ptr& allChannelsGroup); + CPVRChannelGroup(bool bRadio, int iGroupId, const std::string& strGroupName, const std::shared_ptr& allChannelsGroup); /*! * @brief Create a new channel group instance from a channel group provided by an add-on. @@ -314,12 +314,6 @@ */ CPVRChannelPtr GetByChannelID(int iChannelID) const; - /*! - * Get the current members of this group - * @return The group members - */ - PVR_CHANNEL_GROUP_SORTED_MEMBERS GetMembers(void) const; - enum class Include { ALL, @@ -328,12 +322,11 @@ }; /*! - * @brief Get a filtered list of channels in this group. - * @param results The file list to store the results in. - * @param eFilter A filter to apply to the list. - * @return The amount of channels that were added to the list. + * @brief Get the current members of this group + * @param eFilter A filter to apply. + * @return The group members */ - int GetMembers(CFileItemList &results, Include eFilter = Include::ONLY_VISIBLE) const; + std::vector GetMembers(Include eFilter = Include::ALL) const; /*! * @brief Get the list of channel numbers in a group. @@ -433,6 +426,8 @@ bool IsMissingChannelsFromClient(int iClientId) const; protected: + CPVRChannelGroup(); + /*! * @brief Init class */ @@ -500,7 +495,7 @@ bool m_bRadio = false; /*!< true if this container holds radio channels, false if it holds TV channels */ int m_iGroupType = PVR_GROUP_TYPE_DEFAULT; /*!< The type of this group */ - int m_iGroupId = -1; /*!< The ID of this group in the database */ + int m_iGroupId = INVALID_GROUP_ID; /*!< The ID of this group in the database */ std::string m_strGroupName; /*!< The name of this group */ bool m_bLoaded = false; /*!< True if this container is loaded, false otherwise */ bool m_bChanged = false; /*!< true if anything changed in this group that hasn't been persisted, false otherwise */ diff -Nru kodi-18.2+git20190422.1151-final/xbmc/pvr/channels/PVRChannelGroupInternal.cpp kodi-18.3+git20190621.1610-final/xbmc/pvr/channels/PVRChannelGroupInternal.cpp --- kodi-18.2+git20190422.1151-final/xbmc/pvr/channels/PVRChannelGroupInternal.cpp 2019-04-22 09:51:08.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/pvr/channels/PVRChannelGroupInternal.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -244,15 +244,19 @@ if (existingChannel.channel->UpdateFromClient(it->second.channel)) { bReturn = true; - CLog::LogFC(LOGDEBUG, LOGPVR, "Updated %s channel '%s' from PVR client", m_bRadio ? "radio" : "TV", it->second.channel->ChannelName().c_str()); + CLog::LogFC(LOGDEBUG, LOGPVR, "Updated {} channel '{}' from PVR client", m_bRadio ? "radio" : "TV", it->second.channel->ChannelName()); } } else { /* new channel */ UpdateFromClient(it->second.channel, bUseBackendChannelNumbers ? it->second.channel->ClientChannelNumber() : CPVRChannelNumber()); + if (it->second.channel->CreateEPG()) + { + CLog::LogFC(LOGDEBUG, LOGPVR, "Created EPG for {} channel '{}' from PVR client", m_bRadio ? "radio" : "TV", it->second.channel->ChannelName()); + } bReturn = true; - CLog::LogFC(LOGDEBUG, LOGPVR,"Added %s channel '%s' from PVR client", m_bRadio ? "radio" : "TV", it->second.channel->ChannelName().c_str()); + CLog::LogFC(LOGDEBUG, LOGPVR, "Added {} channel '{}' from PVR client", m_bRadio ? "radio" : "TV", it->second.channel->ChannelName()); } } diff -Nru kodi-18.2+git20190422.1151-final/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp kodi-18.3+git20190621.1610-final/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp --- kodi-18.2+git20190422.1151-final/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp 2019-04-22 09:51:08.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -8,13 +8,9 @@ #include "PVRChannelGroupsContainer.h" -#include "URL.h" -#include "guilib/LocalizeStrings.h" -#include "utils/StringUtils.h" -#include "utils/URIUtils.h" +#include "FileItem.h" #include "utils/log.h" -#include "pvr/PVRManager.h" #include "pvr/epg/EpgInfoTag.h" using namespace PVR; @@ -115,17 +111,6 @@ return groups->GetGroupAll()->GetByUniqueID(epgTag->UniqueChannelID(), epgTag->ClientID()); } -bool CPVRChannelGroupsContainer::GetGroupsDirectory(CFileItemList *results, bool bRadio) const -{ - const CPVRChannelGroups *channelGroups = Get(bRadio); - if (channelGroups) - { - channelGroups->GetGroupList(results); - return true; - } - return false; -} - CFileItemPtr CPVRChannelGroupsContainer::GetByPath(const std::string &strPath) const { for (unsigned int bRadio = 0; bRadio <= 1; ++bRadio) @@ -140,127 +125,6 @@ return retVal; } -bool CPVRChannelGroupsContainer::GetDirectory(const std::string& strPath, CFileItemList &results) const -{ - std::string strBase(strPath); - URIUtils::RemoveSlashAtEnd(strBase); - - /* get the filename from curl */ - CURL url(strPath); - std::string fileName = url.GetFileName(); - URIUtils::RemoveSlashAtEnd(fileName); - - if (fileName == "channels") - { - CFileItemPtr item; - - /* all tv channels */ - item.reset(new CFileItem(strBase + "/tv/", true)); - item->SetLabel(g_localizeStrings.Get(19020)); - item->SetLabelPreformatted(true); - results.Add(item); - - /* all radio channels */ - item.reset(new CFileItem(strBase + "/radio/", true)); - item->SetLabel(g_localizeStrings.Get(19021)); - item->SetLabelPreformatted(true); - results.Add(item); - - return true; - } - else if (fileName == "channels/tv") - { - return GetGroupsDirectory(&results, false); - } - else if (fileName == "channels/radio") - { - return GetGroupsDirectory(&results, true); - } - else if (StringUtils::StartsWith(fileName, "channels/tv/")) - { - std::string strGroupName(fileName.substr(12)); - URIUtils::RemoveSlashAtEnd(strGroupName); - - CPVRChannelGroupPtr group; - bool bShowHiddenChannels = StringUtils::EndsWithNoCase(fileName, ".hidden"); - if (strGroupName == "*" || bShowHiddenChannels) // all channels - group = GetGroupAllTV(); - else - group = GetTV()->GetByName(strGroupName); - - if (group) - { - group->GetMembers(results, bShowHiddenChannels ? CPVRChannelGroup::Include::ONLY_HIDDEN : CPVRChannelGroup::Include::ONLY_VISIBLE); - } - else - { - CLog::LogF(LOGERROR, "Unable to obtain members of channel group '%s'", strGroupName.c_str()); - return false; - } - - FilterDirectory(url, results); - return true; - } - else if (StringUtils::StartsWith(fileName, "channels/radio/")) - { - std::string strGroupName(fileName.substr(15)); - URIUtils::RemoveSlashAtEnd(strGroupName); - - CPVRChannelGroupPtr group; - bool bShowHiddenChannels = StringUtils::EndsWithNoCase(fileName, ".hidden"); - if (strGroupName == "*" || bShowHiddenChannels) // all channels - group = GetGroupAllRadio(); - else - group = GetRadio()->GetByName(strGroupName); - - if (group) - { - group->GetMembers(results, bShowHiddenChannels ? CPVRChannelGroup::Include::ONLY_HIDDEN : CPVRChannelGroup::Include::ONLY_VISIBLE); - } - else - { - CLog::LogF(LOGERROR, "Unable to obtain members of channel group '%s'", strGroupName.c_str()); - return false; - } - - FilterDirectory(url, results); - return true; - } - - return false; -} - -bool CPVRChannelGroupsContainer::FilterDirectory(const CURL &url, CFileItemList &results) const -{ - if (!results.IsEmpty()) - { - if (url.HasOption("view")) - { - const std::string view(url.GetOption("view")); - if (view == "lastplayed") - { - // remove channels never played so far - for (int i = 0; i < results.Size(); ++i) - { - const CPVRChannelPtr channel(results.Get(i)->GetPVRChannelInfoTag()); - time_t lastWatched = channel->LastWatched(); - if (!lastWatched) - { - results.Remove(i); - --i; - } - } - } - else - { - CLog::LogF(LOGERROR, "Unsupported value '%s' for channel list URL parameter 'view'", view.c_str()); - return false; - } - } - } - return true; -} - CPVRChannelGroupPtr CPVRChannelGroupsContainer::GetSelectedGroup(bool bRadio) const { return Get(bRadio)->GetSelectedGroup(); diff -Nru kodi-18.2+git20190422.1151-final/xbmc/pvr/channels/PVRChannelGroupsContainer.h kodi-18.3+git20190621.1610-final/xbmc/pvr/channels/PVRChannelGroupsContainer.h --- kodi-18.2+git20190422.1151-final/xbmc/pvr/channels/PVRChannelGroupsContainer.h 2019-04-22 09:51:08.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/pvr/channels/PVRChannelGroupsContainer.h 2019-06-21 14:09:24.000000000 +0000 @@ -12,8 +12,6 @@ #include "pvr/channels/PVRChannelGroups.h" -class CURL; - namespace PVR { class CPVRChannelGroupsContainer @@ -120,15 +118,6 @@ std::shared_ptr GetChannelForEpgTag(const std::shared_ptr& epgTag) const; /*! - * @brief Get the groups list for a directory. - * @param strBase The directory path. - * @param results The file list to store the results in. - * @param bRadio Get radio channels or tv channels. - * @return True if the list was filled successfully. - */ - bool GetGroupsDirectory(CFileItemList *results, bool bRadio) const; - - /*! * @brief Get a channel given it's path. * @param strPath The path. * @return The channel or NULL if it wasn't found. @@ -136,14 +125,6 @@ CFileItemPtr GetByPath(const std::string &strPath) const; /*! - * @brief Get the directory for a path. - * @param strPath The path. - * @param results The file list to store the results in. - * @return True if the directory was found, false if not. - */ - bool GetDirectory(const std::string& strPath, CFileItemList &results) const; - - /*! * @brief Get the group that is currently selected in the UI. * @param bRadio True to get the selected radio group, false to get the selected TV group. * @return The selected group. @@ -206,8 +187,6 @@ CPVRChannelGroupsContainer& operator=(const CPVRChannelGroupsContainer&) = delete; CPVRChannelGroupsContainer(const CPVRChannelGroupsContainer&) = delete; - bool FilterDirectory(const CURL &url, CFileItemList &results) const; - bool m_bLoaded = false; }; } diff -Nru kodi-18.2+git20190422.1151-final/xbmc/pvr/channels/PVRChannelGroups.cpp kodi-18.3+git20190621.1610-final/xbmc/pvr/channels/PVRChannelGroups.cpp --- kodi-18.2+git20190422.1151-final/xbmc/pvr/channels/PVRChannelGroups.cpp 2019-04-22 09:51:08.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/pvr/channels/PVRChannelGroups.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -500,9 +500,8 @@ if (!group) { // create a new group - group = CPVRChannelGroupPtr(new CPVRChannelGroup()); - group->SetRadio(m_bRadio); - group->SetGroupName(strName); + group.reset(new CPVRChannelGroup(m_bRadio, CPVRChannelGroup::INVALID_GROUP_ID, strName, GetGroupAll())); + m_groups.push_back(group); bPersist = true; } diff -Nru kodi-18.2+git20190422.1151-final/xbmc/pvr/CMakeLists.txt kodi-18.3+git20190621.1610-final/xbmc/pvr/CMakeLists.txt --- kodi-18.2+git20190422.1151-final/xbmc/pvr/CMakeLists.txt 2018-11-04 08:12:29.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/pvr/CMakeLists.txt 2019-06-21 14:09:24.000000000 +0000 @@ -9,6 +9,7 @@ PVRChannelNumberInputHandler.cpp PVRJobs.cpp PVRGUIChannelNavigator.cpp + PVRGUIDirectory.cpp PVRGUIProgressHandler.cpp PVRGUITimerInfo.cpp PVRGUITimesInfo.cpp) @@ -25,6 +26,7 @@ PVRChannelNumberInputHandler.h PVRJobs.h PVRGUIChannelNavigator.h + PVRGUIDirectory.h PVRGUIProgressHandler.h PVRGUITimerInfo.h PVRGUITimesInfo.h) diff -Nru kodi-18.2+git20190422.1151-final/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp kodi-18.3+git20190621.1610-final/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp --- kodi-18.2+git20190422.1151-final/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp 2019-04-22 09:51:08.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -166,7 +166,12 @@ const CPVRChannelGroupPtr group = pvrMgr.GetPlayingGroup(channel->IsRadio()); if (group) { - group->GetMembers(*m_vecItems); + const std::vector groupMembers = group->GetMembers(CPVRChannelGroup::Include::ONLY_VISIBLE); + for (const auto& groupMember : groupMembers) + { + m_vecItems->Add(std::make_shared(groupMember.channel)); + } + m_viewControl.SetItems(*m_vecItems); if (!m_group) diff -Nru kodi-18.2+git20190422.1151-final/xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp kodi-18.3+git20190621.1610-final/xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp --- kodi-18.2+git20190422.1151-final/xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp 2018-08-26 13:40:15.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -403,21 +403,30 @@ // Slightly different handling for "all" group... if (m_selectedGroup->IsInternalGroup()) { - m_selectedGroup->GetMembers(*m_groupMembers, CPVRChannelGroup::Include::ONLY_VISIBLE); - m_selectedGroup->GetMembers(*m_ungroupedChannels, CPVRChannelGroup::Include::ONLY_HIDDEN); + const std::vector groupMembers = m_selectedGroup->GetMembers(CPVRChannelGroup::Include::ALL); + for (const auto& groupMember : groupMembers) + { + if (groupMember.channel->IsHidden()) + m_ungroupedChannels->Add(std::make_shared(groupMember.channel)); + else + m_groupMembers->Add(std::make_shared(groupMember.channel)); + } } else { - m_selectedGroup->GetMembers(*m_groupMembers, CPVRChannelGroup::Include::ALL); + const std::vector groupMembers = m_selectedGroup->GetMembers(CPVRChannelGroup::Include::ONLY_VISIBLE); + for (const auto& groupMember : groupMembers) + { + m_groupMembers->Add(std::make_shared(groupMember.channel)); + } /* for the center part, get all channels of the "all" channels group that are not in this group */ const CPVRChannelGroupPtr allGroup = CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupAll(m_bIsRadio); - CFileItemList allChannels; - allGroup->GetMembers(allChannels, CPVRChannelGroup::Include::ALL); - for (const auto& channelItem : allChannels) + const std::vector allGroupMembers = allGroup->GetMembers(CPVRChannelGroup::Include::ONLY_VISIBLE); + for (const auto& groupMember : allGroupMembers) { - if (!m_selectedGroup->IsGroupMember(channelItem->GetPVRChannelInfoTag())) - m_ungroupedChannels->Add(channelItem); + if (!m_selectedGroup->IsGroupMember(groupMember.channel)) + m_ungroupedChannels->Add(std::make_shared(groupMember.channel)); } } m_viewGroupMembers.SetItems(*m_groupMembers); diff -Nru kodi-18.2+git20190422.1151-final/xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.cpp kodi-18.3+git20190621.1610-final/xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.cpp --- kodi-18.2+git20190422.1151-final/xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.cpp 2018-07-31 18:47:40.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -67,7 +67,7 @@ group = CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupAll(m_searchFilter->IsRadio()); m_channelNumbersMap.clear(); - const std::vector groupMembers(group->GetMembers()); + const std::vector groupMembers(group->GetMembers(CPVRChannelGroup::Include::ONLY_VISIBLE)); int iIndex = 0; int iSelectedChannel = EPG_SEARCH_UNSET; for (const auto& groupMember : groupMembers) diff -Nru kodi-18.2+git20190422.1151-final/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp kodi-18.3+git20190621.1610-final/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp --- kodi-18.2+git20190422.1151-final/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp 2019-04-22 09:51:08.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -771,16 +771,17 @@ { m_channelEntries.clear(); - CFileItemList channelsList; - CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupAll(m_bIsRadio)->GetMembers(channelsList); - - for (int i = 0; i < channelsList.Size(); ++i) + const std::shared_ptr allGroup = CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupAll(m_bIsRadio); + const std::vector groupMembers = allGroup->GetMembers(CPVRChannelGroup::Include::ONLY_VISIBLE); + int i = 0; + for (const auto& groupMember : groupMembers) { - const CPVRChannelPtr channel(channelsList[i]->GetPVRChannelInfoTag()); + const std::shared_ptr channel = groupMember.channel; std::string channelDescription( StringUtils::Format("%s %s", channel->ChannelNumber().FormattedChannelNumber().c_str(), channel->ChannelName().c_str())); m_channelEntries.insert( std::make_pair(i, ChannelDescriptor(channel->UniqueID(), channel->ClientID(), channelDescription))); + i++; } // Add special "any channel" entry (used for epg-based timer rules). diff -Nru kodi-18.2+git20190422.1151-final/xbmc/pvr/epg/Epg.cpp kodi-18.3+git20190621.1610-final/xbmc/pvr/epg/Epg.cpp --- kodi-18.2+git20190422.1151-final/xbmc/pvr/epg/Epg.cpp 2019-04-22 09:51:08.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/pvr/epg/Epg.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -258,11 +258,12 @@ newTag = it->second; else { - newTag = std::make_shared(m_channelData, m_iEpgID); + newTag.reset(new CPVREpgInfoTag()); m_tags.insert(std::make_pair(tag.StartAsUTC(), newTag)); } newTag->Update(tag); + newTag->SetChannelData(m_channelData); newTag->SetEpgID(m_iEpgID); } @@ -348,13 +349,14 @@ } else { - infoTag = std::make_shared(m_channelData, m_iEpgID); + infoTag.reset(new CPVREpgInfoTag()); infoTag->SetUniqueBroadcastID(tag->UniqueBroadcastID()); m_tags.insert(std::make_pair(tag->StartAsUTC(), infoTag)); bNewTag = true; } infoTag->Update(*tag, bNewTag); + infoTag->SetChannelData(m_channelData); infoTag->SetEpgID(m_iEpgID); if (bUpdateDatabase) diff -Nru kodi-18.2+git20190422.1151-final/xbmc/pvr/PVRGUIDirectory.cpp kodi-18.3+git20190621.1610-final/xbmc/pvr/PVRGUIDirectory.cpp --- kodi-18.2+git20190422.1151-final/xbmc/pvr/PVRGUIDirectory.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/pvr/PVRGUIDirectory.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -0,0 +1,507 @@ +/* + * Copyright (C) 2012-2019 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 "PVRGUIDirectory.h" + +#include "FileItem.h" +#include "ServiceBroker.h" +#include "URL.h" +#include "guilib/LocalizeStrings.h" +#include "settings/Settings.h" +#include "settings/SettingsComponent.h" +#include "utils/StringUtils.h" +#include "utils/URIUtils.h" +#include "utils/log.h" + +#include "pvr/PVRManager.h" +#include "pvr/channels/PVRChannelGroups.h" +#include "pvr/channels/PVRChannelGroupsContainer.h" +#include "pvr/recordings/PVRRecordings.h" +#include "pvr/recordings/PVRRecordingsPath.h" +#include "pvr/timers/PVRTimers.h" +#include "pvr/timers/PVRTimersPath.h" + +using namespace PVR; + +bool CPVRGUIDirectory::Exists() const +{ + if (!CServiceBroker::GetPVRManager().IsStarted()) + return false; + + return m_url.IsProtocol("pvr") && StringUtils::StartsWith(m_url.GetFileName(), "recordings"); +} + +bool CPVRGUIDirectory::SupportsWriteFileOperations() const +{ + if (!CServiceBroker::GetPVRManager().IsStarted()) + return false; + + const std::string filename = m_url.GetFileName(); + return URIUtils::IsPVRRecording(filename); +} + +bool CPVRGUIDirectory::GetDirectory(CFileItemList& results) const +{ + std::string base = m_url.Get(); + URIUtils::RemoveSlashAtEnd(base); + + std::string fileName = m_url.GetFileName(); + URIUtils::RemoveSlashAtEnd(fileName); + + results.SetCacheToDisc(CFileItemList::CACHE_NEVER); + + if (fileName.empty()) + { + if (CServiceBroker::GetPVRManager().IsStarted()) + { + std::shared_ptr item; + + item.reset(new CFileItem(base + "channels/", true)); + item->SetLabel(g_localizeStrings.Get(19019)); + item->SetLabelPreformatted(true); + results.Add(item); + + item.reset(new CFileItem(base + "recordings/active/", true)); + item->SetLabel(g_localizeStrings.Get(19017)); // TV Recordings + item->SetLabelPreformatted(true); + results.Add(item); + + item.reset(new CFileItem(base + "recordings/deleted/", true)); + item->SetLabel(g_localizeStrings.Get(19108)); // Deleted TV Recordings + item->SetLabelPreformatted(true); + results.Add(item); + + // Sort by name only. Labels are preformatted. + results.AddSortMethod(SortByLabel, 551 /* Name */, LABEL_MASKS("%L", "", "%L", "")); + } + return true; + } + else if (StringUtils::StartsWith(fileName, "recordings")) + { + if (CServiceBroker::GetPVRManager().IsStarted()) + { + return GetRecordingsDirectory(results); + } + return true; + } + else if (StringUtils::StartsWith(fileName, "channels")) + { + if (CServiceBroker::GetPVRManager().ChannelGroups() && + CServiceBroker::GetPVRManager().ChannelGroups()->Loaded()) + { + return GetChannelsDirectory(results); + } + return true; + } + else if (StringUtils::StartsWith(fileName, "timers")) + { + if (CServiceBroker::GetPVRManager().IsStarted()) + { + return GetTimersDirectory(results); + } + return true; + } + + return false; +} + +bool CPVRGUIDirectory::HasTVRecordings() +{ + return CServiceBroker::GetPVRManager().IsStarted() && + CServiceBroker::GetPVRManager().Recordings()->GetNumTVRecordings() > 0; +} + +bool CPVRGUIDirectory::HasDeletedTVRecordings() +{ + return CServiceBroker::GetPVRManager().IsStarted() && + CServiceBroker::GetPVRManager().Recordings()->HasDeletedTVRecordings(); +} + +bool CPVRGUIDirectory::HasRadioRecordings() +{ + return CServiceBroker::GetPVRManager().IsStarted() && + CServiceBroker::GetPVRManager().Recordings()->GetNumRadioRecordings() > 0; +} + +bool CPVRGUIDirectory::HasDeletedRadioRecordings() +{ + return CServiceBroker::GetPVRManager().IsStarted() && + CServiceBroker::GetPVRManager().Recordings()->HasDeletedRadioRecordings(); +} + +namespace +{ + +std::string TrimSlashes(const std::string& strOrig) +{ + std::string strReturn = strOrig; + while (strReturn[0] == '/') + strReturn.erase(0, 1); + + URIUtils::RemoveSlashAtEnd(strReturn); + return strReturn; +} + +bool IsDirectoryMember(const std::string& strDirectory, + const std::string& strEntryDirectory, + bool bGrouped) +{ + const std::string strUseDirectory = TrimSlashes(strDirectory); + const std::string strUseEntryDirectory = TrimSlashes(strEntryDirectory); + + // Case-insensitive comparison since sub folders are created with case-insensitive matching (GetSubDirectories) + if (bGrouped) + return StringUtils::EqualsNoCase(strUseDirectory, strUseEntryDirectory); + else + return StringUtils::StartsWithNoCase(strUseEntryDirectory, strUseDirectory); +} + +void GetSubDirectories(const CPVRRecordingsPath& recParentPath, + CVideoDatabase& videoDB, + const std::vector>& recordings, + CFileItemList& results) +{ + // Only active recordings are fetched to provide sub directories. + // Not applicable for deleted view which is supposed to be flattened. + std::set> unwatchedFolders; + bool bRadio = recParentPath.IsRadio(); + + for (const auto& recording : recordings) + { + if (recording->IsDeleted()) + continue; + + if (recording->IsRadio() != bRadio) + continue; + + const std::string strCurrent = recParentPath.GetUnescapedSubDirectoryPath(recording->m_strDirectory); + if (strCurrent.empty()) + continue; + + CPVRRecordingsPath recChildPath(recParentPath); + recChildPath.AppendSegment(strCurrent); + const std::string strFilePath = recChildPath; + + recording->UpdateMetadata(videoDB); + + std::shared_ptr item; + if (!results.Contains(strFilePath)) + { + item.reset(new CFileItem(strCurrent, true)); + item->SetPath(strFilePath); + item->SetLabel(strCurrent); + item->SetLabelPreformatted(true); + item->m_dateTime = recording->RecordingTimeAsLocalTime(); + + // Assume all folders are watched, we'll change the overlay later + item->SetOverlayImage(CGUIListItem::ICON_OVERLAY_WATCHED, false); + results.Add(item); + } + else + { + item = results.Get(strFilePath); + if (item->m_dateTime < recording->RecordingTimeAsLocalTime()) + item->m_dateTime = recording->RecordingTimeAsLocalTime(); + } + + if (recording->GetPlayCount() == 0) + unwatchedFolders.insert(item); + } + + // Change the watched overlay to unwatched for folders containing unwatched entries + for (auto& item : unwatchedFolders) + item->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, false); +} + +} // unnamed namespace + +bool CPVRGUIDirectory::GetRecordingsDirectory(CFileItemList& results) const +{ + bool bGrouped = false; + const std::shared_ptr recs = CServiceBroker::GetPVRManager().Recordings(); + const std::vector> recordings = recs->GetAll(); + CVideoDatabase& videoDB = recs->GetVideoDatabase(); + + if (m_url.HasOption("view")) + { + const std::string view = m_url.GetOption("view"); + if (view == "grouped") + bGrouped = true; + else if (view == "flat") + bGrouped = false; + else + { + CLog::LogF(LOGERROR, "Unsupported value '%s' for url parameter 'view'", view.c_str()); + return false; + } + } + else + { + bGrouped = CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_PVRRECORD_GROUPRECORDINGS); + } + + const CPVRRecordingsPath recPath(m_url.GetWithoutOptions()); + if (recPath.IsValid()) + { + // Get the directory structure if in non-flatten mode + // Deleted view is always flatten. So only for an active view + const std::string strDirectory = recPath.GetUnescapedDirectoryPath(); + if (!recPath.IsDeleted() && bGrouped) + GetSubDirectories(recPath, videoDB, recordings, results); + + // get all files of the current directory or recursively all files starting at the current directory if in flatten mode + std::shared_ptr item; + for (const auto& recording : recordings) + { + // Omit recordings not matching criteria + if (recording->IsDeleted() != recPath.IsDeleted() || + recording->IsRadio() != recPath.IsRadio() || + !IsDirectoryMember(strDirectory, recording->m_strDirectory, bGrouped)) + continue; + + recording->UpdateMetadata(videoDB); + + item = std::make_shared(recording); + item->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, recording->GetPlayCount() > 0); + results.Add(item); + } + } + + return recPath.IsValid(); +} + +bool CPVRGUIDirectory::FilterDirectory(CFileItemList& results) const +{ + if (!results.IsEmpty()) + { + if (m_url.HasOption("view")) + { + const std::string view = m_url.GetOption("view"); + if (view == "lastplayed") + { + // remove channels never played so far + for (int i = 0; i < results.Size(); ++i) + { + const std::shared_ptr channel = results.Get(i)->GetPVRChannelInfoTag(); + time_t lastWatched = channel->LastWatched(); + if (!lastWatched) + { + results.Remove(i); + --i; + } + } + } + else + { + CLog::LogF(LOGERROR, "Unsupported value '%s' for channel list URL parameter 'view'", view.c_str()); + return false; + } + } + } + return true; +} + +bool CPVRGUIDirectory::GetChannelGroupsDirectory(bool bRadio, CFileItemList& results) const +{ + const CPVRChannelGroups* channelGroups = CServiceBroker::GetPVRManager().ChannelGroups()->Get(bRadio); + if (channelGroups) + { + channelGroups->GetGroupList(&results); + return true; + } + return false; +} + +bool CPVRGUIDirectory::GetChannelsDirectory(CFileItemList& results) const +{ + std::string base = m_url.Get(); + URIUtils::RemoveSlashAtEnd(base); + + std::string fileName = m_url.GetFileName(); + URIUtils::RemoveSlashAtEnd(fileName); + + if (fileName == "channels") + { + std::shared_ptr item; + + // all tv channels + item.reset(new CFileItem(base + "/tv/", true)); + item->SetLabel(g_localizeStrings.Get(19020)); + item->SetLabelPreformatted(true); + results.Add(item); + + // all radio channels + item.reset(new CFileItem(base + "/radio/", true)); + item->SetLabel(g_localizeStrings.Get(19021)); + item->SetLabelPreformatted(true); + results.Add(item); + + return true; + } + else if (fileName == "channels/tv") + { + return GetChannelGroupsDirectory(false, results); + } + else if (fileName == "channels/radio") + { + return GetChannelGroupsDirectory(true, results); + } + else if (StringUtils::StartsWith(fileName, "channels/tv/")) + { + std::string strGroupName = fileName.substr(12); + URIUtils::RemoveSlashAtEnd(strGroupName); + + std::shared_ptr group; + bool bShowHiddenChannels = StringUtils::EndsWithNoCase(fileName, ".hidden"); + if (bShowHiddenChannels || strGroupName == "*") // all channels + group = CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupAllTV(); + else + group = CServiceBroker::GetPVRManager().ChannelGroups()->GetTV()->GetByName(strGroupName); + + if (group) + { + const std::vector groupMembers = group->GetMembers(); + for (const auto& groupMember : groupMembers) + { + if (bShowHiddenChannels != groupMember.channel->IsHidden()) + continue; + + results.Add(std::make_shared(groupMember.channel)); + } + } + else + { + CLog::LogF(LOGERROR, "Unable to obtain members of channel group '%s'", strGroupName.c_str()); + return false; + } + + FilterDirectory(results); + return true; + } + else if (StringUtils::StartsWith(fileName, "channels/radio/")) + { + std::string strGroupName = fileName.substr(15); + URIUtils::RemoveSlashAtEnd(strGroupName); + + std::shared_ptr group; + bool bShowHiddenChannels = StringUtils::EndsWithNoCase(fileName, ".hidden"); + if (bShowHiddenChannels || strGroupName == "*") // all channels + group = CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupAllRadio(); + else + group = CServiceBroker::GetPVRManager().ChannelGroups()->GetRadio()->GetByName(strGroupName); + + if (group) + { + const std::vector groupMembers = group->GetMembers(); + for (const auto& groupMember : groupMembers) + { + if (bShowHiddenChannels != groupMember.channel->IsHidden()) + continue; + + results.Add(std::make_shared(groupMember.channel)); + } + } + else + { + CLog::LogF(LOGERROR, "Unable to obtain members of channel group '%s'", strGroupName.c_str()); + return false; + } + + FilterDirectory(results); + return true; + } + + return false; +} + +namespace +{ + +bool GetTimersRootDirectory(const CPVRTimersPath& path, + const std::vector>& timers, + CFileItemList& results) +{ + std::shared_ptr item(new CFileItem(CPVRTimersPath::PATH_ADDTIMER, false)); + item->SetLabel(g_localizeStrings.Get(19026)); // "Add timer..." + item->SetLabelPreformatted(true); + item->SetSpecialSort(SortSpecialOnTop); + item->SetIconImage("DefaultTVShows.png"); + results.Add(item); + + bool bRadio = path.IsRadio(); + bool bRules = path.IsRules(); + + bool bHideDisabled = CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_PVRTIMERS_HIDEDISABLEDTIMERS); + + for (const auto& timer : timers) + { + if ((bRadio == timer->m_bIsRadio || (bRules && timer->m_iClientChannelUid == PVR_TIMER_ANY_CHANNEL)) && + (bRules == timer->IsTimerRule()) && + (!bHideDisabled || (timer->m_state != PVR_TIMER_STATE_DISABLED))) + { + item.reset(new CFileItem(timer)); + const CPVRTimersPath timersPath(path.GetPath(), timer->m_iClientId, timer->m_iClientIndex); + item->SetPath(timersPath.GetPath()); + results.Add(item); + } + } + return true; +} + +bool GetTimersSubDirectory(const CPVRTimersPath& path, + const std::vector>& timers, + CFileItemList& results) +{ + bool bRadio = path.IsRadio(); + unsigned int iParentId = path.GetParentId(); + int iClientId = path.GetClientId(); + + bool bHideDisabled = CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_PVRTIMERS_HIDEDISABLEDTIMERS); + + std::shared_ptr item; + + for (const auto& timer : timers) + { + if ((timer->m_bIsRadio == bRadio) && + (timer->m_iParentClientIndex != PVR_TIMER_NO_PARENT) && + (timer->m_iClientId == iClientId) && + (timer->m_iParentClientIndex == iParentId) && + (!bHideDisabled || (timer->m_state != PVR_TIMER_STATE_DISABLED))) + { + item.reset(new CFileItem(timer)); + const CPVRTimersPath timersPath(path.GetPath(), timer->m_iClientId, timer->m_iClientIndex); + item->SetPath(timersPath.GetPath()); + results.Add(item); + } + } + return true; +} + +} // unnamed namespace + +bool CPVRGUIDirectory::GetTimersDirectory(CFileItemList& results) const +{ + const CPVRTimersPath path(m_url.GetWithoutOptions()); + if (path.IsValid()) + { + const std::vector> timers = CServiceBroker::GetPVRManager().Timers()->GetAll(); + + if (path.IsTimersRoot()) + { + /* Root folder containing either timer rules or timers. */ + return GetTimersRootDirectory(path, timers, results); + } + else if (path.IsTimerRule()) + { + /* Sub folder containing the timers scheduled by the given timer rule. */ + return GetTimersSubDirectory(path, timers, results); + } + } + + return false; +} diff -Nru kodi-18.2+git20190422.1151-final/xbmc/pvr/PVRGUIDirectory.h kodi-18.3+git20190621.1610-final/xbmc/pvr/PVRGUIDirectory.h --- kodi-18.2+git20190422.1151-final/xbmc/pvr/PVRGUIDirectory.h 1970-01-01 00:00:00.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/pvr/PVRGUIDirectory.h 2019-06-21 14:09:24.000000000 +0000 @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2012-2019 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 "URL.h" + +class CFileItemList; + +namespace PVR +{ + +class CPVRGUIDirectory +{ +public: + /*! + * @brief PVR GUI directory ctor. + * @param url The directory's URL. + */ + explicit CPVRGUIDirectory(const CURL& url) : m_url(url) {} + + /*! + * @brief PVR GUI directory ctor. + * @param path The directory's path. + */ + explicit CPVRGUIDirectory(const std::string& path) : m_url(path) {} + + /*! + * @brief PVR GUI directory dtor. + */ + virtual ~CPVRGUIDirectory() = default; + + /*! + * @brief Check existense of this directory. + * @return True if the directory exists, false otherwise. + */ + bool Exists() const; + + /*! + * @brief Obtain the directory listing. + * @param results The list to fill with the results. + * @return True on success, false otherwise. + */ + bool GetDirectory(CFileItemList& results) const; + + /*! + * @brief Check if this directory supports file write operations. + * @return True if the directory supports file write operations, false otherwise. + */ + bool SupportsWriteFileOperations() const; + + /*! + * @brief Check if any TV recordings are existing. + * @return True if TV recordings exists, false otherwise. + */ + static bool HasTVRecordings(); + + /*! + * @brief Check if any deleted TV recordings are existing. + * @return True if deleted TV recordings exists, false otherwise. + */ + static bool HasDeletedTVRecordings(); + + /*! + * @brief Check if any radio recordings are existing. + * @return True if radio recordings exists, false otherwise. + */ + static bool HasRadioRecordings(); + + /*! + * @brief Check if any deleted radio recordings are existing. + * @return True if deleted radio recordings exists, false otherwise. + */ + static bool HasDeletedRadioRecordings(); + +private: + + bool FilterDirectory(CFileItemList& results) const; + + bool GetChannelGroupsDirectory(bool bRadio, CFileItemList& results) const; + bool GetChannelsDirectory(CFileItemList& results) const; + bool GetTimersDirectory(CFileItemList& results) const; + bool GetRecordingsDirectory(CFileItemList& results) const; + + const CURL m_url; +}; + +} diff -Nru kodi-18.2+git20190422.1151-final/xbmc/pvr/recordings/PVRRecordings.cpp kodi-18.3+git20190621.1610-final/xbmc/pvr/recordings/PVRRecordings.cpp --- kodi-18.2+git20190422.1151-final/xbmc/pvr/recordings/PVRRecordings.cpp 2019-04-22 09:51:08.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/pvr/recordings/PVRRecordings.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -12,12 +12,8 @@ #include "FileItem.h" #include "ServiceBroker.h" -#include "URL.h" #include "filesystem/Directory.h" -#include "settings/Settings.h" -#include "settings/SettingsComponent.h" #include "threads/SingleLock.h" -#include "utils/StringUtils.h" #include "utils/URIUtils.h" #include "utils/log.h" #include "video/VideoDatabase.h" @@ -44,84 +40,6 @@ CServiceBroker::GetPVRManager().Clients()->GetRecordings(this, true); } -std::string CPVRRecordings::TrimSlashes(const std::string &strOrig) const -{ - std::string strReturn(strOrig); - while (strReturn[0] == '/') - strReturn.erase(0, 1); - - URIUtils::RemoveSlashAtEnd(strReturn); - - return strReturn; -} - -bool CPVRRecordings::IsDirectoryMember(const std::string &strDirectory, const std::string &strEntryDirectory, bool bGrouped) const -{ - std::string strUseDirectory = TrimSlashes(strDirectory); - std::string strUseEntryDirectory = TrimSlashes(strEntryDirectory); - - /* Case-insensitive comparison since sub folders are created with case-insensitive matching (GetSubDirectories) */ - if (bGrouped) - return StringUtils::EqualsNoCase(strUseDirectory, strUseEntryDirectory); - else - return StringUtils::StartsWithNoCase(strUseEntryDirectory, strUseDirectory); -} - -void CPVRRecordings::GetSubDirectories(const CPVRRecordingsPath &recParentPath, CFileItemList *results) -{ - // Only active recordings are fetched to provide sub directories. - // Not applicable for deleted view which is supposed to be flattened. - std::set unwatchedFolders; - bool bRadio = recParentPath.IsRadio(); - - for (const auto recording : m_recordings) - { - CPVRRecordingPtr current = recording.second; - if (current->IsDeleted()) - continue; - - if (current->IsRadio() != bRadio) - continue; - - const std::string strCurrent(recParentPath.GetUnescapedSubDirectoryPath(current->m_strDirectory)); - if (strCurrent.empty()) - continue; - - CPVRRecordingsPath recChildPath(recParentPath); - recChildPath.AppendSegment(strCurrent); - std::string strFilePath(recChildPath); - - current->UpdateMetadata(GetVideoDatabase()); - - CFileItemPtr pFileItem; - if (!results->Contains(strFilePath)) - { - pFileItem.reset(new CFileItem(strCurrent, true)); - pFileItem->SetPath(strFilePath); - pFileItem->SetLabel(strCurrent); - pFileItem->SetLabelPreformatted(true); - pFileItem->m_dateTime = current->RecordingTimeAsLocalTime(); - - // Assume all folders are watched, we'll change the overlay later - pFileItem->SetOverlayImage(CGUIListItem::ICON_OVERLAY_WATCHED, false); - results->Add(pFileItem); - } - else - { - pFileItem = results->Get(strFilePath); - if (pFileItem->m_dateTime < current->RecordingTimeAsLocalTime()) - pFileItem->m_dateTime = current->RecordingTimeAsLocalTime(); - } - - if (current->GetPlayCount() == 0) - unwatchedFolders.insert(pFileItem); - } - - // Change the watched overlay to unwatched for folders containing unwatched entries - for (auto item : unwatchedFolders) - item->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, false); -} - int CPVRRecordings::Load(void) { Unload(); @@ -251,76 +169,17 @@ return ChangeRecordingsPlayCount(item, INCREMENT_PLAY_COUNT); } -bool CPVRRecordings::GetDirectory(const std::string& strPath, CFileItemList &items) +std::vector> CPVRRecordings::GetAll() const { - CSingleLock lock(m_critSection); - - bool bGrouped = false; - const CURL url(strPath); - if (url.HasOption("view")) - { - const std::string view(url.GetOption("view")); - if (view == "grouped") - bGrouped = true; - else if (view == "flat") - bGrouped = false; - else - { - CLog::LogF(LOGERROR, "Unsupported value '%s' for url parameter 'view'", view.c_str()); - return false; - } - } - else - { - bGrouped = CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_PVRRECORD_GROUPRECORDINGS); - } - - CPVRRecordingsPath recPath(url.GetWithoutOptions()); - if (recPath.IsValid()) - { - // Get the directory structure if in non-flatten mode - // Deleted view is always flatten. So only for an active view - std::string strDirectory(recPath.GetUnescapedDirectoryPath()); - if (!recPath.IsDeleted() && bGrouped) - GetSubDirectories(recPath, &items); - - // get all files of the current directory or recursively all files starting at the current directory if in flatten mode - for (const auto recording : m_recordings) - { - const CPVRRecordingPtr current = recording.second; - - // Omit recordings not matching criteria - if (!IsDirectoryMember(strDirectory, current->m_strDirectory, bGrouped) || - current->IsDeleted() != recPath.IsDeleted() || - current->IsRadio() != recPath.IsRadio()) - continue; + std::vector> recordings; - current->UpdateMetadata(GetVideoDatabase()); - - const CFileItemPtr item = std::make_shared(current); - item->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, current->GetPlayCount() > 0); - items.Add(item); - } - } - - return recPath.IsValid(); -} - -void CPVRRecordings::GetAll(CFileItemList &items, bool bDeleted) -{ CSingleLock lock(m_critSection); - for (const auto recording : m_recordings) + for (const auto& recordingEntry : m_recordings) { - const CPVRRecordingPtr current = recording.second; - if (current->IsDeleted() != bDeleted) - continue; - - current->UpdateMetadata(GetVideoDatabase()); - - const CFileItemPtr item = std::make_shared(current); - item->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, current->GetPlayCount() > 0); - items.Add(item); + recordings.emplace_back(recordingEntry.second); } + + return recordings; } CFileItemPtr CPVRRecordings::GetById(unsigned int iId) const @@ -367,7 +226,7 @@ { CPVRRecordingPtr retVal; CSingleLock lock(m_critSection); - PVR_RECORDINGMAP_CITR it = m_recordings.find(CPVRRecordingUid(iClientId, strRecordingId)); + const auto it = m_recordings.find(CPVRRecordingUid(iClientId, strRecordingId)); if (it != m_recordings.end()) retVal = it->second; diff -Nru kodi-18.2+git20190422.1151-final/xbmc/pvr/recordings/PVRRecordings.h kodi-18.3+git20190621.1610-final/xbmc/pvr/recordings/PVRRecordings.h --- kodi-18.2+git20190422.1151-final/xbmc/pvr/recordings/PVRRecordings.h 2018-07-31 18:47:40.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/pvr/recordings/PVRRecordings.h 2019-06-21 14:09:24.000000000 +0000 @@ -70,10 +70,10 @@ */ bool ResetResumePoint(const CFileItemPtr item); - bool GetDirectory(const std::string& strPath, CFileItemList &items); + std::vector> GetAll() const; + CFileItemPtr GetByPath(const std::string &path); CPVRRecordingPtr GetById(int iClientId, const std::string &strRecordingId) const; - void GetAll(CFileItemList &items, bool bDeleted = false); CFileItemPtr GetById(unsigned int iId) const; /*! @@ -83,14 +83,16 @@ */ CPVRRecordingPtr GetRecordingForEpgTag(const CPVREpgInfoTagPtr &epgTag) const; - private: - typedef std::map PVR_RECORDINGMAP; - typedef PVR_RECORDINGMAP::iterator PVR_RECORDINGMAP_ITR; - typedef PVR_RECORDINGMAP::const_iterator PVR_RECORDINGMAP_CITR; + /** + * @brief Get/Open the video database. + * @return A reference to the video database. + */ + CVideoDatabase& GetVideoDatabase(); + private: mutable CCriticalSection m_critSection; bool m_bIsUpdating = false; - PVR_RECORDINGMAP m_recordings; + std::map m_recordings; unsigned int m_iLastId = 0; std::unique_ptr m_database; bool m_bDeletedTVRecordings = false; @@ -99,15 +101,6 @@ unsigned int m_iRadioRecordings = 0; void UpdateFromClients(void); - std::string TrimSlashes(const std::string &strOrig) const; - bool IsDirectoryMember(const std::string &strDirectory, const std::string &strEntryDirectory, bool bGrouped) const; - void GetSubDirectories(const CPVRRecordingsPath &recParentPath, CFileItemList *results); - - /** - * @brief Get/Open the video database. - * @return A reference to the video database. - */ - CVideoDatabase& GetVideoDatabase(); /** * @brief recursively deletes all recordings in the specified directory diff -Nru kodi-18.2+git20190422.1151-final/xbmc/pvr/timers/PVRTimers.cpp kodi-18.3+git20190621.1610-final/xbmc/pvr/timers/PVRTimers.cpp --- kodi-18.2+git20190422.1151-final/xbmc/pvr/timers/PVRTimers.cpp 2019-04-22 09:51:08.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/pvr/timers/PVRTimers.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -13,7 +13,6 @@ #include "FileItem.h" #include "ServiceBroker.h" #include "addons/PVRClient.h" -#include "guilib/LocalizeStrings.h" #include "settings/Settings.h" #include "threads/SingleLock.h" #include "utils/log.h" @@ -23,7 +22,6 @@ #include "pvr/addons/PVRClients.h" #include "pvr/channels/PVRChannelGroupsContainer.h" #include "pvr/epg/EpgContainer.h" -#include "pvr/timers/PVRTimersPath.h" using namespace PVR; @@ -78,8 +76,7 @@ CSettings::SETTING_PVRPOWERMANAGEMENT_PREWAKEUP, CSettings::SETTING_PVRPOWERMANAGEMENT_BACKENDIDLETIME, CSettings::SETTING_PVRPOWERMANAGEMENT_DAILYWAKEUPTIME, - CSettings::SETTING_PVRRECORD_TIMERNOTIFICATIONS, - CSettings::SETTING_PVRTIMERS_HIDEDISABLEDTIMERS + CSettings::SETTING_PVRRECORD_TIMERNOTIFICATIONS }) { } @@ -491,93 +488,6 @@ return false; } -bool CPVRTimers::GetRootDirectory(const CPVRTimersPath &path, CFileItemList &items) const -{ - CFileItemPtr item(new CFileItem(CPVRTimersPath::PATH_ADDTIMER, false)); - item->SetLabel(g_localizeStrings.Get(19026)); // "Add timer..." - item->SetLabelPreformatted(true); - item->SetSpecialSort(SortSpecialOnTop); - item->SetIconImage("DefaultTVShows.png"); - items.Add(item); - - bool bRadio = path.IsRadio(); - bool bRules = path.IsRules(); - - bool bHideDisabled = m_settings.GetBoolValue(CSettings::SETTING_PVRTIMERS_HIDEDISABLEDTIMERS); - - CSingleLock lock(m_critSection); - for (const auto &tagsEntry : m_tags) - { - for (const auto &timer : tagsEntry.second) - { - if ((bRadio == timer->m_bIsRadio || (bRules && timer->m_iClientChannelUid == PVR_TIMER_ANY_CHANNEL)) && - (bRules == timer->IsTimerRule()) && - (!bHideDisabled || (timer->m_state != PVR_TIMER_STATE_DISABLED))) - { - item.reset(new CFileItem(timer)); - std::string strItemPath( - CPVRTimersPath(path.GetPath(), timer->m_iClientId, timer->m_iClientIndex).GetPath()); - item->SetPath(strItemPath); - items.Add(item); - } - } - } - return true; -} - -bool CPVRTimers::GetSubDirectory(const CPVRTimersPath &path, CFileItemList &items) const -{ - bool bRadio = path.IsRadio(); - unsigned int iParentId = path.GetParentId(); - int iClientId = path.GetClientId(); - - bool bHideDisabled = m_settings.GetBoolValue(CSettings::SETTING_PVRTIMERS_HIDEDISABLEDTIMERS); - - CFileItemPtr item; - - CSingleLock lock(m_critSection); - for (const auto &tagsEntry : m_tags) - { - for (const auto &timer : tagsEntry.second) - { - if ((timer->m_bIsRadio == bRadio) && - (timer->m_iParentClientIndex != PVR_TIMER_NO_PARENT) && - (timer->m_iClientId == iClientId) && - (timer->m_iParentClientIndex == iParentId) && - (!bHideDisabled || (timer->m_state != PVR_TIMER_STATE_DISABLED))) - { - item.reset(new CFileItem(timer)); - std::string strItemPath( - CPVRTimersPath(path.GetPath(), timer->m_iClientId, timer->m_iClientIndex).GetPath()); - item->SetPath(strItemPath); - items.Add(item); - } - } - } - return true; -} - -bool CPVRTimers::GetDirectory(const std::string& strPath, CFileItemList &items) const -{ - CPVRTimersPath path(strPath); - if (path.IsValid()) - { - if (path.IsTimersRoot()) - { - /* Root folder containing either timer rules or timers. */ - return GetRootDirectory(path, items); - } - else if (path.IsTimerRule()) - { - /* Sub folder containing the timers scheduled by the given timer rule. */ - return GetSubDirectory(path, items); - } - } - - CLog::LogF(LOGERROR,"Invalid URL %s", strPath.c_str()); - return false; -} - /********** channel methods **********/ bool CPVRTimers::DeleteTimersOnChannel(const CPVRChannelPtr &channel, bool bDeleteTimerRules /* = true */, bool bCurrentlyActiveOnly /* = false */) @@ -823,18 +733,20 @@ } } -void CPVRTimers::GetAll(CFileItemList& items) const +std::vector> CPVRTimers::GetAll() const { - CFileItemPtr item; + std::vector> timers; + CSingleLock lock(m_critSection); - for (MapTags::const_iterator it = m_tags.begin(); it != m_tags.end(); ++it) + for (const auto& tagsEntry : m_tags) { - for (VecTimerInfoTag::const_iterator timerIt = it->second.begin(); timerIt != it->second.end(); ++timerIt) + for (const auto& timer : tagsEntry.second) { - item.reset(new CFileItem(*timerIt)); - items.Add(item); + timers.emplace_back(timer); } } + + return timers; } CPVRTimerInfoTagPtr CPVRTimers::GetById(unsigned int iTimerId) const diff -Nru kodi-18.2+git20190422.1151-final/xbmc/pvr/timers/PVRTimers.h kodi-18.3+git20190621.1610-final/xbmc/pvr/timers/PVRTimers.h --- kodi-18.2+git20190422.1151-final/xbmc/pvr/timers/PVRTimers.h 2019-04-22 09:51:08.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/pvr/timers/PVRTimers.h 2019-06-21 14:09:24.000000000 +0000 @@ -21,7 +21,6 @@ #include "pvr/timers/PVRTimerInfoTag.h" class CFileItem; -class CFileItemList; typedef std::shared_ptr CFileItemPtr; namespace PVR @@ -107,9 +106,9 @@ /*! * Get all timers - * @param items The list to add the timers to + * @return The list of all timers */ - void GetAll(CFileItemList& items) const; + std::vector> GetAll() const; /*! * @return True when there is at least one timer that is active (states scheduled or recording), false otherwise. @@ -181,14 +180,6 @@ int AmountActiveRadioRecordings(void) const; /*! - * @brief Get all timers for the given path. - * @param strPath The vfs path to get the timers for. - * @param items The results. - * @return True when the path was valid, false otherwise. - */ - bool GetDirectory(const std::string& strPath, CFileItemList &items) const; - - /*! * @brief Delete all timers on a channel. * @param channel The channel to delete the timers for. * @param bDeleteTimerRules True to delete timer rules too, false otherwise. @@ -270,8 +261,6 @@ private: bool UpdateEntries(const CPVRTimersContainer &timers, const std::vector &failedClients); - bool GetRootDirectory(const CPVRTimersPath &path, CFileItemList &items) const; - bool GetSubDirectory(const CPVRTimersPath &path, CFileItemList &items) const; enum TimerKind { diff -Nru kodi-18.2+git20190422.1151-final/xbmc/pvr/windows/GUIWindowPVRBase.cpp kodi-18.3+git20190621.1610-final/xbmc/pvr/windows/GUIWindowPVRBase.cpp --- kodi-18.2+git20190422.1151-final/xbmc/pvr/windows/GUIWindowPVRBase.cpp 2019-04-22 09:51:08.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/pvr/windows/GUIWindowPVRBase.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -437,6 +437,14 @@ bool CGUIWindowPVRBase::Update(const std::string &strDirectory, bool updateFilterPath /*= true*/) { + if (m_bUpdating) + { + // no concurrent updates + return false; + } + + CUpdateGuard guard(m_bUpdating); + if (!GetChannelGroup()) { // no updates before fully initialized diff -Nru kodi-18.2+git20190422.1151-final/xbmc/pvr/windows/GUIWindowPVRBase.h kodi-18.3+git20190621.1610-final/xbmc/pvr/windows/GUIWindowPVRBase.h --- kodi-18.2+git20190422.1151-final/xbmc/pvr/windows/GUIWindowPVRBase.h 2018-07-31 18:47:40.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/pvr/windows/GUIWindowPVRBase.h 2019-06-21 14:09:24.000000000 +0000 @@ -102,6 +102,7 @@ CCriticalSection m_critSection; bool m_bRadio; + std::atomic_bool m_bUpdating = {false}; private: bool OpenChannelGroupSelectionDialog(void); diff -Nru kodi-18.2+git20190422.1151-final/xbmc/pvr/windows/GUIWindowPVRGuide.cpp kodi-18.3+git20190621.1610-final/xbmc/pvr/windows/GUIWindowPVRGuide.cpp --- kodi-18.2+git20190422.1151-final/xbmc/pvr/windows/GUIWindowPVRGuide.cpp 2019-04-22 09:51:08.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/pvr/windows/GUIWindowPVRGuide.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -192,15 +192,13 @@ bool CGUIWindowPVRGuideBase::Update(const std::string &strDirectory, bool updateFilterPath /* = true */) { - if (m_vecItemsUpdating) + if (m_bUpdating) { // Prevent concurrent updates. Instead, let the timeline items refresh thread pick it up later. m_bRefreshTimelineItems = true; return true; } - CUpdateGuard guard(m_vecItemsUpdating); - bool bReturn = CGUIWindowPVRBase::Update(strDirectory, updateFilterPath); if (bReturn && !m_bChannelSelectionRestored) @@ -625,7 +623,7 @@ m_bFirstOpen = false; // very first open of the window. come up with some data very fast... - const std::vector groupMembers = group->GetMembers(); + const std::vector groupMembers = group->GetMembers(CPVRChannelGroup::Include::ONLY_VISIBLE); for (const auto& groupMember : groupMembers) { // fake a channel without epg diff -Nru kodi-18.2+git20190422.1151-final/xbmc/settings/AdvancedSettings.cpp kodi-18.3+git20190621.1610-final/xbmc/settings/AdvancedSettings.cpp --- kodi-18.2+git20190422.1151-final/xbmc/settings/AdvancedSettings.cpp 2019-04-22 09:48:19.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/settings/AdvancedSettings.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -103,7 +103,7 @@ params.SetAdvancedSettings(*this); settingsMgr.RegisterSettingOptionsFiller("loggingcomponents", SettingOptionsLoggingComponentsFiller); - settingsMgr.RegisterSettingsHandler(this); + settingsMgr.RegisterSettingsHandler(this, true); std::set settingSet; settingSet.insert(CSettings::SETTING_DEBUG_SHOWLOGINFO); settingSet.insert(CSettings::SETTING_DEBUG_EXTRALOGGING); @@ -428,7 +428,7 @@ m_databaseVideo.Reset(); m_pictureExtensions = ".png|.jpg|.jpeg|.bmp|.gif|.ico|.tif|.tiff|.tga|.pcx|.cbz|.zip|.rss|.webp|.jp2|.apng"; - m_musicExtensions = ".nsv|.m4a|.flac|.aac|.strm|.pls|.rm|.rma|.mpa|.wav|.wma|.ogg|.mp3|.mp2|.m3u|.gdm|.imf|.m15|.sfx|.uni|.ac3|.dts|.cue|.aif|.aiff|.wpl|.xspf|.ape|.mac|.mpc|.mp+|.mpp|.shn|.zip|.wv|.dsp|.xsp|.xwav|.waa|.wvs|.wam|.gcm|.idsp|.mpdsp|.mss|.spt|.rsd|.sap|.cmc|.cmr|.dmc|.mpt|.mpd|.rmt|.tmc|.tm8|.tm2|.oga|.url|.pxml|.tta|.rss|.wtv|.mka|.tak|.opus|.dff|.dsf|.m4b"; + m_musicExtensions = ".nsv|.m4a|.flac|.aac|.strm|.pls|.rm|.rma|.mpa|.wav|.wma|.ogg|.mp3|.mp2|.m3u|.gdm|.imf|.m15|.sfx|.uni|.ac3|.dts|.cue|.aif|.aiff|.wpl|.xspf|.ape|.mac|.mpc|.mp+|.mpp|.shn|.zip|.wv|.dsp|.xsp|.xwav|.waa|.wvs|.wam|.gcm|.idsp|.mpdsp|.mss|.spt|.rsd|.sap|.cmc|.cmr|.dmc|.mpt|.mpd|.rmt|.tmc|.tm8|.tm2|.oga|.url|.pxml|.tta|.rss|.wtv|.mka|.tak|.opus|.dff|.dsf|.m4b|.dtshd"; m_videoExtensions = ".m4v|.3g2|.3gp|.nsv|.tp|.ts|.ty|.strm|.pls|.rm|.rmvb|.mpd|.m3u|.m3u8|.ifo|.mov|.qt|.divx|.xvid|.bivx|.vob|.nrg|.img|.iso|.udf|.pva|.wmv|.asf|.asx|.ogm|.m2v|.avi|.bin|.dat|.mpg|.mpeg|.mp4|.mkv|.mk3d|.avc|.vp3|.svq3|.nuv|.viv|.dv|.fli|.flv|.001|.wpl|.xspf|.zip|.vdr|.dvr-ms|.xsp|.mts|.m2t|.m2ts|.evo|.ogv|.sdp|.avs|.rec|.url|.pxml|.vc1|.h264|.rcv|.rss|.mpls|.webm|.bdmv|.wtv|.trp|.f4v"; m_subtitlesExtensions = ".utf|.utf8|.utf-8|.sub|.srt|.smi|.rt|.txt|.ssa|.text|.ssa|.aqt|.jss|.ass|.idx|.ifo|.zip"; m_discStubExtensions = ".disc"; @@ -1049,10 +1049,10 @@ { std::string strFrom, strTo; TiXmlNode* pFrom = pSubstitute->FirstChild("from"); - if (pFrom) + if (pFrom && !pFrom->NoChildren()) strFrom = CSpecialProtocol::TranslatePath(pFrom->FirstChild()->Value()).c_str(); TiXmlNode* pTo = pSubstitute->FirstChild("to"); - if (pTo) + if (pTo && !pTo->NoChildren()) strTo = pTo->FirstChild()->Value(); if (!strFrom.empty() && !strTo.empty()) diff -Nru kodi-18.2+git20190422.1151-final/xbmc/settings/lib/SettingsManager.cpp kodi-18.3+git20190621.1610-final/xbmc/settings/lib/SettingsManager.cpp --- kodi-18.2+git20190422.1151-final/xbmc/settings/lib/SettingsManager.cpp 2018-11-21 19:38:54.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/settings/lib/SettingsManager.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -423,14 +423,19 @@ m_settingControlCreators.insert(std::make_pair(controlType, settingControlCreator)); } -void CSettingsManager::RegisterSettingsHandler(ISettingsHandler *settingsHandler) +void CSettingsManager::RegisterSettingsHandler(ISettingsHandler *settingsHandler, bool bFront /* = false */) { if (settingsHandler == nullptr) return; CExclusiveLock lock(m_critical); if (find(m_settingsHandlers.begin(), m_settingsHandlers.end(), settingsHandler) == m_settingsHandlers.end()) - m_settingsHandlers.push_back(settingsHandler); + { + if (bFront) + m_settingsHandlers.insert(m_settingsHandlers.begin(), settingsHandler); + else + m_settingsHandlers.emplace_back(settingsHandler); + } } void CSettingsManager::UnregisterSettingsHandler(ISettingsHandler *settingsHandler) diff -Nru kodi-18.2+git20190422.1151-final/xbmc/settings/lib/SettingsManager.h kodi-18.3+git20190621.1610-final/xbmc/settings/lib/SettingsManager.h --- kodi-18.2+git20190422.1151-final/xbmc/settings/lib/SettingsManager.h 2018-11-04 08:12:29.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/settings/lib/SettingsManager.h 2019-06-21 14:09:24.000000000 +0000 @@ -223,8 +223,9 @@ \brief Registers the given ISettingsHandler implementation. \param settingsHandler ISettingsHandler implementation + \param bFront If True, insert the handler in front of other registered handlers, insert at the end otherwise. */ - void RegisterSettingsHandler(ISettingsHandler *settingsHandler); + void RegisterSettingsHandler(ISettingsHandler *settingsHandler, bool bFront = false); /*! \brief Unregisters the given ISettingsHandler implementation. diff -Nru kodi-18.2+git20190422.1151-final/xbmc/utils/ActorProtocol.cpp kodi-18.3+git20190621.1610-final/xbmc/utils/ActorProtocol.cpp --- kodi-18.2+git20190422.1151-final/xbmc/utils/ActorProtocol.cpp 2018-07-31 18:47:40.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/utils/ActorProtocol.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -28,7 +28,7 @@ if (data != buffer) delete [] data; - payloadObj.release(); + payloadObj.reset(); // delete event in case of sync message delete event; diff -Nru kodi-18.2+git20190422.1151-final/xbmc/utils/CMakeLists.txt kodi-18.3+git20190621.1610-final/xbmc/utils/CMakeLists.txt --- kodi-18.2+git20190422.1151-final/xbmc/utils/CMakeLists.txt 2019-04-22 09:48:19.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/utils/CMakeLists.txt 2019-06-21 14:09:24.000000000 +0000 @@ -169,8 +169,10 @@ list(APPEND HEADERS XSLTUtils.h) endif() if(EGL_FOUND) - list(APPEND SOURCES EGLUtils.cpp) - list(APPEND HEADERS EGLUtils.h) + list(APPEND SOURCES EGLUtils.cpp + EGLFence.cpp) + list(APPEND HEADERS EGLUtils.h + EGLFence.h) endif() # The large map trips the clang optimizer diff -Nru kodi-18.2+git20190422.1151-final/xbmc/utils/EGLFence.cpp kodi-18.3+git20190621.1610-final/xbmc/utils/EGLFence.cpp --- kodi-18.2+git20190422.1151-final/xbmc/utils/EGLFence.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/utils/EGLFence.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2017-2018 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 "EGLFence.h" + +#include "EGLUtils.h" + +using namespace KODI::UTILS::EGL; + +CEGLFence::CEGLFence(EGLDisplay display) : + m_display(display) +{ + m_eglCreateSyncKHR = CEGLUtils::GetRequiredProcAddress("eglCreateSyncKHR"); + m_eglDestroySyncKHR = CEGLUtils::GetRequiredProcAddress("eglDestroySyncKHR"); + m_eglGetSyncAttribKHR = CEGLUtils::GetRequiredProcAddress("eglGetSyncAttribKHR"); +} + +void CEGLFence::CreateFence() +{ + m_fence = m_eglCreateSyncKHR(m_display, EGL_SYNC_FENCE_KHR, nullptr); + if (m_fence == EGL_NO_SYNC_KHR) + { + CEGLUtils::LogError("failed to create egl sync fence"); + throw std::runtime_error("failed to create egl sync fence"); + } +} + +void CEGLFence::DestroyFence() +{ + if (m_fence == EGL_NO_SYNC_KHR) + { + return; + } + + if (m_eglDestroySyncKHR(m_display, m_fence) != EGL_TRUE) + { + CEGLUtils::LogError("failed to destroy egl sync fence"); + } + + m_fence = EGL_NO_SYNC_KHR; +} + +bool CEGLFence::IsSignaled() +{ + // fence has been destroyed so return true immediately so buffer can be used + if (m_fence == EGL_NO_SYNC_KHR) + { + return true; + } + + EGLint status = EGL_UNSIGNALED_KHR; + if (m_eglGetSyncAttribKHR(m_display, m_fence, EGL_SYNC_STATUS_KHR, &status) != EGL_TRUE) + { + CEGLUtils::LogError("failed to query egl sync fence"); + return false; + } + + if (status == EGL_SIGNALED_KHR) + { + return true; + } + + return false; +} diff -Nru kodi-18.2+git20190422.1151-final/xbmc/utils/EGLFence.h kodi-18.3+git20190621.1610-final/xbmc/utils/EGLFence.h --- kodi-18.2+git20190422.1151-final/xbmc/utils/EGLFence.h 1970-01-01 00:00:00.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/utils/EGLFence.h 2019-06-21 14:09:24.000000000 +0000 @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2017-2018 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 +#include + +namespace KODI +{ +namespace UTILS +{ +namespace EGL +{ + +class CEGLFence +{ +public: + explicit CEGLFence(EGLDisplay display); + CEGLFence(CEGLFence const& other) = delete; + CEGLFence& operator=(CEGLFence const& other) = delete; + + void CreateFence(); + void DestroyFence(); + bool IsSignaled(); + +private: + EGLDisplay m_display{nullptr}; + EGLSyncKHR m_fence{nullptr}; + + PFNEGLCREATESYNCKHRPROC m_eglCreateSyncKHR{nullptr}; + PFNEGLDESTROYSYNCKHRPROC m_eglDestroySyncKHR{nullptr}; + PFNEGLGETSYNCATTRIBKHRPROC m_eglGetSyncAttribKHR{nullptr}; +}; + +} +} +} diff -Nru kodi-18.2+git20190422.1151-final/xbmc/utils/ScraperUrl.cpp kodi-18.3+git20190621.1610-final/xbmc/utils/ScraperUrl.cpp --- kodi-18.2+git20190422.1151-final/xbmc/utils/ScraperUrl.cpp 2019-04-22 09:51:08.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/utils/ScraperUrl.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -139,7 +139,7 @@ { for (std::vector::const_iterator iter=m_url.begin();iter != m_url.end();++iter) { - if (iter->m_type == URL_TYPE_GENERAL && (type.empty() || type == "thumb" || iter->m_aspect == type)) + if (iter->m_type == URL_TYPE_GENERAL && (type.empty() || iter->m_aspect == type)) return *iter; } @@ -374,7 +374,7 @@ { for (std::vector::const_iterator iter = m_url.begin(); iter != m_url.end(); ++iter) { - if (iter->m_aspect == type || type.empty() || type == "thumb" || iter->m_aspect.empty()) + if (iter->m_aspect == type || type.empty() || iter->m_aspect.empty()) { if ((iter->m_type == CScraperUrl::URL_TYPE_GENERAL && season == -1) || (iter->m_type == CScraperUrl::URL_TYPE_SEASON && iter->m_season == season)) diff -Nru kodi-18.2+git20190422.1151-final/xbmc/video/windows/GUIWindowVideoNav.cpp kodi-18.3+git20190621.1610-final/xbmc/video/windows/GUIWindowVideoNav.cpp --- kodi-18.2+git20190422.1151-final/xbmc/video/windows/GUIWindowVideoNav.cpp 2018-10-23 16:19:51.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/video/windows/GUIWindowVideoNav.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -271,8 +271,10 @@ { int iIndex = 0; int iUnwatchedSeason = INT_MAX; + int iUnwatchedEpisode = INT_MAX; + NODE_TYPE nodeType = CVideoDatabaseDirectory::GetDirectoryChildType(m_vecItems->GetPath()); - // Run through the list of items and find the season number of the first season with unwatched episodes + // Run through the list of items and find the first unwatched season/episode for (int i = 0; i < m_vecItems->Size(); ++i) { CFileItemPtr pItem = m_vecItems->Get(i); @@ -284,36 +286,29 @@ if ((!includeAllSeasons && pTag->m_iSeason < 0) || (!includeSpecials && pTag->m_iSeason == 0)) continue; - // Is the season unwatched, and is its season number lower than the currently identified - // first unwatched season - if (pTag->GetPlayCount() == 0 && pTag->m_iSeason < iUnwatchedSeason) + // Use the special sort values if they're available + int iSeason = pTag->m_iSpecialSortSeason >= 0 ? pTag->m_iSpecialSortSeason : pTag->m_iSeason; + int iEpisode = pTag->m_iSpecialSortEpisode >= 0 ? pTag->m_iSpecialSortEpisode : pTag->m_iEpisode; + + if (nodeType == NODE_TYPE::NODE_TYPE_SEASONS) { - iUnwatchedSeason = pTag->m_iSeason; - iIndex = i; + // Is the season unwatched, and is its season number lower than the currently identified + // first unwatched season + if (pTag->GetPlayCount() == 0 && iSeason < iUnwatchedSeason) + { + iUnwatchedSeason = iSeason; + iIndex = i; + } } - } - - NODE_TYPE nodeType = CVideoDatabaseDirectory::GetDirectoryChildType(m_vecItems->GetPath()); - if (nodeType == NODE_TYPE::NODE_TYPE_EPISODES) - { - iIndex = 0; - int iUnwatchedEpisode = INT_MAX; - // Now run through the list of items and check episodes from the season identified above - // to find the first (lowest episode number) unwatched episode. - for (int i = 0; i < m_vecItems->Size(); ++i) + if (nodeType == NODE_TYPE::NODE_TYPE_EPISODES) { - CFileItemPtr pItem = m_vecItems->Get(i); - if (pItem->IsParentFolder() || !pItem->HasVideoInfoTag()) - continue; - - CVideoInfoTag *pTag = pItem->GetVideoInfoTag(); - - // Does the episode belong to the unwatched season and Is the episode unwatched, and is its episode number - // lower than the currently identified first unwatched episode - if (pTag->m_iSeason == iUnwatchedSeason && pTag->GetPlayCount() == 0 && pTag->m_iEpisode < iUnwatchedEpisode) + // Is the episode unwatched, and is its season number lower + // or is its episode number lower within the current season + if (pTag->GetPlayCount() == 0 && (iSeason < iUnwatchedSeason || (iSeason == iUnwatchedSeason && iEpisode < iUnwatchedEpisode))) { - iUnwatchedEpisode = pTag->m_iEpisode; + iUnwatchedSeason = iSeason; + iUnwatchedEpisode = iEpisode; iIndex = i; } } diff -Nru kodi-18.2+git20190422.1151-final/xbmc/windowing/gbm/DRMUtils.cpp kodi-18.3+git20190621.1610-final/xbmc/windowing/gbm/DRMUtils.cpp --- kodi-18.2+git20190422.1151-final/xbmc/windowing/gbm/DRMUtils.cpp 2019-04-22 09:48:20.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/windowing/gbm/DRMUtils.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -109,27 +109,43 @@ memset(offsets, 0, 16); #endif - if (modifiers[0] == DRM_FORMAT_MOD_INVALID) - modifiers[0] = DRM_FORMAT_MOD_LINEAR; + uint32_t flags = 0; - CLog::Log(LOGDEBUG, "CDRMUtils::%s - using modifier: %lli", __FUNCTION__, modifiers[0]); + if (modifiers[0] && modifiers[0] != DRM_FORMAT_MOD_INVALID) + { + flags |= DRM_MODE_FB_MODIFIERS; + CLog::Log(LOGDEBUG, "CDRMUtils::{} - using modifier: {:#x}", __FUNCTION__, modifiers[0]); + } - auto ret = drmModeAddFB2WithModifiers(m_fd, - width, - height, - fb->format, - handles, - strides, - offsets, - modifiers, - &fb->fb_id, - (modifiers[0] > 0) ? DRM_MODE_FB_MODIFIERS : 0); - - if(ret) - { - delete (fb); - CLog::Log(LOGDEBUG, "CDRMUtils::%s - failed to add framebuffer", __FUNCTION__); - return nullptr; + int ret = drmModeAddFB2WithModifiers(m_fd, + width, + height, + fb->format, + handles, + strides, + offsets, + modifiers, + &fb->fb_id, + flags); + + if(ret < 0) + { + ret = drmModeAddFB2(m_fd, + width, + height, + fb->format, + handles, + strides, + offsets, + &fb->fb_id, + flags); + + if (ret < 0) + { + delete (fb); + CLog::Log(LOGDEBUG, "CDRMUtils::{} - failed to add framebuffer: {} ({})", __FUNCTION__, strerror(errno), errno); + return nullptr; + } } gbm_bo_set_user_data(bo, fb, DrmFbDestroyCallback); @@ -579,10 +595,26 @@ auto ret = drmSetClientCap(m_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); if (ret) { - CLog::Log(LOGERROR, "CDRMUtils::%s - failed to set Universal planes capability: %s", __FUNCTION__, strerror(errno)); + CLog::Log(LOGERROR, "CDRMUtils::{} - failed to set universal planes capability: {}", __FUNCTION__, strerror(errno)); + return false; + } + + ret = drmSetClientCap(m_fd, DRM_CLIENT_CAP_STEREO_3D, 1); + if (ret) + { + CLog::Log(LOGERROR, "CDRMUtils::{} - failed to set stereo 3d capability: {}", __FUNCTION__, strerror(errno)); return false; } +#if defined(DRM_CLIENT_CAP_ASPECT_RATIO) + ret = drmSetClientCap(m_fd, DRM_CLIENT_CAP_ASPECT_RATIO, 0); + if (ret) + { + CLog::Log(LOGERROR, "CDRMUtils::{} - failed to unset aspect ratio capability: {}", __FUNCTION__, strerror(errno)); + return false; + } +#endif + if(!GetResources()) { return false; diff -Nru kodi-18.2+git20190422.1151-final/xbmc/windowing/gbm/WinSystemGbm.cpp kodi-18.3+git20190621.1610-final/xbmc/windowing/gbm/WinSystemGbm.cpp --- kodi-18.2+git20190422.1151-final/xbmc/windowing/gbm/WinSystemGbm.cpp 2018-11-21 19:38:54.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/windowing/gbm/WinSystemGbm.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -207,11 +207,19 @@ m_videoLayerBridge->Disable(); } - struct gbm_bo *bo = m_GBM->LockFrontBuffer(); + struct gbm_bo *bo = nullptr; + + if (rendered) + { + bo = m_GBM->LockFrontBuffer(); + } m_DRM->FlipPage(bo, rendered, videoLayer); - m_GBM->ReleaseBuffer(); + if (rendered) + { + m_GBM->ReleaseBuffer(); + } if (m_videoLayerBridge && !videoLayer) { diff -Nru kodi-18.2+git20190422.1151-final/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp kodi-18.3+git20190621.1610-final/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp --- kodi-18.2+git20190422.1151-final/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp 2018-11-21 19:38:54.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -14,6 +14,7 @@ #include "cores/RetroPlayer/rendering/VideoRenderers/RPRendererGBM.h" #include "cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGLES.h" #include "cores/VideoPlayer/DVDCodecs/DVDFactoryCodec.h" +#include "cores/VideoPlayer/Process/gbm/ProcessInfoGBM.h" #include "cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.h" #include "cores/VideoPlayer/VideoRenderers/RenderFactory.h" @@ -65,6 +66,7 @@ CRendererDRMPRIMEGLES::Register(); CRendererDRMPRIME::Register(); CDVDVideoCodecDRMPRIME::Register(); + VIDEOPLAYER::CProcessInfoGBM::Register(); return true; } diff -Nru kodi-18.2+git20190422.1151-final/xbmc/windowing/Resolution.cpp kodi-18.3+git20190621.1610-final/xbmc/windowing/Resolution.cpp --- kodi-18.2+git20190422.1151-final/xbmc/windowing/Resolution.cpp 2019-04-22 09:51:08.000000000 +0000 +++ kodi-18.3+git20190621.1610-final/xbmc/windowing/Resolution.cpp 2019-06-21 14:09:24.000000000 +0000 @@ -163,13 +163,12 @@ } } - CLog::Log(LOGDEBUG, "No double refresh rate whitelisted resolution matched, trying current resolution"); + CLog::Log(LOGDEBUG, "No 3:2 pullback refresh rate whitelisted resolution matched, trying current resolution"); if (width <= curr.iScreenWidth && height <= curr.iScreenHeight && (MathUtils::FloatEquals(curr.fRefreshRate, fps, 0.01f) - || MathUtils::FloatEquals(curr.fRefreshRate, fps * 2, 0.01f) - || MathUtils::FloatEquals(curr.fRefreshRate, fps * 2.5f, 0.01f))) + || MathUtils::FloatEquals(curr.fRefreshRate, fps * 2, 0.01f))) { CLog::Log(LOGDEBUG, "Matched current Resolution %s (%d)", curr.strMode.c_str(), resolution); return;