make sure cue-event sync to all tracks

This commit is contained in:
getroot
2025-03-10 16:46:02 +09:00
parent b9b766b6a9
commit c15135232a
3 changed files with 96 additions and 32 deletions

View File

@ -9,6 +9,52 @@
#include "marker_box.h"
#include "marker_box_private.h"
bool MarkerBox::CanInsertMarker(const Marker &marker) const
{
std::shared_lock<std::shared_mutex> lock(_markers_guard);
if (marker.tag.UpperCaseString() == "CUEEVENT-OUT")
{
if (_last_inserted_marker.tag.UpperCaseString() == "CUEEVENT-OUT")
{
logtw("CUEEVENT-OUT marker cannot be inserted after CUEEVENT-OUT marker");
return false;
}
else if (_last_inserted_marker.tag.UpperCaseString() == "CUEEVENT-IN" && _last_inserted_marker.timestamp > marker.timestamp)
{
logtw("CUEEVENT-OUT marker cannot be inserted before CUEEVENT-IN marker");
return false;
}
}
else if (marker.tag.UpperCaseString() == "CUEEVENT-IN")
{
if (_last_inserted_marker.tag.UpperCaseString() == "CUEEVENT-IN")
{
if (_last_inserted_marker.timestamp > marker.timestamp)
{
return true;
}
else
{
logtw("CUEEVENT-IN marker only can be modified with the less timestamp");
return false;
}
}
else if (_last_inserted_marker.tag.UpperCaseString() == "CUEEVENT-OUT" && _last_inserted_marker.timestamp > marker.timestamp)
{
logtw("CUEEVENT-IN marker cannot be inserted before CUEEVENT-OUT marker");
return false;
}
}
else
{
logtw("Unsupported marker tag: %s", marker.tag.CStr());
return false;
}
return true;
}
bool MarkerBox::InsertMarker(const Marker &marker)
{
std::lock_guard<std::shared_mutex> lock(_markers_guard);

View File

@ -22,6 +22,7 @@ class MarkerBox
{
public:
bool InsertMarker(const Marker &marker);
bool CanInsertMarker(const Marker &marker) const;
protected:
bool HasMarker() const;

View File

@ -1061,42 +1061,59 @@ void LLHlsStream::SendDataFrame(const std::shared_ptr<MediaPacket> &media_packet
}
else if (media_packet->GetBitstreamFormat() == cmn::BitstreamFormat::CUE)
{
// Insert marker to all packagers
for (const auto &it : GetTracks())
// 0: check if it can insert
// 1: insert
for (int i=0; i<2; i++)
{
auto track = it.second;
// Only video and audio tracks are supported
if (track->GetMediaType() != cmn::MediaType::Video && track->GetMediaType() != cmn::MediaType::Audio)
// Insert marker to all packagers
for (const auto &it : GetTracks())
{
continue;
}
auto track = it.second;
// Only video and audio tracks are supported
if (track->GetMediaType() != cmn::MediaType::Video && track->GetMediaType() != cmn::MediaType::Audio)
{
continue;
}
// Get Packager
auto packager = GetPackager(track->GetId());
if (packager == nullptr)
{
logtd("Could not find packager. track id: %d", track->GetId());
continue;
}
// Get Packager
auto packager = GetPackager(track->GetId());
if (packager == nullptr)
{
logtd("Could not find packager. track id: %d", track->GetId());
continue;
}
Marker marker;
marker.timestamp = static_cast<double>(media_packet->GetDts()) / data_track->GetTimeBase().GetTimescale() * track->GetTimeBase().GetTimescale();
marker.data = media_packet->GetData()->Clone();
// Parse the cue data
auto cue_event = CueEvent::Parse(marker.data);
if (cue_event == nullptr)
{
logte("(%s/%s) Failed to parse the cue event data", GetApplication()->GetVHostAppName().CStr(), GetName().CStr());
return;
}
marker.tag = ov::String::FormatString("CueEvent-%s", cue_event->GetCueTypeName().CStr());
auto result = packager->InsertMarker(marker);
if (result == false)
{
logte("Failed to insert marker (timestamp: %lld, tag: %s)", marker.timestamp, marker.tag.CStr());
Marker marker;
marker.timestamp = static_cast<double>(media_packet->GetDts()) / data_track->GetTimeBase().GetTimescale() * track->GetTimeBase().GetTimescale();
marker.data = media_packet->GetData()->Clone();
// Parse the cue data
auto cue_event = CueEvent::Parse(marker.data);
if (cue_event == nullptr)
{
logte("(%s/%s) Failed to parse the cue event data", GetApplication()->GetVHostAppName().CStr(), GetName().CStr());
return;
}
marker.tag = ov::String::FormatString("CueEvent-%s", cue_event->GetCueTypeName().CStr());
if (i == 0) // check
{
auto result = packager->CanInsertMarker(marker);
if (result == false)
{
logte("Failed to insert marker (timestamp: %lld, tag: %s)", marker.timestamp, marker.tag.CStr());
return;
}
}
else
{
auto result = packager->InsertMarker(marker);
if (result == false)
{
logte("Failed to insert marker (timestamp: %lld, tag: %s)", marker.timestamp, marker.tag.CStr());
}
}
}
}
}