Skip to content

Commit

Permalink
(draft) Implemented Multi Audio Track in ScheduledChannel
Browse files Browse the repository at this point in the history
  • Loading branch information
getroot committed Feb 10, 2025
1 parent 5376a54 commit f0a4f60
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 22 deletions.
2 changes: 1 addition & 1 deletion src/projects/base/info/audio_map_item.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,6 @@ namespace info
private:
int _index;
ov::String _name;
ov::String _language;
ov::String _language = "und";
};
} // namespace info
87 changes: 87 additions & 0 deletions src/projects/providers/scheduled/schedule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,57 @@ namespace pvd

_stream = MakeStream(name, bypass_transcoder, video_track, audio_track);

// audioMap

/*
"audioMap": [
{
"name": "Korean",
"language": "kor"
},
{
"name": "English",
"language": "eng"
}
]
for (uint32_t i=0; i<programs_object.size(); i++)
{
auto program_object = programs_object[i];
*/

auto audio_map_object = stream_object["audioMap"];
if (audio_map_object.isNull() == false)
{
if (audio_map_object.isArray() == false)
{
_last_error = "audioMap must be an array";
return false;
}

for (uint32_t i=0; i<audio_map_object.size(); i++)
{
auto audio_map_item_object = audio_map_object[i];
ov::String public_name;
ov::String language;

auto public_name_object = audio_map_item_object["name"];
if (public_name_object.isNull() == false || public_name_object.isString() == true)
{
public_name = public_name_object.asString().c_str();
}

auto language_object = audio_map_item_object["language"];
if (language_object.isNull() == false || language_object.isString() == true)
{
language = language_object.asString().c_str();
}

_stream.audio_map.push_back({static_cast<int>(i), public_name, language});
}
}

return true;
}

Expand Down Expand Up @@ -422,6 +473,42 @@ namespace pvd

_stream = MakeStream(name, bypass_transcoder, video_track, audio_track);

// Optional
/*
<AudioMap>
<Item>
<Name>Korean</Name>
<Language>kor</Language>
</Item>
<Item>
<Name>English</Name>
<Language>eng</Language>
</Item>
</AudioMap>
*/
auto audio_map_node = stream_node.child("AudioMap");
uint32_t index = 0;
for (auto audio_map_item_node = audio_map_node.child("Item"); audio_map_item_node; audio_map_item_node = audio_map_item_node.next_sibling("Item"))
{
ov::String public_name;
ov::String language;

auto public_name_node = audio_map_item_node.child("Name");
if (public_name_node)
{
public_name = public_name_node.text().as_string();
}

auto language_node = audio_map_item_node.child("Language");
if (language_node)
{
language = language_node.text().as_string();
}

_stream.audio_map.push_back({static_cast<int>(index), public_name, language});
index ++;
}

return true;
}

Expand Down
3 changes: 3 additions & 0 deletions src/projects/providers/scheduled/schedule.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <base/ovlibrary/ovlibrary.h>
#include <base/common_types.h>
#include <base/info/audio_map_item.h>
#include <pugixml-1.9/src/pugixml.hpp>

/*
Expand Down Expand Up @@ -100,6 +101,8 @@ namespace pvd
bool bypass_transcoder = false;
bool video_track = true;
bool audio_track = true;

std::vector<info::AudioMapItem> audio_map;
};

struct Program
Expand Down
45 changes: 35 additions & 10 deletions src/projects/providers/scheduled/scheduled_application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,16 +206,41 @@ namespace pvd

if (channel_info.audio_track == true)
{
auto track = std::make_shared<MediaTrack>();
track->SetId(kScheduledAudioTrackId);
auto public_name = ov::String::FormatString("Audio_%d", track->GetId());
track->SetPublicName(public_name);
track->SetMediaType(cmn::MediaType::Audio);

// Set Timebase to 1/1000 fixed
track->SetTimeBase(1, 1000);

stream->AddTrack(track);
if (channel_info.audio_map.empty())
{
auto track = std::make_shared<MediaTrack>();
track->SetId(kScheduledAudioTrackId);
auto public_name = ov::String::FormatString("Audio_%d", track->GetId());
track->SetPublicName(public_name);
track->SetMediaType(cmn::MediaType::Audio);

// Set Timebase to 1/1000 fixed
track->SetTimeBase(1, 1000);

stream->AddTrack(track);
}
else
{
for (const auto &audio_map_item : channel_info.audio_map)
{
auto track = std::make_shared<MediaTrack>();
track->SetId(kScheduledAudioTrackId + audio_map_item.GetIndex());

ov::String public_name = audio_map_item.GetName();
if (public_name.IsEmpty())
{
public_name = ov::String::FormatString("Audio_%d", track->GetId());
}
track->SetPublicName(public_name);
track->SetLanguage(audio_map_item.GetLanguage());
track->SetMediaType(cmn::MediaType::Audio);

// Set Timebase to 1/1000 fixed
track->SetTimeBase(1, 1000);

stream->AddTrack(track);
}
}
}

if (AddStream(stream) == false)
Expand Down
34 changes: 26 additions & 8 deletions src/projects/providers/scheduled/scheduled_stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,7 @@ namespace pvd
auto single_file_dts = dts - track_single_file_dts_offset_map[track_id];

AdjustTimestampByBase(track_id, pts, dts, std::numeric_limits<int64_t>::max(), duration);
logtd("Scheduled Channel Send Packet : %s/%s: Track %d, origin dts : %lld, pts %lld, dts %lld, duration %lld, tb %f", GetApplicationName(), GetName().CStr(), track_id, single_file_dts, pts, dts, duration, track->GetTimeBase().GetExpr());

media_packet->SetPts(pts);
media_packet->SetDts(dts);
Expand Down Expand Up @@ -714,6 +715,7 @@ namespace pvd
bool video_track_needed = _channel_info.video_track;
bool audio_track_needed = _channel_info.audio_track;

uint32_t audio_index = 0;
int64_t total_duration_ms = 0;
_origin_id_track_id_map.clear();
for (uint32_t track_id = 0; track_id < format_context->nb_streams; track_id++)
Expand Down Expand Up @@ -763,9 +765,15 @@ namespace pvd
continue;
}

new_track->SetId(kScheduledAudioTrackId);
auto audio_track_id = kScheduledAudioTrackId + audio_index;
audio_index++;
auto old_track = GetTrack(audio_track_id);

new_track->SetId(audio_track_id);
new_track->SetTimeBase(1, new_track->GetSampleRate());
_origin_id_track_id_map.emplace(stream->index, kScheduledAudioTrackId);
new_track->SetPublicName(old_track->GetPublicName());
new_track->SetLanguage(old_track->GetLanguage());
_origin_id_track_id_map.emplace(stream->index, audio_track_id);
UpdateTrack(new_track);

if (total_duration_ms == 0)
Expand All @@ -776,8 +784,11 @@ namespace pvd
{
total_duration_ms = std::min(total_duration_ms, (int64_t)(stream->duration * 1000 * ::av_q2d(stream->time_base)));
}

audio_track_needed = false;

if (audio_index + 1 > _channel_info.audio_map.size())
{
audio_track_needed = false;
}
}
else
{
Expand Down Expand Up @@ -1116,6 +1127,7 @@ namespace pvd
_origin_id_track_id_map.clear();
bool video_track_needed = _channel_info.video_track;
bool audio_track_needed = _channel_info.audio_track;
uint32_t audio_index = 0;
for (const auto &[track_id, track] : stream_tap->GetStreamInfo()->GetTracks())
{
if (video_track_needed == false && audio_track_needed == false)
Expand Down Expand Up @@ -1147,13 +1159,19 @@ namespace pvd
{
continue;
}

auto audio_track_id = kScheduledAudioTrackId + audio_index;
audio_index++;

new_track->SetId(kScheduledAudioTrackId);
new_track->SetId(audio_track_id);
new_track->SetTimeBase(1, new_track->GetSampleRate());
_origin_id_track_id_map.emplace(track_id, kScheduledAudioTrackId);
_origin_id_track_id_map.emplace(track_id, audio_track_id);
UpdateTrack(new_track);

audio_track_needed = false;

if (audio_index + 1 > _channel_info.audio_map.size())
{
audio_track_needed = false;
}
}
else
{
Expand Down
4 changes: 2 additions & 2 deletions src/projects/providers/scheduled/scheduled_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ namespace pvd
{
// ScheduledStream doesn't support multiple tracks yet
constexpr int kScheduledVideoTrackId = 0;
constexpr int kScheduledAudioTrackId = 1;
constexpr int kScheduledDataTrackId = 2;
constexpr int kScheduledAudioTrackId = 100;
constexpr int kScheduledDataTrackId = 200;
constexpr int kScheduledVideoTimebase = 90000;

class ScheduledStream : public Stream
Expand Down
2 changes: 1 addition & 1 deletion src/projects/publishers/llhls/llhls_master_playlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ bool LLHlsMasterPlaylist::AddStreamInfo(const ov::String &video_group_id, int vi
if (video_group_id.IsEmpty() == false)
{
auto video_group = GetMediaGroup(video_group_id);
if (video_group == nullptr || video_group->_media_infos.size() <= video_index_hint)
if (video_group == nullptr || video_group->_media_infos.size() <= static_cast<std::size_t>(video_index_hint))
{
logte("Could not find valid video group: %s", video_group_id.CStr());
return false;
Expand Down

0 comments on commit f0a4f60

Please sign in to comment.