/*
 * Copyright 2010 Trident Microsystems (Far East) Ltd. All rights reserved.
 * All prior copyright rights in this work and the accompanying software
 * products transferred to Trident Microsystems (Far East) Ltd. by written
 * agreement.
 */
#ifdef __KERNEL__
#include <linux/uio.h>
#else
#include <sys/uio.h>
#endif

/*****************************************************************************/
/* Copyright (c) 2010 NXP B.V.  All rights are reserved.                     */
/*                                                                           */
/* Redistribution and use in source and binary forms, with or without        */
/* modification, are permitted provided that the following conditions        */
/* are met:                                                                  */
/*                                                                           */
/* Redistributions of source code must retain the above copyright            */
/* notice, this list of conditions and the following disclaimer.             */
/*                                                                           */
/* 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.      */
/*                                                                           */
/* Neither the name of NXP nor the names of its                              */
/* contributors may be used to endorse or promote products derived from      */
/* this software without specific prior written permission.                  */
/*                                                                           */
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       */
/* "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 COPYRIGHT      */
/* OWNER OR CONTRIBUTORS 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.                                                                   */
/*                                                                           */
/*****************************************************************************/
/**
   @file   phStbSbmSink.h
   @brief  Implementation of SBM Sink Pin Streaming System Resource

   INTRODUCTION

   This component allows 'Sink' streaming instances to be created.

   A 'Sink' instance registers itself as a "StbSbmSinkX" resource with the Streaming System
   defined by phStbStreamingSystem, and may be used by an application to write data into an
   SBM buffer.

   Set your editor for 4 space indentation.
*//*

Rev Date        Author      Comments
--------------------------------------------------------------------------------
  1 20060919    G.Lawrance  Original
  2 20060926    G.Lawrance  QAC/QMORE
  3 20061002    G.Lawrance  Rework
  4 20061004    G.Lawrance  Rework
  5 20061026    G.Lawrance  Refactor phStbSbm
  6 20061116    G.Lawrance  Refactor phStbSbmDev
  7 20061120    G.Lawrance  Rework
  8 20061122    G.Lawrance  Integrate Device
  9 20061123    G.Lawrance  Rework
 10 20061128    G.Lawrance  Add KernelIfce
 11 20061130    G.Lawrance  Refactor create function
 12 20061207    G.Lawrance  Fix GSL subscription
 13 20070821    barnish     sbm sink no longer has a default buffer.
 14 20071024    barnish     remove unused includes
 15 20071217    burningh    Import 20071212 WinCE code drop
 16 20080118    hutchinson  Import 20080117 WinCE code drop
 17 20080206    burningh    Add EsMetaData parsing functionality; update header
 18 20080218    laird       Adding PIN definitions here instead of streaming system.
 19 20080228    hutch       added 20080227 WinCe changes
 20 20080416    griffiths   Added phStbSbmSink_Send
 21 20080512    griffiths   Add support for DMA transfer from KBuffMgr memory
 22 20080710    griffiths   Add phStbSbmSink_SendFlush prototype
 23 20080725    griffiths   Make phStbSbmSink_Send non-blocking
 24 20080904    griffiths   API changes to phStbSbmSink_Send functions
 25 20081023    griffiths   Add debug option to dump ES to file
 26 20081105    mpage       Add custom ioctl to release blocked writes 
 27 20081117    mpage       Add phStbSbmSink_SendTimeout 
 28 20090120    batelaan    Update file copyright/license text
 29 20090421    mpage       Adding sendFlags.
 30 20090519    laird       Add padding bytes api to make sure we play all frames.
 xx 20091105    mpage       Add dynamic dma input enable.
--------------------------------------------------------------------------------
    For consistency and standardisation retain the Section Separators.
*/

#ifndef PHSTBSBMSINK_H
#define PHSTBSBMSINK_H

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

#include <tmNxTypes.h>

#ifdef __cplusplus
extern "C" {
#endif

/**************************************************************************
* EXPORTED MACROS                          PH_STBSBMSINK_<_WORD>+         *
***************************************************************************/

#define PH_STBSBMSINK_ERR_BASE   \
        (CID_COMP_STBSBMSINK | CID_LAYER_DEVLIB)

#define PH_STBSBMSINK_ERR_BAD_INSTANCE \
        (PH_STBSBMSINK_ERR_BASE + TM_ERR_BAD_INSTANCE)

#define PH_STBSBMSINK_ERR_NO_INSTANCES \
        (PH_STBSBMSINK_ERR_BASE + TM_ERR_NO_INSTANCES)

#define PH_STBSBMSINK_ERR_OUT_OF_MEMORY \
        (PH_STBSBMSINK_ERR_BASE + TM_ERR_OUT_OF_MEMORY)

#define PH_STBSBMSINK_ERR_BAD_PIN \
        (PH_STBSBMSINK_ERR_BASE + TM_ERR_COMP_UNIQUE_START + 0x1)

#define PH_STBSBMSINK_ERR_INVALID_OPERATION \
        (PH_STBSBMSINK_ERR_BASE + TM_ERR_COMP_UNIQUE_START + 0x2)

#define PH_STBSBMSINK_ERR_STREAMINGSYSTEM \
        (PH_STBSBMSINK_ERR_BASE + TM_ERR_COMP_UNIQUE_START + 0x3)

#define PH_STBSBMSINK_ERR_INVALID_STATE \
        (PH_STBSBMSINK_ERR_BASE + TM_ERR_COMP_UNIQUE_START + 0x4)

#define PH_STBSBMSINK_ERR_INTERNAL_GSL \
        (PH_STBSBMSINK_ERR_BASE + TM_ERR_COMP_UNIQUE_START + 0x5)

#define PH_STBSBMSINK_ERR_INTERNAL_SBM \
        (PH_STBSBMSINK_ERR_BASE + TM_ERR_COMP_UNIQUE_START + 0x6)

#define PH_STBSBMSINK_ERR_INVALID_SBMBUFFER \
        (PH_STBSBMSINK_ERR_BASE + TM_ERR_COMP_UNIQUE_START + 0x7)

#define PH_STBSBMSINK_ERR_DEVICE \
        (PH_STBSBMSINK_ERR_BASE + TM_ERR_COMP_UNIQUE_START + 0x8)

/** Streaming resource name format string */
#define PH_STBSBMSINK_NAME "stbsbmsink"
#define PH_STBSBMSINK_MAX_RESOURCE_NAME_LENGTH (64)

/** Debug flag used to enable ES dumping */
#define PH_STBSBMSINK_DEBUG_DUMP_ES     (0x010000)

/**!
 * \attention
 * The current implementation for WinCE limits the number of instances to 10!
 * Increasing the define beyond this limit requires drastic code changes!
 */
#define PH_STBSBMSINK_MAX_NUM_INSTANCES (8)
#define PH_STBSBMSINK_DEFAULT_PIN (0)

/** Value used when no flag is set 
 *  @note Must match the values in phStbStreamingSystem_SBMPinFlags.h */
#define PH_STBSBMSINK_SBMPINFLAGS_NOFLAGSET 0x00000000
/** Indicates pin SBM buffer connection type : set = hardware, clear = software 
 *  @note Must match the values in phStbStreamingSystem_SBMPinFlags.h */
#define PH_STBSBMSINK_SBMPINFLAGS_HWBUFFER  0x00000001  
/** Indicates the the data transfer shall be performed from a KBuffMgr memory
    region using DMA.
 *  @note Must match the values in phStbStreamingSystem_SBMPinFlags.h */
#define PH_STBSBMSINK_SBMPINFLAGS_CONTIGUOUS_XFER  0x00000002

/** Indicates that LITE meta-data should be used. */
#define PH_STBSBMSINK_SBMSENDFLAGS_NONE  0x00000000
/** Indicates that LITE meta-data should be used. */
#define PH_STBSBMSINK_SBMSENDFLAGS_LITEMETA  0x00000001
/** Indicates that LITE meta-data should be used. */
#define PH_STBSBMSINK_SBMSENDFLAGS_VECTOREDWRITES  0x00000002

/* IOCTL for releasing blocked write calls. */
#define PH_STBSBMSINK_IOCTL_RELEASE_WRITE   (1)
/* IOCTL for releasing blocked write calls. */
#define PH_STBSBMSINK_IOCTL_SEND_PADDING    (2)

/* Denotes an infinite timeout for use in calls to phStbSbmSink_SendTimeout. */
#define PH_STBSBMSINK_TIMEOUT_INFINTE       (0xFFFFFFFF)

/*********************************************************************
* EXPORTED TYPEDEFS                      [p]phStbSbmSink_<Word>+_t   *
**********************************************************************/

/** Sink instance definition */
typedef UInt32 phStbSbmSink_t;

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

/****************************************************************************
* EXPORTED FUNCTION PROTOTYPES                    phStbSbmSink[_<Word>+]    *
*****************************************************************************/

/* Component Operations */

/******************************************************************************/
/** Initialise component

    @retval None
*/
void phStbSbmSink_Init(void);


/******************************************************************************/
/** Deinitialise component

    @retval None
*/
void phStbSbmSink_Deinit(void);


/******************************************************************************/
/** Create Sink instance

    Newly created instances have Meta Data parsing disabled by default.
    @see phStbSbmSink_SetMetaDataParsingMode for details.

    @param  pinFlags        IN              SBM buffer pinFlags
    @param  pSink           OUT             Instance handle of new Sink instance
    @param  pName           OUT             Streaming resource name of new Sink instance

    @retval TM_OK                               Success
    @retval PH_STBSBMSINK_ERR_NO_INSTANCES      No available instances
    @retval PH_STBSBMSINK_ERR_STREAMINGSYSTEM   Internal Streaming System Error
    @retval PH_STBSBMSINK_ERR_DEVICE            Internal Linux Device Error
*/
tmErrorCode_t phStbSbmSink_Create(
    UInt32 pinFlags,
    phStbSbmSink_t* pSink,
    char *pName );

/* Instance Operations */

/******************************************************************************/
/** Destroy Sink instance

    @param  sink            IN/OUT          Instance to destroy

    @retval TM_OK                               Success
    @retval PH_STBSBMSINK_ERR_BAD_INSTANCE      Bad instance
    @retval PH_STBSBMSINK_ERR_STREAMINGSYSTEM   Internal Streaming System Error
    @retval PH_STBSBMSINK_ERR_INVALID_STATE     Invalid state of instance
    @retval PH_STBSBMSINK_ERR_DEVICE            Internal Linux Device Error

*/
tmErrorCode_t phStbSbmSink_Destroy(
    phStbSbmSink_t sink );

/******************************************************************************/
/** Perform synchronous write to SBM Buffer

    @param  sink            IN              Sink instance
    @param  pData           IN              Data pointer
    @param  pNbytes         IN/OUT          Requested length of data transfer,
                                            returning actual length transferred

    @retval TM_OK                               Success
    @retval PH_STBSBMSINK_ERR_BAD_INSTANCE      Bad instance
    @retval PH_STBSBMSINK_ERR_INVALID_STATE     Invalid state of instance
    @retval PH_STBSBMSINK_ERR_INTERNAL_SBM      Internal SBM error
*/
tmErrorCode_t phStbSbmSink_Write(
    phStbSbmSink_t sink,
    UInt8 *pData,
    UInt32 *pNbytes);

/******************************************************************************/
/** Enable or disable Meta Data parsing and forwarding on an SBM Sink instance.
    This function cannot be called whilst streaming is in progress.

    @param  sink            IN              Sink instance
    @param  enable          IN              True to enable Meta Data parsing,
                                            False to disable it.

    @retval TM_OK                               Success
    @retval PH_STBSBMSINK_ERR_BAD_INSTANCE      Bad instance
    @retval PH_STBSBMSINK_ERR_INVALID_STATE     Invalid state of instance
*/
tmErrorCode_t phStbSbmSink_SetMetaDataParsingMode(
    phStbSbmSink_t sink,
    Bool enable);
    
/******************************************************************************/
/** Enable or disable DMA input.
    This function cannot be called whilst streaming is in progress.

    @param  sink            IN              Sink instance
    @param  enable          IN              True to enable DMA input,
                                            False to disable it.

    @retval TM_OK                               Success
    @retval PH_STBSBMSINK_ERR_BAD_INSTANCE      Bad instance
*/
tmErrorCode_t phStbSbmSink_DmaInputEnable(
    phStbSbmSink_t sink,
    Bool enable);

#if TMFL_OS_IS_LINUX   
/******************************************************************************/
/** Create buffering for phStbSbmSink_Send operations.

    @param fd           IN      Handle to the file descriptor of the sbm sink
    @param max_messages IN      Maximum number of messages that can be buffered
    @param pReleaseFunc IN      Pointer to the release function called after data
                                is consumed by the SBM sink

Additional "Ex" params
    @param sendFlags    IN      Additional send options (see PH_STBSBMSINK_SBMSENDFLAGS_XXX)

    @retval TM_OK                               Success
    @retval TM_ERR_NO_RESOURCES                 Create could not complete.
    
    On error any data already buffered is not released.
*/    
tmErrorCode_t phStbSbmSink_SendCreate(
    Int32 fd, 
    Int maxMessages, 
    void (*pReleaseFunc)(void *));

tmErrorCode_t phStbSbmSink_SendCreateEx(
    Int32 fd,
    Int maxMessages,
    void (*pReleaseFunc)(void *),
    Int sendFlags);

/******************************************************************************/
/** Send data to an sbm device.

    Data pointers are buffered internally, after data is passed to the sbm sink
    the release function referenced in the phStbSbmSink_SendCreate function is called
    with pReleaseData as a parameter.

    The data pointer should be valid until the relase function is called.

    @param fd           IN      Handle to the file descriptor of the sbm sink
    @param pts          IN      The play time stamp for this data. 
    @param ptsValid     IN      True if the playtimestamp is valid
    @param data         IN      A pointer to the data.
    @param length       IN      Numbner of bytes to be writen.
    @param pReleaseData IN      Data to be passed to the release function

    @retval TM_OK                               Success
    @retval PH_STBSBMSINK_ERR_DEVICE            There was a problem writing the the SBM buffer
    @retval TM_ERR_NO_RESOURCES                 Send could not complete
	 
    The sbm sink should be opened in blocking mode (the default mode). If an error has occurred
    in the device, phStbSbmSink_Send will start to return PH_STBSBMSINK_ERR_DEVICE. To remedy
    the situation phStbSbmSink_SendFlush should be called.

*/
Int32 phStbSbmSink_Send(
    Int32 fd, 
    Int64 pts, 
    Bool ptsValid,
    UInt8 *data,
    UInt32 length,
    void *pReleaseData);

Int32 phStbSbmSink_SendSG(
    Int32 fd, 
    Int64 pts, 
    Bool ptsValid,
    struct iovec *data,
    UInt32 length,
    void *pReleaseData);

/******************************************************************************/
/** Identical behaviour to phStbSbmSink_Send apart from a timeout may also be
    specified in milliseconds. If the call times out, none of the send operation
    has completed (i.e. the release function will not be called) so the client
    may try again.
    Additional Info:
    @param timeout IN      Timeout in milliseconds. For an infinite timeout
                           specify PH_STBSBMSINK_TIMEOUT_INFINTE (or call
                           phStbSbmSink_Send instead).
    @retval TM_ERR_TIMEOUT Send operation timed out.
*/
Int32 phStbSbmSink_SendTimeout(
    Int32 fd,
    Int64 pts,
    Bool ptsValid,
    UInt8 *data,
    UInt32 length,
    void *pReleaseData,
    UInt32 timeout);

/******************************************************************************/
/** Shut down phStbSbmSink_Send operations. Data already passed to the sbm sink
    is not removed and will continue to be processed. All buffered data (waiting 
    to be sent to the sbm sink) is destroyed, no release calls are made to the 
    destroyed data.

    @param fd       IN      Handle to the file descriptor of the sbm sink

    @retval TM_OK                               Success
    @retval TM_ERR_NO_RESOURCES                 Destory could not complete.
    
    On error any data already buffered is not released.
*/    
tmErrorCode_t phStbSbmSink_SendDestroy(Int32 fd);

/******************************************************************************/
/** Flush all phStbSbmSink_Send operations. For all messages waiting to be passed
    to the sbm sink file, the release function is called wihtout passing it
    to the sbm sink. Data already passed to the sbm sink will continue to be processed.

    @param fd                IN      Handle to the file descriptor of the sbm sink

    @retval TM_OK                               Success
    @retval TM_ERR_NO_RESOURCES                 Flush could not complete.
    
    On error any data already buffered is not released.
*/    
tmErrorCode_t phStbSbmSink_SendFlush(Int32 fd);

/******************************************************************************/
/** The Video decoder holds on to some data internally which can stop
    some of the last frames of a particular sequence being displayed.  This function
    internally sends some padding bytes into the Video decoder which plays out the
    remaining frames so that the last frame can be seen.

    @param fd                IN      Handle to the file descriptor of the sbm sink

    @retval TM_OK                               Success
    @retval TM_ERR_NO_RESOURCES                 Padding could not complete.

    On error any data already buffered is not released.
*/
tmErrorCode_t phStbSbmSink_SendPaddingBytes(Int32 fd);

/******************************************************************************/
/** !!Private function!! Flush buffers for an audio subsystem specific use case

    @param  sink          IN       Sink instance

    @retval TM_OK                               Success
    @retval PH_STBSBMSINK_ERR_BAD_INSTANCE      Bad instance
    @retval PH_STBSBMSINK_ERR_INVALID_STATE     Invalid state of instance
*/
tmErrorCode_t phStbSbmSink_Flush(phStbSbmSink_t sink);

#endif /*TMFL_OS_IS_LINUX */

/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

#ifdef __cplusplus
}
#endif

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