/*
 *  Copyright (c) 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.
 */

/*
 * video_processing.h
 * This header file contains the API required for the video
 * processing module class.
 */


#ifndef WEBRTC_MODULES_INTERFACE_VIDEO_PROCESSING_H
#define WEBRTC_MODULES_INTERFACE_VIDEO_PROCESSING_H

#include "webrtc/modules/interface/module.h"
#include "webrtc/modules/interface/module_common_types.h"
#include "webrtc/modules/video_processing/main/interface/video_processing_defines.h"
#include "webrtc/video_frame.h"

/**
   The module is largely intended to process video streams, except functionality
   provided by static functions which operate independent of previous frames. It
   is recommended, but not required that a unique instance be used for each
   concurrently processed stream. Similarly, it is recommended to call Reset()
   before switching to a new stream, but this is not absolutely required.

   The module provides basic thread safety by permitting only a single function
   to execute concurrently.
*/

namespace webrtc {

class VideoProcessingModule : public Module {
 public:
  /**
     Structure to hold frame statistics. Populate it with GetFrameStats().
  */
  struct FrameStats {
      FrameStats() :
          mean(0),
          sum(0),
          num_pixels(0),
          subSamplWidth(0),
          subSamplHeight(0) {
    memset(hist, 0, sizeof(hist));
  }

  uint32_t hist[256];       // FRame histogram.
  uint32_t mean;            // Frame Mean value.
  uint32_t sum;             // Sum of frame.
  uint32_t num_pixels;       // Number of pixels.
  uint8_t  subSamplWidth;   // Subsampling rate of width in powers of 2.
  uint8_t  subSamplHeight;  // Subsampling rate of height in powers of 2.
};

  /**
     Specifies the warning types returned by BrightnessDetection().
  */
  enum BrightnessWarning {
    kNoWarning,     // Frame has acceptable brightness.
    kDarkWarning,   // Frame is too dark.
    kBrightWarning  // Frame is too bright.
  };

  /*
     Creates a VPM object.

     \param[in] id
         Unique identifier of this object.

     \return Pointer to a VPM object.
  */
  static VideoProcessingModule* Create();

  /**
     Destroys a VPM object.

     \param[in] module
         Pointer to the VPM object to destroy.
  */
  static void Destroy(VideoProcessingModule* module);

  /**
     Not supported.
  */
  int64_t TimeUntilNextProcess() override { return -1; }

  /**
     Not supported.
  */
  int32_t Process() override { return -1; }

  /**
     Resets all processing components to their initial states. This should be
     called whenever a new video stream is started.
  */
  virtual void Reset() = 0;

  /**
     Retrieves statistics for the input frame. This function must be used to
     prepare a FrameStats struct for use in certain VPM functions.

     \param[out] stats
         The frame statistics will be stored here on return.

     \param[in]  frame
         Reference to the video frame.

     \return 0 on success, -1 on failure.
  */
  static int32_t GetFrameStats(FrameStats* stats, const VideoFrame& frame);

  /**
     Checks the validity of a FrameStats struct. Currently, valid implies only
     that is had changed from its initialized state.

     \param[in] stats
         Frame statistics.

     \return True on valid stats, false on invalid stats.
  */
  static bool ValidFrameStats(const FrameStats& stats);

  /**
     Returns a FrameStats struct to its intialized state.

     \param[in,out] stats
         Frame statistics.
  */
  static void ClearFrameStats(FrameStats* stats);

  /**
     Increases/decreases the luminance value.

     \param[in,out] frame
         Pointer to the video frame.

    \param[in] delta
         The amount to change the chrominance value of every single pixel.
         Can be < 0 also.

     \return 0 on success, -1 on failure.
  */
  static int32_t Brighten(VideoFrame* frame, int delta);

  /**
     Detects and removes camera flicker from a video stream. Every frame from
     the stream must be passed in. A frame will only be altered if flicker has
     been detected. Has a fixed-point implementation.

     \param[in,out] frame
         Pointer to the video frame.

     \param[in,out] stats
         Frame statistics provided by GetFrameStats(). On return the stats will
         be reset to zero if the frame was altered. Call GetFrameStats() again
         if the statistics for the altered frame are required.

     \return 0 on success, -1 on failure.
  */
  virtual int32_t Deflickering(VideoFrame* frame, FrameStats* stats) = 0;

  /**
     Detects if a video frame is excessively bright or dark. Returns a
     warning if this is the case. Multiple frames should be passed in before
     expecting a warning. Has a floating-point implementation.

     \param[in] frame
         Pointer to the video frame.

     \param[in] stats
         Frame statistics provided by GetFrameStats().

     \return A member of BrightnessWarning on success, -1 on error
  */
  virtual int32_t BrightnessDetection(const VideoFrame& frame,
                                      const FrameStats& stats) = 0;

  /**
  The following functions refer to the pre-processor unit within VPM. The
  pre-processor perfoms spatial/temporal decimation and content analysis on
  the frames prior to encoding.
  */

  /**
  Enable/disable temporal decimation

  \param[in] enable when true, temporal decimation is enabled
  */
  virtual void EnableTemporalDecimation(bool enable) = 0;

  /**
 Set target resolution

 \param[in] width
 Target width

 \param[in] height
 Target height

  \param[in] frame_rate
  Target frame_rate

  \return VPM_OK on success, a negative value on error (see error codes)

  */
  virtual int32_t SetTargetResolution(uint32_t width,
                                      uint32_t height,
                                      uint32_t frame_rate) = 0;

  virtual void SetTargetFramerate(int frame_rate) {}

  /**
  Get decimated(target) frame rate
  */
  virtual uint32_t Decimatedframe_rate() = 0;

  /**
  Get decimated(target) frame width
  */
  virtual uint32_t DecimatedWidth() const = 0;

  /**
  Get decimated(target) frame height
  */
  virtual uint32_t DecimatedHeight() const = 0 ;

  /**
  Set the spatial resampling settings of the VPM: The resampler may either be
  disabled or one of the following:
  scaling to a close to target dimension followed by crop/pad

  \param[in] resampling_mode
  Set resampling mode (a member of VideoFrameResampling)
  */
  virtual void SetInputFrameResampleMode(VideoFrameResampling
                                         resampling_mode) = 0;

  /**
  Get Processed (decimated) frame

  \param[in] frame pointer to the video frame.
  \param[in] processed_frame pointer (double) to the processed frame. If no
             processing is required, processed_frame will be NULL.

  \return VPM_OK on success, a negative value on error (see error codes)
  */
  virtual int32_t PreprocessFrame(const VideoFrame& frame,
                                  VideoFrame** processed_frame) = 0;

  /**
  Return content metrics for the last processed frame
  */
  virtual VideoContentMetrics* ContentMetrics() const = 0 ;

  /**
  Enable content analysis
  */
  virtual void EnableContentAnalysis(bool enable) = 0;
};

}  // namespace webrtc

#endif  // WEBRTC_MODULES_INTERFACE_VIDEO_PROCESSING_H
