Skip to content

Commit

Permalink
[Android] Allow ignoring HDR10+ and Dolby Vision dynamic HDR formats
Browse files Browse the repository at this point in the history
  • Loading branch information
quietvoid committed Sep 9, 2023
1 parent 4d639b8 commit 20a46b2
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 11 deletions.
24 changes: 24 additions & 0 deletions addons/resource.language.en_gb/resources/strings.po
Expand Up @@ -23493,3 +23493,27 @@ msgstr ""
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 ""

#. Title of allowed dynamic HDR formats setting
#: system/settings/settings.xml
msgctxt "#39198"
msgid "Allowed dynamic HDR formats"
msgstr ""

#. Help text for setting "Allowed dynamic HDR formats" of label #39198
#: system/settings/settings.xml
msgctxt "#39199"
msgid "Alters the video bitstream to remove HDR10+, Dolby Vision metadata or both"
msgstr ""

#. Label of HDR10+ option for setting "Allowed dynamic HDR formats" of label #39198
#: system/settings/settings.xml
msgctxt "#39200"
msgid "HDR10+"
msgstr ""

#. Label of Dolby Vision option for setting "Allowed dynamic HDR formats" of label #39198
#: system/settings/settings.xml
msgctxt "#39201"
msgid "Dolby Vision"
msgstr ""
16 changes: 16 additions & 0 deletions system/settings/settings.xml
Expand Up @@ -190,6 +190,22 @@
<default>false</default>
<control type="toggle" />
</setting>
<setting id="videoplayer.allowedhdrformats" type="list[integer]" label="39198" help="39199">
<requirement>HAS_MEDIACODEC</requirement>
<level>2</level>
<default>0,1</default> <!-- Allow all HDR formats -->
<constraints>
<options>
<option label="39200">0</option> <!-- HDR10+ -->
<option label="39201">1</option> <!-- Dolby Vision -->
</options>
<delimiter>,</delimiter>
</constraints>
<control type="list" format="string">
<multiselect>true</multiselect>
<hidevalue>false</hidevalue>
</control>
</setting>
</group>
<group id="4" label="14232">
<setting id="videoplayer.stereoscopicplaybackmode" type="integer" label="36520" help="36537">
Expand Down
Expand Up @@ -23,8 +23,10 @@
#include "cores/VideoPlayer/VideoRenderers/RenderManager.h"
#include "media/decoderfilter/DecoderFilterManager.h"
#include "messaging/ApplicationMessenger.h"
#include "settings/SettingUtils.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
#include "settings/lib/Setting.h"
#include "utils/BitstreamConverter.h"
#include "utils/BitstreamWriter.h"
#include "utils/CPUInfo.h"
Expand Down Expand Up @@ -516,6 +518,15 @@ bool CDVDVideoCodecAndroidMediaCodec::Open(CDVDStreamInfo &hints, CDVDCodecOptio
m_mime = "video/hevc";
m_formatname = "amc-hevc";

const std::shared_ptr<CSettingList> allowedHdrFormatsSetting(
std::dynamic_pointer_cast<CSettingList>(
CServiceBroker::GetSettingsComponent()->GetSettings()->GetSetting(
CSettings::SETTING_VIDEOPLAYER_ALLOWEDHDRFORMATS)));
bool removeHdr10Plus = !CSettingUtils::FindIntInList(
allowedHdrFormatsSetting, CSettings::VIDEOPLAYER_ALLOWED_HDR_TYPE_HDR10PLUS);
bool removeDovi = !CSettingUtils::FindIntInList(
allowedHdrFormatsSetting, CSettings::VIDEOPLAYER_ALLOWED_HDR_TYPE_DOLBY_VISION);

bool isDvhe = (m_hints.codec_tag == MKTAG('d', 'v', 'h', 'e'));
bool isDvh1 = (m_hints.codec_tag == MKTAG('d', 'v', 'h', '1'));

Expand All @@ -529,7 +540,7 @@ bool CDVDVideoCodecAndroidMediaCodec::Open(CDVDStreamInfo &hints, CDVDCodecOptio
isDvhe = true;
}

if (isDvhe || isDvh1)
if (!removeDovi && (isDvhe || isDvh1))
{
bool displaySupportsDovi{false};
bool mediaCodecSupportsDovi{false};
Expand Down Expand Up @@ -561,18 +572,24 @@ 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)
if (m_bitstream)
{
bool convertDovi = CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
CSettings::SETTING_VIDEOPLAYER_CONVERTDOVI);
m_bitstream->SetRemoveHdr10Plus(removeHdr10Plus);
m_bitstream->SetRemoveDovi(removeDovi);

CLog::Log(LOGDEBUG,
"CDVDVideoCodecAndroidMediaCodec::Open Dolby Vision compatibility mode "
"enabled: {}",
convertDovi);
// Only set for profile 7, container hint allows to skip parsing unnecessarily
if (m_hints.dovi.dv_profile == 7)
{
bool convertDovi = CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
CSettings::SETTING_VIDEOPLAYER_CONVERTDOVI);

m_bitstream->SetConvertDovi(convertDovi);
CLog::Log(LOGDEBUG,
"CDVDVideoCodecAndroidMediaCodec::Open Dolby Vision compatibility mode "
"enabled: {}",
convertDovi);

m_bitstream->SetConvertDovi(convertDovi);
}
}
}

Expand Down
5 changes: 5 additions & 0 deletions xbmc/settings/Settings.h
Expand Up @@ -130,6 +130,7 @@ class CSettings : public CSettingsBase, public CSettingCreator, public CSettingC
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_VIDEOPLAYER_ALLOWEDHDRFORMATS = "videoplayer.allowedhdrformats";
static constexpr auto SETTING_MYVIDEOS_SELECTACTION = "myvideos.selectaction";
static constexpr auto SETTING_MYVIDEOS_USETAGS = "myvideos.usetags";
static constexpr auto SETTING_MYVIDEOS_EXTRACTFLAGS = "myvideos.extractflags";
Expand Down Expand Up @@ -483,6 +484,10 @@ class CSettings : public CSettingsBase, public CSettingCreator, public CSettingC
static constexpr int SETTING_AUTOPLAYNEXT_MOVIES = 3;
static constexpr int SETTING_AUTOPLAYNEXT_UNCATEGORIZED = 4;

// values for SETTING_VIDEOPLAYER_ALLOWEDHDRFORMATS
static const int VIDEOPLAYER_ALLOWED_HDR_TYPE_HDR10PLUS = 0;
static const int VIDEOPLAYER_ALLOWED_HDR_TYPE_DOLBY_VISION = 1;

/*!
\brief Creates a new settings wrapper around a new settings manager.
Expand Down
13 changes: 12 additions & 1 deletion xbmc/utils/BitstreamConverter.cpp
Expand Up @@ -356,6 +356,8 @@ CBitstreamConverter::CBitstreamConverter()
m_sps_pps_context.sps_pps_data = NULL;
m_start_decode = true;
m_convert_dovi = false;
m_remove_hdr10plus = false;
m_remove_dovi = false;
}

CBitstreamConverter::~CBitstreamConverter()
Expand Down Expand Up @@ -976,7 +978,16 @@ bool CBitstreamConverter::BitstreamConvert(uint8_t* pData, int iSize, uint8_t **
m_sps_pps_context.idr_sps_pps_seen = 0;
}

if (m_convert_dovi)
if (m_remove_dovi && (unit_type == HEVC_NAL_UNSPEC62 || unit_type == HEVC_NAL_UNSPEC63))
write_buf = false;

// Skip ITU-T T.35 SMPTE ST 2094-40 SEI prefix NALUs
// Note: Only works if SEI has a single message, or if HDR10+ is first message
if (m_remove_hdr10plus && unit_type == HEVC_NAL_SEI_PREFIX && buf[0] == 78 && buf[1] == 1 &&
buf[2] == 4)
write_buf = false;

if (write_buf && m_convert_dovi)
{
if (unit_type == HEVC_NAL_UNSPEC62)
{
Expand Down
4 changes: 4 additions & 0 deletions xbmc/utils/BitstreamConverter.h
Expand Up @@ -100,6 +100,8 @@ class CBitstreamConverter
void ResetStartDecode(void);
bool CanStartDecode() const;
void SetConvertDovi(bool value) { m_convert_dovi = value; }
void SetRemoveHdr10Plus(bool value) { m_remove_hdr10plus = value; }
void SetRemoveDovi(bool value) { m_remove_dovi = value; }

static bool mpeg2_sequence_header(const uint8_t *data, const uint32_t size, mpeg2_sequence *sequence);

Expand Down Expand Up @@ -145,4 +147,6 @@ class CBitstreamConverter
AVCodecID m_codec;
bool m_start_decode;
bool m_convert_dovi;
bool m_remove_hdr10plus;
bool m_remove_dovi;
};

0 comments on commit 20a46b2

Please sign in to comment.