// Copyright (c) 2012 The WebM 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.
//
// Defines the video sink filter used to obtain raw frames from user input
// devices available via DirectShow. Based on WebRTC's CaptureInputPin and
// CaptureSinkFilter.
#ifndef WEBMLIVE_ENCODER_WIN_VIDEO_SINK_FILTER_H_
#define WEBMLIVE_ENCODER_WIN_VIDEO_SINK_FILTER_H_

#include <memory>

// Wrap include of streams.h with include guard used in the file: including the
// file twice results in the output "STREAMS.H included TWICE" for debug
// builds.
#ifndef __STREAMS__
#pragma warning(push)
#pragma warning(disable:4005)
// Disable C4005 via pragma
// Pragma required because streams.h includes intsafe.h, which defines
// INTSAFE_E_ARITHMETIC_OVERFLOW without an ifndef check, resulting in a
// warning that breaks our build when compiling with warnings-as-errors flag
// enabled.
#include "baseclasses/streams.h"
#pragma warning(pop)
#endif  // __STREAMS__
#include "encoder/basictypes.h"
#include "encoder/encoder_base.h"
#include "encoder/video_encoder.h"
#include "encoder/webm_encoder.h"

namespace webmlive {

// Forward declare |VideoSinkFilter| for use in |VideoSinkPin|.
class VideoSinkFilter;

// Pin class used by |VideoSinkFilter|. Accepts only I420 video input.
class VideoSinkPin : public CBaseInputPin {
 public:
  // Constructs CBaseInputPin and returns result via |ptr_result|. Returns
  // S_OK when successful.
  VideoSinkPin(TCHAR* ptr_object_name,
               VideoSinkFilter* ptr_filter,
               CCritSec* ptr_filter_lock,
               HRESULT* ptr_result,
               LPCWSTR ptr_pin_name);
  virtual ~VideoSinkPin();

  //
  // CBasePin methods
  //

  // Stores preferred media type for |type_index| in |ptr_media_type|. Supports
  // only a single type, I420.
  // Return values:
  // S_OK - success, |type_index| in range and |ptr_media_type| written.
  // VFW_S_NO_MORE_ITEMS - |type_index| != 0.
  // E_OUTOFMEMORY - could not allocate format buffer.
  virtual HRESULT GetMediaType(int32 type_index, CMediaType* ptr_media_type);

  // Checks if AM_MEDIA_TYPE stored in CMediaType pointer is acceptable.
  // Supports only MEDIASUBTYPE_I420 wrapped in VIDEOINFOHEADER or
  // VIDEOINFOHEADER2 structures.
  // Return values:
  // S_OK - |ptr_media_type| is supported.
  // E_INVALIDARG - NULL |ptr_media_type|.
  // VFW_E_TYPE_NOT_ACCEPTED - |ptr_media_type| is not supported.
  virtual HRESULT CheckMediaType(const CMediaType* ptr_media_type);

  //
  // IMemInputPin method(s).
  //

  // Receives video buffers from the upstream filter and passes them to
  // |VideoSinkFilter::OnFrameReceived|.
  // Returns S_OK, or the HRESULT error value returned CBaseInputPin::Receive
  // if it fails.
  virtual HRESULT STDMETHODCALLTYPE Receive(IMediaSample* ptr_sample);

 private:
  // Copies |actual_config_| to |ptr_config| and returns S_OK. Returns
  // E_POINTER when |ptr_config| is NULL.
  HRESULT config(VideoConfig* ptr_config) const;

  // Resets |actual_config_| and copies |config| values to |requested_config_|,
  // then returns S_OK.
  HRESULT set_config(const VideoConfig& config);

  // Returns true when |media_sub_type| is an acceptable video format.
  bool AcceptableSubType(const GUID& media_sub_type);

  // Filter user's requested video config.
  VideoConfig requested_config_;

  // Actual video config (from upstream filter).
  VideoConfig actual_config_;
  WEBMLIVE_DISALLOW_COPY_AND_ASSIGN(VideoSinkPin);

  // |VideoSinkFilter| requires access to private member |actual_config_|, and
  // private methods |config| and |set_config| for configuration retrieval and
  // control.
  friend class VideoSinkFilter;
};

// Video sink filter class. Receives I420 video frames from upstream
// DirectShow filter via |VideoSinkPin|.
class VideoSinkFilter : public CBaseFilter {
 public:
  // Stores |ptr_frame_callback|, constructs CBaseFilter and |VideoSinkPin, and
  // returns result via |ptr_result|.
  // Return values:
  // S_OK - success.
  // E_INVALIDARG - |ptr_Frame_callback| is NULL.
  // E_OUTOFMEMORY - cannot construct |sink_pin_|.
  VideoSinkFilter(const TCHAR* ptr_filter_name,
                  LPUNKNOWN ptr_iunknown,
                  VideoFrameCallbackInterface* ptr_frame_callback,
                  HRESULT* ptr_result);
  virtual ~VideoSinkFilter();

  // Copies actual video configuration to |ptr_config| and returns S_OK.
  HRESULT config(VideoConfig* ptr_config) const;

  // Sets actual requested video configuration and returns S_OK.
  HRESULT set_config(const VideoConfig& config);

  // IUnknown
  DECLARE_IUNKNOWN;

  // CBaseFilter methods
  virtual int GetPinCount() { return 1; }

  // Returns the pin at |index|, or NULL. The value of |index| must be 0.
  virtual CBasePin* GetPin(int index);

 private:
  // Copes video frame from |ptr_sample| to |frame_|, and passes |frame_| to
  // |VideoFrameCallbackInterface::OnVideoFrameReceived| for processing.
  // Returns S_OK when successful.
  HRESULT OnFrameReceived(IMediaSample* ptr_sample);
  mutable CCritSec filter_lock_;
  VideoFrame frame_;
  std::unique_ptr<VideoSinkPin> sink_pin_;
  VideoFrameCallbackInterface* ptr_frame_callback_;
  WEBMLIVE_DISALLOW_COPY_AND_ASSIGN(VideoSinkFilter);

  // |VideoSinkPin| requires access to private member |filter_lock_|, and
  // private method |OnFrameReceived| to lock the filter and safely deliver
  // video frame buffers.
  friend class VideoSinkPin;
};

}  // namespace webmlive

#endif  // WEBMLIVE_ENCODER_WIN_VIDEO_SINK_FILTER_H_
