srs/trunk/src/app/srs_app_stream_bridge.cpp
Winlin d4d1d5d8b5
AI: Move some app files to kernel. v7.0.86 (#4486)
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
2025-09-13 10:26:47 -04:00

259 lines
5.6 KiB
C++

//
// Copyright (c) 2013-2025 The SRS Authors
//
// SPDX-License-Identifier: MIT
//
#include <srs_app_stream_bridge.hpp>
#include <srs_app_config.hpp>
#include <srs_app_rtc_source.hpp>
#include <srs_app_rtmp_source.hpp>
#include <srs_core_autofree.hpp>
#include <srs_kernel_rtc_rtp.hpp>
#include <srs_protocol_format.hpp>
#include <srs_protocol_rtmp_stack.hpp>
#ifdef SRS_RTSP
#include <srs_app_rtsp_source.hpp>
#endif
#include <vector>
using namespace std;
ISrsStreamBridge::ISrsStreamBridge()
{
}
ISrsStreamBridge::~ISrsStreamBridge()
{
}
SrsFrameToRtmpBridge::SrsFrameToRtmpBridge(SrsSharedPtr<SrsLiveSource> source)
{
source_ = source;
}
SrsFrameToRtmpBridge::~SrsFrameToRtmpBridge()
{
}
srs_error_t SrsFrameToRtmpBridge::initialize(ISrsRequest *r)
{
return srs_success;
}
srs_error_t SrsFrameToRtmpBridge::on_publish()
{
srs_error_t err = srs_success;
// TODO: FIXME: Should sync with bridge?
if ((err = source_->on_publish()) != srs_success) {
return srs_error_wrap(err, "source publish");
}
return err;
}
void SrsFrameToRtmpBridge::on_unpublish()
{
// TODO: FIXME: Should sync with bridge?
source_->on_unpublish();
}
srs_error_t SrsFrameToRtmpBridge::on_frame(SrsMediaPacket *frame)
{
return source_->on_frame(frame);
}
SrsFrameToRtcBridge::SrsFrameToRtcBridge(SrsSharedPtr<SrsRtcSource> source)
{
source_ = source;
#if defined(SRS_FFMPEG_FIT)
// Use lazy initialization - no need to determine codec/track parameters here
rtp_builder_ = new SrsRtcRtpBuilder(this, source);
#endif
}
SrsFrameToRtcBridge::~SrsFrameToRtcBridge()
{
#ifdef SRS_FFMPEG_FIT
srs_freep(rtp_builder_);
#endif
}
srs_error_t SrsFrameToRtcBridge::initialize(ISrsRequest *r)
{
#ifdef SRS_FFMPEG_FIT
return rtp_builder_->initialize(r);
#else
return srs_success;
#endif
}
srs_error_t SrsFrameToRtcBridge::on_publish()
{
srs_error_t err = srs_success;
// TODO: FIXME: Should sync with bridge?
if ((err = source_->on_publish()) != srs_success) {
return srs_error_wrap(err, "source publish");
}
#ifdef SRS_FFMPEG_FIT
if ((err = rtp_builder_->on_publish()) != srs_success) {
return srs_error_wrap(err, "rtp builder publish");
}
#endif
return err;
}
void SrsFrameToRtcBridge::on_unpublish()
{
#ifdef SRS_FFMPEG_FIT
rtp_builder_->on_unpublish();
#endif
// @remark This bridge might be disposed here, so never use it.
// TODO: FIXME: Should sync with bridge?
source_->on_unpublish();
}
srs_error_t SrsFrameToRtcBridge::on_frame(SrsMediaPacket *frame)
{
#ifdef SRS_FFMPEG_FIT
return rtp_builder_->on_frame(frame);
#else
return srs_success;
#endif
}
srs_error_t SrsFrameToRtcBridge::on_rtp(SrsRtpPacket *pkt)
{
return source_->on_rtp(pkt);
}
#ifdef SRS_RTSP
SrsFrameToRtspBridge::SrsFrameToRtspBridge(SrsSharedPtr<SrsRtspSource> source)
{
source_ = source;
// Use lazy initialization - no need to determine codec/track parameters here
rtp_builder_ = new SrsRtspRtpBuilder(this, source);
}
SrsFrameToRtspBridge::~SrsFrameToRtspBridge()
{
srs_freep(rtp_builder_);
}
srs_error_t SrsFrameToRtspBridge::initialize(ISrsRequest *r)
{
return rtp_builder_->initialize(r);
}
srs_error_t SrsFrameToRtspBridge::on_publish()
{
srs_error_t err = srs_success;
// TODO: FIXME: Should sync with bridge?
if ((err = source_->on_publish()) != srs_success) {
return srs_error_wrap(err, "source publish");
}
if ((err = rtp_builder_->on_publish()) != srs_success) {
return srs_error_wrap(err, "rtp builder publish");
}
return err;
}
void SrsFrameToRtspBridge::on_unpublish()
{
rtp_builder_->on_unpublish();
// @remark This bridge might be disposed here, so never use it.
// TODO: FIXME: Should sync with bridge?
source_->on_unpublish();
}
srs_error_t SrsFrameToRtspBridge::on_frame(SrsMediaPacket *frame)
{
return rtp_builder_->on_frame(frame);
}
srs_error_t SrsFrameToRtspBridge::on_rtp(SrsRtpPacket *pkt)
{
return source_->on_rtp(pkt);
}
#endif
SrsCompositeBridge::SrsCompositeBridge()
{
}
SrsCompositeBridge::~SrsCompositeBridge()
{
for (vector<ISrsStreamBridge *>::iterator it = bridges_.begin(); it != bridges_.end(); ++it) {
ISrsStreamBridge *bridge = *it;
srs_freep(bridge);
}
}
srs_error_t SrsCompositeBridge::initialize(ISrsRequest *r)
{
srs_error_t err = srs_success;
for (vector<ISrsStreamBridge *>::iterator it = bridges_.begin(); it != bridges_.end(); ++it) {
ISrsStreamBridge *bridge = *it;
if ((err = bridge->initialize(r)) != srs_success) {
return err;
}
}
return err;
}
srs_error_t SrsCompositeBridge::on_publish()
{
srs_error_t err = srs_success;
for (vector<ISrsStreamBridge *>::iterator it = bridges_.begin(); it != bridges_.end(); ++it) {
ISrsStreamBridge *bridge = *it;
if ((err = bridge->on_publish()) != srs_success) {
return err;
}
}
return err;
}
void SrsCompositeBridge::on_unpublish()
{
for (vector<ISrsStreamBridge *>::iterator it = bridges_.begin(); it != bridges_.end(); ++it) {
ISrsStreamBridge *bridge = *it;
bridge->on_unpublish();
}
}
srs_error_t SrsCompositeBridge::on_frame(SrsMediaPacket *frame)
{
srs_error_t err = srs_success;
for (vector<ISrsStreamBridge *>::iterator it = bridges_.begin(); it != bridges_.end(); ++it) {
ISrsStreamBridge *bridge = *it;
if ((err = bridge->on_frame(frame)) != srs_success) {
return err;
}
}
return err;
}
SrsCompositeBridge *SrsCompositeBridge::append(ISrsStreamBridge *bridge)
{
bridges_.push_back(bridge);
return this;
}