Skip to content

Commit

Permalink
[DashTree] Cleanups and fixes
Browse files Browse the repository at this point in the history
Most important changes are:
-No more unclear uses of `period->SetDuration`/`period->SetTimescale`
-Fix wrong behaviour of `SegmentList` tag parsing, where was setting the duration of a single segment in the period duration
  • Loading branch information
CastagnaIT committed Feb 22, 2024
1 parent e77ce44 commit c94f64e
Show file tree
Hide file tree
Showing 15 changed files with 403 additions and 349 deletions.
22 changes: 22 additions & 0 deletions src/common/AdaptationSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,3 +215,25 @@ CAdaptationSet* PLAYLIST::CAdaptationSet::FindMergeable(

return nullptr;
}

PLAYLIST::CAdaptationSet* PLAYLIST::CAdaptationSet::FindByStreamType(
std::vector<std::unique_ptr<CAdaptationSet>>& adpSets, StreamType type)
{
auto itAdpSet = std::find_if(adpSets.cbegin(), adpSets.cend(),
[&type](const std::unique_ptr<CAdaptationSet>& item)
{ return item->GetStreamType() == type; });
if (itAdpSet != adpSets.cend())
return (*itAdpSet).get();

return nullptr;
}

PLAYLIST::CAdaptationSet* PLAYLIST::CAdaptationSet::FindByFirstAVStream(
std::vector<std::unique_ptr<CAdaptationSet>>& adpSets)
{
CAdaptationSet* adp = CAdaptationSet::FindByStreamType(adpSets, StreamType::VIDEO);
if (!adp)
adp = CAdaptationSet::FindByStreamType(adpSets, StreamType::AUDIO);

return adp;
}
34 changes: 28 additions & 6 deletions src/common/AdaptationSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,17 @@ class ATTR_DLL_LOCAL CAdaptationSet : public CCommonSegAttribs, public CCommonAt
CSpinCache<uint32_t>& SegmentTimelineDuration() { return m_segmentTimelineDuration; }
bool HasSegmentTimelineDuration() { return !m_segmentTimelineDuration.IsEmpty(); }

std::optional<CSegmentTemplate>& GetSegmentTemplate() { return m_segmentTemplate; }
std::optional<CSegmentTemplate> GetSegmentTemplate() const { return m_segmentTemplate; }
void SetSegmentTemplate(const CSegmentTemplate& segTemplate) { m_segmentTemplate = segTemplate; }
bool HasSegmentTemplate() const { return m_segmentTemplate.has_value(); }
/*!
* \brief Get the timescale of segment durations tag.
* \return The timescale value if set, otherwise NO_VALUE.
*/
uint64_t GetSegDurationsTimescale() const { return m_segDurationsTimescale; }

/*!
* \brief Set the timescale of segment durations tag.
* \param timescale The timescale value.
*/
void SetSegDurationsTimescale(const uint64_t timescale) { m_segDurationsTimescale = timescale; }

void AddRepresentation(std::unique_ptr<CRepresentation>& representation);
std::vector<std::unique_ptr<CRepresentation>>& GetRepresentations() { return m_representations; }
Expand Down Expand Up @@ -139,6 +146,22 @@ class ATTR_DLL_LOCAL CAdaptationSet : public CCommonSegAttribs, public CCommonAt
static CAdaptationSet* FindMergeable(std::vector<std::unique_ptr<CAdaptationSet>>& adpSets,
CAdaptationSet* adpSet);

/*!
* \brief Try find the first adpSet of specified type.
* \param adpSets The adaptation set list where to search
* \param type The type to search
* \return The adaptation set if found, otherwise nullptr
*/
static CAdaptationSet* FindByStreamType(std::vector<std::unique_ptr<CAdaptationSet>>& adpSets,
StreamType type);

/*!
* \brief Try find the first video adpSet, if not found, try find the first audio adpSet.
* \param adpSets The adaptation set list where to search
* \return The adaptation set if found, otherwise nullptr
*/
static CAdaptationSet* FindByFirstAVStream(std::vector<std::unique_ptr<CAdaptationSet>>& adpSets);

protected:
std::vector<std::unique_ptr<CRepresentation>> m_representations;

Expand All @@ -157,8 +180,7 @@ class ATTR_DLL_LOCAL CAdaptationSet : public CCommonSegAttribs, public CCommonAt
std::vector<std::string> m_switchingIds;

CSpinCache<uint32_t> m_segmentTimelineDuration;

std::optional<CSegmentTemplate> m_segmentTemplate;
uint64_t m_segDurationsTimescale{NO_VALUE};

// Custom ISAdaptive attributes (used on DASH only)
bool m_isImpaired{false};
Expand Down
2 changes: 1 addition & 1 deletion src/common/AdaptiveTree.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class ATTR_DLL_LOCAL AdaptiveTree
std::string base_url_;

std::optional<uint32_t> initial_sequence_; // HLS only
uint64_t m_totalTimeSecs{0}; // Total playing time in seconds
uint64_t m_totalTimeSecs{0}; // Total playing time in seconds (can include all periods/chapters or timeshift)
uint64_t stream_start_{0};
uint64_t available_time_{0};
uint64_t m_liveDelay{0}; // Apply a delay in seconds from the live edge
Expand Down
16 changes: 0 additions & 16 deletions src/common/CommonSegAttribs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,6 @@ PLAYLIST::CCommonSegAttribs::CCommonSegAttribs(CCommonSegAttribs* parent /* = nu
m_parentCommonSegAttribs = parent;
}

std::optional<CSegmentList>& PLAYLIST::CCommonSegAttribs::GetSegmentList()
{
if (m_segmentList.has_value())
return m_segmentList;
if (m_parentCommonSegAttribs && m_parentCommonSegAttribs->m_segmentList.has_value())
return m_parentCommonSegAttribs->m_segmentList;

return m_segmentList; // Empty data
}

bool PLAYLIST::CCommonSegAttribs::HasSegmentList()
{
return m_segmentList.has_value() ||
(m_parentCommonSegAttribs && m_parentCommonSegAttribs->m_segmentList.has_value());
}

uint64_t PLAYLIST::CCommonSegAttribs::GetSegmentEndNr()
{
if (m_segEndNr.has_value())
Expand Down
15 changes: 11 additions & 4 deletions src/common/CommonSegAttribs.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,29 @@

#pragma once

#include "SegTemplate.h"
#include "SegmentList.h"

#include <optional>

namespace PLAYLIST
{
// CCommonSegAttribs class provide attribute data
// of class itself or when not set of the parent class (if any).
// This class provide common place for shared members/methods
// with the possibility to retrieve the value from the parent class, when needed.
class ATTR_DLL_LOCAL CCommonSegAttribs
{
public:
CCommonSegAttribs(CCommonSegAttribs* parent = nullptr);
virtual ~CCommonSegAttribs() {}

std::optional<CSegmentList>& GetSegmentList();
std::optional<CSegmentList>& GetSegmentList() { return m_segmentList; }
void SetSegmentList(const CSegmentList& segmentList) { m_segmentList = segmentList; }
bool HasSegmentList();
bool HasSegmentList() { return m_segmentList.has_value(); }

std::optional<CSegmentTemplate>& GetSegmentTemplate() { return m_segmentTemplate; }
std::optional<CSegmentTemplate> GetSegmentTemplate() const { return m_segmentTemplate; }
void SetSegmentTemplate(const CSegmentTemplate& segTemplate) { m_segmentTemplate = segTemplate; }
bool HasSegmentTemplate() const { return m_segmentTemplate.has_value(); }

/*!
* \brief Get the optional segment end number. Use HasSegmentEndNr method to know if the value is set.
Expand All @@ -37,6 +43,7 @@ class ATTR_DLL_LOCAL CCommonSegAttribs
protected:
CCommonSegAttribs* m_parentCommonSegAttribs{nullptr};
std::optional<CSegmentList> m_segmentList;
std::optional<CSegmentTemplate> m_segmentTemplate;
std::optional<uint64_t> m_segEndNr;
};

Expand Down
43 changes: 29 additions & 14 deletions src/common/Period.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,24 +43,45 @@ class ATTR_DLL_LOCAL CPeriod : public CCommonSegAttribs
std::string GetBaseUrl() const { return m_baseUrl; }
void SetBaseUrl(std::string_view baseUrl) { m_baseUrl = baseUrl; }

//! @todo: SetTimescale can be set/updated by period, adaptationSet and/or representation
//! maybe is possible improve how are updated these variables in a better way
uint32_t GetTimescale() const { return m_timescale; }
void SetTimescale(uint32_t timescale) { m_timescale = timescale; }

uint32_t GetSequence() const { return m_sequence; }
void SetSequence(uint32_t sequence) { m_sequence = sequence; }

/*!
* \brief Get the start time, in ms.
* \return The start time value, otherwise NO_VALUE if not set.
*/
uint64_t GetStart() const { return m_start; }

/*!
* \brief Set the start time, in ms.
*/
void SetStart(uint64_t start) { m_start = start; }

uint64_t GetStartPTS() const { return m_startPts; }
void SetStartPTS(uint64_t startPts) { m_startPts = startPts; }

// Could be set also by adaptation set or representation (in ms)

/*!
* \brief Get the duration, in timescale units.
* \return The duration value.
*/
uint64_t GetDuration() const { return m_duration; }

/*!
* \brief Set the duration, in timescale units.
*/
void SetDuration(uint64_t duration) { m_duration = duration; }

/*!
* \brief Get the timescale unit.
* \return The timescale unit, if not set default value is 1000.
*/
uint32_t GetTimescale() const { return m_timescale; }

/*!
* \brief Set the timescale unit.
*/
void SetTimescale(uint32_t timescale) { m_timescale = timescale; }

EncryptionState GetEncryptionState() const { return m_encryptionState; }
void SetEncryptionState(EncryptionState encryptState) { m_encryptionState = encryptState; }

Expand All @@ -74,11 +95,6 @@ class ATTR_DLL_LOCAL CPeriod : public CCommonSegAttribs
CSpinCache<uint32_t>& SegmentTimelineDuration() { return m_segmentTimelineDuration; }
bool HasSegmentTimelineDuration() { return !m_segmentTimelineDuration.IsEmpty(); }

std::optional<CSegmentTemplate>& GetSegmentTemplate() { return m_segmentTemplate; }
std::optional<CSegmentTemplate> GetSegmentTemplate() const { return m_segmentTemplate; }
void SetSegmentTemplate(const CSegmentTemplate& segTemplate) { m_segmentTemplate = segTemplate; }
bool HasSegmentTemplate() const { return m_segmentTemplate.has_value(); }

void CopyHLSData(const CPeriod* other);

void AddAdaptationSet(std::unique_ptr<CAdaptationSet>& adaptationSet);
Expand Down Expand Up @@ -126,13 +142,12 @@ class ATTR_DLL_LOCAL CPeriod : public CCommonSegAttribs
std::string m_baseUrl;
uint32_t m_timescale{1000};
uint32_t m_sequence{0};
uint64_t m_start{0};
uint64_t m_start{NO_VALUE};
uint64_t m_startPts{0};
uint64_t m_duration{0};
EncryptionState m_encryptionState{EncryptionState::UNENCRYPTED};
bool m_isSecureDecoderNeeded{false};
CSpinCache<uint32_t> m_segmentTimelineDuration;
std::optional<CSegmentTemplate> m_segmentTemplate;
};

} // namespace adaptive
25 changes: 25 additions & 0 deletions src/common/Representation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

#include "utils/StringUtils.h"

#include <kodi/addon-instance/inputstream/TimingConstants.h>

using namespace PLAYLIST;
using namespace UTILS;

Expand Down Expand Up @@ -50,3 +52,26 @@ void PLAYLIST::CRepresentation::CopyHLSData(const CRepresentation* other)
m_isWaitForSegment = other->m_isWaitForSegment;
m_initSegment = other->m_initSegment;
}

void PLAYLIST::CRepresentation::SetScaling()
{
if (!m_timescale)
{
timescale_ext_ = timescale_int_ = 1;
return;
}

timescale_ext_ = STREAM_TIME_BASE;
timescale_int_ = m_timescale;

while (timescale_ext_ > 1)
{
if ((timescale_int_ / 10) * 10 == timescale_int_)
{
timescale_ext_ /= 10;
timescale_int_ /= 10;
}
else
break;
}
}
51 changes: 20 additions & 31 deletions src/common/Representation.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,24 +107,35 @@ class ATTR_DLL_LOCAL CRepresentation : public CCommonSegAttribs, public CCommonA
CSpinCache<CSegment> SegmentTimeline() const { return m_segmentTimeline; }
bool HasSegmentTimeline() { return !m_segmentTimeline.IsEmpty(); }

std::optional<CSegmentTemplate>& GetSegmentTemplate() { return m_segmentTemplate; }
std::optional<CSegmentTemplate> GetSegmentTemplate() const { return m_segmentTemplate; }
void SetSegmentTemplate(const CSegmentTemplate& segTemplate) { m_segmentTemplate = segTemplate; }
bool HasSegmentTemplate() const { return m_segmentTemplate.has_value(); }

std::optional<CSegmentBase>& GetSegmentBase() { return m_segmentBase; }
void SetSegmentBase(const CSegmentBase& segBase) { m_segmentBase = segBase; }
bool HasSegmentBase() const { return m_segmentBase.has_value(); }

uint32_t GetTimescale() const { return m_timescale; }
void SetTimescale(uint32_t timescale) { m_timescale = timescale; }

uint64_t GetStartNumber() const { return m_startNumber; }
void SetStartNumber(uint64_t startNumber) { m_startNumber = startNumber; }

/*!
* \brief Get the duration, in timescale units.
* \return The duration value.
*/
uint64_t GetDuration() const { return m_duration; }

/*!
* \brief Set the duration, in timescale units.
*/
void SetDuration(uint64_t duration) { m_duration = duration; }

/*!
* \brief Get the timescale unit.
* \return The timescale unit, otherwise 0 if not set.
*/
uint32_t GetTimescale() const { return m_timescale; }

/*!
* \brief Set the timescale unit.
*/
void SetTimescale(uint32_t timescale) { m_timescale = timescale; }

/*!
* \brief Determines when the representation contains subtitles as single file
* for the entire duration of the video.
Expand Down Expand Up @@ -225,28 +236,7 @@ class ATTR_DLL_LOCAL CRepresentation : public CCommonSegAttribs, public CCommonA
uint32_t timescale_ext_{0};
uint32_t timescale_int_{0};

void SetScaling()
{
if (!m_timescale)
{
timescale_ext_ = timescale_int_ = 1;
return;
}

timescale_ext_ = 1000000;
timescale_int_ = m_timescale;

while (timescale_ext_ > 1)
{
if ((timescale_int_ / 10) * 10 == timescale_int_)
{
timescale_ext_ /= 10;
timescale_int_ /= 10;
}
else
break;
}
}
void SetScaling();

std::chrono::time_point<std::chrono::system_clock> repLastUpdated_;

Expand All @@ -269,7 +259,6 @@ class ATTR_DLL_LOCAL CRepresentation : public CCommonSegAttribs, public CCommonA

uint16_t m_hdcpVersion{0}; // 0 if not set

std::optional<CSegmentTemplate> m_segmentTemplate;
std::optional<CSegmentBase> m_segmentBase;
std::optional<CSegment> m_initSegment;

Expand Down
Loading

0 comments on commit c94f64e

Please sign in to comment.