Skip to content

Commit

Permalink
Prevent segments from becoming too long in HLSv3, force creation
Browse files Browse the repository at this point in the history
  • Loading branch information
getroot committed Sep 20, 2024
1 parent ea24f69 commit 0b1465e
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 8 deletions.
25 changes: 18 additions & 7 deletions src/projects/modules/containers/mpegts/mpegts_packager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ namespace mpegts

auto track_id = media_packet->GetTrackId();
auto track = GetMediaTrack(track_id);

auto sample_buffer = GetSampleBuffer(track_id);
if (track == nullptr || sample_buffer == nullptr)
{
Expand Down Expand Up @@ -215,15 +216,23 @@ namespace mpegts
return;
}

if (main_sample_buffer->HasSegmentBoundary() == false)
{
if (main_sample_buffer->GetCurrentDurationUs() >= MAX_SEGMENT_DURATION_US)
// If the segment duration is too long (twice the target duration), a new segment is forcibly created.
if (force_create == false && main_sample_buffer->GetTotalAvailableDurationUs() >= _config.target_duration_ms * 2000)
{
logtw("Stream(%s) Main Track(%u) has too long duration (%llu us, twice the target duration %u us), force to create a new segment", _config.stream_id_meta.CStr(), _main_track_id, main_sample_buffer->GetTotalAvailableDurationUs(), _config.target_duration_ms * 1000);

if (main_sample_buffer->HasSegmentBoundary() == false)
{
logtw("Stream (%s) Main track (%u) does not have a segment boundary. However, the queued segment duration is too long: %u ms. A new segment will be forcibly created.", _config.stream_id_meta.CStr(), _main_track_id, main_sample_buffer->GetCurrentDurationUs());

Flush();
}

else
{
force_create = true;
}
}

if (main_sample_buffer->HasSegmentBoundary() == false)
{
return;
}

Expand All @@ -242,6 +251,8 @@ namespace mpegts

auto total_sample_segment_duration_us = sample_buffer->GetTotalConsumedDurationUs() + sample_buffer->GetCurrentDurationUs();

logtd("Stream(%s) Track(%u) total_sample_segment_duration_us(%llu) total_main_segment_duration_us(%llu) main_sample_buffer->GetDurationUntilSegmentBoundaryUs()(%llu) sample_buffer->GetCurrentDurationUs()(%llu) main_sample_buffer->GetTotalAvailableDurationUs()(%llu)", _config.stream_id_meta.CStr(), track_id, total_sample_segment_duration_us, total_main_segment_duration_us, main_sample_buffer->GetDurationUntilSegmentBoundaryUs(), sample_buffer->GetCurrentDurationUs(), main_sample_buffer->GetTotalAvailableDurationUs());

// if video segment is 6000, audio segment is at least 6000*0.97(=5820), it is normal case, wait for more samples
if (total_sample_segment_duration_us < total_main_segment_duration_us * 0.97)
{
Expand All @@ -250,7 +261,7 @@ namespace mpegts
{
logtw("Stream(%s) Track(%u) has insufficient sample duration (%llu us) for the main track duration (%llu us)", _config.stream_id_meta.CStr(), track_id, total_sample_segment_duration_us, total_main_segment_duration_us);
}

return;
}
}
Expand Down
18 changes: 17 additions & 1 deletion src/projects/modules/containers/mpegts/mpegts_packager.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
namespace mpegts
{
constexpr size_t SEGMENT_BUFFER_SIZE = 2000000;
constexpr size_t MAX_SEGMENT_DURATION_US = 5 * 60 * 1000 * 1000; // 5 minutes

class Segment
{
Expand Down Expand Up @@ -175,6 +174,9 @@ namespace mpegts
_current_samples_count++;
_current_samples_duration_us += duration_us;

_total_available_count++;
_total_available_duration_us += duration_us;

return true;
}

Expand Down Expand Up @@ -215,6 +217,11 @@ namespace mpegts

return _segment_boundaries.front().duration_us;
}

uint64_t GetTotalAvailableDurationUs() const
{
return _total_available_duration_us;
}

bool IsEmpty() const
{
Expand All @@ -235,6 +242,9 @@ namespace mpegts

_current_samples_count--;
_current_samples_duration_us -= sample_duration_us;

_total_available_count--;
_total_available_duration_us -= sample_duration_us;

_total_consumed_samples_count++;
_total_consumed_samples_duration_us += sample_duration_us;
Expand Down Expand Up @@ -278,6 +288,9 @@ namespace mpegts
_total_consumed_samples_count += boundary.sample_count;
_total_consumed_samples_duration_us += boundary.duration_us;

_total_available_duration_us -= boundary.duration_us;
_total_available_count -= boundary.sample_count;

return samples;
}

Expand All @@ -301,6 +314,9 @@ namespace mpegts
uint64_t _current_samples_count = 0;
uint64_t _current_samples_duration_us = 0;

uint64_t _total_available_duration_us = 0;
uint64_t _total_available_count = 0;

uint64_t _total_consumed_samples_count = 0;
uint64_t _total_consumed_samples_duration_us = 0;
};
Expand Down

0 comments on commit 0b1465e

Please sign in to comment.