Skip to content
Open
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
32 changes: 12 additions & 20 deletions mp4demux/AampMp4Demuxer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,20 +126,6 @@ AampMp4Demuxer::~AampMp4Demuxer()
// std::unique_ptr automatically handles cleanup
}

/**
* @brief Advance trickmode restamp timeline on discontinuity boundary.
*/
void AampMp4Demuxer::HandleTrickModeDiscontinuity()
{
if (mTrickPhase == Mp4TrickPhase::STEADY)
{
mRestampedPts += mRestampedDuration;
mTrickPhase = Mp4TrickPhase::DISCONTINUITY;
AAMPLOG_WARN("[%s] Trickmode discontinuity: advancing restampedPts by %.6f to %.6f",
GetMediaTypeName(mMediaType), mRestampedDuration, mRestampedPts);
}
}

/**
* @brief Apply trickmode PTS restamping to a sample, dynamically adjusting duration based on rate and frame rate
* Similar to qtdemux approach but with dynamic duration calculation for smoother trickmode playback
Expand All @@ -156,6 +142,18 @@ void AampMp4Demuxer::TrickmodePtsRestamp(AampMediaSample& sample, double duratio
double fragmentPtsDelta = 0.0;
double restampedDuration = 0.0;

// On the first keyframe of a discontinuous segment (while in STEADY state), advance
// the output PTS by the last known duration so the stream stays gapless, then switch
// to DISCONTINUITY so the switch below reuses that duration instead of computing a
// (potentially huge) cross-discontinuity PTS delta.
if (discontinuous && mTrickPhase == Mp4TrickPhase::STEADY)
{
mRestampedPts += mRestampedDuration;
mTrickPhase = Mp4TrickPhase::DISCONTINUITY;
AAMPLOG_WARN("[%s] Trickmode discontinuity: advancing restampedPts by %.6f to %.6f",
GetMediaTypeName(mMediaType), mRestampedDuration, mRestampedPts);
}

// All phase transitions are owned here.
switch (mTrickPhase)
{
Expand Down Expand Up @@ -294,12 +292,6 @@ bool AampMp4Demuxer::sendSegment(std::vector<uint8_t>&& buffer, double position,
AAMPLOG_ERR("No samples for type:%d and invalid codec format:%d", mMediaType, codecInfo.mCodecFormat);
ret = false;
}
// Init segments can carry discontinuity without samples.
// Pre-mark discontinuity so next data sample avoids cross-period PTS delta spikes.
if (ret && mIsTrickMode && isInit && discontinuous)
{
HandleTrickModeDiscontinuity();
}
}
}
}
Expand Down
8 changes: 0 additions & 8 deletions mp4demux/AampMp4Demuxer.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,14 +152,6 @@ class AampMp4Demuxer : public MediaProcessor
*/
void TrickmodePtsRestamp(AampMediaSample& sample, double duration, bool discontinuous);

/**
* @brief Handle trickmode discontinuity by pre-advancing state machine
* @note Called when a discontinuous init segment arrives to prevent large PTS
* deltas from being computed when the next data segment is processed.
* Transitions state from STEADY → DISCONTINUITY if discontinuous=true.
*/
void HandleTrickModeDiscontinuity();

/**
* @brief Reset only trickmode state variables.
* Called internally whenever trickmode state must be cleared (e.g. on
Expand Down
Loading