2828
2929#include < bento4/Ap4SencAtom.h>
3030
31+ #include < limits>
32+
3133using namespace UTILS ;
3234
3335namespace
@@ -838,22 +840,57 @@ AP4_Result CLinearReader::SeekSample(AP4_UI32 track_id,
838840
839841 AP4_Result result;
840842
841- if (!tracker->m_SampleTable && AP4_FAILED (result = Advance ()))
842- return result;
843+ if (!tracker->m_SampleTable )
844+ {
845+ LOG::LogF (LOGWARNING, " NO SAMPLETABLE Advance" );
846+ if (AP4_FAILED (result = Advance ()))
847+ return result;
848+ }
849+
850+ // ! @todo: remove our custom GetNearestSyncSampleIndex from Bento4
851+ const AP4_Cardinal samplesCount = tracker->m_SampleTable ->GetSampleCount ();
852+ constexpr AP4_Cardinal indexNoValue = std::numeric_limits<AP4_Cardinal>::max ();
843853
844- while (AP4_FAILED (result = tracker->m_SampleTable ->GetSampleIndexForTimeStamp (ts, sample_index)))
854+ AP4_UI64 bestSyncDiff = std::numeric_limits<AP4_UI64>::max ();
855+ AP4_Cardinal syncIndex{indexNoValue};
856+ AP4_Cardinal sampleIndex{0 };
857+ // Try find a sample sync closer to the target ts
858+ // or fallback to the closer sample without sync
859+ for (AP4_Cardinal index{0 }; index < samplesCount; ++index)
845860 {
846- if (result == AP4_ERROR_NOT_ENOUGH_DATA)
847- {
848- tracker->m_NextSampleIndex = tracker->m_SampleTable ->GetSampleCount ();
849- if (AP4_FAILED (result = Advance ()))
850- return result;
861+ AP4_Sample sample;
862+ if (AP4_FAILED (tracker->m_SampleTable ->GetSample (index, sample)))
851863 continue ;
864+
865+ LOG::LogF (LOGWARNING, " sample CTS %llu -- ts %llu -- is sync: %i" , sample.GetCts (), ts,
866+ sample.IsSync ());
867+
868+ const AP4_UI64 cts = sample.GetCts ();
869+ if (sample.IsSync ())
870+ {
871+ const AP4_UI64 diff = (cts > ts) ? (cts - ts) : (ts - cts);
872+ // choose the sample sync with the smallest difference to ts
873+ // preferring if available a ts less than or equal to the target ts
874+ if (diff < bestSyncDiff || (diff == bestSyncDiff && cts <= ts))
875+ {
876+ bestSyncDiff = diff;
877+ syncIndex = index;
878+ }
852879 }
853- return result;
880+ // Find a sample (without sync) closer to the target ts
881+ if (cts <= ts)
882+ sampleIndex = index;
854883 }
855884
856- sample_index = tracker->m_SampleTable ->GetNearestSyncSampleIndex (sample_index, preceedingSync);
885+ if (syncIndex == indexNoValue)
886+ {
887+ LOG::LogF (LOGWARNING, " Sync sample NOT FOUND, fallback to nearest ts" );
888+ sample_index = sampleIndex;
889+ }
890+ else
891+ sample_index = syncIndex;
892+ LOG::LogF (LOGWARNING, " sample_index %u" , sample_index);
893+
857894 // we have reached the end -> go for the first sample of the next segment
858895 if (sample_index == tracker->m_SampleTable ->GetSampleCount ())
859896 {
@@ -863,7 +900,7 @@ AP4_Result CLinearReader::SeekSample(AP4_UI32 track_id,
863900 // Temporarily set m_SampleTableIsOwned to false to prevent "Advance" method
864901 // from deleting the tracker sample table
865902 tracker->m_SampleTableIsOwned = false ;
866-
903+ LOG::LogF (LOGWARNING, " sample_index END Advance " );
867904 if (AP4_FAILED (result = Advance ()))
868905 {
869906 tracker->m_SampleTableIsOwned = isOwned;
0 commit comments