Skip to content

Instantly share code, notes, and snippets.

@quietvoid
Created January 21, 2021 03:11
Show Gist options
  • Save quietvoid/db7ac49bd8621a82f914888bca730c74 to your computer and use it in GitHub Desktop.
Save quietvoid/db7ac49bd8621a82f914888bca730c74 to your computer and use it in GitHub Desktop.
Kodi MTK Dolby Vision patch
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp
index 415d336292..45d823294e 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp
@@ -745,11 +745,23 @@ bool CDVDVideoCodecAndroidMediaCodec::Open(CDVDStreamInfo &hints, CDVDCodecOptio
goto FAIL;
if (m_codecname.find("OMX.Nvidia", 0, 10) == 0)
+ {
m_invalidPTSValue = AV_NOPTS_VALUE;
+ }
else if (m_codecname.find("OMX.MTK", 0, 7) == 0)
+ {
m_invalidPTSValue = -1; //Use DTS
+
+ if (m_bitstream && m_mime == "video/dolby-vision")
+ {
+ CLog::Log(LOGDEBUG, "Dolby Vision MTK decoder, using NAL header size 4 workaround");
+ m_bitstream->SetDoviWorkaround();
+ }
+ }
else
+ {
m_invalidPTSValue = 0;
+ }
CLog::Log(LOGINFO, "CDVDVideoCodecAndroidMediaCodec:: "
"Open Android MediaCodec %s", m_codecname.c_str());
diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
index a208e01c8a..5f9facb571 100644
--- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
+++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
@@ -1631,17 +1631,22 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int streamIdx)
if (!stereoMode.empty())
st->stereo_mode = stereoMode;
- if (m_bMatroska)
+ int size;
+ uint8_t* side_data = av_stream_get_side_data(pStream, AV_PKT_DATA_DOVI_CONF, &size);
+ if (size > 0 && side_data)
{
- int size;
- uint8_t* side_data = av_stream_get_side_data(pStream, AV_PKT_DATA_DOVI_CONF, &size);
- if (size > 0 && side_data)
+ auto dovi = reinterpret_cast<AVDOVIDecoderConfigurationRecord*>(side_data);
+
+ if (m_bMatroska)
{
- auto dovi = reinterpret_cast<AVDOVIDecoderConfigurationRecord*>(side_data);
- if (dovi->dv_profile > 7)
- pStream->codecpar->codec_tag = MKBETAG('d', 'v', 'v', 'C');
- else
- pStream->codecpar->codec_tag = MKBETAG('d', 'v', 'c', 'C');
+ if (dovi->dv_profile > 7)
+ pStream->codecpar->codec_tag = MKBETAG('d', 'v', 'v', 'C');
+ else
+ pStream->codecpar->codec_tag = MKBETAG('d', 'v', 'c', 'C');
+ } else
+ {
+ // Try giving the hint to decode as Dolby Vision anyways, as the side data is present
+ pStream->codecpar->codec_tag = MKTAG('d', 'v', 'h', 'e');
}
}
diff --git a/xbmc/utils/BitstreamConverter.cpp b/xbmc/utils/BitstreamConverter.cpp
index 0aaa4d491b..9715dee771 100644
--- a/xbmc/utils/BitstreamConverter.cpp
+++ b/xbmc/utils/BitstreamConverter.cpp
@@ -321,6 +321,7 @@ CBitstreamConverter::CBitstreamConverter()
m_convert_bytestream = false;
m_sps_pps_context.sps_pps_data = NULL;
m_start_decode = true;
+ m_dovi_workaround = false;
}
CBitstreamConverter::~CBitstreamConverter()
@@ -659,6 +660,11 @@ bool CBitstreamConverter::CanStartDecode() const
return m_start_decode;
}
+void CBitstreamConverter::SetDoviWorkaround(void)
+{
+ m_dovi_workaround = true;
+}
+
bool CBitstreamConverter::BitstreamConvertInitAVC(void *in_extradata, int in_extrasize)
{
// based on h264_mp4toannexb_bsf.c (ffmpeg)
@@ -927,12 +933,12 @@ bool CBitstreamConverter::BitstreamConvert(uint8_t* pData, int iSize, uint8_t **
if (m_sps_pps_context.first_idr && IsIDR(unit_type) && !m_sps_pps_context.idr_sps_pps_seen)
{
BitstreamAllocAndCopy(poutbuf, poutbuf_size,
- m_sps_pps_context.sps_pps_data, m_sps_pps_context.size, buf, nal_size);
+ m_sps_pps_context.sps_pps_data, m_sps_pps_context.size, buf, nal_size, unit_type, m_dovi_workaround);
m_sps_pps_context.first_idr = 0;
}
else
{
- BitstreamAllocAndCopy(poutbuf, poutbuf_size, NULL, 0, buf, nal_size);
+ BitstreamAllocAndCopy(poutbuf, poutbuf_size, NULL, 0, buf, nal_size, unit_type, m_dovi_workaround);
if (!m_sps_pps_context.first_idr && IsSlice(unit_type))
{
m_sps_pps_context.first_idr = 1;
@@ -953,7 +959,7 @@ fail:
}
void CBitstreamConverter::BitstreamAllocAndCopy( uint8_t **poutbuf, int *poutbuf_size,
- const uint8_t *sps_pps, uint32_t sps_pps_size, const uint8_t *in, uint32_t in_size)
+ const uint8_t *sps_pps, uint32_t sps_pps_size, const uint8_t *in, uint32_t in_size, uint8_t nal_type, bool dovi_workaround)
{
// based on h264_mp4toannexb_bsf.c (ffmpeg)
// which is Copyright (c) 2007 Benoit Fouet <[email protected]>
@@ -961,6 +967,13 @@ void CBitstreamConverter::BitstreamAllocAndCopy( uint8_t **poutbuf, int *poutbuf
uint32_t offset = *poutbuf_size;
uint8_t nal_header_size = offset ? 3 : 4;
+
+ // MTK Dolby Vision decoder expects header of size 4
+ if (dovi_workaround && (nal_type == 62 || nal_type == 63))
+ {
+ nal_header_size = 4;
+ }
+
void *tmp;
*poutbuf_size += sps_pps_size + in_size + nal_header_size;
@@ -976,6 +989,13 @@ void CBitstreamConverter::BitstreamAllocAndCopy( uint8_t **poutbuf, int *poutbuf
{
BS_WB32(*poutbuf + sps_pps_size, 1);
}
+ else if (dovi_workaround && (nal_type == 62 || nal_type == 63))
+ {
+ (*poutbuf + offset + sps_pps_size)[0] = 0;
+ (*poutbuf + offset + sps_pps_size)[1] = 0;
+ (*poutbuf + offset + sps_pps_size)[2] = 0;
+ (*poutbuf + offset + sps_pps_size)[3] = 1;
+ }
else
{
(*poutbuf + offset + sps_pps_size)[0] = 0;
diff --git a/xbmc/utils/BitstreamConverter.h b/xbmc/utils/BitstreamConverter.h
index 7d98a15d7e..5629366431 100644
--- a/xbmc/utils/BitstreamConverter.h
+++ b/xbmc/utils/BitstreamConverter.h
@@ -96,6 +96,7 @@ public:
int GetExtraSize() const;
void ResetStartDecode(void);
bool CanStartDecode() const;
+ void SetDoviWorkaround(void);
static bool mpeg2_sequence_header(const uint8_t *data, const uint32_t size, mpeg2_sequence *sequence);
@@ -110,7 +111,7 @@ protected:
bool BitstreamConvertInitHEVC(void *in_extradata, int in_extrasize);
bool BitstreamConvert(uint8_t* pData, int iSize, uint8_t **poutbuf, int *poutbuf_size);
static void BitstreamAllocAndCopy(uint8_t **poutbuf, int *poutbuf_size,
- const uint8_t *sps_pps, uint32_t sps_pps_size, const uint8_t *in, uint32_t in_size);
+ const uint8_t *sps_pps, uint32_t sps_pps_size, const uint8_t *in, uint32_t in_size, uint8_t nal_type, bool dovi_workaround);
typedef struct omx_bitstream_ctx {
uint8_t length_size;
@@ -136,4 +137,5 @@ protected:
bool m_convert_bytestream;
AVCodecID m_codec;
bool m_start_decode;
+ bool m_dovi_workaround;
};
@Shawn9347
Copy link

Kodi 19 does not support dolby vision. I tried it on nvidia shield. You need a special build for it to work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment