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

Is this really a DV patch for kodi? How can I use this?

@quietvoid
Copy link
Author

Is this really a DV patch for kodi? How can I use this?

This patch is outdated, it is already present in Kodi 20 Nexus.

@Shawn9347
Copy link

So Kodi 20 will support DV?

@quietvoid
Copy link
Author

So Kodi 20 will support DV?

No, it is dependent on the playback device.
This patch was implemented here: xbmc/xbmc#19099

@Shawn9347
Copy link

Of course but will Kodi 20 support dolby vision? Kodi 19 doesn't so no matter the playback device you'll never get dolby vision.

@quietvoid
Copy link
Author

Kodi 19 doesn't so no matter the playback device you'll never get dolby vision.

That's not true. Go read the 19 version notes.
I'm done replying here. You can find the answer to your questions by googling.

@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