Analyse du code source MediaStream (1)

Service de licence et analyse des processus de démarrage

Analyse du code source MediaStream (1)

Analyse du code source MediaStream (deux)

Analyse du code source MediaStream (3)

Analyse du code source WebRtcConnection (1)

Analyse du code source WebRtcConnection (deux)

Analyse du code source WebRtcConnection (3)

Analysez MediaStream:

// MediaStream构造函数
MediaStream::MediaStream(std::shared_ptr<Worker> worker,
  std::shared_ptr<WebRtcConnection> connection,
  const std::string& media_stream_id,
  const std::string& media_stream_label,
  bool is_publisher) :
    audio_enabled_{false}, video_enabled_{false},
    media_stream_event_listener_{nullptr},
    connection_{std::move(connection)},
    stream_id_{media_stream_id},
    mslabel_ {media_stream_label},
    bundle_{false},
    pipeline_{Pipeline::create()},
    worker_{std::move(worker)},
    audio_muted_{false}, video_muted_{false},
    pipeline_initialized_{false},
    is_publisher_{is_publisher},
    simulcast_{false},
    bitrate_from_max_quality_layer_{0},
    video_bitrate_{0},
    random_generator_{random_device_()} {
  if (is_publisher) {
    setVideoSinkSSRC(kDefaultVideoSinkSSRC);
    setAudioSinkSSRC(kDefaultAudioSinkSSRC);
  } else {
    setAudioSinkSSRC(1000000000 + getRandomValue(0, 999999999));
    setVideoSinkSSRC(1000000000 + getRandomValue(0, 999999999));
  }
  ELOG_INFO("%s message: constructor, id: %s",
      toLog(), media_stream_id.c_str());
  source_fb_sink_ = this;
  sink_fb_source_ = this;
  stats_ = std::make_shared<Stats>();
  log_stats_ = std::make_shared<Stats>();
  quality_manager_ = std::make_shared<QualityManager>();
  packet_buffer_ = std::make_shared<PacketBufferService>();

  rtcp_processor_ = std::make_shared<RtcpForwarder>(static_cast<MediaSink*>(this), static_cast<MediaSource*>(this));

  should_send_feedback_ = true;
  slide_show_mode_ = false;

  mark_ = clock::now();

  rate_control_ = 0;
  sending_ = true;
  ready_ = false;
}

// MediaStream析构函数
MediaStream::~MediaStream() {
  ELOG_DEBUG("%s message:Destructor called", toLog());
  ELOG_DEBUG("%s message: Destructor ended", toLog());
}

// 获取随机值
uint32_t MediaStream::getRandomValue(uint32_t min, uint32_t max) {
  std::uniform_int_distribution<> distr(min, max);
  return std::round(distr(random_generator_));
}

// 得到最大视频编码码率
uint32_t MediaStream::getMaxVideoBW() {
  uint32_t bitrate = rtcp_processor_ ? rtcp_processor_->getMaxVideoBW() : 0;
  return bitrate;
}

// 设置最大视频编码码率
void MediaStream::setMaxVideoBW(uint32_t max_video_bw) {
  asyncTask([max_video_bw] (std::shared_ptr<MediaStream> stream) {
    if (stream->rtcp_processor_) {
      stream->rtcp_processor_->setMaxVideoBW(max_video_bw * 1000);
      if (stream->pipeline_) {
        stream->pipeline_->notifyUpdate();
      }
    }
  });
}

// 同步关闭MediaStream,停止发送,vide_sink_和audio_sink_置空
void MediaStream::syncClose() {
  ELOG_DEBUG("%s message:Close called", toLog());
  if (!sending_) {
    return;
  }
  sending_ = false;
  ready_ = false;
  video_sink_ = nullptr;
  audio_sink_ = nullptr;
  fb_sink_ = nullptr;
  pipeline_initialized_ = false;
  pipeline_->close();
  pipeline_.reset();
  connection_.reset();
  ELOG_DEBUG("%s message: Close ended", toLog());
}

// 异步关闭MediaStream
boost::future<void> MediaStream::close() {
  ELOG_DEBUG("%s message: Async close called", toLog());
  std::shared_ptr<MediaStream> shared_this = shared_from_this();
  return asyncTask([shared_this] (std::shared_ptr<MediaStream> stream) {
    shared_this->syncClose();
  });
}

// 初始化MediaStream, 设置ready_
bool MediaStream::init(bool doNotWaitForRemoteSdp) {
  if (doNotWaitForRemoteSdp) {
    ready_ = true;
  }
  return true;
}

// 判断是否是source SSRC标识符
bool MediaStream::isSourceSSRC(uint32_t ssrc) {
  return isVideoSourceSSRC(ssrc) || isAudioSourceSSRC(ssrc);
}

// 判断是否是sink SSRC标识符
bool MediaStream::isSinkSSRC(uint32_t ssrc) {
  return isVideoSinkSSRC(ssrc) || isAudioSinkSSRC(ssrc);
}

// 设置远端sdp信息,向rtcp_processor中加入ssrc信息,初始化pipeline和stats,并通知上层已经ready了
bool MediaStream::setRemoteSdp(std::shared_ptr<SdpInfo> sdp) {
  ELOG_DEBUG("%s message: setting remote SDP to Stream, sending: %d, initialized: %d",
    toLog(), sending_, pipeline_initialized_);
  if (!sending_) {
    return true;
  }

  std::shared_ptr<SdpInfo> remote_sdp = std::make_shared<SdpInfo>(*sdp.get());
  auto video_ssrc_list_it = remote_sdp->video_ssrc_map.find(getLabel());
  auto audio_ssrc_it = remote_sdp->audio_ssrc_map.find(getLabel());

  if (isPublisher() && !ready_) {
    bool stream_found = false;

    if (video_ssrc_list_it != remote_sdp->video_ssrc_map.end() ||
        audio_ssrc_it != remote_sdp->audio_ssrc_map.end()) {
      stream_found = true;
    }

    if (!stream_found) {
      return true;
    }
  }

  remote_sdp_ = remote_sdp;

  if (remote_sdp_->videoBandwidth != 0) {
    ELOG_DEBUG("%s message: Setting remote BW, maxVideoBW: %u", toLog(), remote_sdp_->videoBandwidth);
    this->rtcp_processor_->setMaxVideoBW(remote_sdp_->videoBandwidth*1000);
  }

  ready_ = true;

  if (pipeline_initialized_ && pipeline_) {
    pipeline_->notifyUpdate();
    return true;
  }

  bundle_ = remote_sdp_->isBundle;
  if (video_ssrc_list_it != remote_sdp_->video_ssrc_map.end()) {
    setVideoSourceSSRCList(video_ssrc_list_it->second);
  }

  if (audio_ssrc_it != remote_sdp_->audio_ssrc_map.end()) {
    setAudioSourceSSRC(audio_ssrc_it->second);
  }

  if (getVideoSourceSSRCList().empty() ||
      (getVideoSourceSSRCList().size() == 1 && getVideoSourceSSRCList()[0] == 0)) {
    std::vector<uint32_t> default_ssrc_list;
    default_ssrc_list.push_back(kDefaultVideoSinkSSRC);
    setVideoSourceSSRCList(default_ssrc_list);
  }

  if (getAudioSourceSSRC() == 0) {
    setAudioSourceSSRC(kDefaultAudioSinkSSRC);
  }

  audio_enabled_ = remote_sdp_->hasAudio;
  video_enabled_ = remote_sdp_->hasVideo;

  rtcp_processor_->addSourceSsrc(getAudioSourceSSRC());
  std::for_each(video_source_ssrc_list_.begin(), video_source_ssrc_list_.end(), [this] (uint32_t new_ssrc){
      rtcp_processor_->addSourceSsrc(new_ssrc);
  });

  initializePipeline();

  initializeStats();

  notifyMediaStreamEvent("ready", "");

  return true;
}

 

Je suppose que tu aimes

Origine blog.csdn.net/tong5956/article/details/108261583
conseillé
Classement