Skip to content

Commit

Permalink
Merge pull request #268 from phunkyfish/sync-with-kodi
Browse files Browse the repository at this point in the history
Sync with kodi's inpustream - part 1
  • Loading branch information
phunkyfish authored Jan 31, 2024
2 parents c34a4cf + 451b2a3 commit 36930e7
Show file tree
Hide file tree
Showing 8 changed files with 395 additions and 124 deletions.
2 changes: 1 addition & 1 deletion inputstream.ffmpegdirect/addon.xml.in
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<addon
id="inputstream.ffmpegdirect"
version="21.2.1"
version="21.3.0"
name="Inputstream FFmpeg Direct"
provider-name="Ross Nicholson">
<requires>@ADDON_DEPENDS@</requires>
Expand Down
3 changes: 3 additions & 0 deletions inputstream.ffmpegdirect/changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
v21.3.0
- Sync FFmpegStream.cpp and DemuxStream.cpp with xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp from https://github.com/xbmc/xbmc. Update for all commits up to the end of 2023 part 1

v21.2.1
- Update dependency xz-utils to version 5.4.3
- Update dependency zlib to version 1.2.13
Expand Down
78 changes: 77 additions & 1 deletion src/stream/DemuxStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ bool DemuxStream::GetInformation(kodi::addon::InputstreamInfo& info)
info.SetCodecName(codecName);
info.SetCodecProfile(static_cast<STREAMCODEC_PROFILE>(profile));
info.SetPhysicalIndex(uniqueId);
info.SetExtraData(ExtraData, ExtraSize);
info.SetExtraData(extraData.GetData(), extraData.GetSize());
info.SetLanguage(language);
info.SetCodecFourCC(codec_fourcc);

Expand Down Expand Up @@ -178,3 +178,79 @@ DemuxParserFFmpeg::~DemuxParserFFmpeg()
m_parserCtx = nullptr;
}
}

FFmpegExtraData::FFmpegExtraData(size_t size)
: m_data(reinterpret_cast<uint8_t*>(av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE))),
m_size(size)
{
// using av_mallocz because some APIs require at least the padding to be zeroed, e.g. AVCodecParameters
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);
}

uint8_t* FFmpegExtraData::TakeData()
{
auto tmp = m_data;
m_data = nullptr;
m_size = 0;
return tmp;
}
61 changes: 54 additions & 7 deletions src/stream/DemuxStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavutil/dovi_meta.h>
#include <libavformat/avformat.h>
#include <libavutil/mastering_display_metadata.h>
}
Expand All @@ -33,6 +34,43 @@ extern "C"
namespace ffmpegdirect
{


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; }
/*!
* \brief Take ownership over the extra data buffer
*
* It's in the responsibility of the caller to free the buffer with av_free. After the call
* FFmpegExtraData is empty.
*
* \return The extra data buffer or nullptr if FFmpegExtraData is empty.
*/
uint8_t* TakeData();

private:
uint8_t* m_data{nullptr};
size_t m_size{};
};

class DemuxStream
{
public:
Expand All @@ -41,38 +79,35 @@ class DemuxStream
uniqueId = 0;
dvdNavId = 0;
demuxerId = -1;
codec = (AVCodecID)0; // AV_CODEC_ID_NONE
codec_fourcc = 0;
profile = FF_PROFILE_UNKNOWN;
level = FF_LEVEL_UNKNOWN;
type = INPUTSTREAM_TYPE_NONE;
iDuration = 0;
pPrivate = NULL;
ExtraData = NULL;
ExtraSize = 0;
disabled = false;
changes = 0;
flags = INPUTSTREAM_FLAG_NONE;
}

virtual ~DemuxStream() { delete[] ExtraData; }
virtual ~DemuxStream() = default;
DemuxStream(DemuxStream&&) = default;

virtual std::string GetStreamName();
virtual bool GetInformation(kodi::addon::InputstreamInfo& info);

int uniqueId; // unique stream id
int dvdNavId;
int64_t demuxerId; // id of the associated demuxer
AVCodecID codec;
AVCodecID codec = AV_CODEC_ID_NONE;
unsigned int codec_fourcc; // if available
int profile; // encoder profile of the stream reported by the decoder. used to qualify hw decoders.
int level; // encoder level of the stream reported by the decoder. used to qualify hw decoders.
INPUTSTREAM_TYPE type;

int iDuration; // in mseconds
void* pPrivate; // private pointer for the demuxer
uint8_t* ExtraData; // extra data for codec to use
unsigned int ExtraSize; // size of extra data
FFmpegExtraData extraData;

INPUTSTREAM_FLAGS flags;
std::string language; // RFC 5646 language code (empty string if undefined)
Expand All @@ -86,6 +121,14 @@ class DemuxStream
std::shared_ptr<kodi::addon::StreamCryptoSession> cryptoSession;
};

enum class StreamHdrType
{
HDR_TYPE_NONE, ///< <b>None</b>, returns an empty string when used in infolabels
HDR_TYPE_HDR10, ///< <b>HDR10</b>, returns `hdr10` when used in infolabels
HDR_TYPE_DOLBYVISION, ///< <b>Dolby Vision</b>, returns `dolbyvision` when used in infolabels
HDR_TYPE_HLG ///< <b>HLG</b>, returns `hlg` when used in infolabels
};

class DemuxStreamVideo : public DemuxStream
{
public:
Expand All @@ -95,6 +138,7 @@ class DemuxStreamVideo : public DemuxStream

int iFpsScale = 0; // scale of 1000 and a rate of 29970 will result in 29.97 fps
int iFpsRate = 0;
bool bInterlaced = false; // unknown or progressive => false, otherwise true.
int iHeight = 0; // height of the stream reported by the demuxer
int iWidth = 0; // width of the stream reported by the demuxer
double fAspect = 0; // display aspect of stream
Expand All @@ -104,6 +148,7 @@ class DemuxStreamVideo : public DemuxStream
int iOrientation = 0; // orientation of the video in degrees counter clockwise
int iBitsPerPixel = 0;
int iBitRate = 0;
int iBitDepth = 0;

AVColorSpace colorSpace = AVCOL_SPC_UNSPECIFIED;
AVColorRange colorRange = AVCOL_RANGE_UNSPECIFIED;
Expand All @@ -114,6 +159,8 @@ class DemuxStreamVideo : public DemuxStream
std::shared_ptr<AVContentLightMetadata> contentLightMetaData;

std::string stereo_mode; // expected stereo mode
AVDOVIDecoderConfigurationRecord dovi{};
StreamHdrType hdr_type = StreamHdrType::HDR_TYPE_NONE; // type of HDR for this stream (hdr10, etc)
};

class DemuxStreamAudio : public DemuxStream
Expand Down
Loading

0 comments on commit 36930e7

Please sign in to comment.