#ifndef PHSTBDFB_LOCAL_H    /* Multi-include protection.   <FILENAME>_H */
#define PHSTBDFB_LOCAL_H


/*****************************************************************************/
/* Copyright (c) 2009 NXP B.V.                                               */
/*                                                                           */
/* This library is free software; you can redistribute it and/or             */
/* modify it under the terms of the GNU Lesser General Public                */
/* License as published by the Free Software Foundation, using               */
/* version 2.1 of the License.                                               */
/*                                                                           */
/* This library 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          */
/* Lesser General Public License for more details.                           */
/*                                                                           */
/* You should have received a copy of the GNU Lesser General Public          */
/* License along with this library; if not, write to the Free Software       */
/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA   */
/*                                                                           */
/*****************************************************************************/
/**
    @file   phStbDFB_Local.h
    @brief  Module local header file for DirectFB graphics driver.

@b  Component:  phStbDFB.

*//*

Rev Date        Author      Comments
--------------------------------------------------------------------------------
  1 20050712    batelaan    Original
  2 20050713    batelaan    Crosscheck fixes
  3 20050714    laird       Removing useless structure values.
  4 20050718    laird       Different func lookup tables for GFX and Video Layers.
  5 20050719    laird       Adding fbdev support
  6 20050823    charrett    Reorganise the code, add function prototypes
  7 20050824    charrett    Remove phStbDFB_GetLayerId and rename multi inclusion protection
  8 20050826    charrett    Add device data structure to store information on all layers
  9 20050831    laird       Adding support for all 5 QVCP layers
 10 20050809    laird       Common layerInit code.
 11 20050912    charrett    Add HW Acceleration functions and device data
 12 20050913    laird       Change Layer Ordering etc
 13 20050921    laird       Updates to layer data type.
 14 20051003    laird       Adding extra DLOP type
 15 20051003    laird       Supporting brightness range (0-1023)
 16 20051005    laird       Store CoreLayer in structure.
 17 20051017    laird       Adding support for extra pixel formats.
 18 20051103    laird       Adding support for HD
 19 20051124    laird       Adding more comments.
 20 20051129    laird       Adding MMIO support macros.
 21 20051201    laird       Added supported config flags for output.
 22 20051208    laird       removing the miniumum size define.
 23 20060308    neill       Add support for PAL60
 23 20060328    mpage       Adding Layer Show
 24 20060621    laird       Adding Video Denc support.
 25 20060630    laird       XCheck fix.
 26 20060630    laird       Xcheck rework.
 27 20060704    laird       Changing Encoder / output caps.
 28 20060710    neill       Add support for 1280x720p
28.1.1 20060617 laird       Removing layer show option.
 29 20060714    laird       Adding support for connectors in video denc framework.
 30 20060717    laird       Merged 'phStbDFB_Local.h=29' with 'phStbDFB_Local.h=28.1.1'.
30.1.1 20060725 neill       Add support for HDMI output signals
 31 20060725    laird       More encoder work.
 32 20060726    laird       Fix checkout bug.
 33 20060726    neill       Change SCART switch to AK470X
 34 20060727    laird       Removing Asserts.
----------------------------STB225----------------------------------------------
 33 20070109    laird       Moving to STB225.
 34 20070116    laird       Crosscheck Rework.
 35 20070117    steel       update for 2.6.19.1 AGAIN!
 36 20070124    neill       Remove compile time warnings
 37 20070308    neill       Add LCD to layers
 38 20070619    neill       Create LCD as separate screen
 39 20070723    neill       Add gamma correction adjustment
 40 20070913    neill       Allow display frequency and scanmode to be configured
 41 20071017    burningh    Fix QA C coverage errors
 42 20071029    burningh    Improve QA C cofidence factor
 43 20071107    neill       Add macrovision support
 44 20071122    neill       Add CGMS support
 45 20080107    neill       Add WSS support
 46 20081022    legendrd    Add UDA3000
 46 20080805    neill       Add VGA support
 46 20080807    laird       Remove unneeded function prototypes.
 47 20080808    laird       Merged from 'phStbDFB_Local.h-SOUsb225#46:incl:ipstb#1' and 'phStbDFB_Local.h-SOUsb225#45.1.1:incl:ipstb#1' by laird.
 48 20081111    steel       add stretch blit.
 49 20081119    neill       improve stretch blit initialisation.
 50 20081209    laird       Merged from 'phStbDFB_Local.h-SOUsb225#49:incl:ipstb#1' and 'phStbDFB_Local.h-CFR_STB#46:incl:ipstb#1' by laird.
 51 20090120    batelaan    Update file copyright/license text
 52 20090218    neill       Correct conversion macro defaults
--------------------------------------------------------------------------------
    For consistency and standardisation retain the Section Separators.
*/


/*******************
* INCLUDE FILES    *
********************/

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
/*Must be included before directfb.h due to bool nonsense*/
#include <tmCompId.h>

#include <phStbCommon.h>

#include <linux/fb.h>
#include <linux/videodenc.h>

#include <asm/page.h>

#include <sys/mman.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <malloc.h>
#include <errno.h>

#include <directfb.h>

#include <direct/debug.h>
#include <direct/messages.h>

#include <dfb_types.h>

#include <core/coredefs.h>
#include <core/coretypes.h>

#include <core/gfxcard.h>
#include <core/state.h>
#include <core/gfxcard.h>
#include <core/surfaces.h>
#include <core/palette.h>
#include <core/layers.h>
#include <core/layers_internal.h>  // to obtain screen from a CoreLayer
#include <core/screens.h>
#include <core/screens_internal.h> // to obtain screen_data from a CoreScreen

#include <gfx/util.h>

#include <misc/conf.h>
#include <misc/util.h>

#include <phStbDbg.h>
#include <phStbDFB.h>
#include <phStbVideoRenderer.h>
#include <phStbStreamingSystem_Server.h>
#include <phStbDraw.h>
#include <phStbVideoTypes.h>
#include <prjconfig.h>

#ifdef CONFIG_SCART_AK470X
#include <ak470x.h>
#elif CONFIG_SCART_UDA3000
#include <phStbScartSwitch.h>
#endif

/**************************************************************************
* EXPORTED MACROS                               PH_STBDFB_<_WORD>+        *
***************************************************************************/
#define PAGE_SIZE (size_t)sysconf(_SC_PAGESIZE)
#define PAGE_MASK (size_t)(~(PAGE_SIZE - 1))
/** to align the pointer to the (next) page boundary */
#define PAGE_ALIGN(addr)	(size_t)(((addr) + PAGE_SIZE - 1) & PAGE_MASK)

/** Number of bits to shift a DFB color adjustment value (range 16 bits)
    to a phStbVideoRenderer value (0-255). */
#define DFB2VIDEORENDERER_COLOR_ADJ_SHIFT 8U

/** Number of bits to shift a DFB brightness adjustment value (range 16 bits)
    to a phStbVideoRenderer brightness value (0-255). */
#define DFB2VIDEORENDERER_BRIGHTNESS_ADJ_SHIFT 8U

/**
 * Define the GFX layer IDs and video layers on each screen
 *
 * The DirectFB Layer numbers are counted from the TV screen back i.e
 *
 * TV  |       |       |       |       |
 *     |   0   |   1   |   2   |   3   |
 *     |  OSD  | Image |  PiP  | Video |
 *
 * LCD                                 |       |
 *                                     |   4   |
 *                                     | Panel |
 */
#define PH_STBDFB_SCREEN_MAIN_GRAPHICS1 0
#define PH_STBDFB_SCREEN_MAIN_GRAPHICS2 1
#define PH_STBDFB_SCREEN_MAIN_DISPLAY1  2
#define PH_STBDFB_SCREEN_MAIN_DISPLAY2  3
#define PH_STBDFB_SCREEN_MAIN_LCD       4

/**
 * Define the screen IDS as an enum
 */
typedef enum
{
    PH_STBDFB_SCREEN_MAIN = DSCID_PRIMARY,
    PH_STBDFB_SCREEN_LCD = 1
} phStbDfb_ScreenID;

/** Total number of layers that we make known to DFB. */
#define PH_STBDFB_NUM_LAYERS_USED 5U

/** Supported Display Layer Options */
#define PH_STBDFB_DLOP_SUPPORTED (DLOP_ALPHACHANNEL | DLOP_OPACITY | DLOP_FLICKER_FILTERING )

/** default Display Layer Options */
#define PH_STBDFB_DEFAULT_DLOP_SUPPORTED (DLOP_ALPHACHANNEL | DLOP_OPACITY)

#define PH_STBDFB_SUPPORTED_DRAWINGFLAGS      (DSDRAW_BLEND)

#define PH_STBDFB_SUPPORTED_DRAWINGFUNCTIONS  (DFXL_FILLRECTANGLE)

#define PH_STBDFB_SUPPORTED_BLITTINGFLAGS     (DSBLIT_SRC_COLORKEY       |  \
                                               DSBLIT_DST_COLORKEY       |  \
                                               DSBLIT_BLEND_ALPHACHANNEL |  \
                                               DSBLIT_BLEND_COLORALPHA   |  \
                                               DSBLIT_COLORIZE           |  \
                                               DSBLIT_SRC_PREMULTIPLY)

#define PH_STBDFB_SUPPORTED_BLITTINGFUNCTIONS (DFXL_BLIT)

#define PH_STBDFB_SUPPORTED_STRETCHFUNCTIONS  (DFXL_STRETCHBLIT)

/**
 * @brief Describe the Screen capabilities.
 */
#define PH_STBDFB_SCREEN_CAPABILITIES         (DSCCAPS_MIXERS)

/**
 * @brief Describe the Mixer capabilities.
 */
#define PH_STBDFB_SCREEN_MIXERS_CAPABILITIES  (DSMCAPS_SUB_LAYERS | \
                                               DSMCAPS_BACKGROUND)

/**
 * @brief Describe the Output capabilities.
 *
 * Outputs now juts output a 656 stream to the encoders.
 */
#define PH_STBDFB_SCREEN_OUTPUT_CAPABILITIES  (DSOCAPS_NONE)

/**
 * @brief Describe the output config flags that are supported by our outputs.
 */
#define PH_STBDFB_SCREEN_OUTPUT_CONFIGFLAGS     ( DSOCONF_SIGNALS    | \
                                                  DSOCONF_CONNECTORS | \
                                                  DSOCONF_SLOW_BLANKING )

/**
 * @brief Describe the Encoder(stb225) capabilities.
 */
#define PH_STBDFB_MAIN_SCREEN_ENCODER_CAPABILITIES    ( DSECAPS_TV_STANDARDS | \
                                                        DSECAPS_CONNECTORS |   \
                                                        DSECAPS_SLOW_BLANKING |\
                                                        DSECAPS_OUT_SIGNALS |\
                                                        DSECAPS_RESOLUTION |\
                                                        DSECAPS_MACROVISION |\
                                                        DSECAPS_CGMS |\
                                                        DSECAPS_WSS )

/**
 * @brief Describe the encoder config flags that are supported by stb225.
 */
#define PH_STBDFB_MAIN_SCREEN_ENCODER_CONFIGFLAGS     ( DSECONF_TV_STANDARD  | \
                                                        DSECONF_CONNECTORS   | \
                                                        DSECONF_OUT_SIGNALS  | \
                                                        DSECONF_SLOW_BLANKING | \
                                                        DSECONF_RESOLUTION   | \
                                                        DSECONF_FREQUENCY    | \
                                                        DSECONF_SCANMODE     | \
                                                        DSECONF_ADJUSTMENT   | \
                                                        DSECONF_MACROVISION  | \
                                                        DSECONF_CGMS         | \
                                                        DSECONF_WSS)

/**
 * @brief Value for Opaque (solid)
 */
#define OPAQUE      ((UInt8)0xFFU)

/**
 * @brief value of TRANSPARENT
 */
#define TRANSPARENT ((UInt8)0x00U)

/**
 * @brief Map 2MB of the MMIO space.
 *        Needed if we do a WaitVSync using direct register access.
 */
#define PH_STBDFB_MMIO_SIZE (2UL * 1024UL * 1024UL)

/**
 * @brief Max number of encoders per renderer. As there is a maximum of
 * 8 encoders in the system and 2 renderers have given 4 to each.
 */
#define PH_STBDFB_MAX_ENCODERS_RENDERER (VIDEODENC_MAX / PH_STBVIDEORENDERER_MAX_INSTANCES)

/**
 * @brief Convert from TM to DFB pixel formats and ViceVersa.
 */
#define CONVERT_TO_DFB_PIXELFORMAT(_rendFormat) \
       ((_rendFormat) == phStbVideoTypes_PixelFormatYUV420)  ?DSPF_UYVY:    \
       ((_rendFormat) == phStbVideoTypes_PixelFormatYUY2)    ?DSPF_YUY2:    \
       ((_rendFormat) == phStbVideoTypes_PixelFormatUYVY)    ?DSPF_UYVY:    \
       ((_rendFormat) == phStbVideoTypes_PixelFormatARGB8888)?DSPF_ARGB:    \
       ((_rendFormat) == phStbVideoTypes_PixelFormatXRGB8888)?DSPF_RGB32:\
       ((_rendFormat) == phStbVideoTypes_PixelFormatARGB4444)?DSPF_ARGB4444:\
       ((_rendFormat) == phStbVideoTypes_PixelFormatXRGB4444)?DSPF_XRGB4444:\
       ((_rendFormat) == phStbVideoTypes_PixelFormatARGB1555)?DSPF_ARGB1555:\
       ((_rendFormat) == phStbVideoTypes_PixelFormatXRGB1555)?DSPF_XRGB1555:\
       ((_rendFormat) == phStbVideoTypes_PixelFormatRGB565)?DSPF_RGB16:\
       DSPF_UNKNOWN

#define CONVERT_TO_TM_PIXELFORMAT(_DFBFormat) \
       ((_DFBFormat) == DSPF_UYVY) ?phStbVideoTypes_PixelFormatYUV420:       \
       ((_DFBFormat) == DSPF_YUY2) ?phStbVideoTypes_PixelFormatYUY2:         \
       ((_DFBFormat) == DSPF_UYVY) ?phStbVideoTypes_PixelFormatUYVY:         \
       ((_DFBFormat) == DSPF_ARGB) ?phStbVideoTypes_PixelFormatARGB8888:     \
       ((_DFBFormat) == DSPF_RGB32) ?phStbVideoTypes_PixelFormatXRGB8888: \
       ((_DFBFormat) == DSPF_ARGB4444) ?phStbVideoTypes_PixelFormatARGB4444: \
       ((_DFBFormat) == DSPF_XRGB4444) ?phStbVideoTypes_PixelFormatXRGB4444: \
       ((_DFBFormat) == DSPF_ARGB1555) ?phStbVideoTypes_PixelFormatARGB1555: \
       ((_DFBFormat) == DSPF_XRGB1555) ?phStbVideoTypes_PixelFormatXRGB1555: \
       ((_DFBFormat) == DSPF_RGB16) ?phStbVideoTypes_PixelFormatRGB565: \
       phStbVideoTypes_PixelFormatNone

/**
 * @brief convert from DFB to Video denc tv standards and vice versa.
 */
#define CONVERT_TO_DFB_TVSTANDARD(_vdencTVStandard) \
       ((_vdencTVStandard) == VIDEODENC_TV_STANDARD_PAL_BG)   ? DSETV_PAL_BG: \
       ((_vdencTVStandard) == VIDEODENC_TV_STANDARD_PAL_I)    ? DSETV_PAL_I:  \
       ((_vdencTVStandard) == VIDEODENC_TV_STANDARD_PAL_M)    ? DSETV_PAL_M:  \
       ((_vdencTVStandard) == VIDEODENC_TV_STANDARD_PAL_N)    ? DSETV_PAL_N:  \
       ((_vdencTVStandard) == VIDEODENC_TV_STANDARD_PAL_NC)   ? DSETV_PAL_NC: \
       ((_vdencTVStandard) == VIDEODENC_TV_STANDARD_NTSC_M)   ? DSETV_NTSC:   \
       ((_vdencTVStandard) == VIDEODENC_TV_STANDARD_NTSC_M_JPN)  ? DSETV_NTSC_M_JPN: \
       ((_vdencTVStandard) == VIDEODENC_TV_STANDARD_SECAM)    ? DSETV_SECAM:  \
       ((_vdencTVStandard) == VIDEODENC_TV_STANDARD_DIGITAL)  ? DSETV_DIGITAL:\
       DSETV_UNKNOWN

#define CONVERT_FROM_DFB_TVSTANDARD(_DFBTVStandard) \
       ((_DFBTVStandard) == DSETV_PAL_BG)   ? VIDEODENC_TV_STANDARD_PAL_BG: \
       ((_DFBTVStandard) == DSETV_PAL_I)    ? VIDEODENC_TV_STANDARD_PAL_I :  \
       ((_DFBTVStandard) == DSETV_PAL_M)    ? VIDEODENC_TV_STANDARD_PAL_M :  \
       ((_DFBTVStandard) == DSETV_PAL_N)    ? VIDEODENC_TV_STANDARD_PAL_N :  \
       ((_DFBTVStandard) == DSETV_PAL_NC)   ? VIDEODENC_TV_STANDARD_PAL_NC : \
       ((_DFBTVStandard) == DSETV_NTSC)     ? VIDEODENC_TV_STANDARD_NTSC_M :   \
       ((_DFBTVStandard) == DSETV_NTSC_M_JPN)  ? VIDEODENC_TV_STANDARD_NTSC_M_JPN : \
       ((_DFBTVStandard) == DSETV_SECAM)    ? VIDEODENC_TV_STANDARD_SECAM:  \
       ((_DFBTVStandard) == DSETV_DIGITAL)  ? VIDEODENC_TV_STANDARD_DIGITAL :\
       VIDEODENC_TV_STANDARD_PAL_BG

/**
 * @brief Convert from DFB scantype to Video denc scantype and vice versa.
 */
#define CONVERT_TO_DFB_SCANTYPE(_vdencScantype) \
       ((_vdencScantype) == VIDEODENC_SCANTYPE_PROGRESSIVE)   ? DSESM_PROGRESSIVE: \
       ((_vdencScantype) == VIDEODENC_SCANTYPE_INTERLACED)    ? DSESM_INTERLACED:  \
       DSESM_UNKNOWN

#define CONVERT_FROM_DFB_SCANTYPE(_DFBScantype) \
       ((_DFBScantype) == DSESM_PROGRESSIVE )   ? VIDEODENC_SCANTYPE_PROGRESSIVE: \
       ((_DFBScantype) == DSESM_INTERLACED )    ? VIDEODENC_SCANTYPE_INTERLACED: \
       VIDEODENC_SCANTYPE_INTERLACED

/**
 * @brief Convert from TM to DFB Framerates and ViceVersa.
 */
#define CONVERT_TO_DFB_FRAMERATE(_rendFrameRate) \
       ((_rendFrameRate) == phStbVideoRenderer_FrameRate_25)    ?DSEF_25HZ: \
       ((_rendFrameRate) == phStbVideoRenderer_FrameRate_29_97) ?DSEF_29_97HZ: \
       ((_rendFrameRate) == phStbVideoRenderer_FrameRate_50)    ?DSEF_50HZ: \
       ((_rendFrameRate) == phStbVideoRenderer_FrameRate_59_94) ?DSEF_59_94HZ: \
       ((_rendFrameRate) == phStbVideoRenderer_FrameRate_60)    ?DSEF_60HZ: \
       ((_rendFrameRate) == phStbVideoRenderer_FrameRate_75)    ?DSEF_75HZ: \
       DSEF_UNKNOWN

/**
 * @brief Convert from DFB to Video denc refresh rates and ViceVersa.
 */
#define CONVERT_TO_DFB_REFRESH_RATE(_vdencRefreshRate) \
       ((_vdencRefreshRate) == VIDEODENC_REFRESH_RATE_25HZ)    ?DSEF_25HZ: \
       ((_vdencRefreshRate) == VIDEODENC_REFRESH_RATE_29_97HZ) ?DSEF_29_97HZ: \
       ((_vdencRefreshRate) == VIDEODENC_REFRESH_RATE_50HZ)    ?DSEF_50HZ: \
       ((_vdencRefreshRate) == VIDEODENC_REFRESH_RATE_59_94HZ) ?DSEF_59_94HZ: \
       ((_vdencRefreshRate) == VIDEODENC_REFRESH_RATE_60HZ)    ?DSEF_60HZ: \
       ((_vdencRefreshRate) == VIDEODENC_REFRESH_RATE_75HZ)    ?DSEF_75HZ: \
       DSEF_UNKNOWN

#define CONVERT_FROM_DFB_REFRESH_RATE(_DFBFrameRate) \
       ((_DFBFrameRate) == DSEF_25HZ)    ? VIDEODENC_REFRESH_RATE_25HZ: \
       ((_DFBFrameRate) == DSEF_29_97HZ) ? VIDEODENC_REFRESH_RATE_29_97HZ: \
       ((_DFBFrameRate) == DSEF_50HZ)    ? VIDEODENC_REFRESH_RATE_50HZ: \
       ((_DFBFrameRate) == DSEF_59_94HZ) ? VIDEODENC_REFRESH_RATE_59_94HZ: \
       ((_DFBFrameRate) == DSEF_60HZ)    ? VIDEODENC_REFRESH_RATE_60HZ: \
       ((_DFBFrameRate) == DSEF_75HZ)    ? VIDEODENC_REFRESH_RATE_75HZ: \
       VIDEODENC_REFRESH_RATE_UNKNOWN

#ifdef CONFIG_SCART_AK470X
/**
 * @brief Convert from Scart switch blanking to Directfb blanking and vice versa.
 */
#define CONVERT_TO_DFB_SLOWBLANKING(_scartBlanking) \
       ((_scartBlanking) == BLANK_SLOW_16_9)    ?DSOSB_16x9: \
       ((_scartBlanking) == BLANK_SLOW_4_3)     ?DSOSB_4x3: \
       ((_scartBlanking) == BLANK_SLOW_FOLLOW)  ?DSOSB_FOLLOW: \
       ((_scartBlanking) == BLANK_SLOW_MONITOR) ?DSOSB_MONITOR: \
       ((_scartBlanking) == BLANK_SLOW_OFF)     ?DSOSB_OFF: \
       DSOSB_OFF

#define CONVERT_FROM_DFB_SLOWBLANKING(_DFBSlowBlanking) \
       ((_DFBSlowBlanking) == DSOSB_16x9) ? BLANK_SLOW_16_9: \
       ((_DFBSlowBlanking) == DSOSB_4x3) ? BLANK_SLOW_4_3: \
       ((_DFBSlowBlanking) == DSOSB_FOLLOW) ? BLANK_SLOW_FOLLOW: \
       ((_DFBSlowBlanking) == DSOSB_MONITOR) ? BLANK_SLOW_MONITOR: \
       ((_DFBSlowBlanking) == DSOSB_OFF) ? BLANK_SLOW_OFF: \
       BLANK_SLOW_4_3

#elif CONFIG_SCART_UDA3000
/**
 * @brief Convert from Scart switch blanking to Directfb blanking and vice versa.
 */
#define CONVERT_TO_DFB_SLOWBLANKING(_scartBlanking) \
       ((_scartBlanking) == PHSTB_SCART_SWITCH_SB_16_9) ? DSOSB_16x9: \
       ((_scartBlanking) == PHSTB_SCART_SWITCH_SB_4_3) ? DSOSB_4x3: \
       ((_scartBlanking) == PHSTB_SCART_SWITCH_SB_LOW) ? DSOSB_OFF: \
       DSOSB_OFF

#define CONVERT_FROM_DFB_SLOWBLANKING(_DFBSlowBlanking) \
       ((_DFBSlowBlanking) == DSOSB_16x9) ? PHSTB_SCART_SWITCH_SB_16_9: \
       ((_DFBSlowBlanking) == DSOSB_4x3) ? PHSTB_SCART_SWITCH_SB_4_3: \
       ((_DFBSlowBlanking) == DSOSB_OFF) ? PHSTB_SCART_SWITCH_SB_LOW: \
       PHSTB_SCART_SWITCH_SB_LOW
#endif

/**
 * @brief Convert from video denc output signals to DFB signals and vice versa.
 */
#define CONVERT_TO_DFB_OUTPUT_SIGNAL(_outSignal) \
       ((_outSignal) == (VIDEODENC_OUTSIGNAL_CVBS|VIDEODENC_OUTSIGNAL_YC)) ? (DSOS_CVBS|DSOS_YC): \
       ((_outSignal) == VIDEODENC_OUTSIGNAL_CVBS)    ?DSOS_CVBS: \
       ((_outSignal) == VIDEODENC_OUTSIGNAL_YC)      ?DSOS_YC: \
       ((_outSignal) == VIDEODENC_OUTSIGNAL_YPRPB)   ?DSOS_YCBCR: \
       ((_outSignal) == VIDEODENC_OUTSIGNAL_RGB)     ?DSOS_RGB: \
       ((_outSignal) == VIDEODENC_OUTSIGNAL_DIGITAL) ?DSOS_HDMI: \
       DSOS_CVBS

#define CONVERT_FROM_DFB_OUTPUT_SIGNAL(_DFBOutputSignal) \       
       ((_DFBOutputSignal) == (DSOS_CVBS|DSOS_YC))  ? (VIDEODENC_OUTSIGNAL_CVBS|VIDEODENC_OUTSIGNAL_YC): \
       ((_DFBOutputSignal) == DSOS_CVBS)  ? VIDEODENC_OUTSIGNAL_CVBS: \
       ((_DFBOutputSignal) == DSOS_YC)    ? VIDEODENC_OUTSIGNAL_YC: \
       ((_DFBOutputSignal) == DSOS_YCBCR) ? VIDEODENC_OUTSIGNAL_YPRPB: \
       ((_DFBOutputSignal) == DSOS_RGB)   ? VIDEODENC_OUTSIGNAL_RGB: \
       ((_DFBOutputSignal) == DSOS_HDMI)  ? VIDEODENC_OUTSIGNAL_DIGITAL: \
       VIDEODENC_OUTSIGNAL_CVBS

/**
 * @brief Convert from video denc output connectors to DFB connectors and vice versa.
 */
#define CONVERT_TO_DFB_OUTPUT_CONNECTOR(_outConnector, _conIndex) \
       ((_outConnector) == VIDEODENC_CONNECTOR_SINGLE_RCA && (_conIndex) == 0)    ?DSOC_CVBS: \
       ((_outConnector) == VIDEODENC_CONNECTOR_SCART && (_conIndex) == 0)         ?DSOC_SCART: \
       ((_outConnector) == VIDEODENC_CONNECTOR_SCART && (_conIndex) == 1)         ?DSOC_SCART2: \
       ((_outConnector) == VIDEODENC_CONNECTOR_MINI_DIN && (_conIndex) == 0)      ?DSOC_YC: \
       ((_outConnector) == VIDEODENC_CONNECTOR_TRIPLE_RCA && (_conIndex) == 0)    ?DSOC_COMPONENT: \
       ((_outConnector) == VIDEODENC_CONNECTOR_VGA && (_conIndex) == 0)           ?DSOC_VGA: \
       ((_outConnector) == VIDEODENC_CONNECTOR_HDMI && (_conIndex) == 0)          ?DSOC_HDMI: \
       DSOC_UNKNOWN

#define CONVERT_FROM_DFB_OUTPUT_CONNECTOR(_DFBOutputConnector) \
       ((_DFBOutputConnector) == DSOC_CVBS)  ? VIDEODENC_CONNECTOR_SINGLE_RCA: \
       ((_DFBOutputConnector) == DSOC_SCART)    ? VIDEODENC_CONNECTOR_SCART: \
       ((_DFBOutputConnector) == DSOC_SCART2) ? VIDEODENC_CONNECTOR_SCART: \
       ((_DFBOutputConnector) == DSOC_YC)   ? VIDEODENC_CONNECTOR_MINI_DIN: \
       ((_DFBOutputConnector) == DSOC_COMPONENT)   ? VIDEODENC_CONNECTOR_TRIPLE_RCA: \
       ((_DFBOutputConnector) == DSOC_VGA)   ? VIDEODENC_CONNECTOR_VGA: \
       ((_DFBOutputConnector) == DSOC_HDMI)   ? VIDEODENC_CONNECTOR_HDMI: \
       VIDEODENC_CONNECTOR_NONE

/**
 * @brief Convert from video denc resolution to a DFB enum type.
 */
#define CONVERT_TO_DFB_OUTPUT_RESOLUTION(_xres, _yres)          \
       ((_xres) == 640 && (_yres) == 480)     ? DSOR_640_480:   \
       ((_xres) == 720 && (_yres) == 480)     ? DSOR_720_480:   \
       ((_xres) == 720 && (_yres) == 576)     ? DSOR_720_576:   \
       ((_xres) == 800 && (_yres) == 600)     ? DSOR_800_600:   \
       ((_xres) == 1024 && (_yres) == 768)    ? DSOR_1024_768:  \
       ((_xres) == 1152 && (_yres) == 864)    ? DSOR_1152_864:  \
       ((_xres) == 1280 && (_yres) == 720)    ? DSOR_1280_720:  \
       ((_xres) == 1280 && (_yres) == 768)    ? DSOR_1280_768:  \
       ((_xres) == 1280 && (_yres) == 960)    ? DSOR_1280_960:  \
       ((_xres) == 1280 && (_yres) == 1024)   ? DSOR_1280_1024: \
       ((_xres) == 1360 && (_yres) == 768)    ? DSOR_1360_768:  \
       ((_xres) == 1400 && (_yres) == 1050)   ? DSOR_1400_1050: \
       ((_xres) == 1600 && (_yres) == 1200)   ? DSOR_1600_1200: \
       ((_xres) == 1920 && (_yres) == 1080)   ? DSOR_1920_1080: \
       DSOR_UNKNOWN

/** @brief Convert from DFB enum type back to video denc X resolution. */
#define CONVERT_FROM_OUTPUT_RESOLUTION_TO_X(_DFBoutputRes) \
       ((_DFBoutputRes) == DSOR_640_480)   ? 640U :        \
       ((_DFBoutputRes) == DSOR_720_480)   ? 720U :        \
       ((_DFBoutputRes) == DSOR_720_576)   ? 720U :        \
       ((_DFBoutputRes) == DSOR_800_600)   ? 800U :        \
       ((_DFBoutputRes) == DSOR_1024_768)  ? 1024U :       \
       ((_DFBoutputRes) == DSOR_1152_864)  ? 1152U :       \
       ((_DFBoutputRes) == DSOR_1280_720)  ? 1280U :       \
       ((_DFBoutputRes) == DSOR_1280_768)  ? 1280U :       \
       ((_DFBoutputRes) == DSOR_1280_960)  ? 1280U :       \
       ((_DFBoutputRes) == DSOR_1280_1024) ? 1280U :       \
       ((_DFBoutputRes) == DSOR_1360_768)  ? 1360U :       \
       ((_DFBoutputRes) == DSOR_1400_1050) ? 1400U :       \
       ((_DFBoutputRes) == DSOR_1600_1200) ? 1600U :       \
       ((_DFBoutputRes) == DSOR_1920_1080) ? 1920U :       \
       0

/** @brief Convert from DFB enum type back to video denc Y resolution. */
#define CONVERT_FROM_OUTPUT_RESOLUTION_TO_Y(_DFBoutputRes) \
       ((_DFBoutputRes) == DSOR_640_480)   ? 480U :        \
       ((_DFBoutputRes) == DSOR_720_480)   ? 480U :        \
       ((_DFBoutputRes) == DSOR_720_576)   ? 576U :        \
       ((_DFBoutputRes) == DSOR_800_600)   ? 600U :        \
       ((_DFBoutputRes) == DSOR_1024_768)  ? 768U :        \
       ((_DFBoutputRes) == DSOR_1152_864)  ? 864U :        \
       ((_DFBoutputRes) == DSOR_1280_720)  ? 720U :        \
       ((_DFBoutputRes) == DSOR_1280_768)  ? 768U :        \
       ((_DFBoutputRes) == DSOR_1360_768)  ? 768U :        \
       ((_DFBoutputRes) == DSOR_1280_960)  ? 960U :        \
       ((_DFBoutputRes) == DSOR_1280_1024) ? 1024U :       \
       ((_DFBoutputRes) == DSOR_1400_1050) ? 1050U :       \
       ((_DFBoutputRes) == DSOR_1600_1200) ? 1200U :       \
       ((_DFBoutputRes) == DSOR_1920_1080) ? 1080U :       \
       0

/**
 * @brief some useful macros for deciding what to do when a DFB error occurs.
 */
#define DFB_RETURN_ON_ERR(x, msg...)                           \
{                                                              \
    DFBResult err;                                             \
    err = (x);                                                 \
                                                               \
    if (err != DFB_OK)                                         \
    {                                                          \
        D_WARN(msg);                                           \
        return err;                                            \
    }                                                          \
}

#define DFB_INFO_ON_ERROR(x, msg)                              \
{                                                              \
    DFBResult err;                                             \
    err = (x);                                                 \
                                                               \
    if (err != DFB_OK)                                         \
    {                                                          \
        D_INFO(msg);                                           \
    }                                                          \
}

#define DFB_GOTO_ON_ERROR(x, msg, label)                       \
{                                                              \
    DFBResult err;                                             \
    err = (x);                                                 \
                                                               \
    if (err != DFB_OK)                                         \
    {                                                          \
        D_WARN(msg);                                           \
        goto (label);                                          \
    }                                                          \
}

#define TM_TO_DFB_RETURN_ON_ERR(x, msg...)                     \
{                                                              \
    tmErrorCode_t err;                                         \
    err = (x);                                                 \
                                                               \
    if (err != TM_OK)                                          \
    {                                                          \
        D_BUG(msg);                                            \
        return DFB_BUG;                                        \
    }                                                          \
}
/*********************************************************************
* EXPORTED TYPEDEFS                           [p]phStbDfb_<Word>+_t  *
**********************************************************************/

/**
 * @brief Storage structure mapping renderers,encoders and file descriptors
 */
typedef struct
{
    bool inUse;
    int renderer;
    int encoder;
    char devName[32];
} phStbDFB_VdencMap_t;

/** Runtime information associated with each DFB Screen.
 *  Maps to a phStbVideoRenderer_t instance.
 */
typedef struct {
    int                   unitId;
    phStbVideoRenderer_DisplayChain_t dispChain;
    UInt32                screenWidth;
    UInt32                screenHeight;
    int                   numberEncoders;
    phStbDFB_VdencMap_t   vdencMapping[PH_STBDFB_MAX_ENCODERS_RENDERER];
} phStbDFB_ScreenData_t;

/** Runtime info associated with a DFB layer.
 *  Maps to a phStbVideoRenderer_Layer_t.
 */
typedef struct
{
    /** This is the DFB layer ID (which is different to the Renderer Layer ID) */
    int                         layerId;

    /** The layer Handle for the renderer*/
    phStbVideoRenderer_Layer_t *pLayer;

    /** The video layer name */
    char                        name[PH_STBVIDEORENDERER_MAX_NAME_LENGTH + 1];

    /**The Coresurface associated with this layer NULL if not being used by DFB*/
    CoreSurface                *surface;

    /** The CoreLayer Object for this layer.*/
    CoreLayer                  *layer;

    /** The CoreLayer configuration*/
    CoreLayerRegionConfig       config;

    /** The supported layer types*/
    DFBDisplayLayerTypeFlags    layerType;

    /** The current type of the layer*/
    DFBDisplayLayerTypeFlags    currentType;

    /** Mark that the layer is currently active, this must be false to go from video->image layer*/
    Bool                        active;

    /** The mmio address so that i can see MMIO registers*/
    int volatile *pMmio;
} phStbDFB_LayerData_t;

/**
 * Device information shared between all instance of phStbDFB by directfb.
 */
typedef struct {
    /* --  HW Acceleration variables -- */
    /* state validation */
    int            v_flags;

    /* prepared register values */
    __u32          SurfAlpha;
    __u32          HAlphaColor;
    __u32          MonoPatFColor;

    /* cached values */
    DFBSurfaceDrawingFlags  drawingflags;
    DFBSurfaceBlittingFlags blittingflags;
    DFBSurfaceBlendFunction src_blend;

    /* -- Layer Variables -- */
    phStbDFB_LayerData_t layers[PH_STBDFB_NUM_LAYERS_USED];
} phStbDFB_DeviceData_t;

/**************************************************************************
* EXPORTED DATA                          g[k|p|kp|pk|kpk]phStbDfb_<Word>+ *
***************************************************************************/

DBG_UNIT_EXTERN(gphStbDFB_DbgUnit);

extern CoreScreen *gpphStbDFB_Screen[PH_STBVIDEORENDERER_MAX_INSTANCES];

extern phStbDFB_DeviceData_t *gpphStbDFB_DeviceData;

extern bool gphStbDFB_stretchSupported;

/****************************************************************************
* EXPORTED FUNCTION PROTOTYPES                         phStbDfb[_<Word>+]   *
*****************************************************************************/
/**
 * Registers the Display Chain Main as a Screen for DirectFB.
 *
 * @param device @b IN The GraphicsDevice pointer as passed to driver_init
 */
DFBResult phStbDFB_ScreenRegister(GraphicsDevice *device);

/**
 * Hook the Primary framebuffer device so that it uses some of this drivers
 * functions, instead of the default ones.
 *
 * @param device The GraphicsDevice pointer as passed to driver_init
 */
void phStbDFB_FBDevGfxLayerRegister(GraphicsDevice *device);

/**
 * Hook the LCD framebuffer device so that it uses some of this drivers
 * functions, instead of the default ones.
 *
 * @param device The GraphicsDevice pointer as passed to driver_init
 */
void phStbDFB_FBDevLCDLayerRegister(GraphicsDevice *device);

/**
 * Register the video layers with directfb.
 */
void phStbDFB_VidLayerRegister(void);

/**
 * Register the GFX layers with directfb.
 *
 * @param device @b IN The GraphicsDevice pointer as passed to driver_init
 * @param rendererID @b IN The renderer that we are registering the layers from.
 * @param screenIdOfRenderer @b IN The screen ID for these layers to be registered on.
 * @param ownsFbDev @b IN Is the framebuffer owned by this screen as well in which case
 *                        (in 5l only register 2 gfx layers not three).
 *
 * @see phStbDfb_ScreenID
 */
void phStbDFB_GfxLayerRegister(GraphicsDevice *device,
                               int rendererID,
                               int screenIdOfRenderer,
                               bool ownsFbDev);

/* Common Layer Function Prototypes */
int phStbDFB_LayerDataSize(void);

DFBResult phStbDFB_LayerInit(CoreLayer                  *layer,
                             void                       *driver_data,
                             void                       *layer_data,
                             DFBDisplayLayerDescription *description,
                             DFBDisplayLayerConfig      *config,
                             DFBColorAdjustment         *adjustment);
DFBResult phStbDFB_SetColorAdjustment(CoreLayer          *layer,
                                      void               *driver_data,
                                      void               *layer_data,
                                      DFBColorAdjustment *adj);
DFBResult phStbDFB_TestRegion(CoreLayer                  *layer,
                              void                       *driver_data,
                              void                       *layer_data,
                              CoreLayerRegionConfig      *config,
                              CoreLayerRegionConfigFlags *failed,
                              CoreSurface                *surface);
DFBResult phStbDFB_SetRegion(CoreLayer                  *layer,
                             void                       *driver_data,
                             void                       *layer_data,
                             void                       *region_data,
                             CoreLayerRegionConfig      *config,
                             CoreLayerRegionConfigFlags  updated,
                             CoreSurface                *surface,
                             CorePalette                *palette );
DFBResult phStbDFB_RemoveRegion(CoreLayer *layer,
                                void      *driver_data,
                                void      *layer_data,
                                void      *region_data );
DFBResult phStbDFB_GetLevel(CoreLayer              *layer,
                            void                   *driver_data,
                            void                   *layer_data,
                            int                    *level );
DFBResult phStbDFB_SetLevel(CoreLayer              *layer,
                            void                   *driver_data,
                            void                   *layer_data,
                            int                     level );
DFBResult phStbDFB_DeallocateSurface(CoreLayer              *layer,
                                     void                   *driver_data,
                                     void                   *layer_data,
                                     void                   *region_data,
                                     CoreSurface            *surface);
DFBResult phStbDFB_ReallocateSurface(CoreLayer              *layer,
                                     void                   *driver_data,
                                     void                   *layer_data,
                                     void                   *region_data,
                                     CoreLayerRegionConfig  *config,
                                     CoreSurface            *surface);

/* Hardware acceleration functions */
void phStbDFB_InitHWAccel(GraphicsDeviceFuncs *funcs);
void phStbDFB_DeInitHwAccel(void);
int phStbDFB_IsHWAccelerated(void);

/** Screen/Encoder/Mixer/Output Functions*/
int StbDFB_ScreenDataSize(void);

DFBResult StbDFB_GetScreenSize(
    CoreScreen                  *screen,
    void                        *driver_data,
    void                        *screen_data,
    int                         *ret_width,
    int                         *ret_height);

DFBResult StbDFB_InitScreen(
    CoreScreen                   *screen,
    GraphicsDevice               *device,
    void                         *driver_data,
    void                         *screen_data,
    DFBScreenDescription         *description );

DFBResult StbDFB_InitMixer(
    CoreScreen                   *screen,
    void                         *driver_data,
    void                         *screen_data,
    int                           mixer,
    DFBScreenMixerDescription    *description,
    DFBScreenMixerConfig         *config );

DFBResult StbDFB_InitEncoder(
    CoreScreen *screen,
    void                         *driver_data,
    void                         *screen_data,
    int                           encoder,
    DFBScreenEncoderDescription  *description,
    DFBScreenEncoderConfig       *config );

DFBResult StbDFB_SetPowerMode(
    CoreScreen             *screen,
    void                   *driver_data,
    void                   *screen_data,
    DFBScreenPowerMode      mode );

DFBResult StbDFB_TestMixerConfig(
    CoreScreen                  *screen,
    void                        *driver_data,
    void                        *screen_data,
    int                          mixer,
    const DFBScreenMixerConfig  *config,
    DFBScreenMixerConfigFlags   *failed );

DFBResult StbDFB_SetMixerConfig(
    CoreScreen                  *screen,
    void                        *driver_data,
    void                        *screen_data,
    int                          mixer,
    const DFBScreenMixerConfig  *config );

DFBResult StbDFB_TestEncoderConfig(
    CoreScreen                   *screen,
    void                         *driver_data,
    void                         *screen_data,
    int                           encoder,
    const DFBScreenEncoderConfig *config,
    DFBScreenEncoderConfigFlags  *failed);

DFBResult StbDFB_SetEncoderConfig(
    CoreScreen                   *screen,
    void                         *driver_data,
    void                         *screen_data,
    int                           encoder,
    const DFBScreenEncoderConfig *config);

/**Utility functions*/
/**
 * Local function to get the number of video dencs on a given renderer.
 *
 * @param rendererNum IN the Renderer we are linking a vdenc to.
 *
 * @return number of encoders found.
 */
int StbDFB_GetNumberVideoDencs(int rendererNum);

/**
 * Local function To map a Video Denc to a Renderer
 *
 * @param screen_data IN the screen data holding the vdenc info structures.
 * @param encoder     IN The encoder number we are looking for.
 * @param pEncDesc    OUT The Encoder description we are filling in.
 *
 * @return 0 for success, otherwise Error.
 */
DFBResult StbDFB_InitVideoDenc(phStbDFB_ScreenData_t *screen_data,
                               int encoder,
                               DFBScreenEncoderDescription *pEncDesc);

/**
 * Local function to get the current denc settings for a specified renderer.
 *
 * @param screen_data IN the screen data holding the vdenc info structures.
 * @param encoder IN The encoder we want to set up.
 * @param pDencSettings IN The settings structure.
 *
 * @return 0 for success, otherwise Error.
 */
DFBResult StbDFB_GetDencSetup(phStbDFB_ScreenData_t *screen_data,
                              int encoder,
                              struct videodenc_var_screeninfo *pDencSettings);

/**
 * Local function to set the current denc settings for a specified renderer.
 *
 * @param screen_data IN the screen data holding the vdenc info structures.
 * @param encoder IN The encoder we want to set up.
 * @param pDencSettings IN The settings structure.
 *
 * @return 0 for success, otherwise Error.
 */
DFBResult StbDFB_SetupDenc(phStbDFB_ScreenData_t *screen_data,
                           int encoder,
                           struct videodenc_var_screeninfo *pDencSettings);

/**
 * Local function to set the denc gamma settings for a specified renderer.
 *
 * @param screen_data IN the screen data holding the vdenc info structures.
 * @param encoder IN The encoder we want to set up.
 * @param pGammaValues IN The gamma value array.
 *
 * @return 0 for success, otherwise Error.
 */
DFBResult StbDFB_SetupDencGamma(phStbDFB_ScreenData_t *screen_data,
                                int encoder,
                                unsigned int *pGammaValues);

#ifdef CONFIG_SCART_AK470X

/**
 * Local function to detect if scart switch exists.
 *
 * @return true if it exists or false otherwise.
 */
bool StbDFB_AK470XInstalled(void);

/**
 * Local function to get the current AK470X settings.
 *
 * @param pAvSwitchSettings IN The settings structure.
 *
 * @return 0 for success, otherwise Error.
 */
DFBResult StbDFB_GetSetupAK470X(av_switch_data *pAvSwitchSettings);

/**
 * Local function to set the current AK470X settings.
 *
 * @param pAvSwitchSettings IN The settings structure.
 *
 * @return 0 for success, otherwise Error.
 */
DFBResult StbDFB_SetupAK470X(av_switch_data *pAvSwitchSettings);

#elif CONFIG_SCART_UDA3000

/**
 * Local function to detect if scart switch exists.
 *
 * @return true if it exists or false otherwise.
 */
bool StbDFB_UDA3000Installed(void);

/**
 * Local function to get the current UDA3000 SB settings.
 *
 * @param kScartNumber IN The SCART number.
 *
 * @param pValue OUT The value of SB
 *
 * @return 0 for success, otherwise Error.
 */
DFBResult StbDFB_GetSetupUDA3000(phStbScartSwitchScartId_t   kScartNumber,
                                                          phStbScartSwitchSBValue_t *pValue);

/**
 * Local function to set the current UDA3000 SB settings.
 *
 * @param kScartNumber IN The SCART number.
 *
 * @param kMode IN The mode of SB
 *
 * @param kValue IN The value of SB
 *
 * @return 0 for success, otherwise Error.
 */
DFBResult StbDFB_SetupUDA3000(phStbScartSwitchScartId_t  kScartNumber, 
                                                     phStbScartSwitchSBMode_t kMode,
                                                     phStbScartSwitchSBValue_t kValue);

#endif

#endif /* PHSTBDFB_LOCAL_H      Do not add any thing below this line */
