// // Copyright (c) 2013-2025 The SRS Authors // // SPDX-License-Identifier: MIT // #include #include #include #include #include #include #include #include #include using namespace std; ISrsStreamBridge::ISrsStreamBridge() { } ISrsStreamBridge::~ISrsStreamBridge() { } SrsFrameToRtmpBridge::SrsFrameToRtmpBridge(SrsSharedPtr source) { source_ = source; } SrsFrameToRtmpBridge::~SrsFrameToRtmpBridge() { } srs_error_t SrsFrameToRtmpBridge::initialize(SrsRequest* 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(SrsSharedPtrMessage* frame) { return source_->on_frame(frame); } #ifdef SRS_RTC SrsFrameToRtcBridge::SrsFrameToRtcBridge(SrsSharedPtr source) { source_ = source; #if defined(SRS_FFMPEG_FIT) uint32_t audio_ssrc = 0; uint8_t audio_payload_type = 0; uint32_t video_ssrc = 0; uint8_t video_payload_type = 0; // audio track ssrc if (true) { std::vector descs = source->get_track_desc("audio", "opus"); if (!descs.empty()) { audio_ssrc = descs.at(0)->ssrc_; } // Note we must use the PT of source, see https://github.com/ossrs/srs/pull/3079 audio_payload_type = descs.empty() ? kAudioPayloadType : descs.front()->media_->pt_; } // video track ssrc if (true) { std::vector descs = source->get_track_desc("video", ""); if (!descs.empty()) { video_ssrc = descs.at(0)->ssrc_; } // Note we must use the PT of source, see https://github.com/ossrs/srs/pull/3079 video_payload_type = descs.empty() ? kVideoPayloadType : descs.front()->media_->pt_; } rtp_builder_ = new SrsRtcRtpBuilder(this, audio_ssrc, audio_payload_type, video_ssrc, video_payload_type); #endif } SrsFrameToRtcBridge::~SrsFrameToRtcBridge() { #ifdef SRS_FFMPEG_FIT srs_freep(rtp_builder_); #endif } srs_error_t SrsFrameToRtcBridge::initialize(SrsRequest* 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(SrsSharedPtrMessage* 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); } #endif SrsCompositeBridge::SrsCompositeBridge() { } SrsCompositeBridge::~SrsCompositeBridge() { for (vector::iterator it = bridges_.begin(); it != bridges_.end(); ++it) { ISrsStreamBridge* bridge = *it; srs_freep(bridge); } } srs_error_t SrsCompositeBridge::initialize(SrsRequest* r) { srs_error_t err = srs_success; for (vector::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::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::iterator it = bridges_.begin(); it != bridges_.end(); ++it) { ISrsStreamBridge* bridge = *it; bridge->on_unpublish(); } } srs_error_t SrsCompositeBridge::on_frame(SrsSharedPtrMessage* frame) { srs_error_t err = srs_success; for (vector::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; }