1
0
mirror of https://github.com/dguglielmi/sunny-overlay.git synced 2025-12-06 16:02:39 +01:00
Files
sunny-overlay/media-tv/kodi/files/kodi-20.2-Handle-FFmpeg-extradata-in-dedicated-class.patch

1123 lines
46 KiB
Diff

From e5922ff2197c5276c7a38891c395a1297da03a96 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Markus=20H=C3=A4rer?= <markus.haerer@gmx.net>
Date: Sat, 22 Apr 2023 00:21:09 +0200
Subject: [PATCH] FFmpeg: Handle FFmpeg extradata in dedicated class
This ensures that everything is allocated with av_malloc and freed with
av_free. The padding is also handled consistently. And as a bonus it's more
ergonomic than handling the raw data.
---
xbmc/cores/FFmpeg.cpp | 105 ++++++++++++++----
xbmc/cores/FFmpeg.h | 30 ++++-
.../Audio/DVDAudioCodecAndroidMediaCodec.cpp | 10 +-
.../DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp | 9 +-
.../Overlay/DVDOverlayCodecFFmpeg.cpp | 13 ++-
.../DVDCodecs/Overlay/DVDOverlayCodecSSA.cpp | 3 +-
.../DVDCodecs/Overlay/OverlayCodecWebVTT.cpp | 3 +-
.../DVDCodecs/Video/AddonVideoCodec.cpp | 4 +-
.../Video/DVDVideoCodecAndroidMediaCodec.cpp | 52 ++++-----
.../DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp | 11 +-
.../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 12 +-
.../DVDCodecs/Video/DVDVideoCodecStarfish.cpp | 10 +-
xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h | 5 +-
.../DVDDemuxers/DVDDemuxClient.cpp | 36 ++----
.../DVDDemuxers/DVDDemuxFFmpeg.cpp | 17 ++-
.../DVDDemuxers/DVDDemuxVobsub.cpp | 5 +-
.../DVDInputStreams/InputStreamAddon.cpp | 5 +-
.../DVDInputStreams/InputStreamPVRBase.cpp | 11 +-
xbmc/cores/VideoPlayer/DVDStreamInfo.cpp | 59 ++++------
xbmc/cores/VideoPlayer/DVDStreamInfo.h | 3 +-
xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp | 2 +-
xbmc/utils/BitstreamConverter.cpp | 51 ++++-----
xbmc/utils/BitstreamConverter.h | 8 +-
23 files changed, 261 insertions(+), 203 deletions(-)
diff --git a/xbmc/cores/FFmpeg.cpp b/xbmc/cores/FFmpeg.cpp
index 73b7ea2ae875c..67dbaedaf92a3 100644
--- a/xbmc/cores/FFmpeg.cpp
+++ b/xbmc/cores/FFmpeg.cpp
@@ -135,15 +135,78 @@ void ff_avutil_log(void* ptr, int level, const char* format, va_list va)
buffer.erase(0, start);
}
-std::tuple<uint8_t*, int> GetPacketExtradata(const AVPacket* pkt, const AVCodecParameters* codecPar)
+FFmpegExtraData::FFmpegExtraData(size_t size)
+ : m_data(reinterpret_cast<uint8_t*>(av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE))), m_size(size)
+{
+ if (!m_data)
+ throw std::bad_alloc();
+}
+
+FFmpegExtraData::FFmpegExtraData(const uint8_t* data, size_t size) : FFmpegExtraData(size)
+{
+ std::memcpy(m_data, data, size);
+}
+
+FFmpegExtraData::~FFmpegExtraData()
+{
+ av_free(m_data);
+}
+
+FFmpegExtraData::FFmpegExtraData(const FFmpegExtraData& e) : FFmpegExtraData(e.m_size)
+{
+ std::memcpy(m_data, e.m_data, m_size);
+}
+
+FFmpegExtraData::FFmpegExtraData(FFmpegExtraData&& other) noexcept : FFmpegExtraData()
+{
+ std::swap(m_data, other.m_data);
+ std::swap(m_size, other.m_size);
+}
+
+FFmpegExtraData& FFmpegExtraData::operator=(const FFmpegExtraData& other)
+{
+ if (this != &other)
+ {
+ if (m_size >= other.m_size) // reuse current buffer if large enough
+ {
+ std::memcpy(m_data, other.m_data, other.m_size);
+ m_size = other.m_size;
+ }
+ else
+ {
+ FFmpegExtraData extraData(other);
+ *this = std::move(extraData);
+ }
+ }
+ return *this;
+}
+
+FFmpegExtraData& FFmpegExtraData::operator=(FFmpegExtraData&& other) noexcept
+{
+ if (this != &other)
+ {
+ std::swap(m_data, other.m_data);
+ std::swap(m_size, other.m_size);
+ }
+ return *this;
+}
+
+bool FFmpegExtraData::operator==(const FFmpegExtraData& other) const
+{
+ return m_size == other.m_size && std::memcmp(m_data, other.m_data, m_size) == 0;
+}
+
+bool FFmpegExtraData::operator!=(const FFmpegExtraData& other) const
+{
+ return !(*this == other);
+}
+
+FFmpegExtraData GetPacketExtradata(const AVPacket* pkt, const AVCodecParameters* codecPar)
{
constexpr int FF_MAX_EXTRADATA_SIZE = ((1 << 28) - AV_INPUT_BUFFER_PADDING_SIZE);
if (!pkt)
- return std::make_tuple(nullptr, 0);
-
- uint8_t* extraData = nullptr;
- int extraDataSize = 0;
+ return {};
/* extract_extradata bitstream filter is implemented only
* for certain codecs, as noted in discussion of PR#21248
@@ -165,29 +228,29 @@ std::tuple<uint8_t*, int> GetPacketExtradata(const AVPacket* pkt, const AVCodecP
codecId != AV_CODEC_ID_CAVS
)
// clang-format on
- return std::make_tuple(nullptr, 0);
+ return {};
const AVBitStreamFilter* f = av_bsf_get_by_name("extract_extradata");
if (!f)
- return std::make_tuple(nullptr, 0);
+ return {};
AVBSFContext* bsf = nullptr;
int ret = av_bsf_alloc(f, &bsf);
if (ret < 0)
- return std::make_tuple(nullptr, 0);
+ return {};
ret = avcodec_parameters_copy(bsf->par_in, codecPar);
if (ret < 0)
{
av_bsf_free(&bsf);
- return std::make_tuple(nullptr, 0);
+ return {};
}
ret = av_bsf_init(bsf);
if (ret < 0)
{
av_bsf_free(&bsf);
- return std::make_tuple(nullptr, 0);
+ return {};
}
AVPacket* dstPkt = av_packet_alloc();
@@ -196,7 +259,7 @@ std::tuple<uint8_t*, int> GetPacketExtradata(const AVPacket* pkt, const AVCodecP
CLog::LogF(LOGERROR, "failed to allocate packet");
av_bsf_free(&bsf);
- return std::make_tuple(nullptr, 0);
+ return {};
}
AVPacket* pktRef = dstPkt;
@@ -205,7 +268,7 @@ std::tuple<uint8_t*, int> GetPacketExtradata(const AVPacket* pkt, const AVCodecP
{
av_bsf_free(&bsf);
av_packet_free(&dstPkt);
- return std::make_tuple(nullptr, 0);
+ return {};
}
ret = av_bsf_send_packet(bsf, pktRef);
@@ -214,9 +277,10 @@ std::tuple<uint8_t*, int> GetPacketExtradata(const AVPacket* pkt, const AVCodecP
av_packet_unref(pktRef);
av_bsf_free(&bsf);
av_packet_free(&dstPkt);
- return std::make_tuple(nullptr, 0);
+ return {};
}
+ FFmpegExtraData extraData;
ret = 0;
while (ret >= 0)
{
@@ -234,23 +298,22 @@ std::tuple<uint8_t*, int> GetPacketExtradata(const AVPacket* pkt, const AVCodecP
av_packet_get_side_data(pktRef, AV_PKT_DATA_NEW_EXTRADATA, &retExtraDataSize);
if (retExtraData && retExtraDataSize > 0 && retExtraDataSize < FF_MAX_EXTRADATA_SIZE)
{
- extraData = static_cast<uint8_t*>(av_malloc(retExtraDataSize + AV_INPUT_BUFFER_PADDING_SIZE));
- if (!extraData)
+ try
+ {
+ extraData = FFmpegExtraData(retExtraData, retExtraDataSize);
+ }
+ catch (const std::bad_alloc&)
{
CLog::LogF(LOGERROR, "failed to allocate {} bytes for extradata", retExtraDataSize);
av_packet_unref(pktRef);
av_bsf_free(&bsf);
av_packet_free(&dstPkt);
- return std::make_tuple(nullptr, 0);
+ return {};
}
CLog::LogF(LOGDEBUG, "fetching extradata, extradata_size({})", retExtraDataSize);
- memcpy(extraData, retExtraData, retExtraDataSize);
- memset(extraData + retExtraDataSize, 0, AV_INPUT_BUFFER_PADDING_SIZE);
- extraDataSize = retExtraDataSize;
-
av_packet_unref(pktRef);
break;
}
@@ -261,5 +324,5 @@ std::tuple<uint8_t*, int> GetPacketExtradata(const AVPacket* pkt, const AVCodecP
av_bsf_free(&bsf);
av_packet_free(&dstPkt);
- return std::make_tuple(extraData, extraDataSize);
+ return extraData;
}
diff --git a/xbmc/cores/FFmpeg.h b/xbmc/cores/FFmpeg.h
index 5e35d58c6b0a6..9f99389a2c3e3 100644
--- a/xbmc/cores/FFmpeg.h
+++ b/xbmc/cores/FFmpeg.h
@@ -72,5 +72,31 @@ class CFFmpegLog
int level;
};
-std::tuple<uint8_t*, int> GetPacketExtradata(const AVPacket* pkt,
- const AVCodecParameters* codecPar);
+class FFmpegExtraData
+{
+public:
+ FFmpegExtraData() = default;
+ explicit FFmpegExtraData(size_t size);
+ FFmpegExtraData(const uint8_t* data, size_t size);
+ FFmpegExtraData(const FFmpegExtraData& other);
+ FFmpegExtraData(FFmpegExtraData&& other) noexcept;
+
+ ~FFmpegExtraData();
+
+ FFmpegExtraData& operator=(const FFmpegExtraData& other);
+ FFmpegExtraData& operator=(FFmpegExtraData&& other) noexcept;
+
+ bool operator==(const FFmpegExtraData& other) const;
+ bool operator!=(const FFmpegExtraData& other) const;
+
+ operator bool() const { return m_data != nullptr && m_size != 0; }
+ uint8_t* GetData() { return m_data; }
+ const uint8_t* GetData() const { return m_data; }
+ size_t GetSize() const { return m_size; }
+
+private:
+ uint8_t* m_data{nullptr};
+ size_t m_size{};
+};
+
+FFmpegExtraData GetPacketExtradata(const AVPacket* pkt, const AVCodecParameters* codecPar);
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecAndroidMediaCodec.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecAndroidMediaCodec.cpp
index 5c2ee81af8be3..30aca1c8d3de6 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecAndroidMediaCodec.cpp
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecAndroidMediaCodec.cpp
@@ -109,7 +109,7 @@ bool CDVDAudioCodecAndroidMediaCodec::Open(CDVDStreamInfo &hints, CDVDCodecOptio
CLog::Log(LOGDEBUG,
"CDVDAudioCodecAndroidMediaCodec::Open codec({}), profile({}), tag({}), extrasize({})",
- hints.codec, hints.profile, hints.codec_tag, hints.extrasize);
+ hints.codec, hints.profile, hints.codec_tag, hints.extradata.GetSize());
// First check if passthrough decoder is supported
CAEStreamInfo::DataType ptStreamType = CAEStreamInfo::STREAM_TYPE_NULL;
@@ -132,7 +132,7 @@ bool CDVDAudioCodecAndroidMediaCodec::Open(CDVDStreamInfo &hints, CDVDCodecOptio
{
case AV_CODEC_ID_AAC:
case AV_CODEC_ID_AAC_LATM:
- if (!m_hints.extrasize)
+ if (!m_hints.extradata)
{
CLog::Log(LOGINFO, "CDVDAudioCodecAndroidMediaCodec: extradata required for aac decoder!");
return false;
@@ -529,10 +529,10 @@ bool CDVDAudioCodecAndroidMediaCodec::ConfigureMediaCodec(void)
if (!m_decryptCodec)
{
// handle codec extradata
- if (m_hints.extrasize)
+ if (m_hints.extradata)
{
- size_t size = m_hints.extrasize;
- void *src_ptr = m_hints.extradata;
+ size_t size = m_hints.extradata.GetSize();
+ void* src_ptr = m_hints.extradata.GetData();
// Allocate a byte buffer via allocateDirect in java instead of NewDirectByteBuffer,
// since the latter doesn't allocate storage of its own, and we don't know how long
// the codec uses the buffer.
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp
index d1fb2cfe96afc..cbc806030dc19 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp
@@ -103,13 +103,14 @@ bool CDVDAudioCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options
if(m_pCodecContext->bits_per_coded_sample == 0)
m_pCodecContext->bits_per_coded_sample = 16;
- if( hints.extradata && hints.extrasize > 0 )
+ if (hints.extradata)
{
- m_pCodecContext->extradata = (uint8_t*)av_mallocz(hints.extrasize + AV_INPUT_BUFFER_PADDING_SIZE);
+ m_pCodecContext->extradata =
+ (uint8_t*)av_mallocz(hints.extradata.GetSize() + AV_INPUT_BUFFER_PADDING_SIZE);
if(m_pCodecContext->extradata)
{
- m_pCodecContext->extradata_size = hints.extrasize;
- memcpy(m_pCodecContext->extradata, hints.extradata, hints.extrasize);
+ m_pCodecContext->extradata_size = hints.extradata.GetSize();
+ memcpy(m_pCodecContext->extradata, hints.extradata.GetData(), hints.extradata.GetSize());
}
}
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp
index 5c74c50229d83..3eb85be4eec7d 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp
@@ -60,16 +60,17 @@ bool CDVDOverlayCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &optio
m_pCodecContext->pkt_timebase.num = 1;
m_pCodecContext->pkt_timebase.den = DVD_TIME_BASE;
- if( hints.extradata && hints.extrasize > 0 )
+ if (hints.extradata)
{
- m_pCodecContext->extradata_size = hints.extrasize;
- m_pCodecContext->extradata = (uint8_t*)av_mallocz(hints.extrasize + AV_INPUT_BUFFER_PADDING_SIZE);
- memcpy(m_pCodecContext->extradata, hints.extradata, hints.extrasize);
+ m_pCodecContext->extradata_size = hints.extradata.GetSize();
+ m_pCodecContext->extradata =
+ (uint8_t*)av_mallocz(hints.extradata.GetSize() + AV_INPUT_BUFFER_PADDING_SIZE);
+ memcpy(m_pCodecContext->extradata, hints.extradata.GetData(), hints.extradata.GetSize());
// start parsing of extra data - create a copy to be safe and make it zero-terminating to avoid access violations!
- unsigned int parse_extrasize = hints.extrasize;
+ unsigned int parse_extrasize = hints.extradata.GetSize();
char* parse_extra = new char[parse_extrasize + 1];
- memcpy(parse_extra, hints.extradata, parse_extrasize);
+ memcpy(parse_extra, hints.extradata.GetData(), parse_extrasize);
parse_extra[parse_extrasize] = '\0';
// assume that the extra data is formatted as a concatenation of lines ('\n' terminated)
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Overlay/DVDOverlayCodecSSA.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Overlay/DVDOverlayCodecSSA.cpp
index 82c1c76dd5564..33e0c7bcc83d4 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Overlay/DVDOverlayCodecSSA.cpp
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Overlay/DVDOverlayCodecSSA.cpp
@@ -38,7 +38,8 @@ bool CDVDOverlayCodecSSA::Open(CDVDStreamInfo& hints, CDVDCodecOptions& options)
m_pOverlay.reset();
- return m_libass->DecodeHeader(static_cast<char*>(hints.extradata), hints.extrasize);
+ return m_libass->DecodeHeader(reinterpret_cast<char*>(hints.extradata.GetData()),
+ hints.extradata.GetSize());
}
OverlayMessage CDVDOverlayCodecSSA::Decode(DemuxPacket* pPacket)
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Overlay/OverlayCodecWebVTT.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Overlay/OverlayCodecWebVTT.cpp
index e33ab1dad503e..d1c03af8d4851 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Overlay/OverlayCodecWebVTT.cpp
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Overlay/OverlayCodecWebVTT.cpp
@@ -39,7 +39,8 @@ bool COverlayCodecWebVTT::Open(CDVDStreamInfo& hints, CDVDCodecOptions& options)
// Extradata can be provided by Inputstream addons (e.g. inputstream.adaptive)
if (hints.extradata)
{
- std::string extradata{static_cast<char*>(hints.extradata), hints.extrasize};
+ std::string extradata{reinterpret_cast<char*>(hints.extradata.GetData()),
+ hints.extradata.GetSize()};
if (extradata == "file")
{
// WebVTT data like single file are sent one time only,
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/AddonVideoCodec.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/AddonVideoCodec.cpp
index 07b2d1b3ccf8d..daf64ea67ac43 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/AddonVideoCodec.cpp
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/AddonVideoCodec.cpp
@@ -231,8 +231,8 @@ bool CAddonVideoCodec::CopyToInitData(VIDEOCODEC_INITDATA &initData, CDVDStreamI
sizeof(initData.cryptoSession.sessionId) - 1);
}
- initData.extraData = reinterpret_cast<const uint8_t*>(hints.extradata);
- initData.extraDataSize = hints.extrasize;
+ initData.extraData = hints.extradata.GetData();
+ initData.extraDataSize = hints.extradata.GetSize();
initData.width = hints.width;
initData.height = hints.height;
initData.videoFormats = m_formats;
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp
index ede663ebe917b..8cc2431498ad2 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp
@@ -387,7 +387,7 @@ bool CDVDVideoCodecAndroidMediaCodec::Open(CDVDStreamInfo &hints, CDVDCodecOptio
"CDVDVideoCodecAndroidMediaCodec::Open hints: Width {} x Height {}, Fpsrate {} / Fpsscale "
"{}, CodecID {}, Level {}, Profile {}, PTS_invalid {}, Tag {}, Extradata-Size: {}",
hints.width, hints.height, hints.fpsrate, hints.fpsscale, hints.codec, hints.level,
- hints.profile, hints.ptsinvalid, hints.codec_tag, hints.extrasize);
+ hints.profile, hints.ptsinvalid, hints.codec_tag, hints.extradata.GetSize());
m_render_surface = CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_VIDEOPLAYER_USEMEDIACODECSURFACE);
m_state = MEDIACODEC_STATE_UNINITIALIZED;
@@ -447,9 +447,7 @@ bool CDVDVideoCodecAndroidMediaCodec::Open(CDVDStreamInfo &hints, CDVDCodecOptio
}
m_mime = "video/x-vnd.on2.vp9";
m_formatname = "amc-vp9";
- free(m_hints.extradata);
- m_hints.extradata = nullptr;
- m_hints.extrasize = 0;
+ m_hints.extradata = {};
break;
case AV_CODEC_ID_AVS:
case AV_CODEC_ID_CAVS:
@@ -493,7 +491,8 @@ bool CDVDVideoCodecAndroidMediaCodec::Open(CDVDStreamInfo &hints, CDVDCodecOptio
if (m_hints.extradata && !m_hints.cryptoSession)
{
m_bitstream = std::make_unique<CBitstreamConverter>();
- if (!m_bitstream->Open(m_hints.codec, (uint8_t*)m_hints.extradata, m_hints.extrasize, true))
+ if (!m_bitstream->Open(m_hints.codec, m_hints.extradata.GetData(),
+ m_hints.extradata.GetSize(), true))
{
m_bitstream.reset();
}
@@ -564,7 +563,8 @@ bool CDVDVideoCodecAndroidMediaCodec::Open(CDVDStreamInfo &hints, CDVDCodecOptio
if (m_hints.extradata && !m_hints.cryptoSession)
{
m_bitstream = std::make_unique<CBitstreamConverter>();
- if (!m_bitstream->Open(m_hints.codec, (uint8_t*)m_hints.extradata, m_hints.extrasize, true))
+ if (!m_bitstream->Open(m_hints.codec, m_hints.extradata.GetData(),
+ m_hints.extradata.GetSize(), true))
{
m_bitstream.reset();
}
@@ -572,28 +572,26 @@ bool CDVDVideoCodecAndroidMediaCodec::Open(CDVDStreamInfo &hints, CDVDCodecOptio
break;
}
case AV_CODEC_ID_WMV3:
- if (m_hints.extrasize == 4 || m_hints.extrasize == 5)
+ if (m_hints.extradata.GetSize() == 4 || m_hints.extradata.GetSize() == 5)
{
// Convert to SMPTE 421M-2006 Annex-L
static uint8_t annexL_hdr1[] = {0x8e, 0x01, 0x00, 0xc5, 0x04, 0x00, 0x00, 0x00};
static uint8_t annexL_hdr2[] = {0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- free(m_hints.extradata);
- m_hints.extrasize = 36;
- m_hints.extradata = malloc(m_hints.extrasize);
+ m_hints.extradata = FFmpegExtraData(36);
unsigned int offset = 0;
char buf[4];
- memcpy(m_hints.extradata, annexL_hdr1, sizeof(annexL_hdr1));
+ memcpy(m_hints.extradata.GetData(), annexL_hdr1, sizeof(annexL_hdr1));
offset += sizeof(annexL_hdr1);
- memcpy(&((char *)(m_hints.extradata))[offset], hints.extradata, 4);
+ memcpy(m_hints.extradata.GetData() + offset, hints.extradata.GetData(), 4);
offset += 4;
BS_WL32(buf, hints.height);
- memcpy(&((char *)(m_hints.extradata))[offset], buf, 4);
+ memcpy(m_hints.extradata.GetData() + offset, buf, 4);
offset += 4;
BS_WL32(buf, hints.width);
- memcpy(&((char *)(m_hints.extradata))[offset], buf, 4);
+ memcpy(m_hints.extradata.GetData() + offset, buf, 4);
offset += 4;
- memcpy(&((char *)(m_hints.extradata))[offset], annexL_hdr2, sizeof(annexL_hdr2));
+ memcpy(m_hints.extradata.GetData() + offset, annexL_hdr2, sizeof(annexL_hdr2));
}
m_mime = "video/x-ms-wmv";
@@ -601,26 +599,24 @@ bool CDVDVideoCodecAndroidMediaCodec::Open(CDVDStreamInfo &hints, CDVDCodecOptio
break;
case AV_CODEC_ID_VC1:
{
- if (m_hints.extrasize < 16)
+ if (m_hints.extradata.GetSize() < 16)
goto FAIL;
// Reduce extradata to first SEQ header
unsigned int seq_offset = 0;
- for (; seq_offset <= m_hints.extrasize-4; ++seq_offset)
+ for (; seq_offset <= m_hints.extradata.GetSize() - 4; ++seq_offset)
{
- char *ptr = &((char*)m_hints.extradata)[seq_offset];
+ const uint8_t* ptr = m_hints.extradata.GetData() + seq_offset;
if (ptr[0] == 0x00 && ptr[1] == 0x00 && ptr[2] == 0x01 && ptr[3] == 0x0f)
break;
}
- if (seq_offset > m_hints.extrasize-4)
+ if (seq_offset > m_hints.extradata.GetSize() - 4)
goto FAIL;
if (seq_offset)
{
- free(m_hints.extradata);
- m_hints.extrasize -= seq_offset;
- m_hints.extradata = malloc(m_hints.extrasize);
- memcpy(m_hints.extradata, &((char *)(hints.extradata))[seq_offset], m_hints.extrasize);
+ hints.extradata = FFmpegExtraData(hints.extradata.GetData() + seq_offset,
+ hints.extradata.GetSize() - seq_offset);
}
m_mime = "video/wvc1";
@@ -643,9 +639,7 @@ bool CDVDVideoCodecAndroidMediaCodec::Open(CDVDStreamInfo &hints, CDVDCodecOptio
}
m_mime = "video/av01";
m_formatname = "amc-av1";
- free(m_hints.extradata);
- m_hints.extradata = nullptr;
- m_hints.extrasize = 0;
+ m_hints.extradata = {};
break;
}
default:
@@ -1314,12 +1308,12 @@ void CDVDVideoCodecAndroidMediaCodec::SignalEndOfStream()
void CDVDVideoCodecAndroidMediaCodec::InjectExtraData(CJNIMediaFormat& mediaformat)
{
- if (!m_hints.extrasize)
+ if (!m_hints.extradata)
return;
CLog::Log(LOGDEBUG, "CDVDVideoCodecAndroidMediaCodec::{}", __func__);
- size_t size = m_hints.extrasize;
- void* src_ptr = m_hints.extradata;
+ size_t size = m_hints.extradata.GetSize();
+ void* src_ptr = m_hints.extradata.GetData();
if (m_bitstream)
{
size = m_bitstream->GetExtraSize();
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
index ab65c4ecd44aa..eb2943bb8ccb9 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
@@ -351,12 +351,15 @@ bool CDVDVideoCodecDRMPRIME::Open(CDVDStreamInfo& hints, CDVDCodecOptions& optio
m_pCodecContext->time_base.den = DVD_TIME_BASE;
m_pCodecContext->thread_count = CServiceBroker::GetCPUInfo()->GetCPUCount();
- if (hints.extradata && hints.extrasize > 0)
+ if (hints.extradata)
{
- m_pCodecContext->extradata_size = hints.extrasize;
m_pCodecContext->extradata =
- static_cast<uint8_t*>(av_mallocz(hints.extrasize + AV_INPUT_BUFFER_PADDING_SIZE));
- memcpy(m_pCodecContext->extradata, hints.extradata, hints.extrasize);
+ static_cast<uint8_t*>(av_mallocz(hints.extradata.GetSize() + AV_INPUT_BUFFER_PADDING_SIZE));
+ if (m_pCodecContext->extradata)
+ {
+ m_pCodecContext->extradata_size = hints.extradata.GetSize();
+ memcpy(m_pCodecContext->extradata, hints.extradata.GetData(), hints.extradata.GetSize());
+ }
}
for (auto&& option : options.m_keys)
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
index c775281791719..032ee16454492 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
@@ -400,11 +400,15 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options
m_pCodecContext->bits_per_coded_sample = hints.bitsperpixel;
m_pCodecContext->bits_per_raw_sample = hints.bitdepth;
- if( hints.extradata && hints.extrasize > 0 )
+ if (hints.extradata)
{
- m_pCodecContext->extradata_size = hints.extrasize;
- m_pCodecContext->extradata = (uint8_t*)av_mallocz(hints.extrasize + AV_INPUT_BUFFER_PADDING_SIZE);
- memcpy(m_pCodecContext->extradata, hints.extradata, hints.extrasize);
+ m_pCodecContext->extradata =
+ (uint8_t*)av_mallocz(hints.extradata.GetSize() + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (m_pCodecContext->extradata)
+ {
+ m_pCodecContext->extradata_size = hints.extradata.GetSize();
+ memcpy(m_pCodecContext->extradata, hints.extradata.GetData(), hints.extradata.GetSize());
+ }
}
// advanced setting override for skip loop filter (see avcodec.h for valid options)
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecStarfish.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecStarfish.cpp
index fcdc441205958..dbf91ea5a54dd 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecStarfish.cpp
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecStarfish.cpp
@@ -93,7 +93,7 @@ bool CDVDVideoCodecStarfish::OpenInternal(CDVDStreamInfo& hints, CDVDCodecOption
"CDVDVideoCodecStarfish: hints: Width {} x Height {}, Fpsrate {} / Fpsscale {}, "
"CodecID {}, Level {}, Profile {}, PTS_invalid {}, Tag {}, Extradata-Size: {}",
hints.width, hints.height, hints.fpsrate, hints.fpsscale, hints.codec, hints.level,
- hints.profile, hints.ptsinvalid, hints.codec_tag, hints.extrasize);
+ hints.profile, hints.ptsinvalid, hints.codec_tag, hints.extradata.GetSize());
if (ms_codecMap.find(hints.codec) == ms_codecMap.cend() ||
ms_formatInfoMap.find(hints.codec) == ms_formatInfoMap.cend())
@@ -115,8 +115,8 @@ bool CDVDVideoCodecStarfish::OpenInternal(CDVDStreamInfo& hints, CDVDCodecOption
if (m_hints.extradata && !m_hints.cryptoSession)
{
m_bitstream = std::make_unique<CBitstreamConverter>();
- if (!m_bitstream->Open(m_hints.codec, reinterpret_cast<uint8_t*>(m_hints.extradata),
- m_hints.extrasize, true))
+ if (!m_bitstream->Open(m_hints.codec, m_hints.extradata.GetData(),
+ m_hints.extradata.GetSize(), true))
{
m_bitstream.reset();
}
@@ -153,8 +153,8 @@ bool CDVDVideoCodecStarfish::OpenInternal(CDVDStreamInfo& hints, CDVDCodecOption
if (m_hints.extradata && !m_hints.cryptoSession)
{
m_bitstream = std::make_unique<CBitstreamConverter>();
- if (!m_bitstream->Open(m_hints.codec, reinterpret_cast<uint8_t*>(m_hints.extradata),
- m_hints.extrasize, true))
+ if (!m_bitstream->Open(m_hints.codec, m_hints.extradata.GetData(),
+ m_hints.extradata.GetSize(), true))
{
m_bitstream.reset();
}
diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h
index aeb6839177e71..af5ff8e513dae 100644
--- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h
+++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h
@@ -9,6 +9,7 @@
#pragma once
#include "Interface/StreamInfo.h"
+#include "cores/FFmpeg.h"
#include <memory>
#include <string>
@@ -83,7 +84,6 @@ class CDemuxStream
source = STREAM_SOURCE_NONE;
iDuration = 0;
pPrivate = NULL;
- ExtraSize = 0;
disabled = false;
changes = 0;
flags = StreamFlags::FLAG_NONE;
@@ -106,8 +106,7 @@ class CDemuxStream
int iDuration; // in mseconds
void* pPrivate; // private pointer for the demuxer
- std::unique_ptr<uint8_t[]> ExtraData; // extra data for codec to use
- unsigned int ExtraSize; // size of extra data
+ FFmpegExtraData extraData;
StreamFlags flags;
std::string language; // RFC 5646 language code (empty string if undefined)
diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp
index 2a42244b62b68..e6986467fa8b8 100644
--- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp
+++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp
@@ -121,7 +121,7 @@ bool CDVDDemuxClient::ParsePacket(DemuxPacket* pkt)
bool change = false;
CDemuxStream* st = GetStream(pkt->iStreamId);
- if (st == nullptr || st->changes < 0 || st->ExtraSize || !CodecHasExtraData(st->codec))
+ if (st == nullptr || st->changes < 0 || st->extraData || !CodecHasExtraData(st->codec))
return change;
CDemuxStreamClientInternal* stream = dynamic_cast<CDemuxStreamClientInternal*>(st);
@@ -174,13 +174,12 @@ bool CDVDDemuxClient::ParsePacket(DemuxPacket* pkt)
return false;
}
- auto [retExtraData, len] = GetPacketExtradata(avpkt, codecPar.get());
- if (len > 0)
+ FFmpegExtraData retExtraData = GetPacketExtradata(avpkt, codecPar.get());
+ if (retExtraData)
{
st->changes++;
st->disabled = false;
- st->ExtraSize = len;
- st->ExtraData = std::unique_ptr<uint8_t[]>(retExtraData);
+ st->extraData = std::move(retExtraData);
stream->m_parser_split = false;
change = true;
CLog::Log(LOGDEBUG, "CDVDDemuxClient::ParsePacket - split extradata");
@@ -444,12 +443,9 @@ void CDVDDemuxClient::SetStreamProps(CDemuxStream *stream, std::map<int, std::sh
streamAudio->iBlockAlign = source->iBlockAlign;
streamAudio->iBitRate = source->iBitRate;
streamAudio->iBitsPerSample = source->iBitsPerSample;
- if (source->ExtraSize > 0 && source->ExtraData)
+ if (source->extraData)
{
- streamAudio->ExtraData = std::make_unique<uint8_t[]>(source->ExtraSize);
- streamAudio->ExtraSize = source->ExtraSize;
- for (unsigned int j=0; j<source->ExtraSize; j++)
- streamAudio->ExtraData[j] = source->ExtraData[j];
+ streamAudio->extraData = source->extraData;
}
streamAudio->m_parser_split = true;
streamAudio->changes++;
@@ -484,12 +480,9 @@ void CDVDDemuxClient::SetStreamProps(CDemuxStream *stream, std::map<int, std::sh
streamVideo->iFpsRate = source->iFpsRate;
}
streamVideo->iBitRate = source->iBitRate;
- if (source->ExtraSize > 0 && source->ExtraData)
+ if (source->extraData)
{
- streamVideo->ExtraData = std::make_unique<uint8_t[]>(source->ExtraSize);
- streamVideo->ExtraSize = source->ExtraSize;
- for (unsigned int j=0; j<source->ExtraSize; j++)
- streamVideo->ExtraData[j] = source->ExtraData[j];
+ streamVideo->extraData = source->extraData;
}
streamVideo->colorPrimaries = source->colorPrimaries;
streamVideo->colorRange = source->colorRange;
@@ -526,12 +519,9 @@ void CDVDDemuxClient::SetStreamProps(CDemuxStream *stream, std::map<int, std::sh
streamSubtitle->m_parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
}
- if (source->ExtraSize == 4)
+ if (source->extraData.GetSize() == 4)
{
- streamSubtitle->ExtraData = std::make_unique<uint8_t[]>(4);
- streamSubtitle->ExtraSize = 4;
- for (int j=0; j<4; j++)
- streamSubtitle->ExtraData[j] = source->ExtraData[j];
+ streamSubtitle->extraData = source->extraData;
}
map[stream->uniqueId] = streamSubtitle;
toStream = streamSubtitle;
@@ -656,10 +646,8 @@ bool CDVDDemuxClient::IsVideoReady()
{
for (const auto& stream : m_streams)
{
- if (stream.first == m_videoStreamPlaying &&
- stream.second->type == STREAM_VIDEO &&
- CodecHasExtraData(stream.second->codec) &&
- stream.second->ExtraData == nullptr)
+ if (stream.first == m_videoStreamPlaying && stream.second->type == STREAM_VIDEO &&
+ CodecHasExtraData(stream.second->codec) && !stream.second->extraData)
return false;
}
return true;
diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
index 9e696cfc8ff8b..4847cdde2900a 100644
--- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
+++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
@@ -1881,10 +1881,8 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int streamIdx)
if (stream->type != STREAM_NONE && pStream->codecpar->extradata && pStream->codecpar->extradata_size > 0)
{
- stream->ExtraSize = pStream->codecpar->extradata_size;
- stream->ExtraData = std::make_unique<uint8_t[]>(pStream->codecpar->extradata_size);
- memcpy(stream->ExtraData.get(), pStream->codecpar->extradata,
- pStream->codecpar->extradata_size);
+ stream->extraData =
+ FFmpegExtraData(pStream->codecpar->extradata, pStream->codecpar->extradata_size);
}
#ifdef HAVE_LIBBLURAY
@@ -2166,7 +2164,8 @@ bool CDVDDemuxFFmpeg::IsProgramChange()
return true;
}
}
- if (m_pFormatContext->streams[idx]->codecpar->extradata_size != static_cast<int>(stream->ExtraSize))
+ if (m_pFormatContext->streams[idx]->codecpar->extradata_size !=
+ static_cast<int>(stream->extraData.GetSize()))
return true;
}
return false;
@@ -2299,11 +2298,11 @@ void CDVDDemuxFFmpeg::ParsePacket(AVPacket* pkt)
parser->second->m_parserCtx->parser &&
!st->codecpar->extradata)
{
- auto [retExtraData, i] = GetPacketExtradata(pkt, st->codecpar);
- if (i > 0)
+ FFmpegExtraData retExtraData = GetPacketExtradata(pkt, st->codecpar);
+ if (retExtraData)
{
- st->codecpar->extradata_size = i;
- st->codecpar->extradata = retExtraData;
+ st->codecpar->extradata_size = retExtraData.GetSize();
+ st->codecpar->extradata = retExtraData.GetData();
if (parser->second->m_parserCtx->parser->parser_parse)
{
diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxVobsub.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxVobsub.cpp
index 5c7ef1bb907c7..ba02a306e5489 100644
--- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxVobsub.cpp
+++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxVobsub.cpp
@@ -113,9 +113,8 @@ bool CDVDDemuxVobsub::Open(const std::string& filename, int source, const std::s
for(unsigned i=0;i<m_Streams.size();i++)
{
- m_Streams[i]->ExtraSize = state.extra.length()+1;
- m_Streams[i]->ExtraData = std::make_unique<uint8_t[]>(m_Streams[i]->ExtraSize);
- strcpy((char*)m_Streams[i]->ExtraData.get(), state.extra.c_str());
+ m_Streams[i]->extraData =
+ FFmpegExtraData(reinterpret_cast<uint8_t*>(state.extra.data()), state.extra.length() + 1);
}
return true;
diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp
index 2ca5d01b2b053..f5bfe16264b2a 100644
--- a/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp
+++ b/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp
@@ -531,10 +531,7 @@ KODI_HANDLE CInputStreamAddon::cb_get_stream_transfer(KODI_HANDLE handle,
if (stream->m_ExtraData && stream->m_ExtraSize)
{
- demuxStream->ExtraData = std::make_unique<uint8_t[]>(stream->m_ExtraSize);
- demuxStream->ExtraSize = stream->m_ExtraSize;
- for (unsigned int j = 0; j < stream->m_ExtraSize; ++j)
- demuxStream->ExtraData[j] = stream->m_ExtraData[j];
+ demuxStream->extraData = FFmpegExtraData(stream->m_ExtraData, stream->m_ExtraSize);
}
if (stream->m_cryptoSession.keySystem != STREAM_CRYPTO_KEY_SYSTEM_NONE &&
diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamPVRBase.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamPVRBase.cpp
index 03c4bf4de7412..00199b6503e2f 100644
--- a/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamPVRBase.cpp
+++ b/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamPVRBase.cpp
@@ -322,12 +322,11 @@ void CInputStreamPVRBase::UpdateStreamMap()
if (stream.iSubtitleInfo)
{
- streamSubtitle->ExtraData = std::make_unique<uint8_t[]>(4);
- streamSubtitle->ExtraSize = 4;
- streamSubtitle->ExtraData[0] = (stream.iSubtitleInfo >> 8) & 0xff;
- streamSubtitle->ExtraData[1] = (stream.iSubtitleInfo >> 0) & 0xff;
- streamSubtitle->ExtraData[2] = (stream.iSubtitleInfo >> 24) & 0xff;
- streamSubtitle->ExtraData[3] = (stream.iSubtitleInfo >> 16) & 0xff;
+ streamSubtitle->extraData = FFmpegExtraData(4);
+ streamSubtitle->extraData.GetData()[0] = (stream.iSubtitleInfo >> 8) & 0xff;
+ streamSubtitle->extraData.GetData()[1] = (stream.iSubtitleInfo >> 0) & 0xff;
+ streamSubtitle->extraData.GetData()[2] = (stream.iSubtitleInfo >> 24) & 0xff;
+ streamSubtitle->extraData.GetData()[3] = (stream.iSubtitleInfo >> 16) & 0xff;
}
dStream = streamSubtitle;
}
diff --git a/xbmc/cores/VideoPlayer/DVDStreamInfo.cpp b/xbmc/cores/VideoPlayer/DVDStreamInfo.cpp
index 696cec5e03d49..f387301e56971 100644
--- a/xbmc/cores/VideoPlayer/DVDStreamInfo.cpp
+++ b/xbmc/cores/VideoPlayer/DVDStreamInfo.cpp
@@ -13,18 +13,25 @@
#include <cstring>
-CDVDStreamInfo::CDVDStreamInfo() { extradata = NULL; Clear(); }
-CDVDStreamInfo::CDVDStreamInfo(const CDVDStreamInfo &right, bool withextradata ) { extradata = NULL; Clear(); Assign(right, withextradata); }
-CDVDStreamInfo::CDVDStreamInfo(const CDemuxStream &right, bool withextradata ) { extradata = NULL; Clear(); Assign(right, withextradata); }
-
-CDVDStreamInfo::~CDVDStreamInfo()
+CDVDStreamInfo::CDVDStreamInfo()
{
- if( extradata && extrasize ) free(extradata);
-
- extradata = NULL;
- extrasize = 0;
+ extradata = {};
+ Clear();
+}
+CDVDStreamInfo::CDVDStreamInfo(const CDVDStreamInfo& right, bool withextradata)
+{
+ extradata = {};
+ Clear();
+ Assign(right, withextradata);
+}
+CDVDStreamInfo::CDVDStreamInfo(const CDemuxStream& right, bool withextradata)
+{
+ extradata = {};
+ Clear();
+ Assign(right, withextradata);
}
+CDVDStreamInfo::~CDVDStreamInfo() = default;
void CDVDStreamInfo::Clear()
{
@@ -38,10 +45,7 @@ void CDVDStreamInfo::Clear()
filename.clear();
dvd = false;
- if( extradata && extrasize ) free(extradata);
-
- extradata = NULL;
- extrasize = 0;
+ extradata = {};
cryptoSession = nullptr;
externalInterfaces = nullptr;
@@ -87,13 +91,9 @@ bool CDVDStreamInfo::Equal(const CDVDStreamInfo& right, int compare)
flags != right.flags)
return false;
- if (compare & COMPARE_EXTRADATA)
+ if (compare & COMPARE_EXTRADATA && extradata != right.extradata)
{
- if( extrasize != right.extrasize ) return false;
- if( extrasize )
- {
- if( memcmp(extradata, right.extradata, extrasize) != 0 ) return false;
- }
+ return false;
}
// VIDEO
@@ -200,20 +200,13 @@ void CDVDStreamInfo::Assign(const CDVDStreamInfo& right, bool withextradata)
filename = right.filename;
dvd = right.dvd;
- if( extradata && extrasize ) free(extradata);
-
- if( withextradata && right.extrasize )
+ if (withextradata && right.extradata)
{
- extrasize = right.extrasize;
- extradata = malloc(extrasize);
- if (!extradata)
- return;
- memcpy(extradata, right.extradata, extrasize);
+ extradata = right.extradata;
}
else
{
- extrasize = 0;
- extradata = 0;
+ extradata = {};
}
cryptoSession = right.cryptoSession;
@@ -270,13 +263,9 @@ void CDVDStreamInfo::Assign(const CDemuxStream& right, bool withextradata)
level = right.level;
flags = right.flags;
- if (withextradata && right.ExtraSize)
+ if (withextradata && right.extraData)
{
- extrasize = right.ExtraSize;
- extradata = malloc(extrasize);
- if (!extradata)
- return;
- memcpy(extradata, right.ExtraData.get(), extrasize);
+ extradata = right.extraData;
}
cryptoSession = right.cryptoSession;
diff --git a/xbmc/cores/VideoPlayer/DVDStreamInfo.h b/xbmc/cores/VideoPlayer/DVDStreamInfo.h
index 4acd85737c9e7..b3d0eb6bf4a3b 100644
--- a/xbmc/cores/VideoPlayer/DVDStreamInfo.h
+++ b/xbmc/cores/VideoPlayer/DVDStreamInfo.h
@@ -91,8 +91,7 @@ class CDVDStreamInfo
// SUBTITLE
// CODEC EXTRADATA
- void* extradata; // extra data for codec to use
- unsigned int extrasize; // size of extra data
+ FFmpegExtraData extradata; // extra data for codec to use
unsigned int codec_tag; // extra identifier hints for decoding
// Crypto initialization Data
diff --git a/xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp b/xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp
index c108091505fb4..ccfca71b7951c 100644
--- a/xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp
+++ b/xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp
@@ -103,7 +103,7 @@ bool CVideoPlayerVideo::OpenStream(CDVDStreamInfo hint)
{
if (hint.flags & AV_DISPOSITION_ATTACHED_PIC)
return false;
- if (hint.extrasize == 0)
+ if (!hint.extradata)
{
// codecs which require extradata
// clang-format off
diff --git a/xbmc/utils/BitstreamConverter.cpp b/xbmc/utils/BitstreamConverter.cpp
index f2224a5457939..1bca7d14d8400 100644
--- a/xbmc/utils/BitstreamConverter.cpp
+++ b/xbmc/utils/BitstreamConverter.cpp
@@ -317,9 +317,7 @@ CBitstreamConverter::CBitstreamConverter()
m_convertSize = 0;
m_inputBuffer = NULL;
m_inputSize = 0;
- m_to_annexb = false;
- m_extradata = NULL;
- m_extrasize = 0;
+ m_to_annexb = false;
m_convert_3byteTo4byteNALSize = false;
m_convert_bytestream = false;
m_sps_pps_context.sps_pps_data = NULL;
@@ -350,10 +348,9 @@ bool CBitstreamConverter::Open(enum AVCodecID codec, uint8_t *in_extradata, int
if ( in_extradata[0] == 1 )
{
CLog::Log(LOGINFO, "CBitstreamConverter::Open bitstream to annexb init");
- m_extrasize = in_extrasize;
- m_extradata = (uint8_t*)av_malloc(in_extrasize);
- memcpy(m_extradata, in_extradata, in_extrasize);
- m_convert_bitstream = BitstreamConvertInitAVC(m_extradata, m_extrasize);
+ m_extraData = FFmpegExtraData(in_extradata, in_extrasize);
+ m_convert_bitstream =
+ BitstreamConvertInitAVC(m_extraData.GetData(), m_extraData.GetSize());
return true;
}
else
@@ -381,9 +378,7 @@ bool CBitstreamConverter::Open(enum AVCodecID codec, uint8_t *in_extradata, int
// extract the avcC atom data into extradata then write it into avcCData for VDADecoder
in_extrasize = avio_close_dyn_buf(pb, &in_extradata);
// make a copy of extradata contents
- m_extradata = (uint8_t *)av_malloc(in_extrasize);
- memcpy(m_extradata, in_extradata, in_extrasize);
- m_extrasize = in_extrasize;
+ m_extraData = FFmpegExtraData(in_extradata, in_extrasize);
// done with the converted extradata, we MUST free using av_free
av_free(in_extradata);
return true;
@@ -404,16 +399,12 @@ bool CBitstreamConverter::Open(enum AVCodecID codec, uint8_t *in_extradata, int
in_extradata[4] = 0xFF;
m_convert_3byteTo4byteNALSize = true;
- m_extradata = (uint8_t *)av_malloc(in_extrasize);
- memcpy(m_extradata, in_extradata, in_extrasize);
- m_extrasize = in_extrasize;
+ m_extraData = FFmpegExtraData(in_extradata, in_extrasize);
return true;
}
}
// valid avcC atom
- m_extradata = (uint8_t*)av_malloc(in_extrasize);
- memcpy(m_extradata, in_extradata, in_extrasize);
- m_extrasize = in_extrasize;
+ m_extraData = FFmpegExtraData(in_extradata, in_extrasize);
return true;
}
return false;
@@ -437,10 +428,9 @@ bool CBitstreamConverter::Open(enum AVCodecID codec, uint8_t *in_extradata, int
if (in_extradata[0] || in_extradata[1] || in_extradata[2] > 1)
{
CLog::Log(LOGINFO, "CBitstreamConverter::Open bitstream to annexb init");
- m_extrasize = in_extrasize;
- m_extradata = (uint8_t*)av_malloc(in_extrasize);
- memcpy(m_extradata, in_extradata, in_extrasize);
- m_convert_bitstream = BitstreamConvertInitHEVC(m_extradata, m_extrasize);
+ m_extraData = FFmpegExtraData(in_extradata, in_extrasize);
+ m_convert_bitstream =
+ BitstreamConvertInitHEVC(m_extraData.GetData(), m_extraData.GetSize());
return true;
}
else
@@ -476,9 +466,7 @@ bool CBitstreamConverter::Open(enum AVCodecID codec, uint8_t *in_extradata, int
}
}
// valid hvcC atom
- m_extradata = (uint8_t*)av_malloc(in_extrasize);
- memcpy(m_extradata, in_extradata, in_extrasize);
- m_extrasize = in_extrasize;
+ m_extraData = FFmpegExtraData(in_extradata, in_extrasize);
return true;
}
return false;
@@ -499,9 +487,7 @@ void CBitstreamConverter::Close(void)
av_free(m_convertBuffer), m_convertBuffer = NULL;
m_convertSize = 0;
- if (m_extradata)
- av_free(m_extradata), m_extradata = NULL;
- m_extrasize = 0;
+ m_extraData = {};
m_inputSize = 0;
m_inputBuffer = NULL;
@@ -637,19 +623,26 @@ int CBitstreamConverter::GetConvertSize() const
return m_inputSize;
}
-uint8_t *CBitstreamConverter::GetExtraData() const
+uint8_t* CBitstreamConverter::GetExtraData()
+{
+ if (m_convert_bitstream)
+ return m_sps_pps_context.sps_pps_data;
+ else
+ return m_extraData.GetData();
+}
+const uint8_t* CBitstreamConverter::GetExtraData() const
{
if(m_convert_bitstream)
return m_sps_pps_context.sps_pps_data;
else
- return m_extradata;
+ return m_extraData.GetData();
}
int CBitstreamConverter::GetExtraSize() const
{
if(m_convert_bitstream)
return m_sps_pps_context.size;
else
- return m_extrasize;
+ return m_extraData.GetSize();
}
void CBitstreamConverter::ResetStartDecode(void)
diff --git a/xbmc/utils/BitstreamConverter.h b/xbmc/utils/BitstreamConverter.h
index 3c57e14057ecd..be63b7590cfad 100644
--- a/xbmc/utils/BitstreamConverter.h
+++ b/xbmc/utils/BitstreamConverter.h
@@ -8,6 +8,8 @@
#pragma once
+#include "cores/FFmpeg.h"
+
#include <stdint.h>
extern "C" {
@@ -92,7 +94,8 @@ class CBitstreamConverter
bool Convert(uint8_t *pData, int iSize);
uint8_t* GetConvertBuffer(void) const;
int GetConvertSize() const;
- uint8_t* GetExtraData(void) const;
+ uint8_t* GetExtraData();
+ const uint8_t* GetExtraData() const;
int GetExtraSize() const;
void ResetStartDecode(void);
bool CanStartDecode() const;
@@ -135,8 +138,7 @@ class CBitstreamConverter
bool m_convert_bitstream;
bool m_to_annexb;
- uint8_t *m_extradata;
- int m_extrasize;
+ FFmpegExtraData m_extraData;
bool m_convert_3byteTo4byteNALSize;
bool m_convert_bytestream;
AVCodecID m_codec;