/** begin streaming to server - MUST run on VcThread */
  void doPublish(VideoStreamsView view) {
    if (mVideoCapturer != null) {
      return;
    }

    MediaConstraints videoConstraints = new MediaConstraints();
    videoConstraints.mandatory.add(new MediaConstraints.KeyValuePair("maxWidth", "320"));
    videoConstraints.mandatory.add(new MediaConstraints.KeyValuePair("maxHeight", "240"));
    videoConstraints.mandatory.add(new MediaConstraints.KeyValuePair("maxFrameRate", "10"));
    MediaConstraints audioConstraints = new MediaConstraints();
    audioConstraints.optional.add(
        new MediaConstraints.KeyValuePair("googEchoCancellation2", "true"));
    audioConstraints.optional.add(
        new MediaConstraints.KeyValuePair("googNoiseSuppression", "true"));
    lMS = sFactory.createLocalMediaStream("ARDAMS");

    if (videoConstraints != null) {
      mVideoCapturer = getVideoCapturer();
      mVideoSource = sFactory.createVideoSource(mVideoCapturer, videoConstraints);
      VideoTrack videoTrack = sFactory.createVideoTrack("ARDAMSv0", mVideoSource);
      lMS.addTrack(videoTrack);
    }
    if (audioConstraints != null) {
      AudioTrack audioTrack =
          sFactory.createAudioTrack("ARDAMSa0", sFactory.createAudioSource(audioConstraints));
      lMS.addTrack(audioTrack);
      audioTrack.setEnabled(false);
    }

    StreamDescription stream = new StreamDescription("", false, true, true, false, null, mNick);
    MediaConstraints pcConstraints = makePcConstraints();
    MyPcObserver pcObs = new MyPcObserver(new LicodeSdpObserver(stream, true), stream);

    PeerConnection pc = sFactory.createPeerConnection(mIceServers, pcConstraints, pcObs);
    pc.addStream(lMS, new MediaConstraints());

    stream.setMedia(lMS);
    if (view != null) {
      stream.attachRenderer(new VideoCallbacks(view, VideoStreamsView.LOCAL_STREAM_ID));
    }
    stream.initLocal(pc, pcObs.getSdpObserver());
  }
  void doSubscribe(final StreamDescription stream) {
    if (stream.isLocal()) {
      return;
    }

    if (stream.getMedia() != null) {
      // already subscribed!
      triggerMediaAvailable(stream);
      return;
    }

    // Uncomment to get ALL WebRTC tracing and SENSITIVE libjingle logging.
    // NOTE: this _must_ happen while |factory| is alive!
    // Logging.enableTracing("logcat:",
    // EnumSet.of(Logging.TraceLevel.TRACE_ALL),
    // Logging.Severity.LS_SENSITIVE);

    MyPcObserver pcObs = new MyPcObserver(new LicodeSdpObserver(stream, false), stream);
    PeerConnection pc = sFactory.createPeerConnection(mIceServers, makePcConstraints(), pcObs);

    stream.initRemote(pc, pcObs.getSdpObserver());
  }