Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 17 additions & 24 deletions AampMPDParseHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
*/
AampMPDParseHelper::AampMPDParseHelper() : mMPDInstance(NULL),mIsLiveManifest(false),mMinUpdateDurationMs(0),
mIsFogMPD(false),
mAvailabilityStartTime(0.0),mPublishTime(0.0),mSegmentDurationSeconds(0),mTSBDepth(0.0),
mAvailabilityStartTime(0.0),mTimelineAvailabilityStartTime(0.0),mPublishTime(0.0),mSegmentDurationSeconds(0),mTSBDepth(0.0),
mPresentationOffsetDelay(0.0),mMediaPresentationDuration(0),
mMyObjectMutex(),mPeriodEncryptionMap(),mNumberOfPeriods(0),mPeriodEmptyMap(),mLiveTimeFragmentSync(false),mHasServerUtcTime(false),mUpperBoundaryPeriod(0),mLowerBoundaryPeriod(0),mMPDPeriodDetails(),mDeltaTime(0.0)
{
Expand All @@ -52,7 +52,7 @@ AampMPDParseHelper::~AampMPDParseHelper()
* @brief Copy Constructor
*/
AampMPDParseHelper::AampMPDParseHelper(const AampMPDParseHelper& cachedMPD) : mIsLiveManifest(cachedMPD.mIsLiveManifest), mIsFogMPD(cachedMPD.mIsFogMPD),
mMinUpdateDurationMs(cachedMPD.mMinUpdateDurationMs), mAvailabilityStartTime(cachedMPD.mAvailabilityStartTime),
mMinUpdateDurationMs(cachedMPD.mMinUpdateDurationMs), mAvailabilityStartTime(cachedMPD.mAvailabilityStartTime), mTimelineAvailabilityStartTime(cachedMPD.mTimelineAvailabilityStartTime),
mSegmentDurationSeconds(cachedMPD.mSegmentDurationSeconds), mTSBDepth(cachedMPD.mTSBDepth),
mPresentationOffsetDelay(cachedMPD.mPresentationOffsetDelay), mMediaPresentationDuration(cachedMPD.mMediaPresentationDuration),
mMyObjectMutex(), mNumberOfPeriods(cachedMPD.mNumberOfPeriods) , mPeriodEncryptionMap(cachedMPD.mPeriodEncryptionMap),
Expand All @@ -67,12 +67,18 @@ AampMPDParseHelper::AampMPDParseHelper(const AampMPDParseHelper& cachedMPD) : mI
*/
void AampMPDParseHelper::Initialize(dash::mpd::IMPD *instance)
{
double timelineAvailabilityStartTime = mTimelineAvailabilityStartTime;
Clear();
std::unique_lock<std::mutex> lck(mMyObjectMutex);
mTimelineAvailabilityStartTime = timelineAvailabilityStartTime;
if(instance != NULL)
{
mMPDInstance = instance;
parseMPD();
if (mAvailabilityStartTime > 0)
{
mTimelineAvailabilityStartTime = mAvailabilityStartTime;
}
}
}

Expand All @@ -88,6 +94,7 @@ void AampMPDParseHelper::Clear()
mIsFogMPD = false;
mMinUpdateDurationMs = 0;
mAvailabilityStartTime = 0.0;
mTimelineAvailabilityStartTime = 0.0;
mPublishTime = 0.0;
mSegmentDurationSeconds = 0;
mTSBDepth = 0.0;
Expand Down Expand Up @@ -527,7 +534,8 @@ double AampMPDParseHelper::GetPeriodStartTime(int periodIndex,uint64_t mLastPlay
else
{
double periodStart = 0;
double periodStartMs = 0;
double periodStartMs = 0;
double timelineAvailabilityStartTime = mAvailabilityStartTime > 0 ? mAvailabilityStartTime : mTimelineAvailabilityStartTime;
if( periodIndex<0 )
{
AAMPLOG_WARN( "periodIndex<0" );
Expand All @@ -541,8 +549,8 @@ double AampMPDParseHelper::GetPeriodStartTime(int periodIndex,uint64_t mLastPlay
{
double deltaInStartTime = aamp_GetPeriodStartTimeDeltaRelativeToPTSOffset(mMPDInstance->GetPeriods().at(periodIndex)) * 1000;
periodStartMs = ParseISO8601Duration(startTimeStr.c_str()) + deltaInStartTime;
periodStart = (periodStartMs / 1000) + mAvailabilityStartTime;
if(mNumberOfPeriods == 1 && periodIndex == 0 && mIsLiveManifest && !mIsFogMPD && (periodStart == mAvailabilityStartTime) && deltaInStartTime == 0)
periodStart = (periodStartMs / 1000) + timelineAvailabilityStartTime;
if(mNumberOfPeriods == 1 && periodIndex == 0 && mIsLiveManifest && !mIsFogMPD && (periodStart == timelineAvailabilityStartTime) && deltaInStartTime == 0)
{
// Temp hack to avoid running below if condition code for segment timeline , Due to this periodStart is getting changed for Cloud TSB or Hot Cloud DVR with segment timeline, which is not required.
bool bHasSegmentTimeline = aamp_HasSegmentTime(mMPDInstance->GetPeriods().at(periodIndex));
Expand All @@ -560,7 +568,7 @@ double AampMPDParseHelper::GetPeriodStartTime(int periodIndex,uint64_t mLastPlay
{
liveTime+=mDeltaTime;
}
if(mAvailabilityStartTime < (liveTime - duration))
if(timelineAvailabilityStartTime < (liveTime - duration))
{
periodStart = liveTime - duration;
}
Expand All @@ -586,9 +594,9 @@ double AampMPDParseHelper::GetPeriodStartTime(int periodIndex,uint64_t mLastPlay
durationTotal += aamp_GetPeriodDuration(idx, mLastPlaylistDownloadTimeMs);
}
periodStart = ((double)durationTotal / (double)1000);
if(mIsLiveManifest && (periodStart >= 0))
if(timelineAvailabilityStartTime > 0 && periodStart >= 0)
{
periodStart += mAvailabilityStartTime;
periodStart += timelineAvailabilityStartTime;
}

AAMPLOG_INFO("StreamAbstractionAAMP_MPD: - MPD periodIndex %d periodId %s periodStart %f", periodIndex, mMPDInstance->GetPeriods().at(periodIndex)->GetId().c_str(), periodStart);
Expand Down Expand Up @@ -668,24 +676,9 @@ double AampMPDParseHelper::GetPeriodEndTime(int periodIndex, uint64_t mLastPlayl
if(startTimeStr.empty() || mLiveTimeFragmentSync)
{
AAMPLOG_INFO("Period startTime is not present in MPD, so calculating start time with previous period durations");
if(mIsLiveManifest)
{
periodStartMs = GetPeriodStartTime(periodIndex,mLastPlaylistDownloadTimeMs) * 1000 - (mAvailabilityStartTime * 1000);
}
else
{
periodStartMs = GetPeriodStartTime(periodIndex,mLastPlaylistDownloadTimeMs) * 1000;
}
}
else
{
periodStartMs = ParseISO8601Duration(startTimeStr.c_str()) + (aamp_GetPeriodStartTimeDeltaRelativeToPTSOffset(period)* 1000);
}
periodStartMs = GetPeriodStartTime(periodIndex,mLastPlaylistDownloadTimeMs) * 1000;
periodEndTime = ((double)(periodStartMs + periodDurationMs) /1000);
if(mIsLiveManifest)
{
periodEndTime += mAvailabilityStartTime;
}
}
AAMPLOG_INFO("StreamAbstractionAAMP_MPD: MPD periodIndex:%d periodId %s periodEndTime %f", periodIndex, period->GetId().c_str(), periodEndTime);
}
Expand Down
3 changes: 3 additions & 0 deletions AampMPDParseHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,8 @@ public :
* @retval double . AvailabilityStartTime
*/
double GetAvailabilityStartTime() { return mAvailabilityStartTime;}
double GetTimelineAvailabilityStartTime() { return mTimelineAvailabilityStartTime;}
void SetTimelineAvailabilityStartTime(double availabilityStartTime) { mTimelineAvailabilityStartTime = availabilityStartTime; }
Comment on lines 250 to +252
/**
*
* @fn GetPublishTime
Expand Down Expand Up @@ -533,6 +535,7 @@ public :
uint64_t mMinUpdateDurationMs;
/* storage for Availability Start Time */
double mAvailabilityStartTime;
double mTimelineAvailabilityStartTime;
/* storage for Publish Time in seconds*/
Comment on lines 536 to 539
double mPublishTime;
/* storage for Segment Duration in seconds */
Expand Down
49 changes: 45 additions & 4 deletions fragmentcollector_mpd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3386,7 +3386,12 @@ AAMPStatusType StreamAbstractionAAMP_MPD::GetMPDFromManifest( ManifestDownloadRe
{
this->mpd = tmpMPD;
// Parse for generic parameters
mMPDParseHelper = mpdDnldResp->GetMPDParseHelper();
auto mpdParseHelper = mpdDnldResp->GetMPDParseHelper();
if (!init && mMPDParseHelper && mpdParseHelper && mpdParseHelper->GetAvailabilityStartTime() == 0)
{
mpdParseHelper->SetTimelineAvailabilityStartTime(mMPDParseHelper->GetTimelineAvailabilityStartTime());
}
mMPDParseHelper = mpdParseHelper;

// this flag for current state of manifest ( Linear to VOD can happen)
if((mMPDParseHelper->IsLiveManifest() != mIsLiveManifest) && !init )
Expand Down Expand Up @@ -10288,11 +10293,19 @@ void StreamAbstractionAAMP_MPD::DetectDiscontinuityAndFetchInit(bool periodChang
usingPTO = true;
}

// Hot→Cold CDVR: Cold manifest has no AST so segment times are relative; suppress false discontinuity.
if (!mIsLiveManifest && mIsLiveStream && mMPDParseHelper->GetAvailabilityStartTime() == 0 && nextSegmentTime != segmentStartTime)
{
Comment thread
srikanthreddybijjam-comcast marked this conversation as resolved.
AAMPLOG_WARN("StreamAbstractionAAMP_MPD: Suppressing spurious discontinuity on Hot→Cold CDVR "
Comment thread
srikanthreddybijjam-comcast marked this conversation as resolved.
"manifest transition (nextSegTime=%" PRIu64 " segStartTime=%" PRIu64 ")",
Comment on lines +10296 to +10300
nextSegmentTime, segmentStartTime);
aamp->SetIsPeriodChangeMarked(false);
}
/* Process the discontinuity,
* 1. If the next segment time is not matching with the next period segment start time.
* 2. To reconfigure the pipeline, if there is a change in the Audio Codec even if there is no change in segment start time in multi period content.
*/
if ((segmentTemplates.GetSegmentTimeline() != NULL && nextSegmentTime != segmentStartTime) || GetESChangeStatus() || ISCONFIGSET(eAAMPConfig_ForceMultiPeriodDiscontinuity))
else if ((segmentTemplates.GetSegmentTimeline() != NULL && nextSegmentTime != segmentStartTime) || GetESChangeStatus() || ISCONFIGSET(eAAMPConfig_ForceMultiPeriodDiscontinuity))
{
AAMPLOG_WARN("StreamAbstractionAAMP_MPD: discontinuity detected nextSegmentTime %" PRIu64 " FirstSegmentStartTime %" PRIu64 " ", nextSegmentTime, segmentStartTime);
discontinuity = true;
Expand Down Expand Up @@ -10369,6 +10382,11 @@ double StreamAbstractionAAMP_MPD::GetCurrentAdStartTimeSeconds() const
mCdaiObject->mCurAdIdx >= static_cast<int>(mCdaiObject->mCurAds->size()) ||
mCdaiObject->mCurPlayingBreakId.empty())
{
AAMPLOG_INFO("ismCdaiObject= %s, mAdState= %d, mCurAdIdx= %d, mCurPlayingBreakId= %s",
mCdaiObject ? "true" : "false",
mCdaiObject ? static_cast<int>(mCdaiObject->mAdState) : -1,
mCdaiObject ? mCdaiObject->mCurAdIdx : -1,
mCdaiObject && !mCdaiObject->mCurPlayingBreakId.empty() ? mCdaiObject->mCurPlayingBreakId.c_str() : "empty");
Comment on lines +10385 to +10389
return -1.0;
}

Expand All @@ -10393,10 +10411,18 @@ double StreamAbstractionAAMP_MPD::GetCurrentAdStartTimeSeconds() const

void StreamAbstractionAAMP_MPD::UpdateStartTimeOfFirstPTS()
{
double startTime = (mMPDParseHelper->GetPeriodStartTime(mCurrentPeriodIdx, mLastPlaylistDownloadTimeMs) - mAvailabilityStartTime);
AAMPLOG_WARN(
"Period state: currentPeriodIdx=%d basePeriodId=%s "
"periodStartTime=%f startTimeOfFirstPTS=%f",
mCurrentPeriodIdx,
mBasePeriodId.c_str(),
mPeriodStartTime,
mStartTimeOfFirstPTS / 1000.0);
double periodStartSec = mMediaStreamContext[eMEDIATYPE_VIDEO]->fragmentTime;
double startTime = periodStartSec - mAvailabilityStartTime;
if (startTime != 0)
{
mStartTimeOfFirstPTS = mMPDParseHelper->GetPeriodStartTime(mCurrentPeriodIdx, mLastPlaylistDownloadTimeMs) * 1000.0;
mStartTimeOfFirstPTS = periodStartSec * 1000.0;
AAMPLOG_INFO("UpdateStartTimeOfFirstPTS: mStartTimeOfFirstPTS=%.0f ms : PeriodStartTime=%f", mStartTimeOfFirstPTS, startTime);
double adStartTimeSec = GetCurrentAdStartTimeSeconds();
if (adStartTimeSec >= 0)
Expand Down Expand Up @@ -13093,6 +13119,21 @@ bool StreamAbstractionAAMP_MPD::onAdEvent(AdEvent evt, double &adOffset)

mBasePeriodId = mCdaiObject->mAdBreaks[mCdaiObject->mCurPlayingBreakId].endPeriodId;
mCdaiObject->mContentSeekOffset = (double)(mCdaiObject->mAdBreaks[mCdaiObject->mCurPlayingBreakId].endPeriodOffset)/ 1000;
const int resumePeriodIndex = mMPDParseHelper->getPeriodIdx(mBasePeriodId);
if (resumePeriodIndex >= 0 && mCdaiObject->mContentSeekOffset >=
mMPDParseHelper->GetPeriodDuration(resumePeriodIndex , mLastPlaylistDownloadTimeMs,
ShouldCheckOnlyIframeAdaptation(), aamp->IsUninterruptedTSB()) / 1000.0)
{
if (resumePeriodIndex + 1 < mNumberOfPeriods)
{
mBasePeriodId = mpd->GetPeriods().at(resumePeriodIndex + 1)->GetId();
mCdaiObject->mContentSeekOffset = 0;
}
else
{
mPostRollAdPlaybackDone = true;
}
}
}
else
{
Expand Down
17 changes: 16 additions & 1 deletion priv_aamp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3630,6 +3630,13 @@ bool PrivateInstanceAAMP::ProcessPendingDiscontinuity()
startTimeofFirstSample = mpStreamAbstractionAAMP->GetStartTimeOfFirstPTS() / 1000;
if(startTimeofFirstSample > 0)
{
AAMPLOG_WARN(
"PrivateInstanceAAMP: Discontinuity position override: seekBase=%f "
"firstSample=%f injectedDuration=%f effectiveInjectedPosition=%f",
seek_pos_seconds,
startTimeofFirstSample,
mpStreamAbstractionAAMP->GetLastInjectedFragmentPosition(),
seek_pos_seconds + mpStreamAbstractionAAMP->GetLastInjectedFragmentPosition());
AAMPLOG_WARN("PrivateInstanceAAMP: Position is updated to start time of discontinuity : %lf", startTimeofFirstSample);
seek_pos_seconds = startTimeofFirstSample;
}
Expand Down Expand Up @@ -8252,7 +8259,14 @@ long long PrivateInstanceAAMP::GetPositionMs()
double seek_pos_seconds_copy = seek_pos_seconds;
if(prevPositionInfo.isPositionValid(seek_pos_seconds_copy))
{
return (prevFirstPeriodStartTime + prevPositionInfo.getPosition());
const long long previousPosition = prevPositionInfo.getPosition();
if (prevFirstPeriodStartTime > 0 && previousPosition < prevFirstPeriodStartTime)
{
AAMPLOG_WARN("prevFirstPeriodStartTime = %lld, relative previousPosition = %lld, seek_pos_seconds = %f", prevFirstPeriodStartTime, previousPosition, seek_pos_seconds_copy);
return prevFirstPeriodStartTime + previousPosition;
}
AAMPLOG_WARN("previousPosition = %lld is already absolute, seek_pos_seconds = %f", previousPosition, seek_pos_seconds_copy);
return previousPosition;
Comment on lines +8268 to +8269
}
else
{
Expand All @@ -8261,6 +8275,7 @@ long long PrivateInstanceAAMP::GetPositionMs()
//previous position values calculated using different values of seek_pos_seconds are considered invalid.
AAMPLOG_WARN("prev-pos-ms (%lld) is invalid. seek_pos_seconds = %f, seek_pos_seconds when prev-pos-ms was stored = %f.",prevPositionInfo.getPosition(), seek_pos_seconds_copy, prevPositionInfo.getSeekPositionSec());
}
AAMPLOG_WARN("GetPositionMilliseconds = %lld", GetPositionMilliseconds());
return GetPositionMilliseconds();
Comment on lines +8278 to 8279
}
}
Expand Down
Loading