diff options
-rw-r--r-- | addons/resource.language.en_gb/resources/strings.po | 12 | ||||
-rwxr-xr-x | system/settings/settings.xml | 11 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp | 15 | ||||
-rw-r--r-- | xbmc/settings/SettingConditions.cpp | 9 | ||||
-rw-r--r-- | xbmc/settings/Settings.h | 1 | ||||
-rw-r--r-- | xbmc/utils/BitstreamConverter.cpp | 76 | ||||
-rw-r--r-- | xbmc/utils/BitstreamConverter.h | 2 |
7 files changed, 125 insertions, 1 deletions
diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index 8c2dcfa3a1..80e144370b 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -23481,3 +23481,15 @@ msgstr "" msgctxt "#39195" msgid "Enable this option for the best picture quality. Disabling reduces the load on resource-limited systems." msgstr "" + +#. Title of Dolby Vision RPU conversion setting +#: system/settings/settings.xml +msgctxt "#39196" +msgid "Dolby Vision compatibility mode" +msgstr "" + +#. Help text for setting "Convert Dolby Vision for compatibility" of label #39196 +#: system/settings/settings.xml +msgctxt "#39197" +msgid "If enabled, Dolby Vision profile 7 will be converted to profile 8.1, which is more commonly supported by devices. Enable if your device supports Dolby Vision, but has issues with some videos." +msgstr "" diff --git a/system/settings/settings.xml b/system/settings/settings.xml index 60539c9b0d..d9218c470d 100755 --- a/system/settings/settings.xml +++ b/system/settings/settings.xml @@ -179,6 +179,17 @@ <default>true</default> <control type="toggle" /> </setting> + <setting id="videoplayer.convertdovi" type="boolean" label="39196" help="39197"> + <requirement>HAS_MEDIACODEC</requirement> + <dependencies> + <dependency type="visible"> + <condition on="property" name="supportsdolbyvision" /> + </dependency> + </dependencies> + <level>2</level> + <default>false</default> + <control type="toggle" /> + </setting> </group> <group id="4" label="14232"> <setting id="videoplayer.stereoscopicplaybackmode" type="integer" label="36520" help="36537"> diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp index 31bf35bfe5..68203861fc 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp @@ -560,7 +560,22 @@ bool CDVDVideoCodecAndroidMediaCodec::Open(CDVDStreamInfo &hints, CDVDCodecOptio { m_bitstream.reset(); } + + // Only set for profile 7, container hint allows to skip parsing unnecessarily + if (m_bitstream && m_hints.dovi.dv_profile == 7) + { + bool convertDovi = CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool( + CSettings::SETTING_VIDEOPLAYER_CONVERTDOVI); + + CLog::Log(LOGDEBUG, + "CDVDVideoCodecAndroidMediaCodec::Open Dolby Vision compatibility mode " + "enabled: {}", + convertDovi); + + m_bitstream->SetConvertDovi(convertDovi); + } } + break; } case AV_CODEC_ID_WMV3: diff --git a/xbmc/settings/SettingConditions.cpp b/xbmc/settings/SettingConditions.cpp index d9710c0e0c..45997a36a4 100644 --- a/xbmc/settings/SettingConditions.cpp +++ b/xbmc/settings/SettingConditions.cpp @@ -118,6 +118,14 @@ bool SupportsVideoSuperResolution(const std::string& condition, return CServiceBroker::GetWinSystem()->SupportsVideoSuperResolution(); } +bool SupportsDolbyVision(const std::string& condition, + const std::string& value, + const SettingConstPtr& setting, + void* data) +{ + return CServiceBroker::GetWinSystem()->GetDisplayHDRCapabilities().SupportsDolbyVision(); +} + bool SupportsScreenMove(const std::string& condition, const std::string& value, const SettingConstPtr& setting, @@ -470,6 +478,7 @@ void CSettingConditions::Initialize() m_complexConditions.emplace("hassystemsdrpeakluminance", HasSystemSdrPeakLuminance); m_complexConditions.emplace("supportsscreenmove", SupportsScreenMove); m_complexConditions.emplace("supportsvideosuperresolution", SupportsVideoSuperResolution); + m_complexConditions.emplace("supportsdolbyvision", SupportsDolbyVision); m_complexConditions.emplace("ishdrdisplay", IsHDRDisplay); m_complexConditions.emplace("ismasteruser", IsMasterUser); m_complexConditions.emplace("hassubtitlesfontextensions", HasSubtitlesFontExtensions); diff --git a/xbmc/settings/Settings.h b/xbmc/settings/Settings.h index 23206f3439..349a153065 100644 --- a/xbmc/settings/Settings.h +++ b/xbmc/settings/Settings.h @@ -129,6 +129,7 @@ public: static constexpr auto SETTING_VIDEOPLAYER_USESTAGEFRIGHT = "videoplayer.usestagefright"; static constexpr auto SETTING_VIDEOPLAYER_LIMITGUIUPDATE = "videoplayer.limitguiupdate"; static constexpr auto SETTING_VIDEOPLAYER_SUPPORTMVC = "videoplayer.supportmvc"; + static constexpr auto SETTING_VIDEOPLAYER_CONVERTDOVI = "videoplayer.convertdovi"; static constexpr auto SETTING_MYVIDEOS_SELECTACTION = "myvideos.selectaction"; static constexpr auto SETTING_MYVIDEOS_USETAGS = "myvideos.usetags"; static constexpr auto SETTING_MYVIDEOS_EXTRACTFLAGS = "myvideos.extractflags"; diff --git a/xbmc/utils/BitstreamConverter.cpp b/xbmc/utils/BitstreamConverter.cpp index 1bca7d14d8..5fb96d4ed5 100644 --- a/xbmc/utils/BitstreamConverter.cpp +++ b/xbmc/utils/BitstreamConverter.cpp @@ -20,6 +20,13 @@ #include <algorithm> +extern "C" +{ +#ifdef HAVE_LIBDOVI +#include <libdovi/rpu_parser.h> +#endif +} + enum { AVC_NAL_SLICE=1, AVC_NAL_DPA, @@ -257,6 +264,32 @@ static bool has_sei_recovery_point(const uint8_t *p, const uint8_t *end) return false; } +#ifdef HAVE_LIBDOVI +// The returned data must be freed with `dovi_data_free` +// May be NULL if no conversion was done +static const DoviData* convert_dovi_rpu_nal(uint8_t* buf, uint32_t nal_size) +{ + DoviRpuOpaque* rpu = dovi_parse_unspec62_nalu(buf, nal_size); + const DoviRpuDataHeader* header = dovi_rpu_get_header(rpu); + const DoviData* rpu_data = NULL; + + if (header && header->guessed_profile == 7) + { + int ret = dovi_convert_rpu_with_mode(rpu, 2); + if (ret < 0) + goto done; + + rpu_data = dovi_write_unspec62_nalu(rpu); + } + +done: + dovi_rpu_free_header(header); + dovi_rpu_free(rpu); + + return rpu_data; +} +#endif + //////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////// CBitstreamParser::CBitstreamParser() = default; @@ -322,6 +355,7 @@ CBitstreamConverter::CBitstreamConverter() m_convert_bytestream = false; m_sps_pps_context.sps_pps_data = NULL; m_start_decode = true; + m_convert_dovi = false; } CBitstreamConverter::~CBitstreamConverter() @@ -875,6 +909,10 @@ bool CBitstreamConverter::BitstreamConvert(uint8_t* pData, int iSize, uint8_t ** uint32_t cumul_size = 0; const uint8_t *buf_end = buf + buf_size; +#ifdef HAVE_LIBDOVI + const DoviData* rpu_data = NULL; +#endif + switch (m_codec) { case AV_CODEC_ID_H264: @@ -928,12 +966,48 @@ bool CBitstreamConverter::BitstreamConvert(uint8_t* pData, int iSize, uint8_t ** } else { - BitstreamAllocAndCopy(poutbuf, poutbuf_size, NULL, 0, buf, nal_size, unit_type); + bool write_buf = true; + const uint8_t* buf_to_write = buf; + int32_t final_nal_size = nal_size; + if (!m_sps_pps_context.first_idr && IsSlice(unit_type)) { m_sps_pps_context.first_idr = 1; m_sps_pps_context.idr_sps_pps_seen = 0; } + + if (m_convert_dovi) + { + if (unit_type == HEVC_NAL_UNSPEC62) + { +#ifdef HAVE_LIBDOVI + // Convert the RPU itself + rpu_data = convert_dovi_rpu_nal(buf, nal_size); + if (rpu_data) + { + buf_to_write = rpu_data->data; + final_nal_size = rpu_data->len; + } +#endif + } + else if (unit_type == HEVC_NAL_UNSPEC63) + { + // Ignore the enhancement layer, may or may not help + write_buf = false; + } + } + + if (write_buf) + BitstreamAllocAndCopy(poutbuf, poutbuf_size, NULL, 0, buf_to_write, final_nal_size, + unit_type); + +#ifdef HAVE_LIBDOVI + if (rpu_data) + { + dovi_data_free(rpu_data); + rpu_data = NULL; + } +#endif } buf += nal_size; diff --git a/xbmc/utils/BitstreamConverter.h b/xbmc/utils/BitstreamConverter.h index be63b7590c..1920212a2a 100644 --- a/xbmc/utils/BitstreamConverter.h +++ b/xbmc/utils/BitstreamConverter.h @@ -99,6 +99,7 @@ public: int GetExtraSize() const; void ResetStartDecode(void); bool CanStartDecode() const; + void SetConvertDovi(bool value) { m_convert_dovi = value; } static bool mpeg2_sequence_header(const uint8_t *data, const uint32_t size, mpeg2_sequence *sequence); @@ -143,4 +144,5 @@ protected: bool m_convert_bytestream; AVCodecID m_codec; bool m_start_decode; + bool m_convert_dovi; }; |