OneToManyProcessorソースコード分析

Licodeサービスと起動プロセスの分析

MediaStreamソースコード分析(1)

MediaStreamソースコード分析(2)

MediaStreamソースコード分析(3)

WebRtcConnectionソースコード分析(1)

WebRtcConnectionソースコード分析(2)

WebRtcConnectionソースコード分析(3)

OneToManyProcessorソースコード分析

DtlsTransportソースコード分析

OneToManyProcessorモジュールの分析:

 

 DEFINE_LOGGER(OneToManyProcessor, "OneToManyProcessor");

  // OneToManyProcessor的构造函数
  OneToManyProcessor::OneToManyProcessor() : feedbackSink_{nullptr} {
    ELOG_DEBUG("OneToManyProcessor constructor");
  }

  // OneToManyProcessor的析构函数
  OneToManyProcessor::~OneToManyProcessor() {
  }

  // 发送音频数据
  int OneToManyProcessor::deliverAudioData_(std::shared_ptr<DataPacket> audio_packet) {
    if (audio_packet->length <= 0)
      return 0;

    boost::unique_lock<boost::mutex> lock(monitor_mutex_);
    if (subscribers.empty())
      return 0;

    std::map<std::string, std::shared_ptr<MediaSink>>::iterator it;
    RtpHeader* head = reinterpret_cast<RtpHeader*>(audio_packet->data);
    for (it = subscribers.begin(); it != subscribers.end(); ++it) {
      if ((*it).second != nullptr) {
        head->setSSRC((*it).second->getAudioSinkSSRC());
        // Note: deliverAudioData must copy the packet inmediately
        (*it).second->deliverAudioData(audio_packet);
      }
    }

    return 0;
  }

  // ssrc是否是audio的音频源
  bool OneToManyProcessor::isSSRCFromAudio(uint32_t ssrc) {
    std::map<std::string, std::shared_ptr<MediaSink>>::iterator it;
    for (it = subscribers.begin(); it != subscribers.end(); ++it) {
      if ((*it).second->getAudioSinkSSRC() == ssrc) {
        return true;
      }
    }
    return false;
  }

  // 发送视频数据
  int OneToManyProcessor::deliverVideoData_(std::shared_ptr<DataPacket> video_packet) {
    if (video_packet->length <= 0)
      return 0;
    RtcpHeader* head = reinterpret_cast<RtcpHeader*>(video_packet->data);
    if (head->isFeedback()) {
      ELOG_WARN("Receiving Feedback in wrong path: %d", head->packettype);
      deliverFeedback_(video_packet);
      return 0;
    }
    boost::unique_lock<boost::mutex> lock(monitor_mutex_);
    if (subscribers.empty())
      return 0;
    std::map<std::string, std::shared_ptr<MediaSink>>::iterator it;
    RtpHeader* rhead = reinterpret_cast<RtpHeader*>(video_packet->data);
    uint32_t ssrc = head->isRtcp() ? head->getSSRC() : rhead->getSSRC();
    uint32_t ssrc_offset = translateAndMaybeAdaptForSimulcast(ssrc);
    for (it = subscribers.begin(); it != subscribers.end(); ++it) {
      if ((*it).second != nullptr) {
        uint32_t base_ssrc = (*it).second->getVideoSinkSSRC();
        if (head->isRtcp()) {
          head->setSSRC(base_ssrc + ssrc_offset);
        } else {
          rhead->setSSRC(base_ssrc + ssrc_offset);
        }
        // Note: deliverVideoData must copy the packet inmediately
        (*it).second->deliverVideoData(video_packet);
      }
    }
    return 0;
  }

 
  uint32_t OneToManyProcessor::translateAndMaybeAdaptForSimulcast(uint32_t orig_ssrc) {
    return orig_ssrc - publisher->getVideoSourceSSRC();
  }

  // 设置发布者
  void OneToManyProcessor::setPublisher(std::shared_ptr<MediaSource> publisher_stream) {
    boost::mutex::scoped_lock lock(monitor_mutex_);
    this->publisher = publisher_stream;
    feedbackSink_ = publisher->getFeedbackSink();
  }

  // 发送反馈包
  int OneToManyProcessor::deliverFeedback_(std::shared_ptr<DataPacket> fb_packet) {
    if (feedbackSink_ != nullptr) {
      RtpUtils::forEachRtcpBlock(fb_packet, [this](RtcpHeader *chead) {
        if (chead->isREMB()) {
          for (uint8_t index = 0; index < chead->getREMBNumSSRC(); index++) {
            if (isSSRCFromAudio(chead->getREMBFeedSSRC(index))) {
              chead->setREMBFeedSSRC(index, publisher->getAudioSourceSSRC());
            } else {
              chead->setREMBFeedSSRC(index, publisher->getVideoSourceSSRC());
            }
          }
        }
        if (isSSRCFromAudio(chead->getSourceSSRC())) {
          chead->setSourceSSRC(publisher->getAudioSourceSSRC());
        } else {
          chead->setSourceSSRC(publisher->getVideoSourceSSRC());
        }
      });
      feedbackSink_->deliverFeedback(fb_packet);
    }
    return 0;
  }

  // 发送事件通知
  int OneToManyProcessor::deliverEvent_(MediaEventPtr event) {
    boost::unique_lock<boost::mutex> lock(monitor_mutex_);
    if (subscribers.empty())
      return 0;
    std::map<std::string, std::shared_ptr<MediaSink>>::iterator it;
    for (it = subscribers.begin(); it != subscribers.end(); ++it) {
      if ((*it).second != nullptr) {
        (*it).second->deliverEvent(event);
      }
    }
    return 0;
  }

  // 添加订阅者的id和stream句柄
  void OneToManyProcessor::addSubscriber(std::shared_ptr<MediaSink> subscriber_stream,
      const std::string& peer_id) {
    ELOG_DEBUG("Adding subscriber");
    boost::mutex::scoped_lock lock(monitor_mutex_);
    ELOG_DEBUG("From %u, %u ", publisher->getAudioSourceSSRC(), publisher->getVideoSourceSSRC());
    ELOG_DEBUG("Subscribers ssrcs: Audio %u, video, %u from %u, %u ",
               subscriber_stream->getAudioSinkSSRC(), subscriber_stream->getVideoSinkSSRC(),
               this->publisher->getAudioSourceSSRC() , this->publisher->getVideoSourceSSRC());
    FeedbackSource* fbsource = subscriber_stream->getFeedbackSource();

    if (fbsource != nullptr) {
      ELOG_DEBUG("adding fbsource");
      fbsource->setFeedbackSink(this);
    }
    if (this->subscribers.find(peer_id) != subscribers.end()) {
        ELOG_WARN("This OTM already has a subscriber with peer_id %s, substituting it", peer_id.c_str());
        this->subscribers.erase(peer_id);
    }
    this->subscribers[peer_id] = subscriber_stream;
  }

  void OneToManyProcessor::removeSubscriber(const std::string& peer_id) {
    ELOG_DEBUG("Remove subscriber %s", peer_id.c_str());
    boost::mutex::scoped_lock lock(monitor_mutex_);
    if (this->subscribers.find(peer_id) != subscribers.end()) {
      this->subscribers.erase(peer_id);
    }
  }

  // 关闭OneToManyProcessor
  boost::future<void> OneToManyProcessor::close() {
    return closeAll();
  }

  // 关闭OneToManyProcessor的具体实现,去除订阅者和将发布者置空
  boost::future<void> OneToManyProcessor::closeAll() {
    ELOG_DEBUG("OneToManyProcessor closeAll");
    std::shared_ptr<boost::promise<void>> p = std::make_shared<boost::promise<void>>();
    boost::future<void> f = p->get_future();
    feedbackSink_ = nullptr;
    publisher.reset();
    boost::unique_lock<boost::mutex> lock(monitor_mutex_);
    std::map<std::string, std::shared_ptr<MediaSink>>::iterator it = subscribers.begin();
    while (it != subscribers.end()) {
      if ((*it).second != nullptr) {
        FeedbackSource* fbsource = (*it).second->getFeedbackSource();
        if (fbsource != nullptr) {
          fbsource->setFeedbackSink(nullptr);
        }
      }
      subscribers.erase(it++);
    }
    subscribers.clear();
    p->set_value();
    ELOG_DEBUG("ClosedAll media in this OneToMany");
    return f;
  }

 

おすすめ

転載: blog.csdn.net/tong5956/article/details/108279497