diff --git a/AampConfig.cpp b/AampConfig.cpp index a91b7d88f0..ecb015de79 100644 --- a/AampConfig.cpp +++ b/AampConfig.cpp @@ -432,7 +432,7 @@ static const ConfigLookupEntryInt mConfigLookupTableInt[AAMPCONFIG_INT_COUNT+CON {MAX_GST_AUDIO_BUFFER_BYTES,"gstAudioBufBytes", eAAMPConfig_GstAudioBufBytes,true}, {DEFAULT_LATENCY_MONITOR_DELAY_MS,"latencyMonitorDelayMs",eAAMPConfig_LatencyMonitorDelayMs,false}, {DEFAULT_LATENCY_MONITOR_INTERVAL_MS,"latencyMonitorIntervalMs",eAAMPConfig_LatencyMonitorIntervalMs,false}, - {DEFAULT_CACHED_FRAGMENT_CHUNKS_PER_TRACK,"downloadBufferChunks",eAAMPConfig_MaxFragmentChunkCached,false}, + {DEFAULT_LLD_CACHED_FRAGMENTS_PER_TRACK,"downloadBufferChunks",eAAMPConfig_MaxLLDFragmentCached,false}, {DEFAULT_AAMP_ABR_CHUNK_THRESHOLD_SIZE,"abrChunkThresholdSize",eAAMPConfig_ABRChunkThresholdSize,false}, {MAX_SEG_DOWNLOAD_FAIL_COUNT,"fragmentDownloadFailThreshold",eAAMPConfig_FragmentDownloadFailThreshold,false,eCONFIG_RANGE_DOWNLOAD_ERROR_THRESHOLD }, {MAX_INIT_FRAGMENT_CACHE_PER_TRACK,"maxInitFragCachePerTrack",eAAMPConfig_MaxInitFragCachePerTrack,true, eCONFIG_RANGE_INIT_FRAGMENT_CACHE }, diff --git a/AampConfig.h b/AampConfig.h index 7e3fb7eb25..168b319cd4 100644 --- a/AampConfig.h +++ b/AampConfig.h @@ -284,7 +284,7 @@ typedef enum eAAMPConfig_GstAudioBufBytes, /**< Gstreamer Max Audio buffering bytes*/ eAAMPConfig_LatencyMonitorDelayMs, /**< Latency Monitor Delay */ eAAMPConfig_LatencyMonitorIntervalMs, /**< Latency Monitor Interval */ - eAAMPConfig_MaxFragmentChunkCached, /**< fragment chunk cache length*/ + eAAMPConfig_MaxLLDFragmentCached, /**< LLD fragment cache length */ eAAMPConfig_ABRChunkThresholdSize, /**< AAMP ABR Chunk threshold size*/ eAAMPConfig_FragmentDownloadFailThreshold, /**< Retry attempts for non-init fragment curl timeout failures*/ eAAMPConfig_MaxInitFragCachePerTrack, /**< Max no of Init fragment cache per track */ diff --git a/AampDefine.h b/AampDefine.h index 8a193057bf..f551add8b4 100644 --- a/AampDefine.h +++ b/AampDefine.h @@ -213,7 +213,7 @@ #define AAMP_FOG_TSB_URL_KEYWORD "tsb?" /**< AAMP expect this keyword in URL to identify it is FOG url */ #define DEFAULT_INITIAL_RATE_CORRECTION_SPEED 1.000001f /**< Initial rate correction speed to avoid audio drop */ -#define DEFAULT_CACHED_FRAGMENT_CHUNKS_PER_TRACK 20 /**< Default cached fragment chunks per track */ +#define DEFAULT_LLD_CACHED_FRAGMENTS_PER_TRACK 20 /**< Default LLD cached fragments per track */ #define DEFAULT_AAMP_ABR_CHUNK_THRESHOLD_SIZE (DEFAULT_AAMP_ABR_THRESHOLD_SIZE) /**< aamp abr Chunk threshold size */ #define DEFAULT_ABR_CHUNK_SPEEDCNT 10 /**< Chunk Speed Count Store Size */ #define DEFAULT_ABR_ELAPSED_MILLIS_FOR_ESTIMATE 100 /**< Duration(ms) to check Chunk Speed */ diff --git a/MediaStreamContext.cpp b/MediaStreamContext.cpp index 6c4acb48e3..150f123e03 100644 --- a/MediaStreamContext.cpp +++ b/MediaStreamContext.cpp @@ -202,10 +202,10 @@ bool MediaStreamContext::CacheFragmentChunk(AampMediaType actualType, const uint return false; } bool ret = true; - if (WaitForCachedFragmentChunkInjected()) + if (WaitForCachedFragmentInjected()) { CachedFragment *cachedFragment = NULL; - cachedFragment = GetFetchChunkBuffer(true); + cachedFragment = GetFetchBuffer(true); if (NULL == cachedFragment) { AAMPLOG_WARN("[%s] Something Went wrong - Can't get FetchChunkBuffer", name); @@ -254,11 +254,11 @@ bool MediaStreamContext::CacheFragmentChunk(AampMediaType actualType, const uint cachedFragment->PTSOffsetSec = GetContext()->mPTSOffset.inSeconds(); AAMPLOG_TRACE("[%s] cachedFragment %p ptr %p", name, cachedFragment, cachedFragment->fragment.data()); - UpdateTSAfterChunkFetch(); + UpdateTSAfterFetch(); } else { - AAMPLOG_TRACE("[%s] WaitForCachedFragmentChunkInjected aborted", name); + AAMPLOG_TRACE("[%s] WaitForCachedFragmentInjected aborted", name); ret = false; } return ret; @@ -627,13 +627,13 @@ bool MediaStreamContext::CacheTsbFragment(std::shared_ptr&& frag // FN_TRACE_F_MPD( __FUNCTION__ ); std::lock_guard lock(fetchChunkBufferMutex); bool ret = false; - if(!fragment->fragment.empty() && WaitForCachedFragmentChunkInjected()) + if(!fragment->fragment.empty() && WaitForCachedFragmentInjected()) { AAMPLOG_TRACE("Type[%s] fragmentTime %f discontinuity %d duration %f initFragment:%d", name, fragment->position, fragment->discontinuity, fragment->duration, fragment->initFragment); - CachedFragment* cachedFragment = GetFetchChunkBuffer(true); + CachedFragment* cachedFragment = GetFetchBuffer(true); if(!cachedFragment) { - AAMPLOG_ERR("[%s] GetFetchChunkBuffer returned null", name); + AAMPLOG_ERR("[%s] GetFetchBuffer returned null", name); return false; } if(!cachedFragment->fragment.empty()) @@ -645,7 +645,7 @@ bool MediaStreamContext::CacheTsbFragment(std::shared_ptr&& frag if(!cachedFragment->fragment.empty()) { ret = true; - UpdateTSAfterChunkFetch(); + UpdateTSAfterFetch(); } else { diff --git a/StreamAbstractionAAMP.h b/StreamAbstractionAAMP.h index dde1666cf2..58aad0c892 100644 --- a/StreamAbstractionAAMP.h +++ b/StreamAbstractionAAMP.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -181,11 +182,11 @@ class MediaTrack uint32_t GetManifestUpdateCounter(); /** - * @fn AbortWaitForCachedFragmentChunk + * @fn AbortWaitForCachedFragmentInjected * * @return void */ - void AbortWaitForCachedFragmentChunk(); + void AbortWaitForCachedFragmentInjected(); /** * @fn WaitForManifestUpdate @@ -346,13 +347,6 @@ class MediaTrack */ void UpdateInjectedDuration(double surplusDuration); - /** - * @brief Get total fragment chunk injected duration - * - * @return Total duration in seconds - */ - double GetTotalInjectedChunkDuration() { return totalInjectedChunksDuration; }; - /** * @fn RunInjectLoop * @@ -369,11 +363,11 @@ class MediaTrack void UpdateTSAfterFetchStats(CachedFragment* cachedFragment, bool isInitSegment); /** - * @fn UpdateTSAfterChunkFetch + * @fn UpdateTSAfterFetch * * @return void */ - void UpdateTSAfterChunkFetch(); + void UpdateTSAfterFetch(); /** * @fn WaitForFreeFragmentAvailable @@ -383,10 +377,10 @@ class MediaTrack bool WaitForFreeFragmentAvailable( int timeoutMs = -1); /** - * @fn WaitForCachedFragmentChunkInjected - * @retval true if fragment chunk injected , false on abort. + * @fn WaitForCachedFragmentInjected + * @retval true if fragment injected, false on abort. */ - bool WaitForCachedFragmentChunkInjected(int timeoutMs = -1); + bool WaitForCachedFragmentInjected(int timeoutMs = -1); /** * @fn AbortWaitForCachedAndFreeFragment @@ -439,11 +433,11 @@ class MediaTrack virtual double GetBufferedDuration (void) = 0; /** - * @fn GetFetchChunkBuffer - * @param[in] initialize true to initialize the fragment chunk - * @retval Pointer to fragment chunk buffer. + * @fn GetFetchBuffer + * @param[in] initialize true to initialize the fragment slot + * @retval Pointer to the next fragment fetch slot. */ - CachedFragment *GetFetchChunkBuffer(bool initialize); + CachedFragment *GetFetchBuffer(bool initialize); /** * @brief Check if the fragment cache buffer is full @@ -478,14 +472,14 @@ class MediaTrack * * @return Total duration in seconds */ - double GetTotalFetchedDuration() { return totalFetchedDuration; }; + double GetTotalFetchedDuration(); /** - * @brief Get total duration of fetched fragments + * @brief Get total duration of injected fragment chunks (LLD chunk mode) * * @return Total duration in seconds */ - double GetTotalInjectedChunksDuration() { return totalInjectedChunksDuration; }; + double GetTotalInjectedChunksDuration() { return totalInjectedChunksDuration; } /** * @brief Check if discontinuity is being processed @@ -583,12 +577,6 @@ class MediaTrack */ void FlushFragments(); - /** - * @fn FlushFragmentChunks - * - * @return void - */ - void FlushFragmentChunks(); /** * @brief API to wait thread until the fragment cached after audio reconfiguration */ @@ -620,18 +608,18 @@ class MediaTrack bool SignalIfEOSReached(); /** - * @brief GetCachedFragmentChunksSize - Getter for fragment chunks cache size + * @brief GetCachedFragmentSize - Getter for fragment cache active window size * * @return size_t */ - std::size_t GetCachedFragmentChunksSize() { return mCachedFragmentChunksSize; } + std::size_t GetCachedFragmentSize() { return mCachedFragmentSize; } /** - * @brief SetCachedFragmentChunksSize - Setter for fragment chunks cache size + * @brief SetCachedFragmentSize - Setter for fragment cache active window size * - * @param[in] size Size for fragment chunks cache + * @param[in] size Active window size (must be > 0 and <= DEFAULT_LLD_CACHED_FRAGMENTS_PER_TRACK) */ - void SetCachedFragmentChunksSize(size_t size); + void SetCachedFragmentSize(size_t size); void SourceFormat(StreamOutputFormat fmt) { mSourceFormat = fmt; } @@ -681,14 +669,14 @@ class MediaTrack * * @return void */ - void UpdateTSAfterChunkInject(); + void UpdateTSAfterInject(); /** - * @fn WaitForCachedFragmentChunkAvailable + * @fn WaitForCachedFragmentAvailable * - * @return TRUE if fragment chunk available, FALSE if aborted/fragment chunk not available. + * @return TRUE if fragment available, FALSE if aborted or not available. */ - bool WaitForCachedFragmentChunkAvailable(); + bool WaitForCachedFragmentAvailable(); /** * @brief Get the context of media track. To be implemented by subclasses @@ -793,7 +781,7 @@ class MediaTrack public: bool eosReached; /**< set to true when a vod asset has been played to completion */ bool enabled; /**< set to true if track is enabled */ - int numberOfFragmentChunksCached; /**< Number of fragments cached in this track*/ + int numberOfFragmentsCached; /**< Number of fragments cached in this track*/ const char* name; /**< Track name used for debugging*/ double fragmentDurationSeconds; /**< duration in seconds for current fragment-of-interest */ int segDLFailCount; /**< Segment download fail count*/ @@ -803,8 +791,8 @@ class MediaTrack std::unique_ptr mSubtitleParser; /**< Parser for subtitle data*/ bool refreshSubtitles; /**< Switch subtitle track in the FetchLoop */ bool refreshAudio; /** Switch audio track in the FetcherLoop */ - int maxCachedFragmentChunksPerTrack; - std::condition_variable fragmentChunkFetched;/**< Signaled after a fragment Chunk is fetched*/ + int maxLLDCachedFragmentsPerTrack; + std::condition_variable fragmentFetched;/**< Signaled after a fragment is fetched*/ int noMDATCount; /**< MDAT Chunk Not Found count continuously while chunk buffer processing*/ double m_totalDurationForPtsRestamping; std::shared_ptr playContext; /**< state for s/w demuxer / pts/pcr restamper module */ @@ -815,7 +803,9 @@ class MediaTrack protected: PrivateInstanceAAMP* aamp; /**< Pointer to the PrivateInstanceAAMP*/ std::shared_ptr mIsoBmffHelper; /**< Helper class for ISO BMFF parsing */ - CachedFragment mCachedFragmentChunks[DEFAULT_CACHED_FRAGMENT_CHUNKS_PER_TRACK]; + /** Per-track ring buffer; static capacity sized for live LLD chunks. + * The active window is `mCachedFragmentSize`, which never exceeds the array size. */ + std::array mCachedFragment{}; std::vector unparsedBufferChunk{}; /**< Unparsed buffer chunk for ISOBMFF chunk processing */ std::vector parsedBufferChunk{}; /**< Parsed buffer chunk for ISOBMFF chunk processing */ bool abort; /**< Abort all operations if flag is set*/ @@ -826,8 +816,8 @@ class MediaTrack bool loadNewAudio; /**< Flag to indicate new audio loading started on seamless audio switch */ std::mutex subtitleMutex; bool loadNewSubtitle; - int fragmentChunkIdxToInject; /**< Write position */ - int fragmentChunkIdxToFetch; /**< Read position */ + int fragmentIdxToInject; /**< Write position */ + int fragmentIdxToFetch; /**< Read position */ StreamOutputFormat mSourceFormat {StreamOutputFormat::FORMAT_INVALID}; std::shared_ptr mTimeBasedBufferManager; /**< Time based buffer for managing fragment download and playback */ @@ -843,7 +833,7 @@ class MediaTrack std::mutex injectorStartMutex; /**< Mutex to protect injector start */ std::thread fragmentInjectorThreadID; /**< Fragment injector thread id*/ - std::condition_variable fragmentChunkInjected; /**< Signaled after a fragment is injected*/ + std::condition_variable fragmentInjected; /**< Signaled after a fragment is injected*/ std::thread bufferMonitorThreadID; /**< Buffer Monitor thread id */ std::thread subtitleClockThreadID; /**< subtitle clock synchronisation thread id */ int totalFragmentsDownloaded; /**< Total fragments downloaded since start by track*/ @@ -865,14 +855,14 @@ class MediaTrack bool abortPlaylistDownloader; /**< Flag used to abort playlist downloader*/ std::condition_variable plDownloadWait; /**< Conditional variable for signaling timed wait*/ std::mutex dwnldMutex; /**< Download mutex for conditional timed wait, used for playlist and fragment downloads*/ - uint32_t mManifestUpdateCounter; /**< Monotonically increasing counter incremented by AbortWaitForManifestUpdate. */ + uint32_t mManifestUpdateCounter; /**< Monotonically increasing counter incremented by AbortWaitForManifestUpdate. */ std::condition_variable mManifestUpdateWait; /**< Conditional variable for signaling manifest update */ std::condition_variable audioFragmentCached; /**< Signal after a audio fragment cached after reconfigure */ - double lastInjectedPosition; /**< Last injected position */ - double lastInjectedDuration; /**< Last injected fragment end position */ + double lastInjectedPosition; /**< Last injected position */ + double lastInjectedDuration; /**< Last injected fragment end position */ std::condition_variable subtitleFragmentCached; std::atomic_bool mIsLocalTSBInjection; - size_t mCachedFragmentChunksSize; /**< Size of fragment chunks cache */ + size_t mCachedFragmentSize; /**< Active window size of the fragment ring buffer */ AampTime mLastFragmentPts; /**< pts of the previous fragment, used in trick modes */ AampTime mRestampedPts; /**< Restamped Pts of the segment, used in trick modes */ AampTime mRestampedDuration; /**< Restamped segment duration, used in trick modes */ @@ -1822,11 +1812,11 @@ class StreamAbstractionAAMP : public AampLicenseFetcher } /** - * @fn UnblockWaitForCachedFragmentChunk + * @fn UnblockWaitForCachedFragmentInjected * * @return void */ - void UnblockWaitForCachedFragmentChunk(); + void UnblockWaitForCachedFragmentInjected(); /** * @brief Get available thumbnail bitrates. diff --git a/fragmentcollector_hls.cpp b/fragmentcollector_hls.cpp index ac46c04aad..8e524ff554 100644 --- a/fragmentcollector_hls.cpp +++ b/fragmentcollector_hls.cpp @@ -1293,10 +1293,10 @@ bool TrackState::FetchFragmentHelper(int &http_error, bool &decryption_error, bo if (!mInjectInitFragment && !fragmentURI.empty() && !bSegmentRepeated) { std::string fragmentUrl; - CachedFragment* cachedFragment = GetFetchChunkBuffer(true); + CachedFragment* cachedFragment = GetFetchBuffer(true); if (!cachedFragment) { - AAMPLOG_WARN("[%s] GetFetchChunkBuffer returned null", name); + AAMPLOG_WARN("[%s] GetFetchBuffer returned null", name); ReleasePlaylistLock(); return false; } @@ -1665,10 +1665,10 @@ void TrackState::FetchFragment() context->mRampDownCount = 0; } - CachedFragment* cachedFragment = GetFetchChunkBuffer(false); + CachedFragment* cachedFragment = GetFetchBuffer(false); if (!cachedFragment) { - AAMPLOG_WARN("[%s] GetFetchChunkBuffer returned null in FetchFragment", name); + AAMPLOG_WARN("[%s] GetFetchBuffer returned null in FetchFragment", name); return; } if (cachedFragment->fragment.capacity() != 0) @@ -1734,11 +1734,11 @@ void TrackState::FetchFragment() AAMPLOG_WARN("%s cachedFragment->fragment has no allocated data buffer", name); } mSkipAbr = false; //To enable ABR since we have cached fragment after init fragment - // Order matters: UpdateTSAfterChunkFetch() increments numberOfFragmentChunksCached, + // Order matters: UpdateTSAfterFetch() increments numberOfFragmentsCached, // which UpdateTSAfterFetchStats() then reads for its cache-full / caching-complete // decision. Calling the stats function first would observe a stale (pre-increment) // count and miss the "chunk cache is full" abort trigger on the slot-filling fragment. - UpdateTSAfterChunkFetch(); + UpdateTSAfterFetch(); UpdateTSAfterFetchStats(cachedFragment, false); } } @@ -6084,10 +6084,10 @@ void TrackState::FetchInitFragment() { aamp->profiler.ProfileEnd(bucketType); - CachedFragment *cachedFragment = GetFetchChunkBuffer(false); + CachedFragment *cachedFragment = GetFetchBuffer(false); if (!cachedFragment) { - AAMPLOG_WARN("[%s] GetFetchChunkBuffer returned null for init fragment in FetchFragment", name); + AAMPLOG_WARN("[%s] GetFetchBuffer returned null for init fragment in FetchFragment", name); mInjectInitFragment = true; // mark for retry return; } @@ -6108,10 +6108,10 @@ void TrackState::FetchInitFragment() mSkipAbr = true; // Skip ABR, since last fragment cached is init fragment. mCheckForInitialFragEnc = false; // Push encrypted header is a one-time operation mFirstEncInitFragmentInfo = NULL; // reset init fragment, since encrypted header already pushed - // Order matters: UpdateTSAfterChunkFetch() increments numberOfFragmentChunksCached, + // Order matters: UpdateTSAfterFetch() increments numberOfFragmentsCached, // which UpdateTSAfterFetchStats() reads for cache-full / caching-complete handling. // Kept consistent with FetchFragment() to avoid divergent stale-count behaviour. - UpdateTSAfterChunkFetch(); + UpdateTSAfterFetch(); UpdateTSAfterFetchStats(cachedFragment, true); } else if (type == eTRACK_VIDEO && aamp->CheckABREnabled() && !context->CheckForRampDownLimitReached()) @@ -6246,10 +6246,10 @@ bool TrackState::FetchInitFragmentHelper(int &http_code, bool forcePushEncrypted std::string fragmentUrl; aamp_ResolveURL(fragmentUrl, mEffectiveUrl, uri.c_str(), ISCONFIGSET(eAAMPConfig_PropagateURIParam)); std::string tempEffectiveUrl; - CachedFragment* cachedFragment = GetFetchChunkBuffer(true); + CachedFragment* cachedFragment = GetFetchBuffer(true); if (!cachedFragment) { - AAMPLOG_WARN("[%s] GetFetchChunkBuffer returned null in FetchInitFragmentHelper", name); + AAMPLOG_WARN("[%s] GetFetchBuffer returned null in FetchInitFragmentHelper", name); return false; } AAMPLOG_WARN("TrackState::[%s] init-fragment = %s", name, fragmentUrl.c_str()); diff --git a/fragmentcollector_mpd.cpp b/fragmentcollector_mpd.cpp index b192db082d..5369b81ccd 100644 --- a/fragmentcollector_mpd.cpp +++ b/fragmentcollector_mpd.cpp @@ -10205,7 +10205,7 @@ bool StreamAbstractionAAMP_MPD::AdvanceTsbFetch(int trackIdx, bool trickPlay, do } bool isAllowNextFrag = true; bool fragmentCached {false}; - int maxCachedFragmentsPerTrack = (int)pMediaStreamContext->GetCachedFragmentChunksSize(); + const int activeCacheSize = static_cast(pMediaStreamContext->GetCachedFragmentSize()); if (waitForFreeFrag && !trickPlay) { @@ -10222,11 +10222,11 @@ bool StreamAbstractionAAMP_MPD::AdvanceTsbFetch(int trackIdx, bool trickPlay, do { int timeoutMs = -1; if(bCacheFullState && - (pMediaStreamContext->numberOfFragmentChunksCached == maxCachedFragmentsPerTrack)) + (pMediaStreamContext->numberOfFragmentsCached == activeCacheSize)) { timeoutMs = MAX_WAIT_TIMEOUT_MS; } - isAllowNextFrag = pMediaStreamContext->WaitForCachedFragmentChunkInjected(timeoutMs); + isAllowNextFrag = pMediaStreamContext->WaitForCachedFragmentInjected(timeoutMs); } } @@ -10235,10 +10235,10 @@ bool StreamAbstractionAAMP_MPD::AdvanceTsbFetch(int trackIdx, bool trickPlay, do // profile not changed and not at EOS if(!pMediaStreamContext->profileChanged && tsbReader->TrackEnabled() && !tsbReader->IsEos()) { - fragmentCached = tsbSessionManager->PushNextTsbFragment(pMediaStreamContext, maxCachedFragmentsPerTrack - pMediaStreamContext->numberOfFragmentChunksCached); + fragmentCached = tsbSessionManager->PushNextTsbFragment(pMediaStreamContext, activeCacheSize - pMediaStreamContext->numberOfFragmentsCached); AAMPLOG_TRACE("[%s] Fragment %s", GetMediaTypeName((AampMediaType)trackIdx), fragmentCached ? "cached" : "not cached"); } - if(pMediaStreamContext->numberOfFragmentChunksCached != maxCachedFragmentsPerTrack && bCacheFullState) + if(pMediaStreamContext->numberOfFragmentsCached != activeCacheSize && bCacheFullState) { bCacheFullState = false; } @@ -10324,7 +10324,7 @@ void StreamAbstractionAAMP_MPD::TsbReader() { int trackIdx = (vEOS && !aEOS) ? eMEDIATYPE_AUDIO : eMEDIATYPE_VIDEO; // play cache is full , wait until cache is available to inject next, max wait of MAX_WAIT_TIMEOUT_MS - (void)mMediaStreamContext[trackIdx]->WaitForCachedFragmentChunkInjected(MAX_WAIT_TIMEOUT_MS); + (void)mMediaStreamContext[trackIdx]->WaitForCachedFragmentInjected(MAX_WAIT_TIMEOUT_MS); } else { @@ -10716,7 +10716,7 @@ void StreamAbstractionAAMP_MPD::StartFromAampLocalTsb(void) // Flush fragments cached during Live SLD mMediaStreamContext[i]->FlushFetchedFragments(); - // Flush fragments from mCachedFragmentChunks + // Flush fragments from mCachedFragment mMediaStreamContext[i]->FlushFragments(); // For seek to live, we will employ chunk cache and hence size has to be increased to max @@ -10724,11 +10724,11 @@ void StreamAbstractionAAMP_MPD::StartFromAampLocalTsb(void) if ((mTuneType == eTUNETYPE_SEEKTOLIVE) && (aamp->GetLLDashChunkMode())) { - mMediaStreamContext[i]->SetCachedFragmentChunksSize(static_cast(mMediaStreamContext[i]->maxCachedFragmentChunksPerTrack)); + mMediaStreamContext[i]->SetCachedFragmentSize(static_cast(mMediaStreamContext[i]->maxLLDCachedFragmentsPerTrack)); } else { - mMediaStreamContext[i]->SetCachedFragmentChunksSize(static_cast(GETCONFIGVALUE(eAAMPConfig_MaxFragmentCached))); + mMediaStreamContext[i]->SetCachedFragmentSize(static_cast(GETCONFIGVALUE(eAAMPConfig_MaxFragmentCached))); } mMediaStreamContext[i]->eosReached = false; @@ -10811,8 +10811,8 @@ void StreamAbstractionAAMP_MPD::Stop(bool clearChannelData) track->AbortWaitForCachedFragment(); if (track->IsLocalTSBInjection()) { - // TSBReader could be waiting indefinitely WaitForCachedFragmentChunkInjected, this will unblock the same - track->AbortWaitForCachedFragmentChunk(); + // TSBReader could be waiting indefinitely WaitForCachedFragmentInjected, this will unblock the same + track->AbortWaitForCachedFragmentInjected(); } } } diff --git a/priv_aamp.cpp b/priv_aamp.cpp index 031c73f392..dc0bcc2bca 100644 --- a/priv_aamp.cpp +++ b/priv_aamp.cpp @@ -8583,7 +8583,7 @@ void PrivateInstanceAAMP::Stop( bool sendStateChangeEvent ) double bufferedDuration = 0.0; if (mpStreamAbstractionAAMP) { - mpStreamAbstractionAAMP->UnblockWaitForCachedFragmentChunk(); // avoid mutex lock if waiting for cached fragments + mpStreamAbstractionAAMP->UnblockWaitForCachedFragmentInjected(); // avoid mutex lock if waiting for cached fragments bufferedDuration = mpStreamAbstractionAAMP->GetBufferedVideoDurationSec(); } double latency = GetCurrentLatencyMs(); diff --git a/streamabstraction.cpp b/streamabstraction.cpp index ca5b4dc2e9..08b329782a 100644 --- a/streamabstraction.cpp +++ b/streamabstraction.cpp @@ -22,6 +22,22 @@ /** * @file streamabstraction.cpp * @brief Definition of common class functions used by fragment collectors. + * + * @section MediaTrack lock order + * + * Two MediaTrack mutexes are used together; acquire in this order, release + * in reverse: + * 1. `mutex` — protects the per-track ring buffer + * (`mCachedFragment[]`, `numberOfFragmentsCached`, + * `fragmentIdxTo*`, the fetch/inject CVs). + * 2. `mTrackParamsMutex` — protects track lifetime counters + * (`totalFetchedDuration`, `totalInjectedDuration`, + * `totalInjectedChunksDuration`, + * `totalFragmentsDownloaded`). + * + * `mTrackParamsMutex` is leaf-level: never take any other MediaTrack mutex + * while holding it. Holding `mutex` and then taking `mTrackParamsMutex` is + * permitted (e.g. UpdateTSAfterFetchStats). */ #include "AampStreamSinkManager.h" #include "StreamAbstractionAAMP.h" @@ -152,7 +168,7 @@ BufferHealthStatus MediaTrack::GetBufferStatus() else if (pContext) { bufferedTime = injectedDuration - pContext->GetElapsedTime(); - CachedFragmentsOrChunks = numberOfFragmentChunksCached; + CachedFragmentsOrChunks = numberOfFragmentsCached; } if ( CachedFragmentsOrChunks <= 0 && (bufferedTime <= thresholdBuffer) && pContext) @@ -370,24 +386,26 @@ void MediaTrack::UpdateSubtitleClockTask() /** * @brief Update segment cache and inject buffer to gstreamer */ -void MediaTrack::UpdateTSAfterChunkInject() +void MediaTrack::UpdateTSAfterInject() { std::lock_guard guard(mutex); - //Free Chunk Cache Buffer - prevDownloadStartTime = mCachedFragmentChunks[fragmentChunkIdxToInject].downloadStartTime; - aamp_utils::ClearAndRelease(mCachedFragmentChunks[fragmentChunkIdxToInject].fragment); + //Free cached fragment slot + prevDownloadStartTime = mCachedFragment[fragmentIdxToInject].downloadStartTime; + aamp_utils::ClearAndRelease(mCachedFragment[fragmentIdxToInject].fragment); aamp_utils::ClearAndRelease(parsedBufferChunk); - //increment Inject Index - ++fragmentChunkIdxToInject; - fragmentChunkIdxToInject = (fragmentChunkIdxToInject) % mCachedFragmentChunksSize; - if(numberOfFragmentChunksCached > 0) numberOfFragmentChunksCached--; + // Advance inject index with ring wrap + fragmentIdxToInject = (fragmentIdxToInject + 1) % mCachedFragmentSize; + if (numberOfFragmentsCached > 0) + { + numberOfFragmentsCached--; + } - AAMPLOG_DEBUG("[%s] updated fragmentChunkIdxToInject = %d numberOfFragmentChunksCached %d", - name, fragmentChunkIdxToInject, numberOfFragmentChunksCached); + AAMPLOG_DEBUG("[%s] updated fragmentIdxToInject = %d numberOfFragmentsCached %d", + name, fragmentIdxToInject, numberOfFragmentsCached); - fragmentChunkInjected.notify_one(); + fragmentInjected.notify_one(); } /** @@ -477,7 +495,13 @@ void MediaTrack::UpdateTSAfterFetchStats(CachedFragment* cachedFragment, bool is cachedFragment->profileIndex = pContext->profileIdxForBandwidthNotification; pContext->UpdateStreamInfoBitrateData(cachedFragment->profileIndex, cachedFragment->cacheFragStreamInfo); } - totalFetchedDuration += cachedFragment->duration; + { + // Lock-order: mutex (held above) -> mTrackParamsMutex (taken here). + // mTrackParamsMutex is leaf-level: nothing else takes it first then + // reaches for mutex. + std::lock_guard trackLock(mTrackParamsMutex); + totalFetchedDuration += cachedFragment->duration; + } currentInitialCacheDurationSeconds += cachedFragment->duration; if ((eTRACK_VIDEO == type) @@ -492,9 +516,9 @@ void MediaTrack::UpdateTSAfterFetchStats(CachedFragment* cachedFragment, bool is notifyCacheCompleted = true; cachingCompleted = true; } - else if (sinkBufferIsFull && numberOfFragmentChunksCached == mCachedFragmentChunksSize) + else if (sinkBufferIsFull && numberOfFragmentsCached == mCachedFragmentSize) { - AAMPLOG_WARN("## [%s] Chunk Cache is Full cacheDuration %d minInitialCacheSeconds %d, aborting caching!##", + AAMPLOG_WARN("## [%s] Fragment Cache is Full cacheDuration %d minInitialCacheSeconds %d, aborting caching!##", name, currentInitialCacheDurationSeconds, minInitialCacheSeconds); notifyCacheCompleted = true; cachingCompleted = true; @@ -539,6 +563,7 @@ void MediaTrack::UpdateTSAfterFetchStats(CachedFragment* cachedFragment, bool is } if (!isInitSegment) { + std::lock_guard trackLock(mTrackParamsMutex); totalFragmentsDownloaded++; } lock.unlock(); @@ -564,22 +589,22 @@ void MediaTrack::LoadNewSubtitle(bool val) /** * @brief Updates internal state after a fragment fetch */ -void MediaTrack::UpdateTSAfterChunkFetch() +void MediaTrack::UpdateTSAfterFetch() { std::lock_guard guard(mutex); - numberOfFragmentChunksCached++; - AAMPLOG_DEBUG("[%s] numberOfFragmentChunksCached++ [%d]", name,numberOfFragmentChunksCached); + numberOfFragmentsCached++; + AAMPLOG_DEBUG("[%s] numberOfFragmentsCached++ [%d]", name,numberOfFragmentsCached); //this should never HIT - assert(numberOfFragmentChunksCached <= mCachedFragmentChunksSize); + assert(numberOfFragmentsCached <= mCachedFragmentSize); - fragmentChunkIdxToFetch = (fragmentChunkIdxToFetch+1) % mCachedFragmentChunksSize; + fragmentIdxToFetch = (fragmentIdxToFetch+1) % mCachedFragmentSize; - AAMPLOG_DEBUG("[%s] updated fragmentChunkIdxToFetch [%d] numberOfFragmentChunksCached [%d]", - name, fragmentChunkIdxToFetch, numberOfFragmentChunksCached); + AAMPLOG_DEBUG("[%s] updated fragmentIdxToFetch [%d] numberOfFragmentsCached [%d]", + name, fragmentIdxToFetch, numberOfFragmentsCached); - fragmentChunkFetched.notify_one(); + fragmentFetched.notify_one(); } /** @@ -602,7 +627,12 @@ bool MediaTrack::WaitForFreeFragmentAvailable( int timeoutMs) // Wait for 100ms std::unique_lock lock(aamp->mMutexPlaystart); state = aamp->GetState(); - if(state == eSTATE_PREPARED && totalFragmentsDownloaded > preplaybuffercount && !aamp->IsFragmentCachingRequired()) + int cachedFragmentCount; + { + std::lock_guard trackLock(mTrackParamsMutex); + cachedFragmentCount = totalFragmentsDownloaded; + } + if(state == eSTATE_PREPARED && cachedFragmentCount > preplaybuffercount && !aamp->IsFragmentCachingRequired()) { timeoutMs = 500; if (std::cv_status::timeout == aamp->waitforplaystart.wait_for(lock,std::chrono::milliseconds(timeoutMs))) @@ -615,15 +645,15 @@ bool MediaTrack::WaitForFreeFragmentAvailable( int timeoutMs) if (ret) { - ret = WaitForCachedFragmentChunkInjected(timeoutMs); + ret = WaitForCachedFragmentInjected(timeoutMs); } return ret; } /** - * @brief Wait until a cached fragment chunk is Injected. + * @brief Wait until a cached fragment is injected. */ -bool MediaTrack::WaitForCachedFragmentChunkInjected(int timeoutMs) +bool MediaTrack::WaitForCachedFragmentInjected(int timeoutMs) { bool ret = true; if(abort) @@ -631,65 +661,65 @@ bool MediaTrack::WaitForCachedFragmentChunkInjected(int timeoutMs) ret = false; } std::unique_lock lock(mutex); - if (ret && (numberOfFragmentChunksCached == mCachedFragmentChunksSize)) + if (ret && (numberOfFragmentsCached == mCachedFragmentSize)) { if (timeoutMs >= 0) { - AAMPLOG_DEBUG("[%s] waiting for fragmentChunkInjected condition (timeout %dms)", name, timeoutMs); - fragmentChunkInjected.wait_for(lock, std::chrono::milliseconds(timeoutMs), [this] { // Predicate to avoid spurious wake ups - return numberOfFragmentChunksCached < mCachedFragmentChunksSize || abort; + AAMPLOG_DEBUG("[%s] waiting for fragmentInjected condition (timeout %dms)", name, timeoutMs); + fragmentInjected.wait_for(lock, std::chrono::milliseconds(timeoutMs), [this] { // Predicate to avoid spurious wake ups + return numberOfFragmentsCached < mCachedFragmentSize || abort; }); } else { - AAMPLOG_DEBUG("[%s] waiting for fragmentChunkInjected condition", name); - fragmentChunkInjected.wait(lock, [this] { // Predicate to avoid spurious wake ups - return numberOfFragmentChunksCached < mCachedFragmentChunksSize || abort; + AAMPLOG_DEBUG("[%s] waiting for fragmentInjected condition", name); + fragmentInjected.wait(lock, [this] { // Predicate to avoid spurious wake ups + return numberOfFragmentsCached < mCachedFragmentSize || abort; }); - AAMPLOG_DEBUG("[%s] wait complete for fragmentChunkInjected", name); + AAMPLOG_DEBUG("[%s] wait complete for fragmentInjected", name); } if (abort) { AAMPLOG_DEBUG("[%s] abort set, returning false", name); ret = false; } - else if (numberOfFragmentChunksCached == mCachedFragmentChunksSize) + else if (numberOfFragmentsCached == mCachedFragmentSize) { - AAMPLOG_DEBUG("[%s] cache still full (%d/%zu), returning false", name, numberOfFragmentChunksCached, mCachedFragmentChunksSize); + AAMPLOG_DEBUG("[%s] cache still full (%d/%zu), returning false", name, numberOfFragmentsCached, mCachedFragmentSize); ret = false; } } - AAMPLOG_DEBUG("[%s] fragmentChunkIdxToFetch = %d numberOfFragmentChunksCached %d mCachedFragmentChunksSize %zu", - name, fragmentChunkIdxToFetch, numberOfFragmentChunksCached, mCachedFragmentChunksSize); + AAMPLOG_DEBUG("[%s] fragmentIdxToFetch = %d numberOfFragmentsCached %d mCachedFragmentSize %zu", + name, fragmentIdxToFetch, numberOfFragmentsCached, mCachedFragmentSize); return ret; } /** - * @brief Wait till cached fragment chunk available + * @brief Wait until a cached fragment is available. */ -bool MediaTrack::WaitForCachedFragmentChunkAvailable() +bool MediaTrack::WaitForCachedFragmentAvailable() { bool ret = true; AAMPLOG_TRACE("DEBUG Enter"); std::unique_lock lock(mutex); - AAMPLOG_DEBUG("[%s] Acquired MUTEX ==> fragmentChunkIdxToInject = %d numberOfFragmentChunksCached %d ret = %d abort = %d abortInject = %d ", name, fragmentChunkIdxToInject, numberOfFragmentChunksCached, ret, abort, abortInject); + AAMPLOG_DEBUG("[%s] Acquired MUTEX ==> fragmentIdxToInject = %d numberOfFragmentsCached %d ret = %d abort = %d abortInject = %d ", name, fragmentIdxToInject, numberOfFragmentsCached, ret, abort, abortInject); - if ((numberOfFragmentChunksCached == 0) && !(abort || abortInject)) + if ((numberOfFragmentsCached == 0) && !(abort || abortInject)) { AAMPLOG_DEBUG("## [%s] Waiting for CachedFragment to be available, eosReached=%d ##", name, eosReached); if (!eosReached) { - fragmentChunkFetched.wait(lock); - AAMPLOG_DEBUG("[%s] wait complete for fragmentChunkFetched", name); + fragmentFetched.wait(lock); + AAMPLOG_DEBUG("[%s] wait complete for fragmentFetched", name); } } - ret = !(abort || abortInject || numberOfFragmentChunksCached == 0); - AAMPLOG_DEBUG("[%s] fragmentChunkIdxToInject = %d numberOfFragmentChunksCached %d ret = %d abort = %d abortInject = %d", - name, fragmentChunkIdxToInject, numberOfFragmentChunksCached, ret, abort, abortInject); + ret = !(abort || abortInject || numberOfFragmentsCached == 0); + AAMPLOG_DEBUG("[%s] fragmentIdxToInject = %d numberOfFragmentsCached %d ret = %d abort = %d abortInject = %d", + name, fragmentIdxToInject, numberOfFragmentsCached, ret, abort, abortInject); return ret; } @@ -702,12 +732,12 @@ void MediaTrack::AbortWaitForCachedAndFreeFragment(bool immediate) if (immediate) { abort = true; - AAMPLOG_DEBUG("[%s] signal fragmentChunkInjected condition", name); - // For TSB playback, WaitForCachedFragmentChunkInject is invoked from TSBReader and CacheFragmentChunk threads - fragmentChunkInjected.notify_all(); + AAMPLOG_DEBUG("[%s] signal fragmentInjected condition", name); + // For TSB playback, WaitForCachedFragmentInjected is invoked from TSBReader and CacheFragment threads + fragmentInjected.notify_all(); } - AAMPLOG_DEBUG("[%s] signal fragmentChunkFetched condition", name); - fragmentChunkFetched.notify_one(); + AAMPLOG_DEBUG("[%s] signal fragmentFetched condition", name); + fragmentFetched.notify_one(); aamp->waitforplaystart.notify_one(); lock.unlock(); @@ -720,8 +750,8 @@ void MediaTrack::AbortWaitForCachedAndFreeFragment(bool immediate) void MediaTrack::AbortWaitForCachedFragment() { std::unique_lock lock(mutex); - AAMPLOG_DEBUG("[%s] signal fragmentChunkFetched condition", name); - fragmentChunkFetched.notify_one(); + AAMPLOG_DEBUG("[%s] signal fragmentFetched condition", name); + fragmentFetched.notify_one(); abortInject = true; lock.unlock(); @@ -730,13 +760,13 @@ void MediaTrack::AbortWaitForCachedFragment() } /** - * @brief Abort the waiting for injected fragment chunks immediately + * @brief Abort waiting for a cached fragment to be injected. */ -void MediaTrack::AbortWaitForCachedFragmentChunk() +void MediaTrack::AbortWaitForCachedFragmentInjected() { std::lock_guard guard(mutex); - AAMPLOG_TRACE("[%s] signal fragmentChunkInjected condition", name); - fragmentChunkInjected.notify_all(); + AAMPLOG_TRACE("[%s] signal fragmentInjected condition", name); + fragmentInjected.notify_all(); } /** @@ -895,7 +925,7 @@ bool MediaTrack::ProcessFragmentChunk() { class StreamAbstractionAAMP* pContext = GetContext(); //Get Cache buffer - CachedFragment* cachedFragment = &this->mCachedFragmentChunks[fragmentChunkIdxToInject]; + CachedFragment* cachedFragment = &this->mCachedFragment[fragmentIdxToInject]; if(cachedFragment != NULL && cachedFragment->fragment.capacity() == 0) { if(!SignalIfEOSReached()) @@ -982,7 +1012,7 @@ bool MediaTrack::ProcessFragmentChunk() } if(!bParse) { - AAMPLOG_INFO("[%s] No Box available in cache chunk: fragmentChunkIdxToInject %d", name, fragmentChunkIdxToInject); + AAMPLOG_INFO("[%s] No Box available in cache chunk: fragmentIdxToInject %d", name, fragmentIdxToInject); return true; } //Print box details @@ -1005,7 +1035,7 @@ bool MediaTrack::ProcessFragmentChunk() { if( noMDATCount > MAX_MDAT_NOT_FOUND_COUNT ) { - AAMPLOG_INFO("[%s] noMDATCount=%d ChunkIndex=%d totchunklen=%zu", name,noMDATCount, fragmentChunkIdxToInject,unParsedBufferSize); + AAMPLOG_INFO("[%s] noMDATCount=%d ChunkIndex=%d totchunklen=%zu", name,noMDATCount, fragmentIdxToInject,unParsedBufferSize); noMDATCount=0; } noMDATCount++; @@ -1050,7 +1080,10 @@ bool MediaTrack::ProcessFragmentChunk() } AAMPLOG_INFO("Injecting chunk for %s br=%" BITSPERSECOND_FORMAT ",chunksize=%zu fpts=%f fduration=%f", name, bandwidthBitsPerSecond, parsedBufferChunk.size(), fpts, fduration); InjectFragmentChunkInternal((AampMediaType)type, parsedBufferChunk, fpts, fpts, fduration, cachedFragment->PTSOffsetSec); - totalInjectedChunksDuration += fduration; + { + std::lock_guard trackLock(mTrackParamsMutex); + totalInjectedChunksDuration += fduration; + } } } // Move unparsed data sections to beginning @@ -1291,16 +1324,16 @@ void MediaTrack::ProcessAndInjectFragment(CachedFragment *cachedFragment, bool f if (aamp->GetLLDashChunkMode()) { bool bIgnore = true; - AAMPLOG_TRACE("[%s] Processing the chunk ==> fragmentChunkIdxToInject = %d numberOfFragmentChunksCached %d", name, fragmentChunkIdxToInject, numberOfFragmentChunksCached); + AAMPLOG_TRACE("[%s] Processing the chunk ==> fragmentIdxToInject = %d numberOfFragmentsCached %d", name, fragmentIdxToInject, numberOfFragmentsCached); if(!cachedFragment->isDummy) { bIgnore = ProcessFragmentChunk(); } if(bIgnore) { - AAMPLOG_TRACE("[%s] Updating the chunk inject ==> fragmentChunkIdxToInject = %d numberOfFragmentChunksCached %d", name, fragmentChunkIdxToInject, numberOfFragmentChunksCached); - UpdateTSAfterChunkInject(); - AAMPLOG_TRACE("[%s] Updated the chunk inject ==> fragmentChunkIdxToInject = %d numberOfFragmentChunksCached %d", name, fragmentChunkIdxToInject, numberOfFragmentChunksCached); + AAMPLOG_TRACE("[%s] Updating the chunk inject ==> fragmentIdxToInject = %d numberOfFragmentsCached %d", name, fragmentIdxToInject, numberOfFragmentsCached); + UpdateTSAfterInject(); + AAMPLOG_TRACE("[%s] Updated the chunk inject ==> fragmentIdxToInject = %d numberOfFragmentsCached %d", name, fragmentIdxToInject, numberOfFragmentsCached); } } else @@ -1418,7 +1451,7 @@ void MediaTrack::ProcessAndInjectFragment(CachedFragment *cachedFragment, bool f } // Release the memory and Update the inject - UpdateTSAfterChunkInject(); + UpdateTSAfterInject(); // Plain SLD DASH (not LLD chunk mode, not AAMP TSB) routes through the chunk // cache but still needs time-based buffer accounting, as it did before. if (!aamp->GetLLDashChunkMode() && !aamp->IsLocalAAMPTsb()) @@ -1446,16 +1479,16 @@ bool MediaTrack::InjectFragment() { aamp->BlockUntilGstreamerWantsData(NULL, 0, type); } - bool notAborted = WaitForCachedFragmentChunkAvailable(); + bool notAborted = WaitForCachedFragmentAvailable(); if (notAborted) { bool stopInjection = false; bool fragmentDiscarded = false; bool isDiscontinuity = false; - CachedFragment* cachedFragment = &this->mCachedFragmentChunks[fragmentChunkIdxToInject]; - AAMPLOG_TRACE("[%s] fragmentChunkIdxToInject : %d Discontinuity %d ", name, fragmentChunkIdxToInject, cachedFragment->discontinuity); - AAMPLOG_TRACE("[%s] - fragmentChunkIdxToInject %d cachedFragment %p ptr %p", - name, fragmentChunkIdxToInject, cachedFragment, cachedFragment->fragment.data()); + CachedFragment* cachedFragment = &this->mCachedFragment[fragmentIdxToInject]; + AAMPLOG_TRACE("[%s] fragmentIdxToInject : %d Discontinuity %d ", name, fragmentIdxToInject, cachedFragment->discontinuity); + AAMPLOG_TRACE("[%s] - fragmentIdxToInject %d cachedFragment %p ptr %p", + name, fragmentIdxToInject, cachedFragment, cachedFragment->fragment.data()); if (cachedFragment->fragment.capacity() != 0) { // This is currently supported for non-LL DASH streams only at normal play rate @@ -1495,14 +1528,14 @@ bool MediaTrack::InjectFragment() } else { - AAMPLOG_WARN("%s - NULL ptr to inject. fragmentChunkIdxToInject %d", name, fragmentChunkIdxToInject); + AAMPLOG_WARN("%s - NULL ptr to inject. fragmentIdxToInject %d", name, fragmentIdxToInject); } ret = false; } } else { - AAMPLOG_WARN("WaitForCachedFragmentChunkAvailable %s aborted LowLatency: %d ChunkMode %d", name, lowLatency,isChunkMode); + AAMPLOG_WARN("WaitForCachedFragmentAvailable %s aborted LowLatency: %d ChunkMode %d", name, lowLatency,isChunkMode); //EOS should not be triggered when subtitle sets its "eosReached" in any circumstances SignalIfEOSReached(); ret = false; @@ -1762,18 +1795,18 @@ bool MediaTrack::isPlaylistDownloaderThreadStarted() /** * @brief Get buffer to fetch and cache next fragment chunk */ -CachedFragment* MediaTrack::GetFetchChunkBuffer(bool initialize) +CachedFragment* MediaTrack::GetFetchBuffer(bool initialize) { - if(fragmentChunkIdxToFetch <0 || fragmentChunkIdxToFetch >= mCachedFragmentChunksSize) + if(fragmentIdxToFetch <0 || fragmentIdxToFetch >= mCachedFragmentSize) { - AAMPLOG_WARN("[%s] OUT OF RANGE => fragmentChunkIdxToFetch: %d mCachedFragmentChunksSize: %zu",name,fragmentChunkIdxToFetch, mCachedFragmentChunksSize); + AAMPLOG_WARN("[%s] OUT OF RANGE => fragmentIdxToFetch: %d mCachedFragmentSize: %zu",name,fragmentIdxToFetch, mCachedFragmentSize); return NULL; } CachedFragment* cachedFragment = NULL; - cachedFragment = &this->mCachedFragmentChunks[fragmentChunkIdxToFetch]; + cachedFragment = &this->mCachedFragment[fragmentIdxToFetch]; - AAMPLOG_DEBUG("[%s] fragmentChunkIdxToFetch: %d cachedFragment: %p",name, fragmentChunkIdxToFetch, cachedFragment); + AAMPLOG_DEBUG("[%s] fragmentIdxToFetch: %d cachedFragment: %p",name, fragmentIdxToFetch, cachedFragment); if(initialize && cachedFragment) { @@ -1794,8 +1827,8 @@ bool MediaTrack::IsFragmentCacheFull() { bool rc = false; std::lock_guard guard(mutex); - AAMPLOG_DEBUG("[%s] numberOfFragmentChunksCached %d mCachedFragmentChunksSize %zu", name, numberOfFragmentChunksCached, mCachedFragmentChunksSize); - rc = (numberOfFragmentChunksCached == mCachedFragmentChunksSize); + AAMPLOG_DEBUG("[%s] numberOfFragmentsCached %d mCachedFragmentSize %zu", name, numberOfFragmentsCached, mCachedFragmentSize); + rc = (numberOfFragmentsCached == mCachedFragmentSize); return rc; } @@ -1831,19 +1864,19 @@ BitsPerSecond MediaTrack::GetCurrentBandWidth() void MediaTrack::FlushFetchedFragments() { std::lock_guard guard(mutex); - while (numberOfFragmentChunksCached) + while (numberOfFragmentsCached) { - AAMPLOG_DEBUG("[%s] Free mCachedFragmentChunks[%d] numberOfFragmentChunksCached %d", name, fragmentChunkIdxToInject, numberOfFragmentChunksCached); - mCachedFragmentChunks[fragmentChunkIdxToInject].Clear(); + AAMPLOG_DEBUG("[%s] Free mCachedFragment[%d] numberOfFragmentsCached %d", name, fragmentIdxToInject, numberOfFragmentsCached); + mCachedFragment[fragmentIdxToInject].Clear(); - fragmentChunkIdxToInject++; - if (fragmentChunkIdxToInject == mCachedFragmentChunksSize) + fragmentIdxToInject++; + if (fragmentIdxToInject == mCachedFragmentSize) { - fragmentChunkIdxToInject = 0; + fragmentIdxToInject = 0; } - numberOfFragmentChunksCached--; + numberOfFragmentsCached--; } - fragmentChunkInjected.notify_one(); + fragmentInjected.notify_one(); } /** @@ -1854,29 +1887,34 @@ void MediaTrack::FlushFetchedFragments() void MediaTrack::FlushFragments() { AAMPLOG_WARN("[%s]", name); - for (size_t i = 0; i < mCachedFragmentChunksSize; i++) + for (size_t i = 0; i < mCachedFragmentSize; i++) { - mCachedFragmentChunks[i].Clear(); + mCachedFragment[i].Clear(); } aamp_utils::ClearAndRelease(unparsedBufferChunk); aamp_utils::ClearAndRelease(parsedBufferChunk); - fragmentChunkIdxToInject = 0; - fragmentChunkIdxToFetch = 0; + fragmentIdxToInject = 0; + fragmentIdxToFetch = 0; std::lock_guard guard(mutex); - numberOfFragmentChunksCached = 0; - // We need to revisit if these variables should be also sync using mTrackParamsMutex - totalInjectedChunksDuration = 0; + numberOfFragmentsCached = 0; - // For audio/subtitle tracks that are not mid-switch, reset the business-logic - // lifetime counters so that post-flush callers (GetBufferStatus, HandleTrackChange, - // ABR) start from a clean slate for the new track content. These counters are - // protected by mTrackParamsMutex (separate from the ring-buffer mutex above). - if (( type == eTRACK_AUDIO && !loadNewAudio ) || ( type == eTRACK_SUBTITLE && !loadNewSubtitle )) + // All fragment-injected/fetched duration counters live under mTrackParamsMutex. + // Always reset totalInjectedChunksDuration here (LLD chunk-mode peer of + // totalInjectedDuration); the audio/subtitle-only counters below are reset + // only when the track is not in the middle of a seamless switch. { - std::lock_guard lock(mTrackParamsMutex); - totalFetchedDuration = 0; - totalFragmentsDownloaded = 0; - totalInjectedDuration = 0; + std::lock_guard trackLock(mTrackParamsMutex); + totalInjectedChunksDuration = 0; + + // For audio/subtitle tracks that are not mid-switch, reset the + // business-logic lifetime counters so post-flush callers (GetBufferStatus, + // HandleTrackChange, ABR) start from a clean slate for the new track. + if (( type == eTRACK_AUDIO && !loadNewAudio ) || ( type == eTRACK_SUBTITLE && !loadNewSubtitle )) + { + totalFetchedDuration = 0; + totalFragmentsDownloaded = 0; + totalInjectedDuration = 0; + } } } @@ -1902,8 +1940,8 @@ void MediaTrack::OffsetTrackParams(double deltaFetchedDuration, double deltaInje * @brief MediaTrack Constructor */ MediaTrack::MediaTrack(TrackType type, PrivateInstanceAAMP* aamp, const char* name) : - eosReached(false), enabled(false), numberOfFragmentChunksCached(0), fragmentChunkIdxToInject(0), - fragmentChunkIdxToFetch(0), abort(false), fragmentInjectorThreadID(), bufferMonitorThreadID(), subtitleClockThreadID(), totalFragmentsDownloaded(0), + eosReached(false), enabled(false), numberOfFragmentsCached(0), fragmentIdxToInject(0), + fragmentIdxToFetch(0), abort(false), fragmentInjectorThreadID(), bufferMonitorThreadID(), subtitleClockThreadID(), totalFragmentsDownloaded(0), UpdateSubtitleClockTaskStarted(false), bufferMonitorThreadDisabled(false), totalInjectedDuration(0), totalInjectedChunksDuration(0), currentInitialCacheDurationSeconds(0), sinkBufferIsFull(false), cachingCompleted(false), fragmentDurationSeconds(0), segDLFailCount(0),segDrmDecryptFailCount(0),mSegInjectFailCount(0), bufferStatus(BUFFER_STATUS_GREEN), prevBufferStatus(BUFFER_STATUS_GREEN), @@ -1911,22 +1949,22 @@ MediaTrack::MediaTrack(TrackType type, PrivateInstanceAAMP* aamp, const char* na discontinuityProcessed(false), ptsError(false), name(name), type(type), aamp(aamp), mutex(), abortInject(false), mSubtitleParser(), refreshSubtitles(false), refreshAudio(false), - mCachedFragmentChunks{}, fragmentChunkFetched(), fragmentChunkInjected(), maxCachedFragmentChunksPerTrack(0), + mCachedFragment{}, fragmentFetched(), fragmentInjected(), maxLLDCachedFragmentsPerTrack(0), noMDATCount(0), loadNewAudio(false), audioFragmentCached(), audioMutex(), loadNewSubtitle(false), subtitleFragmentCached(), subtitleMutex(), abortPlaylistDownloader(true), plDownloadWait() ,dwnldMutex(), playlistDownloaderThread(NULL), mManifestUpdateCounter(0) ,mManifestUpdateWait(),prevDownloadStartTime(-1) ,playContext(nullptr), seamlessAudioSwitchInProgress(false), lastInjectedPosition(0), lastInjectedDuration(0), seamlessSubtitleSwitchInProgress(false) - ,mIsLocalTSBInjection(false), mCachedFragmentChunksSize(0) + ,mIsLocalTSBInjection(false), mCachedFragmentSize(0) ,mIsoBmffHelper(std::make_shared()) ,mLastFragmentPts(0), mRestampedPts(0), mRestampedDuration(0), mTrickmodeState(TrickmodeState::UNDEF) ,mTrackParamsMutex(), mCheckForRampdown(false), mTimeBasedBufferManager(nullptr) ,gotLocalTime(false),ptsRollover(false),currentLocalTimeMs(0) { - const int sldChunkCacheSize = GETCONFIGVALUE(eAAMPConfig_MaxFragmentCached); + const int sldCacheSize = GETCONFIGVALUE(eAAMPConfig_MaxFragmentCached); - maxCachedFragmentChunksPerTrack = GETCONFIGVALUE(eAAMPConfig_MaxFragmentChunkCached); - SetCachedFragmentChunksSize((aamp->GetLLDashChunkMode()) ? maxCachedFragmentChunksPerTrack : sldChunkCacheSize); + maxLLDCachedFragmentsPerTrack = GETCONFIGVALUE(eAAMPConfig_MaxLLDFragmentCached); + SetCachedFragmentSize((aamp->GetLLDashChunkMode()) ? maxLLDCachedFragmentsPerTrack : sldCacheSize); } @@ -2812,9 +2850,9 @@ bool StreamAbstractionAAMP::CheckIfPlayerRunningDry() { return false; } - bool videoBufferIsEmpty = (videoTrack->numberOfFragmentChunksCached == 0) && aamp->IsSinkCacheEmpty(eMEDIATYPE_VIDEO); + bool videoBufferIsEmpty = (videoTrack->numberOfFragmentsCached == 0) && aamp->IsSinkCacheEmpty(eMEDIATYPE_VIDEO); bool audioBufferIsEmpty = (audioTrack->Enabled() - ? audioTrack->numberOfFragmentChunksCached == 0 + ? audioTrack->numberOfFragmentsCached == 0 : true) && aamp->IsSinkCacheEmpty(eMEDIATYPE_AUDIO); if (videoBufferIsEmpty || audioBufferIsEmpty) /* Changed the condition from '&&' to '||', because if video getting stalled it doesn't need to wait until audio become dry */ { @@ -3027,7 +3065,7 @@ void StreamAbstractionAAMP::CheckForPlaybackStall(bool fragmentParsed) if(mediatrack != NULL) { int stalltimeout = GETCONFIGVALUE(eAAMPConfig_StallTimeoutMS); - bool cacheEmpty = mediatrack->numberOfFragmentChunksCached == 0; + bool cacheEmpty = mediatrack->numberOfFragmentsCached == 0; if (!mNetworkDownDetected && (timeElapsedSinceLastFragment > stalltimeout) && cacheEmpty) { AAMPLOG_INFO("StreamAbstractionAAMP: Didn't download a new fragment for a long time(%f) and cache empty!", timeElapsedSinceLastFragment); @@ -3391,10 +3429,10 @@ bool MediaTrack::CheckForFutureDiscontinuity(double &cachedDuration) std::lock_guard guard(mutex); - index = fragmentChunkIdxToInject; - count = numberOfFragmentChunksCached; - maxFrags = static_cast(mCachedFragmentChunksSize); - pCachedFragment = mCachedFragmentChunks; + index = fragmentIdxToInject; + count = numberOfFragmentsCached; + maxFrags = static_cast(mCachedFragmentSize); + pCachedFragment = mCachedFragment.data(); while (count > 0) { @@ -3403,7 +3441,7 @@ bool MediaTrack::CheckForFutureDiscontinuity(double &cachedDuration) ret = ret || pCachedFragment[index].discontinuity; if (ret) { - AAMPLOG_WARN("Found discontinuity for track %s at index: %d and position - %f", name, index, pCachedFragment[index].position); + AAMPLOG_WARN("Found discontinuity for track %s at index: %d and position : %f", name, index, pCachedFragment[index].position); } } cachedDuration += pCachedFragment[index].duration; @@ -3413,7 +3451,7 @@ bool MediaTrack::CheckForFutureDiscontinuity(double &cachedDuration) } count--; } - AAMPLOG_WARN("track %s numberOfFragmentChunksCached %d, cachedDuration %f", name, numberOfFragmentChunksCached, cachedDuration); + AAMPLOG_WARN("track %s numberOfFragmentsCached %d, cachedDuration %f", name, numberOfFragmentsCached, cachedDuration); return ret; } @@ -3716,20 +3754,20 @@ bool StreamAbstractionAAMP::CheckForRampDownLimitReached() } /** - * @brief Unblocks all waiting tracks by calling AbortWaitForCachedFragmentChunk() on each track. + * @brief Unblocks all waiting tracks by calling AbortWaitForCachedFragmentInjected() on each track. * - * Iterates over all track types and invokes AbortWaitForCachedFragmentChunk() + * Iterates over all track types and invokes AbortWaitForCachedFragmentInjected() * on each MediaTrack, ensuring that any threads waiting for cached fragments * are unblocked. */ -void StreamAbstractionAAMP::UnblockWaitForCachedFragmentChunk() +void StreamAbstractionAAMP::UnblockWaitForCachedFragmentInjected() { for ( int type = eTRACK_VIDEO; type <= eTRACK_SUBTITLE; type++) { MediaTrack *track = GetMediaTrack((TrackType)type); if(track) { - track->AbortWaitForCachedFragmentChunk(); + track->AbortWaitForCachedFragmentInjected(); } } } @@ -4640,6 +4678,17 @@ double MediaTrack::GetTotalInjectedDuration() return ret; } +/** + * @brief Get total duration of fetched fragments + * + * @return Total duration in seconds + */ +double MediaTrack::GetTotalFetchedDuration() +{ + std::lock_guard lock(mTrackParamsMutex); + return totalFetchedDuration; +} + /** * @brief update total fragment injected duration * @@ -4647,20 +4696,21 @@ double MediaTrack::GetTotalInjectedDuration() */ void MediaTrack::UpdateInjectedDuration(double surplusDuration) { + std::lock_guard lock(mTrackParamsMutex); totalInjectedDuration -= surplusDuration ; } /** - * @brief SetCachedFragmentChunksSize - Setter for fragment chunks cache size + * @brief SetCachedFragmentSize - Setter for fragment cache size * * @param[in] size Size for fragment chunks cache */ -void MediaTrack::SetCachedFragmentChunksSize(size_t size) +void MediaTrack::SetCachedFragmentSize(size_t size) { - if (size > 0 && size <= maxCachedFragmentChunksPerTrack) + if (size > 0 && size <= maxLLDCachedFragmentsPerTrack) { - AAMPLOG_TRACE("Set mCachedFragmentChunks size:%zu successfully", size); - mCachedFragmentChunksSize = size; + AAMPLOG_TRACE("Set mCachedFragment size:%zu successfully", size); + mCachedFragmentSize = size; } else { diff --git a/test/utests/fakes/FakeStreamAbstractionAamp.cpp b/test/utests/fakes/FakeStreamAbstractionAamp.cpp index d7645b15c3..b293ed971e 100644 --- a/test/utests/fakes/FakeStreamAbstractionAamp.cpp +++ b/test/utests/fakes/FakeStreamAbstractionAamp.cpp @@ -118,7 +118,7 @@ void StreamAbstractionAAMP::RefreshSubtitles() { } -void StreamAbstractionAAMP::UnblockWaitForCachedFragmentChunk() +void StreamAbstractionAAMP::UnblockWaitForCachedFragmentInjected() { } @@ -325,7 +325,7 @@ uint32_t MediaTrack::GetManifestUpdateCounter() return 0; } -bool MediaTrack::WaitForCachedFragmentChunkInjected(int timeoutMs) +bool MediaTrack::WaitForCachedFragmentInjected(int timeoutMs) { return true; } @@ -464,11 +464,11 @@ void StreamAbstractionAAMP::SetIsAtLivePoint(bool isAtLivePoint) } } -CachedFragment* MediaTrack::GetFetchChunkBuffer(bool initialize) +CachedFragment* MediaTrack::GetFetchBuffer(bool initialize) { if (g_mockMediaTrack != nullptr) { - return g_mockMediaTrack->GetFetchChunkBuffer(initialize); + return g_mockMediaTrack->GetFetchBuffer(initialize); } else { @@ -476,11 +476,11 @@ CachedFragment* MediaTrack::GetFetchChunkBuffer(bool initialize) } } -void MediaTrack::UpdateTSAfterChunkFetch() +void MediaTrack::UpdateTSAfterFetch() { if(g_mockMediaTrack != nullptr) { - g_mockMediaTrack->UpdateTSAfterChunkFetch(); + g_mockMediaTrack->UpdateTSAfterFetch(); } } @@ -496,7 +496,7 @@ void MediaTrack::LoadNewAudio(bool) { } -void MediaTrack::AbortWaitForCachedFragmentChunk() +void MediaTrack::AbortWaitForCachedFragmentInjected() { } @@ -504,7 +504,7 @@ double StreamAbstractionAAMP::GetBufferValue(MediaTrack *track) { return 0; } -void MediaTrack::SetCachedFragmentChunksSize(size_t size) +void MediaTrack::SetCachedFragmentSize(size_t size) { } void StreamAbstractionAAMP::UpdateStreamInfoBitrateData(int profileIndex, StreamInfo &cacheFragStreamInfo) @@ -542,10 +542,6 @@ void StreamAbstractionAAMP::SendVTTCueDataHandler(VTTCue* cueData) { } -void MediaTrack::FlushFragmentChunks() -{ -} - void MediaTrack::ClearMediaHeaderDuration(CachedFragment* cachedFragment) { } diff --git a/test/utests/mocks/MockMediaTrack.h b/test/utests/mocks/MockMediaTrack.h index 740f0d300b..7146e73bee 100644 --- a/test/utests/mocks/MockMediaTrack.h +++ b/test/utests/mocks/MockMediaTrack.h @@ -30,8 +30,8 @@ class MockMediaTrack : public MediaTrack : MediaTrack(type, aamp, name) {} MockMediaTrack() : MediaTrack(eTRACK_VIDEO, nullptr, "mock") {} - MOCK_METHOD(CachedFragment*, GetFetchChunkBuffer, (bool initialize)); - MOCK_METHOD(void, UpdateTSAfterChunkFetch, ()); + MOCK_METHOD(CachedFragment*, GetFetchBuffer, (bool initialize)); + MOCK_METHOD(void, UpdateTSAfterFetch, ()); MOCK_METHOD(void, SetLocalTSBInjection, (bool value)); MOCK_METHOD(bool, IsLocalTSBInjection, ()); MOCK_METHOD(bool, Enabled, ()); diff --git a/test/utests/tests/CacheFragmentTests/CacheFragmentTests.cpp b/test/utests/tests/CacheFragmentTests/CacheFragmentTests.cpp index 53842851b3..c70516a996 100644 --- a/test/utests/tests/CacheFragmentTests/CacheFragmentTests.cpp +++ b/test/utests/tests/CacheFragmentTests/CacheFragmentTests.cpp @@ -47,69 +47,69 @@ using ::testing::DoAll; AampConfig *gpGlobalConfig{nullptr}; struct TestParams { - bool lowlatency; // true for low-latency mode, false for standard mode - bool chunk; // true for chunk mode, false for standard mode - bool tsb; // true if AAMP TSB is enabled, false otherwise - bool eos; // true if simulating EOS, false otherwise; EOS tests inject from the TSB, the rest from live - bool paused; // true if pipeline is paused, false otherwise - bool underflow; // true if underflow occurred, false otherwise - bool init; // true if init fragment, false if media fragment - float rate; // play rate - int expectedFragmentChunksCached; // expected number of fragments added to chunk cache + bool lowlatency; // true for low-latency mode, false for standard mode + bool chunk; // true for chunk mode, false for standard mode + bool tsb; // true if AAMP TSB is enabled, false otherwise + bool eos; // true if simulating EOS, false otherwise; EOS tests inject from the TSB, the rest from live + bool paused; // true if pipeline is paused, false otherwise + bool underflow; // true if underflow occurred, false otherwise + bool init; // true if init fragment, false if media fragment + float rate; // play rate + int expectedFragmentsCached; // expected number of fragments added to fragment cache }; // Test cases TestParams testCases[] = { - {.lowlatency = true, .chunk = true, .tsb = false, .eos = false, .paused = false, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 0}, - {.lowlatency = true, .chunk = true, .tsb = false, .eos = false, .paused = false, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 1}, + {.lowlatency = true, .chunk = true, .tsb = false, .eos = false, .paused = false, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 0}, + {.lowlatency = true, .chunk = true, .tsb = false, .eos = false, .paused = false, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 1}, // Non-TSB, non-LLD-chunk DASH: CacheStagingFragmentForInjection() routes all plain SLD - // DASH fragments through the chunk cache, so expectedFragmentChunksCached=1. - {.lowlatency = true, .chunk = false, .tsb = false, .eos = false, .paused = false, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 1}, - {.lowlatency = true, .chunk = false, .tsb = false, .eos = false, .paused = false, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 1}, - {.lowlatency = false, .chunk = false, .tsb = false, .eos = false, .paused = false, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 1}, - {.lowlatency = false, .chunk = false, .tsb = false, .eos = false, .paused = false, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 1}, - - // Test with AAMP TSB enabled, chunk cache is used for non-chunked fragments - {.lowlatency = true, .chunk = true, .tsb = true, .eos = false, .paused = false, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 0}, - {.lowlatency = true, .chunk = true, .tsb = true, .eos = false, .paused = false, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 1}, - {.lowlatency = true, .chunk = false, .tsb = true, .eos = false, .paused = false, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 1}, - {.lowlatency = true, .chunk = false, .tsb = true, .eos = false, .paused = false, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 1}, - {.lowlatency = false, .chunk = false, .tsb = true, .eos = false, .paused = false, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 1}, - {.lowlatency = false, .chunk = false, .tsb = true, .eos = false, .paused = false, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 1}, + // DASH fragments through the fragment cache, so expectedFragmentsCached=1. + {.lowlatency = true, .chunk = false, .tsb = false, .eos = false, .paused = false, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 1}, + {.lowlatency = true, .chunk = false, .tsb = false, .eos = false, .paused = false, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 1}, + {.lowlatency = false, .chunk = false, .tsb = false, .eos = false, .paused = false, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 1}, + {.lowlatency = false, .chunk = false, .tsb = false, .eos = false, .paused = false, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 1}, + + // Test with AAMP TSB enabled, fragment cache is used for non-chunked fragments + {.lowlatency = true, .chunk = true, .tsb = true, .eos = false, .paused = false, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 0}, + {.lowlatency = true, .chunk = true, .tsb = true, .eos = false, .paused = false, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 1}, + {.lowlatency = true, .chunk = false, .tsb = true, .eos = false, .paused = false, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 1}, + {.lowlatency = true, .chunk = false, .tsb = true, .eos = false, .paused = false, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 1}, + {.lowlatency = false, .chunk = false, .tsb = true, .eos = false, .paused = false, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 1}, + {.lowlatency = false, .chunk = false, .tsb = true, .eos = false, .paused = false, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 1}, // Test EOS with AAMP TSB enabled - {.lowlatency = true, .chunk = true, .tsb = true, .eos = true, .paused = false, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 1}, - {.lowlatency = true, .chunk = true, .tsb = true, .eos = true, .paused = false, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 1}, - {.lowlatency = true, .chunk = false, .tsb = true, .eos = true, .paused = false, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 1}, - {.lowlatency = true, .chunk = false, .tsb = true, .eos = true, .paused = false, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 1}, - {.lowlatency = false, .chunk = false, .tsb = true, .eos = true, .paused = false, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 1}, - {.lowlatency = false, .chunk = false, .tsb = true, .eos = true, .paused = false, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 1}, + {.lowlatency = true, .chunk = true, .tsb = true, .eos = true, .paused = false, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 1}, + {.lowlatency = true, .chunk = true, .tsb = true, .eos = true, .paused = false, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 1}, + {.lowlatency = true, .chunk = false, .tsb = true, .eos = true, .paused = false, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 1}, + {.lowlatency = true, .chunk = false, .tsb = true, .eos = true, .paused = false, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 1}, + {.lowlatency = false, .chunk = false, .tsb = true, .eos = true, .paused = false, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 1}, + {.lowlatency = false, .chunk = false, .tsb = true, .eos = true, .paused = false, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 1}, // Test with pipeline paused - {.lowlatency = true, .chunk = true, .tsb = false, .eos = false, .paused = true, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 0}, - {.lowlatency = true, .chunk = true, .tsb = false, .eos = false, .paused = true, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 1}, + {.lowlatency = true, .chunk = true, .tsb = false, .eos = false, .paused = true, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 0}, + {.lowlatency = true, .chunk = true, .tsb = false, .eos = false, .paused = true, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 1}, // Non-TSB, non-LLD-chunk DASH paused (no underflow): no tsbSessionManager so the paused // guard doesn't apply; else block calls CacheStagingFragmentForInjection → chunk cache. - {.lowlatency = true, .chunk = false, .tsb = false, .eos = false, .paused = true, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 1}, - {.lowlatency = true, .chunk = false, .tsb = false, .eos = false, .paused = true, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 1}, - {.lowlatency = false, .chunk = false, .tsb = false, .eos = false, .paused = true, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 1}, - {.lowlatency = false, .chunk = false, .tsb = false, .eos = false, .paused = true, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 1}, + {.lowlatency = true, .chunk = false, .tsb = false, .eos = false, .paused = true, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 1}, + {.lowlatency = true, .chunk = false, .tsb = false, .eos = false, .paused = true, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 1}, + {.lowlatency = false, .chunk = false, .tsb = false, .eos = false, .paused = true, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 1}, + {.lowlatency = false, .chunk = false, .tsb = false, .eos = false, .paused = true, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 1}, // Test with AAMP TSB enabled and pipeline paused - {.lowlatency = true, .chunk = true, .tsb = true, .eos = false, .paused = true, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 0}, - {.lowlatency = true, .chunk = true, .tsb = true, .eos = false, .paused = true, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 0}, - {.lowlatency = true, .chunk = false, .tsb = true, .eos = false, .paused = true, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 0}, - {.lowlatency = true, .chunk = false, .tsb = true, .eos = false, .paused = true, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 0}, - {.lowlatency = false, .chunk = false, .tsb = true, .eos = false, .paused = true, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 0}, - {.lowlatency = false, .chunk = false, .tsb = true, .eos = false, .paused = true, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 0}, + {.lowlatency = true, .chunk = true, .tsb = true, .eos = false, .paused = true, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 0}, + {.lowlatency = true, .chunk = true, .tsb = true, .eos = false, .paused = true, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 0}, + {.lowlatency = true, .chunk = false, .tsb = true, .eos = false, .paused = true, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 0}, + {.lowlatency = true, .chunk = false, .tsb = true, .eos = false, .paused = true, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 0}, + {.lowlatency = false, .chunk = false, .tsb = true, .eos = false, .paused = true, .underflow = false, .init = true, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 0}, + {.lowlatency = false, .chunk = false, .tsb = true, .eos = false, .paused = true, .underflow = false, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 0}, // Test with pipeline paused and underflow - {.lowlatency = false, .chunk = false, .tsb = true, .eos = false, .paused = true, .underflow = true, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 1}, - {.lowlatency = false, .chunk = false, .tsb = true, .eos = true, .paused = true, .underflow = true, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentChunksCached = 1}, + {.lowlatency = false, .chunk = false, .tsb = true, .eos = false, .paused = true, .underflow = true, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 1}, + {.lowlatency = false, .chunk = false, .tsb = true, .eos = true, .paused = true, .underflow = true, .init = false, .rate = AAMP_NORMAL_PLAY_RATE, .expectedFragmentsCached = 1}, // Test with rate != AAMP_NORMAL_PLAY_RATE - {.lowlatency = true, .chunk = true, .tsb = true, .eos = false, .paused = true, .underflow = false, .init = true, .rate = (AAMP_NORMAL_PLAY_RATE*2), .expectedFragmentChunksCached = 0} + {.lowlatency = true, .chunk = true, .tsb = true, .eos = false, .paused = true, .underflow = false, .init = true, .rate = (AAMP_NORMAL_PLAY_RATE*2), .expectedFragmentsCached = 0} }; @@ -174,7 +174,7 @@ class MediaStreamContextTest : public ::testing::TestWithParam {eAAMPConfig_VODTrickPlayFPS, TRICKPLAY_VOD_PLAYBACK_FPS}, {eAAMPConfig_ABRBufferCounter,DEFAULT_ABR_BUFFER_COUNTER}, {eAAMPConfig_MaxDownloadBuffer, DEFAULT_MAX_DOWNLOAD_BUFFER}, - {eAAMPConfig_MaxFragmentChunkCached,DEFAULT_CACHED_FRAGMENT_CHUNKS_PER_TRACK} + {eAAMPConfig_MaxLLDFragmentCached,DEFAULT_LLD_CACHED_FRAGMENTS_PER_TRACK} }; IntConfigSettings mIntConfigSettings; @@ -346,7 +346,7 @@ class MediaStreamContextTest : public ::testing::TestWithParam TEST_P(MediaStreamContextTest, CacheFragment) { TestParams testParam = GetParam(); - AAMPLOG_INFO("Test with lowlatency: %d, chunk: %d, AAMP TSB: %d, eos: %d, paused: %d, underflow: %d, init: %d, rate: %f, expectedFragmentChunksCached: %d", + AAMPLOG_INFO("Test with lowlatency: %d, chunk: %d, AAMP TSB: %d, eos: %d, paused: %d, underflow: %d, init: %d, rate: %f, expectedFragmentsCached: %d", testParam.lowlatency, testParam.chunk, testParam.tsb, @@ -355,7 +355,7 @@ TEST_P(MediaStreamContextTest, CacheFragment) testParam.underflow, testParam.init, testParam.rate, - testParam.expectedFragmentChunksCached); + testParam.expectedFragmentsCached); Initialize(testParam.lowlatency, testParam.chunk, testParam.tsb, testParam.eos, testParam.paused, testParam.underflow, testParam.init, testParam.rate); URIInfo uriInfo; uriInfo.url = "remoteUrl"; @@ -383,8 +383,8 @@ TEST_P(MediaStreamContextTest, CacheFragment) EXPECT_EQ(mMediaStreamContext->IsLocalTSBInjection(), testParam.eos); } - // Check expected results for fragment chunks cached - EXPECT_EQ(mMediaStreamContext->numberOfFragmentChunksCached, testParam.expectedFragmentChunksCached); + // Check expected results for fragment cache count + EXPECT_EQ(mMediaStreamContext->numberOfFragmentsCached, testParam.expectedFragmentsCached); } INSTANTIATE_TEST_SUITE_P( diff --git a/test/utests/tests/FragmentCollectorAdTests/AdSelectionTests.cpp b/test/utests/tests/FragmentCollectorAdTests/AdSelectionTests.cpp index 61e1e46cd5..4f29d2bba1 100644 --- a/test/utests/tests/FragmentCollectorAdTests/AdSelectionTests.cpp +++ b/test/utests/tests/FragmentCollectorAdTests/AdSelectionTests.cpp @@ -345,7 +345,7 @@ class AdSelectionTests : public ::testing::Test {eAAMPConfig_AdFulfillmentTimeout, DEFAULT_AD_FULFILLMENT_TIMEOUT}, {eAAMPConfig_AdFulfillmentTimeoutMax, MAX_AD_FULFILLMENT_TIMEOUT}, {eAAMPConfig_MaxDownloadBuffer, DEFAULT_MAX_DOWNLOAD_BUFFER}, - {eAAMPConfig_MaxFragmentChunkCached, DEFAULT_CACHED_FRAGMENT_CHUNKS_PER_TRACK} + {eAAMPConfig_MaxLLDFragmentCached, DEFAULT_LLD_CACHED_FRAGMENTS_PER_TRACK} }; IntConfigSettings mIntConfigSettings; diff --git a/test/utests/tests/MediaStreamContextTests/FragmentDownloadTests.cpp b/test/utests/tests/MediaStreamContextTests/FragmentDownloadTests.cpp index b40b9f1947..64c4acd2ec 100644 --- a/test/utests/tests/MediaStreamContextTests/FragmentDownloadTests.cpp +++ b/test/utests/tests/MediaStreamContextTests/FragmentDownloadTests.cpp @@ -180,8 +180,8 @@ class FragmentDownloadSuccessParamTest * After unifying DASH onto the chunk cache, OnFragmentDownloadSuccess no longer * uses the per-fragment ring buffer. Instead: * - Non-LLD (chunkMode=false): CacheStagingFragmentForInjection() copies the - * staging fragment into a chunk-buffer slot via GetFetchChunkBuffer / - * UpdateTSAfterChunkFetch so the inject thread picks it up. + * staging fragment into a chunk-buffer slot via GetFetchBuffer / + * UpdateTSAfterFetch so the inject thread picks it up. * - LLD (chunkMode=true): media data was already pushed during SSL callbacks; * here only the time-based buffer counter is consumed. */ @@ -222,8 +222,8 @@ TEST_P(FragmentDownloadSuccessParamTest, OnFragmentDownloadSuccess) auto chunkSlot = std::make_shared(); if (!chunkMode) { - EXPECT_CALL(*g_mockMediaTrack, GetFetchChunkBuffer(true)).WillOnce(Return(chunkSlot.get())); - EXPECT_CALL(*g_mockMediaTrack, UpdateTSAfterChunkFetch()); + EXPECT_CALL(*g_mockMediaTrack, GetFetchBuffer(true)).WillOnce(Return(chunkSlot.get())); + EXPECT_CALL(*g_mockMediaTrack, UpdateTSAfterFetch()); } EXPECT_NO_THROW(mMediaStreamContext->OnFragmentDownloadSuccess(dlInfo)); @@ -447,7 +447,7 @@ TEST_F(FragmentDownloadTests, DownloadFragment_LLD_TrackDownloadsDisabled_DoesNo // Ensure there is cache capacity so only the "track downloads disabled" // condition prevents caching. - mMediaStreamContext->numberOfFragmentChunksCached = 0; + mMediaStreamContext->numberOfFragmentsCached = 0; // Configure the max fragment cache size (not full). EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentCached)) @@ -504,7 +504,7 @@ TEST_F(FragmentDownloadTests, DownloadFragment_CacheFull_DoesNotCache) constexpr int maxCache = 1; // Simulate cache already at capacity. - mMediaStreamContext->numberOfFragmentChunksCached = maxCache; + mMediaStreamContext->numberOfFragmentsCached = maxCache; // Configure the cache size so "full" condition is true. EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentCached)) @@ -547,7 +547,7 @@ TEST_F(FragmentDownloadTests, DownloadFragment_LLD_LocalTSBInjection_Caches) // Enable low-latency mode and leave cache capacity available. mPrivateInstanceAAMP->GetLLDashServiceData()->lowLatencyMode = true; - mMediaStreamContext->numberOfFragmentChunksCached = 0; + mMediaStreamContext->numberOfFragmentsCached = 0; // Simulate local TSB injection; this should bypass the LLD wait loop. EXPECT_CALL(*g_mockPrivateInstanceAAMP, IsLocalAAMPTsbInjection()) @@ -594,7 +594,7 @@ TEST_F(FragmentDownloadTests, DownloadFragment_NotBlocked_CachesExpected) // Enable low-latency mode and ensure cache has room. mPrivateInstanceAAMP->GetLLDashServiceData()->lowLatencyMode = true; - mMediaStreamContext->numberOfFragmentChunksCached = 0; + mMediaStreamContext->numberOfFragmentsCached = 0; // Configure cache size to permit caching. EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentCached)) @@ -690,7 +690,7 @@ TEST_F(FragmentDownloadTests, OnFragmentDownloadSuccess_CheckEos_PausedDueToUnde reinterpret_cast(testData.data()), reinterpret_cast(testData.data()) + testData.size()); - // A CachedFragment for CacheStagingFragmentForInjection's GetFetchChunkBuffer call. + // A CachedFragment for CacheStagingFragmentForInjection's GetFetchBuffer call. auto chunkBuffer = std::make_shared(); mMediaStreamContext->mActiveDownloadInfo = std::make_shared(); @@ -741,9 +741,9 @@ TEST_F(FragmentDownloadTests, OnFragmentDownloadSuccess_CheckEos_PausedDueToUnde .Times(1); // Else block: SLD re-cache via CacheStagingFragmentForInjection. - EXPECT_CALL(*g_mockMediaTrack, GetFetchChunkBuffer(true)) + EXPECT_CALL(*g_mockMediaTrack, GetFetchBuffer(true)) .WillOnce(Return(chunkBuffer.get())); - EXPECT_CALL(*g_mockMediaTrack, UpdateTSAfterChunkFetch()); + EXPECT_CALL(*g_mockMediaTrack, UpdateTSAfterFetch()); // --- Execute --- EXPECT_NO_THROW(mMediaStreamContext->OnFragmentDownloadSuccess(dlInfo)); @@ -778,13 +778,13 @@ TEST_F(FragmentDownloadTests, CacheTsbFragment_MoveSemantics_TransfersOwnership) sourceFragment->initFragment = true; sourceFragment->discontinuity = true; - // The ring buffer slot that GetFetchChunkBuffer will return. + // The ring buffer slot that GetFetchBuffer will return. auto ringBufferSlot = std::make_shared(); - // WaitForCachedFragmentChunkInjected is handled by the fake (always returns true). - EXPECT_CALL(*g_mockMediaTrack, GetFetchChunkBuffer(true)) + // WaitForCachedFragmentInjected is handled by the fake (always returns true). + EXPECT_CALL(*g_mockMediaTrack, GetFetchBuffer(true)) .WillOnce(Return(ringBufferSlot.get())); - EXPECT_CALL(*g_mockMediaTrack, UpdateTSAfterChunkFetch()); + EXPECT_CALL(*g_mockMediaTrack, UpdateTSAfterFetch()); // --- Act --- // std::move transfers the shared_ptr into the && parameter without @@ -865,7 +865,7 @@ TEST_F(FragmentDownloadTests, OnFragmentDownloadSuccess_UnderflowRecoveryRace_Fr // Pre-populate the staging fragment so CacheStagingFragmentForInjection has // data to write. // An empty fragment would short-circuit through the "Empty cachedFragment ignored" - // warning path, preventing GetFetchChunkBuffer from ever being called. + // warning path, preventing GetFetchBuffer from ever being called. // EnqueueWrite (fake no-op) evaluates context->GetPeriod()->GetId() as an // argument, so GetPeriod() must be stubbed to return a valid period. static constexpr uint8_t kTestData[] = {0xAA, 0xBB, 0xCC, 0xDD}; @@ -873,7 +873,7 @@ TEST_F(FragmentDownloadTests, OnFragmentDownloadSuccess_UnderflowRecoveryRace_Fr kTestData, kTestData + sizeof(kTestData)); DummyPeriod dummyPeriod; - // A CachedFragment for CacheStagingFragmentForInjection's GetFetchChunkBuffer call. + // A CachedFragment for CacheStagingFragmentForInjection's GetFetchBuffer call. auto chunkBuffer = std::make_shared(); // --- Mock setup --- @@ -887,12 +887,12 @@ TEST_F(FragmentDownloadTests, OnFragmentDownloadSuccess_UnderflowRecoveryRace_Fr EXPECT_CALL(*g_mockStreamAbstractionAAMP_MPD, GetPeriod()) .WillOnce(Return(&dummyPeriod)); - // KEY assertion: GetFetchChunkBuffer + UpdateTSAfterChunkFetch are called iff + // KEY assertion: GetFetchBuffer + UpdateTSAfterFetch are called iff // the fragment is NOT discarded. Without the !wasUnderFlowActive guard the // discard path would be taken and neither call would occur (stall bug). - EXPECT_CALL(*g_mockMediaTrack, GetFetchChunkBuffer(true)) + EXPECT_CALL(*g_mockMediaTrack, GetFetchBuffer(true)) .WillOnce(Return(chunkBuffer.get())); - EXPECT_CALL(*g_mockMediaTrack, UpdateTSAfterChunkFetch()).Times(1); + EXPECT_CALL(*g_mockMediaTrack, UpdateTSAfterFetch()).Times(1); // IsLocalTSBInjection() is checked in the discard-guard condition; // must be non-blocking with StrictMock. EXPECT_CALL(*g_mockMediaTrack, IsLocalTSBInjection()).WillRepeatedly(Return(false)); diff --git a/test/utests/tests/MediaStreamContextTests/MediaStreamContextTests.cpp b/test/utests/tests/MediaStreamContextTests/MediaStreamContextTests.cpp index bc4e750459..f9bfb27712 100644 --- a/test/utests/tests/MediaStreamContextTests/MediaStreamContextTests.cpp +++ b/test/utests/tests/MediaStreamContextTests/MediaStreamContextTests.cpp @@ -225,7 +225,7 @@ TEST_F(MediaStreamContextTest, CacheFragmentChunkTestWithDurationInTicks) mMediaStreamContext->mActiveDownloadInfo = downloadInfo; CachedFragment cachedFragment; - EXPECT_CALL(*g_mockMediaTrack, GetFetchChunkBuffer(true)) + EXPECT_CALL(*g_mockMediaTrack, GetFetchBuffer(true)) .WillOnce(Return(&cachedFragment)); bool result = mMediaStreamContext->CacheFragmentChunk(eMEDIATYPE_VIDEO, testData, testDataSize, remoteUrl, dnldStartTime, durationInTicks); diff --git a/test/utests/tests/MediaTrackTests/MediaTrackTests.cpp b/test/utests/tests/MediaTrackTests/MediaTrackTests.cpp index 711e1375df..9c81a10def 100644 --- a/test/utests/tests/MediaTrackTests/MediaTrackTests.cpp +++ b/test/utests/tests/MediaTrackTests/MediaTrackTests.cpp @@ -97,7 +97,7 @@ class TestableMediaTrack : public MediaTrack double GetBufferedDuration() override { return 0; }; // Promote protected members so tests can set them directly. - using MediaTrack::fragmentChunkIdxToFetch; + using MediaTrack::fragmentIdxToFetch; protected: // Must return something non-null to avoid a crash @@ -169,8 +169,8 @@ class MediaTrackTests : public testing::Test CachedFragment* bufferedFragment{nullptr}; // Always use the chunk cache buffer - bufferedFragment = mediaTrack.GetFetchChunkBuffer(true); - mediaTrack.numberOfFragmentChunksCached = 1; + bufferedFragment = mediaTrack.GetFetchBuffer(true); + mediaTrack.numberOfFragmentsCached = 1; bufferedFragment->Copy(testFragment); if (lowLatencyMode && !bufferedFragment->initFragment) { @@ -241,7 +241,7 @@ class MediaTrackTests : public testing::Test .WillRepeatedly(Return(false)); EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentCached)) .WillRepeatedly(Return(1)); - EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentChunkCached)) + EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxLLDFragmentCached)) .WillRepeatedly(Return(1)); EXPECT_CALL(*g_mockIsoBmffBuffer, parseBuffer(_, _)).WillRepeatedly(Return(true)); EXPECT_CALL(*g_mockPrivateInstanceAAMP, GetLLDashChunkMode()).WillRepeatedly(Return(true)); @@ -253,8 +253,8 @@ class MediaTrackTests : public testing::Test CachedFragment initFragment{}; initFragment.initFragment = true; initFragment.fragment.assign(FRAGMENT_TEST_DATA, FRAGMENT_TEST_DATA + FRAGMENT_TEST_DATA_SIZE); - CachedFragment* buf = videoTrack->GetFetchChunkBuffer(true); - videoTrack->numberOfFragmentChunksCached = 1; + CachedFragment* buf = videoTrack->GetFetchBuffer(true); + videoTrack->numberOfFragmentsCached = 1; buf->Copy(initFragment); EXPECT_TRUE(videoTrack->InjectFragment()); @@ -267,8 +267,8 @@ class MediaTrackTests : public testing::Test mediaFragment.uri = "test_segment.m4s"; mediaFragment.fragment.assign(FRAGMENT_TEST_DATA, FRAGMENT_TEST_DATA + FRAGMENT_TEST_DATA_SIZE); - buf = videoTrack->GetFetchChunkBuffer(true); - videoTrack->numberOfFragmentChunksCached = 1; + buf = videoTrack->GetFetchBuffer(true); + videoTrack->numberOfFragmentsCached = 1; buf->Copy(mediaFragment); return {std::move(videoTrack), buf}; @@ -312,7 +312,7 @@ TEST_P(MediaTrackDashPtsRestampNotConfiguredTests, PtsRestampNotConfiguredTest) .WillRepeatedly(Return(false)); EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentCached)) .WillRepeatedly(Return(1)); - EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentChunkCached)) + EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxLLDFragmentCached)) .WillRepeatedly(Return(1)); EXPECT_CALL(*g_mockIsoBmffBuffer, parseBuffer(_, _)).WillRepeatedly(Return(true)); EXPECT_CALL(*g_mockPrivateInstanceAAMP, GetLLDashChunkMode()).WillRepeatedly(Return(testParam.lowLatencyMode)); @@ -371,7 +371,7 @@ TEST_P(MediaTrackDashQtDemuxOverrideConfiguredTests, QtDemuxOverrideConfiguredTe .WillRepeatedly(Return(false)); EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentCached)) .WillRepeatedly(Return(1)); - EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentChunkCached)) + EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxLLDFragmentCached)) .WillRepeatedly(Return(1)); EXPECT_CALL(*g_mockIsoBmffBuffer, parseBuffer(_, _)).WillRepeatedly(Return(true)); EXPECT_CALL(*g_mockPrivateInstanceAAMP, GetLLDashChunkMode()).WillRepeatedly(Return(testParam.lowLatencyMode)); @@ -432,7 +432,7 @@ TEST_P(MediaTrackDashTrickModePtsRestampValidPlayRateTests, ValidPlayRateTest) .WillRepeatedly(Return(TRICKMODE_FPS)); EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentCached)) .WillRepeatedly(Return(1)); - EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentChunkCached)) + EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxLLDFragmentCached)) .WillRepeatedly(Return(1)); EXPECT_CALL(*g_mockIsoBmffBuffer, parseBuffer(_, _)).WillRepeatedly(Return(true)); EXPECT_CALL(*g_mockPrivateInstanceAAMP, GetLLDashChunkMode()).WillRepeatedly(Return(testParam.lowLatencyMode)); @@ -603,7 +603,7 @@ TEST_P(MediaTrackDashPlaybackPtsRestampTests, PlaybackTest) .WillRepeatedly(Return(true)); EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentCached)) .WillRepeatedly(Return(1)); - EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentChunkCached)) + EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxLLDFragmentCached)) .WillRepeatedly(Return(1)); EXPECT_CALL(*g_mockIsoBmffBuffer, parseBuffer(_, _)).WillRepeatedly(Return(true)); EXPECT_CALL(*g_mockPrivateInstanceAAMP, GetLLDashChunkMode()).WillRepeatedly(Return(lowLatencyMode)); @@ -652,7 +652,7 @@ TEST_P(MediaTrackDashPlaybackPtsRestampTests, PlaybackTest) testFragment.uri = expectedUri; testFragment.fragment.assign(FRAGMENT_TEST_DATA, FRAGMENT_TEST_DATA + FRAGMENT_TEST_DATA_SIZE); bufferedFragment = AddFragmentToBuffer(videoTrack, testFragment, lowLatencyMode, aampTsb); - videoTrack.numberOfFragmentChunksCached = 1; + videoTrack.numberOfFragmentsCached = 1; ASSERT_NE(bufferedFragment, nullptr); ASSERT_GT(bufferedFragment->fragment.size(), 0); EXPECT_CALL(*g_mockIsoBmffHelper, RestampPts(_, _, _, _, _)).Times(0); @@ -704,7 +704,7 @@ TEST_P(MediaTrackDashTrickModePtsRestampInvalidPlayRateTests, InvalidPlayRateTes .WillRepeatedly(Return(true)); EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentCached)) .WillRepeatedly(Return(1)); - EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentChunkCached)) + EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxLLDFragmentCached)) .WillRepeatedly(Return(1)); EXPECT_CALL(*g_mockIsoBmffBuffer, parseBuffer(_, _)).WillRepeatedly(Return(true)); @@ -748,7 +748,7 @@ TEST_F(MediaTrackTests, DashTrickModePtsRestampDiscontinuityTest) .WillRepeatedly(Return(TRICKMODE_FPS)); EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentCached)) .WillRepeatedly(Return(1)); - EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentChunkCached)) + EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxLLDFragmentCached)) .WillRepeatedly(Return(1)); TestableMediaTrack iframeTrack{eTRACK_VIDEO, mPrivateInstanceAAMP, "iframe", @@ -871,35 +871,35 @@ TEST_F(MediaTrackTests, FlushFetchedFragmentsTest) .WillRepeatedly(Return(true)); EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentCached)) .WillRepeatedly(Return(5)); - EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentChunkCached)) + EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxLLDFragmentCached)) .WillRepeatedly(Return(5)); TestableMediaTrack videoTrack{eTRACK_VIDEO, mPrivateInstanceAAMP, "video", mStreamAbstractionAAMP_MPD}; // Init fragment at chunk slot 0 - bufferedFragment1 = videoTrack.GetFetchChunkBuffer(true); + bufferedFragment1 = videoTrack.GetFetchBuffer(true); bufferedFragment1->initFragment = true; bufferedFragment1->fragment.assign(FRAGMENT_TEST_DATA, FRAGMENT_TEST_DATA + FRAGMENT_TEST_DATA_SIZE); - videoTrack.numberOfFragmentChunksCached = 1; - videoTrack.fragmentChunkIdxToFetch = 1; + videoTrack.numberOfFragmentsCached = 1; + videoTrack.fragmentIdxToFetch = 1; // First media fragment at chunk slot 1 - bufferedFragment2 = videoTrack.GetFetchChunkBuffer(true); + bufferedFragment2 = videoTrack.GetFetchBuffer(true); bufferedFragment2->initFragment = false; bufferedFragment2->duration = FRAGMENT_DURATION.inSeconds(); bufferedFragment2->position = FIRST_PTS.inSeconds(); bufferedFragment2->fragment.assign(FRAGMENT_TEST_DATA, FRAGMENT_TEST_DATA + FRAGMENT_TEST_DATA_SIZE); - videoTrack.numberOfFragmentChunksCached = 2; - videoTrack.fragmentChunkIdxToFetch = 2; + videoTrack.numberOfFragmentsCached = 2; + videoTrack.fragmentIdxToFetch = 2; // Second media fragment at chunk slot 2 (not counted for injection) - bufferedFragment3 = videoTrack.GetFetchChunkBuffer(true); + bufferedFragment3 = videoTrack.GetFetchBuffer(true); bufferedFragment3->initFragment = false; bufferedFragment3->duration = FRAGMENT_DURATION.inSeconds(); bufferedFragment3->position = 2 * FIRST_PTS.inSeconds(); bufferedFragment3->fragment.assign(FRAGMENT_TEST_DATA, FRAGMENT_TEST_DATA + FRAGMENT_TEST_DATA_SIZE); - ASSERT_EQ(videoTrack.numberOfFragmentChunksCached, 2); + ASSERT_EQ(videoTrack.numberOfFragmentsCached, 2); ASSERT_EQ(bufferedFragment1->position, 0); ASSERT_EQ(bufferedFragment2->position, FIRST_PTS.inSeconds()); ASSERT_EQ(bufferedFragment3->position, (2 * FIRST_PTS.inSeconds())); @@ -907,7 +907,7 @@ TEST_F(MediaTrackTests, FlushFetchedFragmentsTest) videoTrack.FlushFetchedFragments(); // Fragments at slots 0 and 1 (counted) should be cleared; slot 2 (uncounted) should not - EXPECT_EQ(videoTrack.numberOfFragmentChunksCached, 0); + EXPECT_EQ(videoTrack.numberOfFragmentsCached, 0); EXPECT_EQ(bufferedFragment1->position, 0); EXPECT_EQ(bufferedFragment2->position, 0); EXPECT_EQ(bufferedFragment3->position, (2 * FIRST_PTS.inSeconds())); @@ -920,11 +920,11 @@ TEST_F(MediaTrackTests, MediaTrackConstructorTest) EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentCached)) .WillRepeatedly(Return(kMaxFragmentCached)); - EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentChunkCached)) + EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxLLDFragmentCached)) .WillRepeatedly(Return(kMaxFragmentChunkCached)); TestableMediaTrack videoTrack{eTRACK_VIDEO, mPrivateInstanceAAMP, "video", mStreamAbstractionAAMP_MPD}; - EXPECT_EQ(videoTrack.GetCachedFragmentChunksSize(), kMaxFragmentCached); + EXPECT_EQ(videoTrack.GetCachedFragmentSize(), kMaxFragmentCached); } TEST_F(MediaTrackTests, MediaTrackConstructorChunkModeTest) @@ -934,11 +934,11 @@ TEST_F(MediaTrackTests, MediaTrackConstructorChunkModeTest) EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentCached)) .WillRepeatedly(Return(kMaxFragmentCached)); - EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentChunkCached)) + EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxLLDFragmentCached)) .WillRepeatedly(Return(kMaxFragmentChunkCached)); EXPECT_CALL(*g_mockPrivateInstanceAAMP, GetLLDashChunkMode()).WillOnce(Return(true)); TestableMediaTrack videoTrack{eTRACK_VIDEO, mPrivateInstanceAAMP, "video", mStreamAbstractionAAMP_MPD}; - EXPECT_EQ(videoTrack.GetCachedFragmentChunksSize(), kMaxFragmentChunkCached); + EXPECT_EQ(videoTrack.GetCachedFragmentSize(), kMaxFragmentChunkCached); } /** @@ -1101,111 +1101,111 @@ TEST_F(MediaTrackTests, GetBufferStatus_ReturnsRed_WhenBufferIsBelowUnderflowThr } /** - * @brief When the chunk cache is not full, WaitForCachedFragmentChunkInjected returns + * @brief When the chunk cache is not full, WaitForCachedFragmentInjected returns * true immediately without waiting. */ -TEST_F(MediaTrackTests, WaitForCachedFragmentChunkInjected_CacheHasSpace_ReturnsTrueImmediately) +TEST_F(MediaTrackTests, WaitForCachedFragmentInjected_CacheHasSpace_ReturnsTrueImmediately) { EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentCached)) .WillRepeatedly(Return(1)); - EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentChunkCached)) + EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxLLDFragmentCached)) .WillRepeatedly(Return(1)); EXPECT_CALL(*g_mockPrivateInstanceAAMP, GetLLDashChunkMode()).WillRepeatedly(Return(false)); TestableMediaTrack videoTrack{eTRACK_VIDEO, mPrivateInstanceAAMP, "video", mStreamAbstractionAAMP_MPD}; // Cache is empty (not full), so no wait is entered and the function returns true. - ASSERT_LT(videoTrack.numberOfFragmentChunksCached, - static_cast(videoTrack.GetCachedFragmentChunksSize())); - EXPECT_TRUE(videoTrack.WaitForCachedFragmentChunkInjected(0)); + ASSERT_LT(videoTrack.numberOfFragmentsCached, + static_cast(videoTrack.GetCachedFragmentSize())); + EXPECT_TRUE(videoTrack.WaitForCachedFragmentInjected(0)); } /** * @brief When the chunk cache is full and the timeout expires with no signal, - * WaitForCachedFragmentChunkInjected returns false. + * WaitForCachedFragmentInjected returns false. */ -TEST_F(MediaTrackTests, WaitForCachedFragmentChunkInjected_TimeoutWithCacheFull_ReturnsFalse) +TEST_F(MediaTrackTests, WaitForCachedFragmentInjected_TimeoutWithCacheFull_ReturnsFalse) { EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentCached)) .WillRepeatedly(Return(1)); - EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentChunkCached)) + EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxLLDFragmentCached)) .WillRepeatedly(Return(1)); EXPECT_CALL(*g_mockPrivateInstanceAAMP, GetLLDashChunkMode()).WillRepeatedly(Return(false)); TestableMediaTrack videoTrack{eTRACK_VIDEO, mPrivateInstanceAAMP, "video", mStreamAbstractionAAMP_MPD}; - // Fill the cache to capacity so WaitForCachedFragmentChunkInjected will block. - videoTrack.numberOfFragmentChunksCached = static_cast(videoTrack.GetCachedFragmentChunksSize()); + // Fill the cache to capacity so WaitForCachedFragmentInjected will block. + videoTrack.numberOfFragmentsCached = static_cast(videoTrack.GetCachedFragmentSize()); // No signal is ever fired; the short timeout must cause a false return. - EXPECT_FALSE(videoTrack.WaitForCachedFragmentChunkInjected(50 /*ms*/)); + EXPECT_FALSE(videoTrack.WaitForCachedFragmentInjected(50 /*ms*/)); } /** * @brief Exercises the "signaled but still full" branch (streamabstraction.cpp ~R725-R729): * the cache is full, the condition variable is signaled without the abort flag being set - * and without numberOfFragmentChunksCached being decremented. - * WaitForCachedFragmentChunkInjected must return false because the cache is still full + * and without numberOfFragmentsCached being decremented. + * WaitForCachedFragmentInjected must return false because the cache is still full * after the wakeup. */ -TEST_F(MediaTrackTests, WaitForCachedFragmentChunkInjected_SignaledButStillFull_ReturnsFalse) +TEST_F(MediaTrackTests, WaitForCachedFragmentInjected_SignaledButStillFull_ReturnsFalse) { EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentCached)) .WillRepeatedly(Return(1)); - EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentChunkCached)) + EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxLLDFragmentCached)) .WillRepeatedly(Return(1)); EXPECT_CALL(*g_mockPrivateInstanceAAMP, GetLLDashChunkMode()).WillRepeatedly(Return(false)); TestableMediaTrack videoTrack{eTRACK_VIDEO, mPrivateInstanceAAMP, "video", mStreamAbstractionAAMP_MPD}; - // Fill the cache to capacity so WaitForCachedFragmentChunkInjected will block. - videoTrack.numberOfFragmentChunksCached = static_cast(videoTrack.GetCachedFragmentChunksSize()); + // Fill the cache to capacity so WaitForCachedFragmentInjected will block. + videoTrack.numberOfFragmentsCached = static_cast(videoTrack.GetCachedFragmentSize()); // From a background thread: signal the CV without draining the cache and without // setting abort — this mirrors the scenario introduced at ~R725-R729 where the // caller is woken up spuriously or by an unrelated event. std::thread signalThread([&videoTrack]() { std::this_thread::sleep_for(std::chrono::milliseconds(50)); - // AbortWaitForCachedFragmentChunk signals fragmentChunkInjected but does NOT - // decrement numberOfFragmentChunksCached or set the abort flag. - videoTrack.AbortWaitForCachedFragmentChunk(); + // AbortWaitForCachedFragmentInjected signals fragmentInjected but does NOT + // decrement numberOfFragmentsCached or set the abort flag. + videoTrack.AbortWaitForCachedFragmentInjected(); }); // Must return false: was signaled, abort is clear, but cache is still full. - bool result = videoTrack.WaitForCachedFragmentChunkInjected(5000 /*ms*/); + bool result = videoTrack.WaitForCachedFragmentInjected(5000 /*ms*/); signalThread.join(); EXPECT_FALSE(result); } /** - * @brief When the condition variable is signaled and numberOfFragmentChunksCached is - * decremented before the caller wakes up, WaitForCachedFragmentChunkInjected returns true. + * @brief When the condition variable is signaled and numberOfFragmentsCached is + * decremented before the caller wakes up, WaitForCachedFragmentInjected returns true. * This is the complementary positive case confirming the non-full path still works. */ -TEST_F(MediaTrackTests, WaitForCachedFragmentChunkInjected_SignaledAndCacheCleared_ReturnsTrue) +TEST_F(MediaTrackTests, WaitForCachedFragmentInjected_SignaledAndCacheCleared_ReturnsTrue) { EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentCached)) .WillRepeatedly(Return(1)); - EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentChunkCached)) + EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxLLDFragmentCached)) .WillRepeatedly(Return(1)); EXPECT_CALL(*g_mockPrivateInstanceAAMP, GetLLDashChunkMode()).WillRepeatedly(Return(false)); TestableMediaTrack videoTrack{eTRACK_VIDEO, mPrivateInstanceAAMP, "video", mStreamAbstractionAAMP_MPD}; - // Fill the cache to capacity so WaitForCachedFragmentChunkInjected will block. - videoTrack.numberOfFragmentChunksCached = static_cast(videoTrack.GetCachedFragmentChunksSize()); + // Fill the cache to capacity so WaitForCachedFragmentInjected will block. + videoTrack.numberOfFragmentsCached = static_cast(videoTrack.GetCachedFragmentSize()); // From a background thread: simulate an injector consuming a slot, then signal. std::thread signalThread([&videoTrack]() { std::this_thread::sleep_for(std::chrono::milliseconds(50)); // Decrement the cache count (simulating a completed injection), then notify. - videoTrack.numberOfFragmentChunksCached--; - videoTrack.AbortWaitForCachedFragmentChunk(); + videoTrack.numberOfFragmentsCached--; + videoTrack.AbortWaitForCachedFragmentInjected(); }); // Must return true: was signaled and cache now has a free slot. - bool result = videoTrack.WaitForCachedFragmentChunkInjected(5000 /*ms*/); + bool result = videoTrack.WaitForCachedFragmentInjected(5000 /*ms*/); signalThread.join(); EXPECT_TRUE(result); diff --git a/test/utests/tests/StreamAbstractionAAMP/FunctionalTests.cpp b/test/utests/tests/StreamAbstractionAAMP/FunctionalTests.cpp index f3ff6d4417..a6bd5b82a9 100644 --- a/test/utests/tests/StreamAbstractionAAMP/FunctionalTests.cpp +++ b/test/utests/tests/StreamAbstractionAAMP/FunctionalTests.cpp @@ -126,7 +126,7 @@ class StreamAbstractionAAMP_Test : public ::testing::Test EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentCached)) .Times(AnyNumber()) .WillRepeatedly(Return(0)); - EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxFragmentChunkCached)) + EXPECT_CALL(*g_mockAampConfig, GetConfigValue(eAAMPConfig_MaxLLDFragmentCached)) .Times(AnyNumber()) .WillRepeatedly(Return(0)); diff --git a/test/utests/tests/StreamAbstractionAAMP_HLS/FunctionalTests.cpp b/test/utests/tests/StreamAbstractionAAMP_HLS/FunctionalTests.cpp index 4773fb239b..d4ab989131 100644 --- a/test/utests/tests/StreamAbstractionAAMP_HLS/FunctionalTests.cpp +++ b/test/utests/tests/StreamAbstractionAAMP_HLS/FunctionalTests.cpp @@ -1865,10 +1865,10 @@ TEST_F(TrackStateTests, EnabledTests) ASSERT_FALSE(result); } -TEST_F(TrackStateTests, GetFetchChunkBufferTest) +TEST_F(TrackStateTests, GetFetchBufferTest) { // Call the function under test with initialize set to true - CachedFragment *cachedFragment = TrackStateobj->GetFetchChunkBuffer(true); + CachedFragment *cachedFragment = TrackStateobj->GetFetchBuffer(true); ASSERT_EQ(cachedFragment, nullptr); } @@ -1915,10 +1915,10 @@ TEST_F(TrackStateTests, GetBufferStatusTest) TEST_F(TrackStateTests, WaitForFreeFragmentAvailableTests) { int timeoutMs = 100; - // Ensure the chunk cache has capacity so WaitForCachedFragmentChunkInjected - // can return true immediately (numberOfFragmentChunksCached=0 < size=4). - TrackStateobj->maxCachedFragmentChunksPerTrack = DEFAULT_CACHED_FRAGMENT_CHUNKS_PER_TRACK; - TrackStateobj->SetCachedFragmentChunksSize(DEFAULT_CACHED_FRAGMENTS_PER_TRACK); + // Ensure the chunk cache has capacity so WaitForCachedFragmentInjected + // can return true immediately (numberOfFragmentsCached=0 < size=4). + TrackStateobj->maxLLDCachedFragmentsPerTrack = DEFAULT_LLD_CACHED_FRAGMENTS_PER_TRACK; + TrackStateobj->SetCachedFragmentSize(DEFAULT_CACHED_FRAGMENTS_PER_TRACK); bool result = TrackStateobj->WaitForFreeFragmentAvailable(timeoutMs); ASSERT_TRUE(result); } @@ -2391,12 +2391,12 @@ TEST_F(TrackStateTests,GetProfileIndexForBW ) TrackStateobj->GetProfileIndexForBW(1); } -TEST_F(TrackStateTests,UpdateTSAfterChunkFetch ) +TEST_F(TrackStateTests,UpdateTSAfterFetch ) { - TrackStateobj->numberOfFragmentChunksCached = 0; - TrackStateobj->maxCachedFragmentChunksPerTrack=1; - TrackStateobj->SetCachedFragmentChunksSize(1); - TrackStateobj->UpdateTSAfterChunkFetch(); + TrackStateobj->numberOfFragmentsCached = 0; + TrackStateobj->maxLLDCachedFragmentsPerTrack=1; + TrackStateobj->SetCachedFragmentSize(1); + TrackStateobj->UpdateTSAfterFetch(); } TEST_F(TrackStateTests,AbortWaitForCachedAndFreeFragment ) diff --git a/test/utests/tests/StreamAbstractionAAMP_MPD/AudioOnlyTests.cpp b/test/utests/tests/StreamAbstractionAAMP_MPD/AudioOnlyTests.cpp index f62eefb4b1..786f7b4b6d 100644 --- a/test/utests/tests/StreamAbstractionAAMP_MPD/AudioOnlyTests.cpp +++ b/test/utests/tests/StreamAbstractionAAMP_MPD/AudioOnlyTests.cpp @@ -112,7 +112,7 @@ class AudioOnlyTests : public ::testing::Test {eAAMPConfig_VODTrickPlayFPS, TRICKPLAY_VOD_PLAYBACK_FPS}, {eAAMPConfig_ABRBufferCounter,DEFAULT_ABR_BUFFER_COUNTER}, {eAAMPConfig_MaxDownloadBuffer, DEFAULT_MAX_DOWNLOAD_BUFFER}, - {eAAMPConfig_MaxFragmentChunkCached, DEFAULT_CACHED_FRAGMENT_CHUNKS_PER_TRACK} + {eAAMPConfig_MaxLLDFragmentCached, DEFAULT_LLD_CACHED_FRAGMENTS_PER_TRACK} }; IntConfigSettings mIntConfigSettings; diff --git a/test/utests/tests/StreamAbstractionAAMP_MPD/FetcherLoopTests.cpp b/test/utests/tests/StreamAbstractionAAMP_MPD/FetcherLoopTests.cpp index 942a07116d..ec54372747 100644 --- a/test/utests/tests/StreamAbstractionAAMP_MPD/FetcherLoopTests.cpp +++ b/test/utests/tests/StreamAbstractionAAMP_MPD/FetcherLoopTests.cpp @@ -311,7 +311,7 @@ class FetcherLoopTests : public ::testing::Test {eAAMPConfig_AdFulfillmentTimeout, DEFAULT_AD_FULFILLMENT_TIMEOUT}, {eAAMPConfig_AdFulfillmentTimeoutMax, MAX_AD_FULFILLMENT_TIMEOUT}, {eAAMPConfig_MaxDownloadBuffer, DEFAULT_MAX_DOWNLOAD_BUFFER}, - {eAAMPConfig_MaxFragmentChunkCached, DEFAULT_CACHED_FRAGMENT_CHUNKS_PER_TRACK} + {eAAMPConfig_MaxLLDFragmentCached, DEFAULT_LLD_CACHED_FRAGMENTS_PER_TRACK} }; IntConfigSettings mIntConfigSettings; diff --git a/test/utests/tests/StreamAbstractionAAMP_MPD/FunctionalTests.cpp b/test/utests/tests/StreamAbstractionAAMP_MPD/FunctionalTests.cpp index f69220ab7d..a617688f66 100644 --- a/test/utests/tests/StreamAbstractionAAMP_MPD/FunctionalTests.cpp +++ b/test/utests/tests/StreamAbstractionAAMP_MPD/FunctionalTests.cpp @@ -141,7 +141,7 @@ class FunctionalTestsBase {eAAMPConfig_VODTrickPlayFPS, TRICKPLAY_VOD_PLAYBACK_FPS}, {eAAMPConfig_ABRBufferCounter, DEFAULT_ABR_BUFFER_COUNTER}, {eAAMPConfig_MaxDownloadBuffer, DEFAULT_MAX_DOWNLOAD_BUFFER}, - {eAAMPConfig_MaxFragmentChunkCached, DEFAULT_CACHED_FRAGMENT_CHUNKS_PER_TRACK}, + {eAAMPConfig_MaxLLDFragmentCached, DEFAULT_LLD_CACHED_FRAGMENTS_PER_TRACK}, {eAAMPConfig_UTCSyncMinIntervalSec, DEFAULT_UTC_SYNC_MIN_INTERVAL_SEC} }; diff --git a/test/utests/tests/StreamAbstractionAAMP_MPD/LinearFOGTests.cpp b/test/utests/tests/StreamAbstractionAAMP_MPD/LinearFOGTests.cpp index f078405c4b..60e9092708 100644 --- a/test/utests/tests/StreamAbstractionAAMP_MPD/LinearFOGTests.cpp +++ b/test/utests/tests/StreamAbstractionAAMP_MPD/LinearFOGTests.cpp @@ -135,7 +135,7 @@ class LinearFOGTests : public testing::TestWithParam {eAAMPConfig_VODTrickPlayFPS, TRICKPLAY_VOD_PLAYBACK_FPS}, {eAAMPConfig_ABRBufferCounter, DEFAULT_ABR_BUFFER_COUNTER}, {eAAMPConfig_MaxDownloadBuffer, DEFAULT_MAX_DOWNLOAD_BUFFER}, - {eAAMPConfig_MaxFragmentChunkCached, DEFAULT_CACHED_FRAGMENT_CHUNKS_PER_TRACK}}; + {eAAMPConfig_MaxLLDFragmentCached, DEFAULT_LLD_CACHED_FRAGMENTS_PER_TRACK}}; IntConfigSettings mIntConfigSettings; diff --git a/test/utests/tests/StreamAbstractionAAMP_MPD/StreamSelectionTest.cpp b/test/utests/tests/StreamAbstractionAAMP_MPD/StreamSelectionTest.cpp index 3e07728c13..105ff73e40 100644 --- a/test/utests/tests/StreamAbstractionAAMP_MPD/StreamSelectionTest.cpp +++ b/test/utests/tests/StreamAbstractionAAMP_MPD/StreamSelectionTest.cpp @@ -398,7 +398,7 @@ class StreamSelectionTests : public testing::TestWithParammCachedFragmentChunks[0]; + CachedFragment *cachFragment = &this->mCachedFragment[0]; cachFragment->timeScale = PLAYBACK_TIMESCALE; cachFragment->initFragment = isInit; cachFragment->discontinuity = isDisc; cachFragment->type = isInit ? eMEDIATYPE_INIT_VIDEO : eMEDIATYPE_VIDEO; cachFragment->fragment.assign(data, data + sizeof(data)); - UpdateTSAfterChunkFetch(); + UpdateTSAfterFetch(); } }; @@ -189,7 +189,7 @@ class TrackInjectTests : public testing::Test {eAAMPConfig_VODTrickPlayFPS, TRICKPLAY_VOD_PLAYBACK_FPS}, {eAAMPConfig_ABRBufferCounter, DEFAULT_ABR_BUFFER_COUNTER}, {eAAMPConfig_StallTimeoutMS, DEFAULT_STALL_DETECTION_TIMEOUT}, - {eAAMPConfig_MaxFragmentChunkCached, 20}, + {eAAMPConfig_MaxLLDFragmentCached, 20}, {eAAMPConfig_DiscontinuityTimeout, 1}}; IntConfigSettings mIntConfigSettings;