
/*
 *  Copyright 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef PC_PEER_CONNECTION_FACTORY_H_
#define PC_PEER_CONNECTION_FACTORY_H_

#include <stdint.h>
#include <stdio.h>

#include <memory>
#include <string>

#include "absl/strings/string_view.h"
#include "api/audio_options.h"
#include "api/environment/environment.h"
#include "api/fec_controller.h"
#include "api/field_trials_view.h"
#include "api/media_stream_interface.h"
#include "api/media_types.h"
#include "api/metronome/metronome.h"
#include "api/neteq/neteq_factory.h"
#include "api/network_state_predictor.h"
#include "api/peer_connection_interface.h"
#include "api/rtc_error.h"
#include "api/rtc_event_log/rtc_event_log_factory_interface.h"
#include "api/rtp_parameters.h"
#include "api/scoped_refptr.h"
#include "api/sequence_checker.h"
#include "api/transport/network_control.h"
#include "api/transport/sctp_transport_factory_interface.h"
#include "api/video/timing/video_jitter_timing_factory.h"
#include "call/call.h"
#include "media/base/media_engine.h"
#include "pc/codec_vendor.h"
#include "pc/connection_context.h"
#include "rtc_base/thread.h"
#include "rtc_base/thread_annotations.h"

namespace webrtc {

class PeerConnectionFactory : public PeerConnectionFactoryInterface {
 public:
  // Creates a PeerConnectionFactory. It returns nullptr on initialization
  // error.
  //
  // The Dependencies structure allows simple management of all new
  // dependencies being added to the PeerConnectionFactory.
  static scoped_refptr<PeerConnectionFactory> Create(
      PeerConnectionFactoryDependencies dependencies);

  void SetOptions(const Options& options) override;

  RTCErrorOr<scoped_refptr<PeerConnectionInterface>>
  CreatePeerConnectionOrError(
      const PeerConnectionInterface::RTCConfiguration& configuration,
      PeerConnectionDependencies dependencies) override;

  RtpCapabilities GetRtpSenderCapabilities(
      webrtc::MediaType kind) const override;

  RtpCapabilities GetRtpReceiverCapabilities(
      webrtc::MediaType kind) const override;

  scoped_refptr<MediaStreamInterface> CreateLocalMediaStream(
      const std::string& stream_id) override;

  scoped_refptr<AudioSourceInterface> CreateAudioSource(
      const AudioOptions& options) override;

  scoped_refptr<VideoTrackInterface> CreateVideoTrack(
      scoped_refptr<VideoTrackSourceInterface> video_source,
      absl::string_view id) override;

  scoped_refptr<AudioTrackInterface> CreateAudioTrack(
      const std::string& id,
      AudioSourceInterface* audio_source) override;

  bool StartAecDump(FILE* file, int64_t max_size_bytes) override;
  void StopAecDump() override;

  SctpTransportFactoryInterface* sctp_transport_factory() {
    return context_->sctp_transport_factory();
  }

  Thread* signaling_thread() const {
    // This method can be called on a different thread when the factory is
    // created in CreatePeerConnectionFactory().
    return context_->signaling_thread();
  }

  Thread* worker_thread() const { return context_->worker_thread(); }

  const Options& options() const {
    RTC_DCHECK_RUN_ON(signaling_thread());
    return options_;
  }

  const FieldTrialsView& field_trials() const { return env_.field_trials(); }

  const MediaEngineInterface* media_engine() const;
  CodecVendor& CodecVendorForTesting() { return codec_vendor_; }

 protected:
  // Constructor used by the static Create() method. Modifies the dependencies.
  PeerConnectionFactory(Environment env,
                        scoped_refptr<ConnectionContext> context,
                        PeerConnectionFactoryDependencies* dependencies);

  // Constructor for use in testing. The dependencies are passed in by
  // std::move().
  explicit PeerConnectionFactory(
      PeerConnectionFactoryDependencies dependencies);

  ~PeerConnectionFactory() override;

 private:
  Thread* network_thread() const { return context_->network_thread(); }

  std::unique_ptr<Call> CreateCall_s(
      const Environment& env,
      const PeerConnectionInterface::RTCConfiguration& configuration);

  Environment env_;
  scoped_refptr<ConnectionContext> context_;
  PeerConnectionFactoryInterface::Options options_
      RTC_GUARDED_BY(signaling_thread());
  CodecVendor codec_vendor_;
  std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory_;
  std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory_;
  std::unique_ptr<NetworkStatePredictorFactoryInterface>
      network_state_predictor_factory_;
  std::unique_ptr<NetworkControllerFactoryInterface>
      injected_network_controller_factory_;
  std::unique_ptr<NetEqFactory> neteq_factory_;
  std::unique_ptr<VideoJitterTimingFactory> video_jitter_timing_factory_;
  std::unique_ptr<Metronome> decode_metronome_
      RTC_GUARDED_BY(signaling_thread());
  std::unique_ptr<Metronome> encode_metronome_
      RTC_GUARDED_BY(signaling_thread());
  // While AEC dump is ongoing, we retain a reference to the media engine.
  std::unique_ptr<ConnectionContext::MediaEngineReference> media_engine_ref_
      RTC_GUARDED_BY(worker_thread());
};

}  // namespace webrtc

#endif  // PC_PEER_CONNECTION_FACTORY_H_
