/* Network-Integrated Multimedia Middleware (NMM)
 * http://www.motama.com/nmm.html
 *  
 * Copyright (C) 2006-2007
 * Motama GmbH, Saarbruecken, Germany
 * http://www.motama.com
 *  
 * This file is part of NMM. 
 * 
 * NMM is free software; you can redistribute it and/or modify it    
 * under the terms of the GNU General Public License as published by 
 * the Free Software Foundation; only version 2 of the License.      
 * 
 * NMM is distributed in the hope that it will be useful, but WITHOUT 
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 
 * License for more details.  
 * 
 * You should have received a copy of the GNU General Public License 
 * along with NMM; if not, write to the Free Software Foundation,    
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */



#ifndef _NMM_VIDEOSCALERNODE_HPP_
#define _NMM_VIDEOSCALERNODE_HPP_ _NMM_VIDEOSCALERNODE_HPP_

#include "nmm/nmm_prefix.hpp"

#include "nmm/multimedia/GenericProcessorNode.hpp"
#include "VideoScaler.hpp"
#include "IScalerImpl.hpp"

#include "visibility_VideoScalerNode.hpp"
namespace NMM {
  
  /**
   * Video scaler node.
   * Scales YUV12 video frames of a given input format to the given output format.
   *
   * The scaler has two modes of operation. The keep_aspect_ratio event is used to switch between both modes.
   *
   * If (keep_aspect_ratio == false), the output resolution is set explicitly. Typically it is set by specifying
   * a format when connecting the nodes. It can also be set through the IScaler interface explicitely.
   * If the input resolution or aspect ratio changes, the output resolution is not affected.
   *
   * If (keep_aspect_ratio == true), the output resolution is calculated from the input resolution and aspect ratio.
   * The input resolution can be changed by sending a resolution_changed event. The aspect ratio is set by the
   * aspect_ratio event.
   * The output resolution is recalculated whenever the input resolution or the aspect ratio is changed.
   */
  class DLLEXPORT VideoScalerNode :
    public GenericProcessorNode,
    public IScalerImpl
  {  
  private:
    bool keep_aspect_ratio;
    bool send_format;
    int ratio_x;
    int ratio_y;
    string channelorder;
    string colorspace;
    string endian;
    string format;
    int bitperpixel;
    float framerate;
    Buffer* saved_buffer;
    
    VideoScaler scaler;
    
    void reaspect();
    void getAspectCorrection(int *w, int *h, int ratio_x, int ratio_y);
    
    /**
     * Setup output format.
     * Sets up the working input/output properties based on the given input format.
     * This is called from doInitOutput and in format changes.
     */
    Result setupOutputFormat(const Format* in_format);
    
  protected:
    virtual Message* processBuffer(Buffer* in_buffer);
    
    virtual Result doInit();
    virtual Result doDeinit();
    virtual Result doInitOutput();
    virtual Result doDeinitOutput();
    virtual Result doActivate();

    // BEGIN> IScaler interface
    /**
     * Set auto aspect mode.
     * If the flag is set, the output resolution is calculated from both the input resolution and the aspect ratio
     * whenever the resolution or aspect ratio changes.
     *
     * If the flag is not set, the output resolution is set to match the input resolution whenever the input resolution
     * changes.
     *
     * You can also set this flag by sending a keep_aspect_ratio event.
     */
    void setAutoAspect(const nmm_bool& value);

    /**
     * Get auto aspect mode.
     */
    nmm_bool getAutoAspect() const;
    
    /**
     * Set output size.
     * Forces the output size to the given value.
     * In auto aspect mode, the output size changes if the input size or aspect ratio changes.
     */
    void setOutputSize(const nmm_int32& w, const nmm_int32& h);
    
    /**
     * Get output size.
     * Returns the current output size of the scaler
     */
    void getOutputSize(nmm_int32& w, nmm_int32& h) const;
    
    /**
     * Enable or disable filtering.
     * Enables bilinear filtering when the output resolution is greater than the input resolution.
     * Currently broken. Do not use.
     */
    void setFiltering(const nmm_bool& filtering);

    /**
     * Get filtering mode.
     */
    nmm_bool getFiltering() const;
    // END< IScaler interface
    
    /**
     * Format change: do-method
     */
    Result doSetFormat(const Format& format);
    
  public:
    VideoScalerNode(const char *name = "VideoScalerNode",
		    const StreamQueue::Mode queue_mode = StreamQueue::MODE_SUSPEND, 
		    const int queue_size = 1 );
    ~VideoScalerNode();
  }; 
}

#include "nmm/nmm_suffix.hpp"

#endif // _NMM_VIDEOSCALERNODE_HPP_
