/*
 * libjingle
 * Copyright 2004--2011, Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef TALK_SESSION_PHONE_WEBRTCVIDEOENGINE_H_
#define TALK_SESSION_PHONE_WEBRTCVIDEOENGINE_H_

#include <map>
#include <vector>

#include "talk/base/scoped_ptr.h"
#include "talk/session/phone/videocommon.h"
#include "talk/session/phone/codec.h"
#include "talk/session/phone/channel.h"
#include "talk/session/phone/webrtccommon.h"
#ifdef WEBRTC_RELATIVE_PATH
#include "video_engine/include/vie_base.h"
#else
#include "third_party/webrtc/files/include/vie_base.h"
#endif  // WEBRTC_RELATIVE_PATH

namespace webrtc {
class VideoCaptureModule;
class VideoRender;
class ViEExternalCapture;
}

namespace cricket {
struct CapturedFrame;
class WebRtcVideoChannelInfo;
struct Device;
class WebRtcLocalStreamInfo;
class VideoCapturer;
class VideoFrame;
class VideoProcessor;
class VideoRenderer;
class ViETraceWrapper;
class ViEWrapper;
class VoiceMediaChannel;
class WebRtcRenderAdapter;
class WebRtcVideoMediaChannel;
class WebRtcVoiceEngine;
class WebRtcDecoderObserver;
class WebRtcEncoderObserver;

class WebRtcVideoEngine : public sigslot::has_slots<>,
                          public webrtc::ViEBaseObserver,
                          public webrtc::TraceCallback {
 public:
  // Creates the WebRtcVideoEngine with internal VideoCaptureModule.
  WebRtcVideoEngine();
  // For testing purposes. Allows the WebRtcVoiceEngine and
  // ViEWrapper to be mocks.
  // TODO: Remove the 2-arg ctor once fake tracing is implemented.
  WebRtcVideoEngine(WebRtcVoiceEngine* voice_engine,
                    ViEWrapper* vie_wrapper);
  WebRtcVideoEngine(WebRtcVoiceEngine* voice_engine,
                    ViEWrapper* vie_wrapper,
                    ViETraceWrapper* tracing);
  ~WebRtcVideoEngine();

  // Basic video engine implementation.
  bool Init();
  void Terminate();

  int GetCapabilities();
  bool SetOptions(int options);
  bool SetDefaultEncoderConfig(const VideoEncoderConfig& config);

  WebRtcVideoMediaChannel* CreateChannel(VoiceMediaChannel* voice_channel);

  const std::vector<VideoCodec>& codecs() const;
  void SetLogging(int min_sev, const char* filter);

  // Capture-related stuff. Will be removed with capture refactor.
  bool SetCaptureDevice(const Device* device);
  bool SetCaptureModule(webrtc::VideoCaptureModule* vcm);
  // If capturer is NULL, unregisters the capturer and stops capturing.
  // Otherwise sets the capturer and starts capturing.
  bool SetVideoCapturer(VideoCapturer* capturer, uint32 /*ssrc*/);
  bool SetLocalRenderer(VideoRenderer* renderer);
  CaptureResult SetCapture(bool capture);
  sigslot::repeater2<VideoCapturer*, CaptureResult> SignalCaptureResult;
  virtual VideoCapturer* CreateVideoCapturer(const Device& device);
  CaptureResult UpdateCapturingState();
  bool IsCapturing() const;
  void OnFrameCaptured(VideoCapturer* capturer, const CapturedFrame* frame);

  // Set the VoiceEngine for A/V sync. This can only be called before Init.
  bool SetVoiceEngine(WebRtcVoiceEngine* voice_engine);
  // Enable the render module with timing control.
  bool EnableTimedRender();

  bool RegisterProcessor(VideoProcessor* video_processor);
  bool UnregisterProcessor(VideoProcessor* video_processor);

  // Functions called by WebRtcVideoMediaChannel.
  ViEWrapper* vie() { return vie_wrapper_.get(); }
  const VideoFormat& default_codec_format() const {
    return default_codec_format_;
  }
  int GetLastEngineError();
  bool FindCodec(const VideoCodec& in);
  bool CanSendCodec(const VideoCodec& in, const VideoCodec& current,
                    VideoCodec* out);
  void RegisterChannel(WebRtcVideoMediaChannel* channel);
  void UnregisterChannel(WebRtcVideoMediaChannel* channel);
  void ConvertToCricketVideoCodec(const webrtc::VideoCodec& in_codec,
                                  VideoCodec*  out_codec);
  bool ConvertFromCricketVideoCodec(const VideoCodec& in_codec,
                                    webrtc::VideoCodec* out_codec);
  // Check whether the supplied trace should be ignored.
  bool ShouldIgnoreTrace(const std::string& trace);
  int GetNumOfChannels();

 protected:
  // When a video processor registers with the engine.
  // SignalMediaFrame will be invoked for every video frame.
  sigslot::signal2<uint32, VideoFrame*> SignalMediaFrame;

 private:
  typedef std::vector<WebRtcVideoMediaChannel*> VideoChannels;
  struct VideoCodecPref {
    const char* name;
    int payload_type;
    int pref;
  };

  static const VideoCodecPref kVideoCodecPrefs[];
  static const VideoFormatPod kVideoFormats[];
  static const VideoFormatPod kDefaultVideoFormat;

  void Construct(ViEWrapper* vie_wrapper,
                 ViETraceWrapper* tracing,
                 WebRtcVoiceEngine* voice_engine);
  bool SetDefaultCodec(const VideoCodec& codec);
  bool RebuildCodecList(const VideoCodec& max_codec);
  void ApplyLogging(const std::string& log_filter);
  bool InitVideoEngine();
  bool SetCapturer(VideoCapturer* capturer, bool own_capturer);

  // webrtc::ViEBaseObserver implementation.
  virtual void PerformanceAlarm(const unsigned int cpu_load);
  // webrtc::TraceCallback implementation.
  virtual void Print(const webrtc::TraceLevel level, const char* trace_string,
                     const int length);

  void ClearCapturer();

  talk_base::scoped_ptr<ViEWrapper> vie_wrapper_;
  bool vie_wrapper_base_initialized_;
  talk_base::scoped_ptr<ViETraceWrapper> tracing_;
  WebRtcVoiceEngine* voice_engine_;
  int log_level_;
  talk_base::scoped_ptr<webrtc::VideoRender> render_module_;
  std::vector<VideoCodec> video_codecs_;
  VideoFormat default_codec_format_;
  bool initialized_;
  talk_base::CriticalSection channels_crit_;
  VideoChannels channels_;

  bool owns_capturer_;
  VideoCapturer* video_capturer_;
  bool capture_started_;
  int local_renderer_w_;
  int local_renderer_h_;
  VideoRenderer* local_renderer_;

  // Critical section to protect the media processor register/unregister
  // while processing a frame
  talk_base::CriticalSection signal_media_critical_;
};

class WebRtcVideoMediaChannel : public VideoMediaChannel,
                                public webrtc::Transport {
 public:
  WebRtcVideoMediaChannel(
      WebRtcVideoEngine* engine, VoiceMediaChannel* voice_channel);
  ~WebRtcVideoMediaChannel();
  bool Init();

  WebRtcVideoEngine* engine() { return engine_; }
  VoiceMediaChannel* voice_channel() { return voice_channel_; }
  int video_channel() const { return vie_channel_; }
  bool sending() const { return sending_; }

  // VideoMediaChannel implementation
  virtual bool SetRecvCodecs(const std::vector<VideoCodec> &codecs);
  virtual bool SetSendCodecs(const std::vector<VideoCodec> &codecs);
  virtual bool SetRender(bool render);
  virtual bool SetSend(bool send);

  virtual bool AddSendStream(const StreamParams& sp);
  virtual bool RemoveSendStream(uint32 ssrc);
  virtual bool AddRecvStream(const StreamParams& sp);
  virtual bool RemoveRecvStream(uint32 ssrc);
  virtual bool SetRenderer(uint32 ssrc, VideoRenderer* renderer);
  virtual bool GetStats(VideoMediaInfo* info);
  virtual bool AddScreencast(uint32 ssrc, const ScreencastId& id) {
    return false;
  }
  virtual bool RemoveScreencast(uint32 ssrc) {
    return false;
  }
  virtual bool SendIntraFrame();
  virtual bool RequestIntraFrame();

  virtual void OnPacketReceived(talk_base::Buffer* packet);
  virtual void OnRtcpReceived(talk_base::Buffer* packet);
  virtual bool Mute(bool on);
  virtual bool SetRecvRtpHeaderExtensions(
      const std::vector<RtpHeaderExtension>& extensions) {
    return false;
  }
  virtual bool SetSendRtpHeaderExtensions(
      const std::vector<RtpHeaderExtension>& extensions) {
    return false;
  }
  virtual bool SetSendBandwidth(bool autobw, int bps);
  virtual bool SetOptions(int options);
  virtual void SetInterface(NetworkInterface* iface);

  // Public functions for use by tests and other specialized code.
  uint32 send_ssrc() const { return 0; }
  bool GetRenderer(uint32 ssrc, VideoRenderer** renderer);
  bool SendFrame(uint32 ssrc, const VideoFrame* frame);

  // Thunk functions for use with HybridVideoEngine
  void OnLocalFrame(VideoCapturer* capturer, const VideoFrame* frame) {
    SendFrame(0, frame);
  }
  void OnLocalFrameFormat(VideoCapturer* capturer, const VideoFormat* format) {
  }

 protected:
  int GetLastEngineError() { return engine()->GetLastEngineError(); }
  virtual int SendPacket(int channel, const void* data, int len);
  virtual int SendRTCPPacket(int channel, const void* data, int len);

 private:
  typedef std::map<uint32, WebRtcVideoChannelInfo*> ChannelMap;

  // Creates and initializes a WebRtc video channel.
  bool ConfigureChannel(int channel_id);
  bool ConfigureReceiving(int channel_id, uint32 remote_ssrc);
  bool SetNackFec(int channel_id, int red_payload_type, int fec_payload_type);
  bool SetSendCodec(const webrtc::VideoCodec& codec,
                    int min_bitrate,
                    int start_bitrate,
                    int max_bitrate);
  // Prepares the channel with channel id |channel_id| to receive all codecs in
  // |receive_codecs_| and start receive packets.
  bool SetReceiveCodecs(int channel_id);
  // Returns the channel number that receives the stream with SSRC |ssrc|.
  int GetChannelNum(uint32 ssrc);
  // Given captured video frame size, checks if we need to reset vie send codec.
  // |reset| is set to whether resetting has happened on vie or not.
  // Returns false on error.
  bool MaybeResetVieSendCodec(int new_width, int new_height, bool* reset);
  // Call Webrtc function to start sending media on |vie_channel_|.
  // Does not affect |sending_|.
  bool StartSend();
  // Call Webrtc function to stop sending media on |vie_channel_|.
  // Does not affect |sending_|.
  bool StopSend();

  WebRtcVideoEngine* engine_;
  VoiceMediaChannel* voice_channel_;
  int vie_channel_;
  int vie_capture_;
  webrtc::ViEExternalCapture* external_capture_;
  bool sending_;
  bool render_started_;
  bool muted_;  // Flag to tell if we need to mute video.
  // Our local SSRC. Currently only one send stream is supported.
  uint32 local_ssrc_;
  int send_min_bitrate_;
  int send_start_bitrate_;
  int send_max_bitrate_;
  talk_base::scoped_ptr<webrtc::VideoCodec> send_codec_;
  std::vector<webrtc::VideoCodec> receive_codecs_;
  talk_base::scoped_ptr<WebRtcEncoderObserver> encoder_observer_;
  talk_base::scoped_ptr<WebRtcLocalStreamInfo> local_stream_info_;
  int channel_options_;

  ChannelMap mux_channels_;  // Contains all receive channels.
};

}  // namespace cricket

#endif  // TALK_SESSION_PHONE_WEBRTCVIDEOENGINE_H_
