15976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/*
25976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * libjingle
35976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Copyright 2004 Google Inc.
45976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *
55976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Redistribution and use in source and binary forms, with or without
65976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * modification, are permitted provided that the following conditions are met:
75976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *
85976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *  1. Redistributions of source code must retain the above copyright notice,
95976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *     this list of conditions and the following disclaimer.
105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *  2. Redistributions in binary form must reproduce the above copyright notice,
115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *     this list of conditions and the following disclaimer in the documentation
125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *     and/or other materials provided with the distribution.
135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *  3. The name of the author may not be used to endorse or promote products
145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *     derived from this software without specific prior written permission.
155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *
165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org */
275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/media/base/hybridvideoengine.h"
295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/logging.h"
315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgnamespace cricket {
335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgHybridVideoMediaChannel::HybridVideoMediaChannel(
355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    HybridVideoEngineInterface* engine,
365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    VideoMediaChannel* channel1,
375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    VideoMediaChannel* channel2)
385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    : engine_(engine),
395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      channel1_(channel1),
405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      channel2_(channel2),
415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      active_channel_(NULL),
425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      sending_(false) {
435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgHybridVideoMediaChannel::~HybridVideoMediaChannel() {
465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid HybridVideoMediaChannel::SetInterface(NetworkInterface* iface) {
495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (channel1_) {
505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    channel1_->SetInterface(iface);
515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (channel2_) {
535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    channel2_->SetInterface(iface);
545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool HybridVideoMediaChannel::SetOptions(const VideoOptions &options) {
585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  bool ret = true;
595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (channel1_) {
605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ret = channel1_->SetOptions(options);
615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (channel2_ && ret) {
635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ret = channel2_->SetOptions(options);
645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return ret;
665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool HybridVideoMediaChannel::GetOptions(VideoOptions *options) const {
695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (active_channel_) {
705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return active_channel_->GetOptions(options);
715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (channel1_) {
735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return channel1_->GetOptions(options);
745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (channel2_) {
765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return channel2_->GetOptions(options);
775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return false;
795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool HybridVideoMediaChannel::SetRecvCodecs(
825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const std::vector<VideoCodec>& codecs) {
835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Only give each channel the codecs it knows about.
845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  bool ret = true;
855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::vector<VideoCodec> codecs1, codecs2;
865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SplitCodecs(codecs, &codecs1, &codecs2);
875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (channel1_) {
885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ret = channel1_->SetRecvCodecs(codecs1);
895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (channel2_ && ret) {
915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ret = channel2_->SetRecvCodecs(codecs2);
925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return ret;
945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool HybridVideoMediaChannel::SetRecvRtpHeaderExtensions(
975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const std::vector<RtpHeaderExtension>& extensions) {
985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  bool ret = true;
995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (channel1_) {
1005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ret = channel1_->SetRecvRtpHeaderExtensions(extensions);
1015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (channel2_ && ret) {
1035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ret = channel2_->SetRecvRtpHeaderExtensions(extensions);
1045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return ret;
1065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool HybridVideoMediaChannel::SetRenderer(uint32 ssrc,
1095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                          VideoRenderer* renderer) {
1105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  bool ret = true;
1115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (channel1_) {
1125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ret = channel1_->SetRenderer(ssrc, renderer);
1135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (channel2_ && ret) {
1155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ret = channel2_->SetRenderer(ssrc, renderer);
1165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return ret;
1185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool HybridVideoMediaChannel::SetRender(bool render) {
1215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  bool ret = true;
1225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (channel1_) {
1235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ret = channel1_->SetRender(render);
1245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (channel2_ && ret) {
1265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ret = channel2_->SetRender(render);
1275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return ret;
1295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool HybridVideoMediaChannel::MuteStream(uint32 ssrc, bool muted) {
1325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  bool ret = true;
1335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (channel1_) {
1345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ret = channel1_->MuteStream(ssrc, muted);
1355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (channel2_ && ret) {
1375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ret = channel2_->MuteStream(ssrc, muted);
1385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return ret;
1405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool HybridVideoMediaChannel::SetSendCodecs(
1435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const std::vector<VideoCodec>& codecs) {
1445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Use the input to this function to decide what impl we're going to use.
1455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (!active_channel_ && !SelectActiveChannel(codecs)) {
1465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    LOG(LS_WARNING) << "Failed to select active channel";
1475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return false;
1485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Only give the active channel the codecs it knows about.
1505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::vector<VideoCodec> codecs1, codecs2;
1515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SplitCodecs(codecs, &codecs1, &codecs2);
1525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  const std::vector<VideoCodec>& codecs_to_set =
1535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      (active_channel_ == channel1_.get()) ? codecs1 : codecs2;
1545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  bool return_value = active_channel_->SetSendCodecs(codecs_to_set);
1555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (!return_value) {
1565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return false;
1575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  VideoCodec send_codec;
1595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return_value = active_channel_->GetSendCodec(&send_codec);
1605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (!return_value) {
1615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return false;
1625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  engine_->OnNewSendResolution(send_codec.width, send_codec.height);
1645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  active_channel_->UpdateAspectRatio(send_codec.width, send_codec.height);
1655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return true;
1665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool HybridVideoMediaChannel::GetSendCodec(VideoCodec* send_codec) {
1695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (!active_channel_) {
1705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return false;
1715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return active_channel_->GetSendCodec(send_codec);
1735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool HybridVideoMediaChannel::SetSendStreamFormat(uint32 ssrc,
1765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                                  const VideoFormat& format) {
1775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return active_channel_ && active_channel_->SetSendStreamFormat(ssrc, format);
1785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool HybridVideoMediaChannel::SetSendRtpHeaderExtensions(
1815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const std::vector<RtpHeaderExtension>& extensions) {
1825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return active_channel_ &&
1835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      active_channel_->SetSendRtpHeaderExtensions(extensions);
1845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool HybridVideoMediaChannel::SetSendBandwidth(bool autobw, int bps) {
1875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return active_channel_ &&
1885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      active_channel_->SetSendBandwidth(autobw, bps);
1895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool HybridVideoMediaChannel::SetSend(bool send) {
1925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (send == sending()) {
1935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return true;  // no action required if already set.
1945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  bool ret = active_channel_ &&
1975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      active_channel_->SetSend(send);
1985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Returns error and don't connect the signal if starting up.
2005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Disconnects the signal anyway if shutting down.
2015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (ret || !send) {
2025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // TODO(juberti): Remove this hack that connects the WebRTC channel
2035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // to the capturer.
2045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (active_channel_ == channel1_.get()) {
2055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      engine_->OnSendChange1(channel1_.get(), send);
2065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    } else {
2075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      engine_->OnSendChange2(channel2_.get(), send);
2085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
2095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // If succeeded, remember the state as is.
2105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // If failed to open, sending_ should be false.
2115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // If failed to stop, sending_ should also be false, as we disconnect the
2125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // capture anyway.
2135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // The failure on SetSend(false) is a known issue in webrtc.
2145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    sending_ = send;
2155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
2165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return ret;
2175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool HybridVideoMediaChannel::SetCapturer(uint32 ssrc,
2205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                          VideoCapturer* capturer) {
2215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  bool ret = true;
2225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (channel1_.get()) {
2235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ret = channel1_->SetCapturer(ssrc, capturer);
2245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
2255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (channel2_.get() && ret) {
2265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ret = channel2_->SetCapturer(ssrc, capturer);
2275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
2285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return ret;
2295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool HybridVideoMediaChannel::AddSendStream(const StreamParams& sp) {
2325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  bool ret = true;
2335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (channel1_) {
2345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ret = channel1_->AddSendStream(sp);
2355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
2365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (channel2_ && ret) {
2375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ret = channel2_->AddSendStream(sp);
2385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
2395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return ret;
2405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool HybridVideoMediaChannel::RemoveSendStream(uint32 ssrc) {
2435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  bool ret = true;
2445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (channel1_) {
2455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ret = channel1_->RemoveSendStream(ssrc);
2465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
2475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (channel2_ && ret) {
2485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ret = channel2_->RemoveSendStream(ssrc);
2495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
2505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return ret;
2515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool HybridVideoMediaChannel::AddRecvStream(const StreamParams& sp) {
2545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return active_channel_ &&
2555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      active_channel_->AddRecvStream(sp);
2565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool HybridVideoMediaChannel::RemoveRecvStream(uint32 ssrc) {
2595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return active_channel_ &&
2605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      active_channel_->RemoveRecvStream(ssrc);
2615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool HybridVideoMediaChannel::SendIntraFrame() {
2645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return active_channel_ &&
2655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      active_channel_->SendIntraFrame();
2665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool HybridVideoMediaChannel::RequestIntraFrame() {
2695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return active_channel_ &&
2705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      active_channel_->RequestIntraFrame();
2715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool HybridVideoMediaChannel::GetStats(VideoMediaInfo* info) {
2745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // TODO(juberti): Ensure that returning no stats until SetSendCodecs is OK.
2755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return active_channel_ &&
2765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      active_channel_->GetStats(info);
2775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
279d3ecbb30dc2684653d61e8ec88a5382aecf62773wu@webrtc.orgvoid HybridVideoMediaChannel::OnPacketReceived(
280d3ecbb30dc2684653d61e8ec88a5382aecf62773wu@webrtc.org    talk_base::Buffer* packet, const talk_base::PacketTime& packet_time) {
2815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Eat packets until we have an active channel;
2825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (active_channel_) {
283d3ecbb30dc2684653d61e8ec88a5382aecf62773wu@webrtc.org    active_channel_->OnPacketReceived(packet, packet_time);
2845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  } else {
2855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    LOG(LS_INFO) << "HybridVideoChannel: Eating early RTP packet";
2865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
2875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
289d3ecbb30dc2684653d61e8ec88a5382aecf62773wu@webrtc.orgvoid HybridVideoMediaChannel::OnRtcpReceived(
290d3ecbb30dc2684653d61e8ec88a5382aecf62773wu@webrtc.org    talk_base::Buffer* packet, const talk_base::PacketTime& packet_time) {
2915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Eat packets until we have an active channel;
2925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (active_channel_) {
293d3ecbb30dc2684653d61e8ec88a5382aecf62773wu@webrtc.org    active_channel_->OnRtcpReceived(packet, packet_time);
2945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  } else {
2955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    LOG(LS_INFO) << "HybridVideoChannel: Eating early RTCP packet";
2965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
2975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid HybridVideoMediaChannel::OnReadyToSend(bool ready) {
3005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (channel1_) {
3015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    channel1_->OnReadyToSend(ready);
3025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
3035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (channel2_) {
3045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    channel2_->OnReadyToSend(ready);
3055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
3065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
3075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid HybridVideoMediaChannel::UpdateAspectRatio(int ratio_w, int ratio_h) {
3095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (active_channel_) active_channel_->UpdateAspectRatio(ratio_w, ratio_h);
3105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
3115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool HybridVideoMediaChannel::SelectActiveChannel(
3135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const std::vector<VideoCodec>& codecs) {
3145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (!active_channel_ && !codecs.empty()) {
3155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (engine_->HasCodec1(codecs[0])) {
3165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      channel2_.reset();
3175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      active_channel_ = channel1_.get();
3185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    } else if (engine_->HasCodec2(codecs[0])) {
3195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      channel1_.reset();
3205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      active_channel_ = channel2_.get();
3215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
3225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
3235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (NULL == active_channel_) {
3245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return false;
3255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
3265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Connect signals from the active channel.
3275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  active_channel_->SignalMediaError.connect(
3285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      this,
3295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      &HybridVideoMediaChannel::OnMediaError);
3305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return true;
3315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
3325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid HybridVideoMediaChannel::SplitCodecs(
3345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const std::vector<VideoCodec>& codecs,
3355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::vector<VideoCodec>* codecs1, std::vector<VideoCodec>* codecs2) {
3365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  codecs1->clear();
3375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  codecs2->clear();
3385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  for (size_t i = 0; i < codecs.size(); ++i) {
3395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (engine_->HasCodec1(codecs[i])) {
3405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      codecs1->push_back(codecs[i]);
3415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
3425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (engine_->HasCodec2(codecs[i])) {
3435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      codecs2->push_back(codecs[i]);
3445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
3455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
3465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
3475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid HybridVideoMediaChannel::OnMediaError(uint32 ssrc, Error error) {
3495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SignalMediaError(ssrc, error);
3505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
3515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}  // namespace cricket
353