Skip to content

Commit

Permalink
Added default playlist to the stream info API
Browse files Browse the repository at this point in the history
  • Loading branch information
dimiden committed Jan 20, 2025
1 parent ba0485a commit e756132
Show file tree
Hide file tree
Showing 16 changed files with 194 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@
//==============================================================================
#include "streams_controller.h"

#include <orchestrator/orchestrator.h>
#include <base/provider/pull_provider/stream_props.h>
#include <orchestrator/orchestrator.h>

#include <functional>

#include "stream_actions_controller.h"
#include "../../../../../api_private.h"
#include "stream_actions_controller.h"

namespace api
{
Expand Down Expand Up @@ -100,7 +101,7 @@ namespace api
properties->EnableIgnoreRtcpSRTimestamp(jv_properties["ignoreRtcpSRTimestamp"].asBool());
}
}

logti("Request to pull stream: %s/%s - persistent(%s) noInputFailoverTimeoutMs(%d) unusedStreamDeletionTimeoutMs(%d) ignoreRtcpSRTimestamp(%s)", app->GetVHostAppName().CStr(), stream_name.CStr(), properties->IsPersistent() ? "true" : "false", properties->GetNoInputFailoverTimeout(), properties->GetUnusedStreamDeletionTimeout(), properties->IsRtcpSRTimestampIgnored() ? "true" : "false");
for (auto &url : request_urls)
{
Expand Down Expand Up @@ -164,42 +165,32 @@ namespace api
const std::shared_ptr<mon::ApplicationMetrics> &app,
const std::shared_ptr<mon::StreamMetrics> &stream, const std::vector<std::shared_ptr<mon::StreamMetrics>> &output_streams)
{
// Update llhls playlist from the LLHLS stream
auto orchestrator = ocst::Orchestrator::GetInstance();
auto app_name = app->GetVHostAppName();
auto stream_name = stream->GetName();

auto publisher = orchestrator->GetPublisherFromType(PublisherType::LLHls);
if (publisher)
// Get default playlist from the publishers
for (
auto publisher_type = PublisherType::Webrtc;
publisher_type < PublisherType::NumberOfPublishers;
publisher_type = static_cast<PublisherType>(ov::ToUnderlyingType(publisher_type) + 1))
{

for (auto &output_stream : output_streams)
{
auto llhls_stream = publisher->GetStream(app->GetId(), output_stream->GetId());
if (llhls_stream)
{
auto llhls_playlist = llhls_stream->GetPlaylist("llhls");
if (llhls_playlist)
{
output_stream->AddPlaylist(std::make_shared<info::Playlist>(*llhls_playlist));
}
}
}
}
auto publisher = orchestrator->GetPublisherFromType(publisher_type);

// update webrtc_default playlist from the WebRTC stream
publisher = orchestrator->GetPublisherFromType(PublisherType::Webrtc);
if (publisher)
{
for (auto &output_stream : output_streams)
if (publisher != nullptr)
{
auto webrtc_stream = publisher->GetStream(app->GetId(), output_stream->GetId());
if (webrtc_stream)
for (auto &output_stream : output_streams)
{
auto webrtc_playlist = webrtc_stream->GetPlaylist("webrtc_default");
if (webrtc_playlist)
auto stream = publisher->GetStream(app->GetId(), output_stream->GetId());

if (stream != nullptr)
{
output_stream->AddPlaylist(std::make_shared<info::Playlist>(*webrtc_playlist));
auto playlist = stream->GetDefaultPlaylist();

if (playlist != nullptr)
{
output_stream->AddPlaylist(std::make_shared<info::Playlist>(*playlist));
}
}
}
}
Expand All @@ -221,7 +212,7 @@ namespace api
auto code = orchestrator->TerminateStream(app_name, stream_name);
auto http_code = http::StatusCodeFromCommonError(code);
if (http_code != http::StatusCode::OK)
{
{
throw http::HttpError(http_code, "Could not terminate the stream");
}

Expand Down
16 changes: 15 additions & 1 deletion src/projects/base/info/playlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,11 @@ namespace info
class Playlist
{
public:
Playlist(const ov::String &name, const ov::String &file_name)
Playlist(const ov::String &name, const ov::String &file_name, bool is_default)
{
_name = name;
_file_name = file_name;
_is_default = is_default;
}
~Playlist() = default;

Expand All @@ -86,6 +87,7 @@ namespace info
{
_name = other._name;
_file_name = other._file_name;
_is_default = other._is_default;
_webrtc_auto_abr = other._webrtc_auto_abr;
_hls_chunklist_path_depth = other._hls_chunklist_path_depth;
_enable_ts_packaging = other._enable_ts_packaging;
Expand Down Expand Up @@ -143,6 +145,11 @@ namespace info
return _file_name;
}

bool IsDefault() const
{
return _is_default;
}

// Get Rendition List
const std::vector<std::shared_ptr<Rendition>> &GetRenditionList() const
{
Expand All @@ -162,6 +169,11 @@ namespace info
return false;
}

if (_is_default != rhs._is_default)
{
return false;
}

if (_webrtc_auto_abr != rhs._webrtc_auto_abr)
{
return false;
Expand Down Expand Up @@ -203,6 +215,8 @@ namespace info
ov::String _name;
ov::String _file_name;

bool _is_default = false;

bool _webrtc_auto_abr = false;
int _hls_chunklist_path_depth = -1;
bool _enable_ts_packaging = false;
Expand Down
12 changes: 12 additions & 0 deletions src/projects/base/publisher/stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,18 @@ namespace pub
{
}

std::shared_ptr<const info::Playlist> Stream::GetDefaultPlaylist() const
{
auto info = GetDefaultPlaylistInfo();

if (info != nullptr)
{
return GetPlaylist(info->file_name);
}

return nullptr;
}

bool Stream::Start()
{
if (_state != State::CREATED)
Expand Down
38 changes: 37 additions & 1 deletion src/projects/base/publisher/stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ namespace pub
class Stream : public info::Stream, public ov::EnableSharedFromThis<Stream>
{
public:

// Create stream --> Start stream --> Stop stream --> Delete stream
enum class State : uint8_t
{
Expand All @@ -78,6 +77,43 @@ namespace pub
ERROR,
};

struct DefaultPlaylistInfo
{
// Playlist name
//
// For example, in LL-HLS, the value is "llhls_default"
ov::String name;

// Playlist file name, used to retrieve a playlist from the Stream, such as with GetPlaylist()
//
// For example, in LL-HLS, the value is "llhls"
ov::String file_name;

// Used internally by the stream of publisher to distinguish playlists based on file names
// (e.g., when caching the master playlist in LLHlsStream)
//
// For example, in LL-HLS, the value is "llhls.m3u8"
ov::String internal_file_name;

DefaultPlaylistInfo(
const ov::String &name,
const ov::String &file_name,
const ov::String &internal_file_name)
: name(name),
file_name(file_name),
internal_file_name(internal_file_name)
{
}
};

public:
virtual std::shared_ptr<const DefaultPlaylistInfo> GetDefaultPlaylistInfo() const
{
return nullptr;
}

std::shared_ptr<const info::Playlist> GetDefaultPlaylist() const;

// Session을 추가한다.
bool AddSession(std::shared_ptr<Session> session);
bool RemoveSession(session_id_t id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ namespace cfg
// Copy cfg to info
std::shared_ptr<info::Playlist> GetPlaylistInfo() const
{
auto playlist = std::make_shared<info::Playlist>(GetName(), GetFileName());
auto playlist = std::make_shared<info::Playlist>(GetName(), GetFileName(), false);
playlist->SetHlsChunklistPathDepth(_options.GetHlsChunklistPathDepth());
playlist->SetWebRtcAutoAbr(_options.IsWebRtcAutoAbr());
playlist->EnableTsPackaging(_options.IsTsPackagingEnabled());
Expand Down
4 changes: 2 additions & 2 deletions src/projects/providers/multiplex/multiplex_profile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ namespace pvd
return false;
}

auto playlist = std::make_shared<info::Playlist>(name_object.asString().c_str(), file_name_object.asString().c_str());
auto playlist = std::make_shared<info::Playlist>(name_object.asString().c_str(), file_name_object.asString().c_str(), false);

// Options
auto options_object = playlist_object["options"];
Expand Down Expand Up @@ -406,7 +406,7 @@ namespace pvd
return false;
}

auto playlist = std::make_shared<info::Playlist>(playlist_name_node.text().as_string(), file_name_node.text().as_string());
auto playlist = std::make_shared<info::Playlist>(playlist_name_node.text().as_string(), file_name_node.text().as_string(), false);

// Options
auto options_node = playlist_node.child("Options");
Expand Down
2 changes: 1 addition & 1 deletion src/projects/providers/ovt/ovt_stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ namespace pvd
ov::String playlist_name = json_playlist["name"].asString().c_str();
ov::String playlist_file_name = json_playlist["fileName"].asString().c_str();

auto playlist = std::make_shared<info::Playlist>(playlist_name, playlist_file_name);
auto playlist = std::make_shared<info::Playlist>(playlist_name, playlist_file_name, false);

// Options
auto json_options = json_playlist["options"];
Expand Down
26 changes: 22 additions & 4 deletions src/projects/publishers/hls/hls_stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,23 @@ HlsStream::~HlsStream()
logtd("TsStream(%s/%s) has been terminated finally", GetApplicationName(), GetName().CStr());
}

std::shared_ptr<const pub::Stream::DefaultPlaylistInfo> HlsStream::GetDefaultPlaylistInfo() const
{
// Since the same value is always stored in info, it is not an issue
// even if multiple instances of info are created due to a race conditio in multi-threading
static auto info = []() -> std::shared_ptr<const pub::Stream::DefaultPlaylistInfo> {
ov::String file_name = "playlist.m3u8";
auto file_name_without_ext = file_name.Substring(0, file_name.IndexOfRev('.'));

return std::make_shared<const pub::Stream::DefaultPlaylistInfo>(
"hls_default",
file_name_without_ext,
file_name);
}();

return info;
}

ov::String HlsStream::GetStreamId() const
{
return ov::String::FormatString("hlsv3/%s", GetUri().CStr());
Expand Down Expand Up @@ -197,12 +214,13 @@ bool HlsStream::CreateDefaultPlaylist()
}

// Create default playlist
ov::String default_playlist_name = TS_HLS_DEFAULT_PLAYLIST_NAME;
auto default_playlist_name_without_ext = default_playlist_name.Substring(0, default_playlist_name.IndexOfRev('.'));
auto default_playlist = Stream::GetPlaylist(default_playlist_name_without_ext);
auto default_playlist_info = GetDefaultPlaylistInfo();
OV_ASSERT2(default_playlist_info != nullptr);

auto default_playlist = Stream::GetPlaylist(default_playlist_info->file_name);
if (default_playlist == nullptr)
{
auto playlist = std::make_shared<info::Playlist>("hls_default", default_playlist_name_without_ext);
auto playlist = std::make_shared<info::Playlist>(default_playlist_info->name, default_playlist_info->file_name, true);
auto rendition = std::make_shared<info::Rendition>("default", first_video_track ? first_video_track->GetVariantName() : "", first_audio_track ? first_audio_track->GetVariantName() : "");

playlist->AddRendition(rendition);
Expand Down
8 changes: 6 additions & 2 deletions src/projects/publishers/hls/hls_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@
#include "hls_master_playlist.h"
#include "hls_media_playlist.h"

#define TS_HLS_DEFAULT_PLAYLIST_NAME "playlist.m3u8"

// max initial media packet buffer size, for OOM protection
#define MAX_INITIAL_MEDIA_PACKET_BUFFER_SIZE 10000

Expand All @@ -34,6 +32,12 @@ class HlsStream final : public pub::Stream, public mpegts::PackagerSink
explicit HlsStream(const std::shared_ptr<pub::Application> application, const info::Stream &info, uint32_t worker_count);
~HlsStream() final;

//--------------------------------------------------------------------
// Implementation of info::Stream
//--------------------------------------------------------------------
std::shared_ptr<const pub::Stream::DefaultPlaylistInfo> GetDefaultPlaylistInfo() const override;
//--------------------------------------------------------------------

void SendVideoFrame(const std::shared_ptr<MediaPacket> &media_packet) override;
void SendAudioFrame(const std::shared_ptr<MediaPacket> &media_packet) override;
void SendDataFrame(const std::shared_ptr<MediaPacket> &media_packet) override;
Expand Down
33 changes: 24 additions & 9 deletions src/projects/publishers/llhls/llhls_stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,15 @@
#include "llhls_stream.h"

#include <base/ovlibrary/hex.h>
#include <base/publisher/application.h>
#include <base/publisher/stream.h>
#include <config/config_manager.h>

#include <pugixml-1.9/src/pugixml.hpp>

#include <base/publisher/application.h>
#include <base/publisher/stream.h>

#include "llhls_application.h"
#include "llhls_session.h"
#include "llhls_private.h"
#include "llhls_session.h"

std::shared_ptr<LLHlsStream> LLHlsStream::Create(const std::shared_ptr<pub::Application> application, const info::Stream &info, uint32_t worker_count)
{
Expand All @@ -41,6 +40,21 @@ ov::String LLHlsStream::GetStreamId() const
return ov::String::FormatString("llhls/%s", GetUri().CStr());
}

std::shared_ptr<const pub::Stream::DefaultPlaylistInfo> LLHlsStream::GetDefaultPlaylistInfo() const
{
static auto info = []() -> std::shared_ptr<const pub::Stream::DefaultPlaylistInfo> {
ov::String file_name = "llhls.m3u8";
auto file_name_without_ext = file_name.Substring(0, file_name.IndexOfRev('.'));

return std::make_shared<const pub::Stream::DefaultPlaylistInfo>(
"llhls_default",
file_name_without_ext,
file_name);
}();

return info;
}

bool LLHlsStream::Start()
{
if (GetState() != State::CREATED)
Expand Down Expand Up @@ -150,12 +164,13 @@ bool LLHlsStream::Start()
{
// If there is no default playlist, make default playlist
// Default playlist is consist of first compatible video and audio track among all tracks
ov::String default_playlist_name = DEFAULT_PLAYLIST_NAME;
auto default_playlist_name_without_ext = default_playlist_name.Substring(0, default_playlist_name.IndexOfRev('.'));
auto default_playlist = Stream::GetPlaylist(default_playlist_name_without_ext);
auto default_playlist_info = GetDefaultPlaylistInfo();
OV_ASSERT2(default_playlist_info != nullptr);

auto default_playlist = Stream::GetPlaylist(default_playlist_info->file_name);
if (default_playlist == nullptr)
{
auto playlist = std::make_shared<info::Playlist>("llhls_default", default_playlist_name_without_ext);
auto playlist = std::make_shared<info::Playlist>(default_playlist_info->name, default_playlist_info->file_name, true);
auto rendition = std::make_shared<info::Rendition>("default", first_video_track ? first_video_track->GetVariantName() : "", first_audio_track ? first_audio_track->GetVariantName() : "");

playlist->AddRendition(rendition);
Expand All @@ -165,7 +180,7 @@ bool LLHlsStream::Start()
auto master_playlist = CreateMasterPlaylist(playlist);

std::lock_guard<std::mutex> guard(_master_playlists_lock);
_master_playlists[default_playlist_name] = master_playlist;
_master_playlists[default_playlist_info->internal_file_name] = master_playlist;
}
}
else
Expand Down
Loading

0 comments on commit e756132

Please sign in to comment.