Skip to content

Commit

Permalink
Refactoring the push provider
Browse files Browse the repository at this point in the history
  • Loading branch information
Keukhan committed Dec 24, 2024
1 parent ac39955 commit 40b6263
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 35 deletions.
25 changes: 24 additions & 1 deletion src/projects/modules/ffmpeg/ffmpeg_conv.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ extern "C"

#include <base/common_types.h>
#include <base/info/media_track.h>
#include <base/info/push.h>
#include <base/mediarouter/media_type.h>
#include <base/ovlibrary/ovlibrary.h>
#include <transcoder/transcoder_context.h>
Expand Down Expand Up @@ -796,6 +797,11 @@ namespace ffmpeg
}
break;

case cmn::MediaType::Data:
{
codecpar->codec_id = AV_CODEC_ID_NONE;
}
break;
default:
return false;
}
Expand All @@ -808,7 +814,7 @@ namespace ffmpeg
return ov::String::FormatString("%s", ::avcodec_get_name(codec_id));
}

static ov::String GetFormatByExtension(ov::String extension, ov::String default_format)
static ov::String GetFormatByExtension(ov::String extension, ov::String default_format = "mpegts")
{
if (extension == "mp4")
{
Expand All @@ -826,6 +832,23 @@ namespace ffmpeg
return default_format;
}

static ov::String GetFormatByProtocolType(const info::Push::ProtocolType protocol_type, ov::String default_format = "flv")
{
switch (protocol_type)
{
case info::Push::ProtocolType::RTMP:
return "flv";
case info::Push::ProtocolType::MPEGTS:
return "mpegts";
case info::Push::ProtocolType::SRT:
return "mpegts";
default:
break;
}

return default_format;
}

static bool IsSupportCodec(ov::String format, cmn::MediaCodecId codec_id)
{
if (format == "mp4")
Expand Down
5 changes: 5 additions & 0 deletions src/projects/modules/ffmpeg/ffmpeg_writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ namespace ffmpeg

bool Writer::AddTrack(const std::shared_ptr<MediaTrack> &media_track)
{
// TODO: This code will move to mediarouter.
if (media_track->GetCodecId() == cmn::MediaCodecId::Opus &&
media_track->GetDecoderConfigurationRecord() == nullptr)
{
Expand Down Expand Up @@ -276,6 +277,7 @@ namespace ffmpeg
switch (packet->GetBitstreamFormat())
{
case cmn::BitstreamFormat::H264_AVCC:
// Do nothing
break;
case cmn::BitstreamFormat::H264_ANNEXB: {
new_data = NalStreamConverter::ConvertAnnexbToXvcc(packet->GetData(), packet->GetFragHeader());
Expand All @@ -301,6 +303,9 @@ namespace ffmpeg
av_packet.data = (uint8_t *)new_data->GetDataAs<uint8_t>();
}
break;
case cmn::BitstreamFormat::AMF:
// Do nothing
break;
default:
// Unsupported bitstream foramt
return false;
Expand Down
117 changes: 83 additions & 34 deletions src/projects/publishers/push/push_session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,16 @@ namespace pub
GetPush()->UpdatePushStartTime();
GetPush()->SetState(info::Push::PushState::Connecting);

ov::String rtmp_url;
ov::String dest_url;
if (GetPush()->GetStreamKey().IsEmpty())
{
rtmp_url = GetPush()->GetUrl();
dest_url = GetPush()->GetUrl();
}
else
{
rtmp_url = ov::String::FormatString("%s/%s", GetPush()->GetUrl().CStr(), GetPush()->GetStreamKey().CStr());
dest_url = ov::String::FormatString("%s/%s", GetPush()->GetUrl().CStr(), GetPush()->GetStreamKey().CStr());
}

auto writer = CreateWriter();
if (writer == nullptr)
{
Expand All @@ -75,8 +75,7 @@ namespace pub
return false;
}

ov::String format = (GetPush()->GetProtocolType() == info::Push::ProtocolType::RTMP) ? "flv" : "mpegts";
if (writer->SetUrl(rtmp_url, format) == false)
if (writer->SetUrl(dest_url, ffmpeg::Conv::GetFormatByProtocolType(GetPush()->GetProtocolType())) == false)
{
SetState(SessionState::Error);
GetPush()->SetState(info::Push::PushState::Error);
Expand All @@ -86,8 +85,9 @@ namespace pub

for (auto &[track_id, track] : GetStream()->GetTracks())
{
if (track->GetMediaType() != cmn::MediaType::Video && track->GetMediaType() != cmn::MediaType::Audio)
if (IsSupportTrack(track) == false)
{
logtw("Could not supported track. track_id:%d, codec_id: %d", track->GetId(), track->GetCodecId());
continue;
}

Expand All @@ -98,14 +98,11 @@ namespace pub
continue;
}

// RTMP protocol does not supported except for H264 and AAC codec.
if (GetPush()->GetProtocolType() == info::Push::ProtocolType::RTMP)
if (IsSupportCodec(GetPush()->GetProtocolType(), track->GetCodecId()) == false)
{
if (!(track->GetCodecId() == cmn::MediaCodecId::H264 || track->GetCodecId() == cmn::MediaCodecId::Aac))
{
logtw("Could not supported codec. track_id:%d, codec_id: %d", track->GetId(), track->GetCodecId());
continue;
}
logtw("Could not supported codec. track_id:%d, codec_id: %d", track->GetId(), track->GetCodecId());

continue;
}

bool ret = writer->AddTrack(track);
Expand All @@ -131,23 +128,6 @@ namespace pub
return Session::Start();
}

bool PushSession::IsSelectedTrack(const std::shared_ptr<MediaTrack> &track)
{
auto selected_track_ids = GetPush()->GetTrackIds();
auto selected_track_names = GetPush()->GetVariantNames();

if (selected_track_ids.size() > 0 || selected_track_names.size() > 0)
{
if ((find(selected_track_ids.begin(), selected_track_ids.end(), track->GetId()) == selected_track_ids.end()) &&
(find(selected_track_names.begin(), selected_track_names.end(), track->GetVariantName()) == selected_track_names.end()))
{
return false;
}
}

return true;
}

bool PushSession::Stop()
{
auto writer = GetWriter();
Expand All @@ -167,9 +147,9 @@ namespace pub
GetPush()->SetState(info::Push::PushState::Stopped);
GetPush()->IncreaseSequence();
}
std::unique_lock<std::shared_mutex> lock(_writer_mutex);
_writer = nullptr;

DestoryWriter();

logtd("PushSession(%d) has stopped", GetId());
}

Expand Down Expand Up @@ -251,9 +231,78 @@ namespace pub
return _writer;
}

void PushSession::DestoryWriter()
{
std::lock_guard<std::shared_mutex> lock(_writer_mutex);
if (_writer != nullptr)
{
_writer->Stop();
_writer = nullptr;
}
}

std::shared_ptr<info::Push> PushSession::GetPush()
{
std::shared_lock<std::shared_mutex> lock(_push_mutex);
return _push;
}

bool PushSession::IsSelectedTrack(const std::shared_ptr<MediaTrack> &track)
{
auto selected_track_ids = GetPush()->GetTrackIds();
auto selected_track_names = GetPush()->GetVariantNames();

if (selected_track_ids.size() > 0 || selected_track_names.size() > 0)
{
if ((find(selected_track_ids.begin(), selected_track_ids.end(), track->GetId()) == selected_track_ids.end()) &&
(find(selected_track_names.begin(), selected_track_names.end(), track->GetVariantName()) == selected_track_names.end()))
{
return false;
}
}

return true;
}

bool PushSession::IsSupportTrack(const std::shared_ptr<MediaTrack> &track)
{
// If the track is not video, audio, or data, ignore it.
if (track->GetMediaType() == cmn::MediaType::Video ||
track->GetMediaType() == cmn::MediaType::Audio ||
track->GetMediaType() == cmn::MediaType::Data)
{
return true;
}

return false;
}

bool PushSession::IsSupportCodec(const info::Push::ProtocolType protocol_type, cmn::MediaCodecId codec_id)
{
// RTMP protocol does not supported except for H264 and AAC codec.
if (protocol_type == info::Push::ProtocolType::RTMP)
{
if (codec_id == cmn::MediaCodecId::H264 ||
codec_id == cmn::MediaCodecId::Aac ||
codec_id == cmn::MediaCodecId::None)
{
return true;
}
}
else if (protocol_type == info::Push::ProtocolType::SRT || protocol_type == info::Push::ProtocolType::MPEGTS)
{
if (codec_id == cmn::MediaCodecId::H264 ||
codec_id == cmn::MediaCodecId::H265 ||
codec_id == cmn::MediaCodecId::Vp8 ||
codec_id == cmn::MediaCodecId::Vp9 ||
codec_id == cmn::MediaCodecId::Aac ||
codec_id == cmn::MediaCodecId::Mp3 ||
codec_id == cmn::MediaCodecId::Opus)
{
return true;
}
}

return false;
}
} // namespace pub
4 changes: 4 additions & 0 deletions src/projects/publishers/push/push_session.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <base/info/media_track.h>
#include <base/publisher/session.h>
#include <modules/ffmpeg/ffmpeg_writer.h>
#include <modules/ffmpeg/ffmpeg_conv.h>

#include "base/info/push.h"

Expand Down Expand Up @@ -41,8 +42,11 @@ namespace pub

private:
std::shared_ptr<ffmpeg::Writer> CreateWriter();
void DestoryWriter();

bool IsSelectedTrack(const std::shared_ptr<MediaTrack> &track);
bool IsSupportTrack(const std::shared_ptr<MediaTrack> &track);
bool IsSupportCodec(const info::Push::ProtocolType protocol_type, cmn::MediaCodecId codec_id);

std::shared_ptr<info::Push> _push = nullptr;
std::shared_mutex _push_mutex;
Expand Down

0 comments on commit 40b6263

Please sign in to comment.