/*****************************************************************************/
/* 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   */
/*                                                                           */
/*****************************************************************************/
/*

Rev Date        Author      Comments
--------------------------------------------------------------------------------
1   20090205    laird       First Version
2   20090326    laird       Adding mute.
--------------------------------------------------------------------------------
    For consistency and standardisation retain the Section Separators.
*/
#ifndef __GST_STB22X_FRAMED_VIDEO_H__
#define __GST_STB22X_FRAMED_VIDEO_H__

/**************************************************************
* INCLUDE FILES                                               *
***************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <gst/gst.h>
#include <gst/video/gstvideosink.h>
#include <tmNxCompId.h>
#include <phStbEsMetaData.h>

/**************************************************************
* EXPORTED MACROS                                             *
***************************************************************/
/**
 * Standard GStreamer Helper macros.
 */
#define GST_TYPE_STB22X_FRAMED_VIDEO              (gst_stb22x_framed_video_get_type())
#define GST_STB22X_FRAMED_VIDEO(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_STB22X_FRAMED_VIDEO,GstStb22xFramedVideo))
#define GST_STB22X_FRAMED_VIDEO_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_STB22X_FRAMED_VIDEO,GstStb22xFramedVideoClass))
#define GST_IS_STB22X_FRAMED_VIDEO(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_STB22X_FRAMED_VIDEO))
#define GST_IS_STB22X_FRAMED_VIDEO_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_STB22X_FRAMED_VIDEO))
#define GST_STB22X_FRAMED_VIDEO_CAST(obj)         ((GstStb22xFramedVideo *)obj)
#define GST_STB22X_FRAMED_VIDEO_FILE_NAME_LENGTH  255

/**
 * Utility macros to convert from GST timestamps into the PTS timestamp
 * format required for ES meta Data API.
 */
#define CLOCK_BASE 9LL
#define CLOCK_FREQ (CLOCK_BASE * 10000)
#define MPEGTIME_TO_GSTTIME(time) (gst_util_uint64_scale ((time), \
                                   GST_MSECOND/10, CLOCK_BASE))
#define GSTTIME_TO_MPEGTIME(time) (gst_util_uint64_scale ((time), \
                                   CLOCK_BASE, GST_MSECOND/10))

/**************************************************************
* EXPORTED TYPEDEFS                                           *
***************************************************************/
/**
 * All the Codecs that can be played via the ES API.
 */
typedef enum
{
    GstStb22xFramedVideo_Mpeg1,
    GstStb22xFramedVideo_Mpeg2,
    GstStb22xFramedVideo_Mpeg4,
    GstStb22xFramedVideo_Wmv,
    GstStb22xFramedVideo_Divx3,
    GstStb22xFramedVideo_Divx4,
    GstStb22xFramedVideo_Divx5,
    GstStb22xFramedVideo_Xvid,
    GstStb22xFramedVideo_H263,
    GstStb22xFramedVideo_H264,
    GstStb22xFramedVideo_VP6,
    GstStb22xFramedVideo_Guard
} GstStb22xFramedVideoSupportedTypes;

/**
 * Macro to convert from DirectFB status to internal status.
 */
#define CONVERT_TO_METADATA_VIDEOTYPE(_gstVideoType)                            \
    (((_gstVideoType) == GstStb22xFramedVideo_Mpeg1)  ? phStbEsFormatVideoMpeg1:\
     ((_gstVideoType) == GstStb22xFramedVideo_Mpeg2)  ? phStbEsFormatVideoMpeg2:\
     ((_gstVideoType) == GstStb22xFramedVideo_Mpeg4)  ? phStbEsFormatVideoMpeg4:\
     ((_gstVideoType) == GstStb22xFramedVideo_Wmv)    ? phStbEsFormatVideoWmv:  \
     ((_gstVideoType) == GstStb22xFramedVideo_Divx3)  ? phStbEsFormatVideoDivx3:\
     ((_gstVideoType) == GstStb22xFramedVideo_Divx4)  ? phStbEsFormatVideoDivx4:\
     ((_gstVideoType) == GstStb22xFramedVideo_Divx5)  ? phStbEsFormatVideoDivx5:\
     ((_gstVideoType) == GstStb22xFramedVideo_Xvid)   ? phStbEsFormatVideoXvid: \
     ((_gstVideoType) == GstStb22xFramedVideo_H263)   ? phStbEsFormatVideoH263: \
     ((_gstVideoType) == GstStb22xFramedVideo_H264)   ? phStbEsFormatVideoH264: \
     ((_gstVideoType) == GstStb22xFramedVideo_VP6)    ? phStbEsFormatVideoVP6:  \
     phStbEsFormatNone)

/**
 * GstStb22xFramedVideoStateError:
 * @STB22X_FRAMED_VIDEO_STATE_ERROR_NONE: no error
 * @STB22X_FRAMED_VIDEO_STATE_ERROR_NULL_READY: cause the NULL to READY state change to fail
 * @STB22X_FRAMED_VIDEO_STATE_ERROR_READY_PAUSED: cause the READY to PAUSED state change to fail:
 * @STB22X_FRAMED_VIDEO_STATE_ERROR_PAUSED_PLAYING: cause the PAUSED to PLAYING state change to fail:
 * @STB22X_FRAMED_VIDEO_STATE_ERROR_PLAYING_PAUSED: cause the PLAYING to PAUSED state change to fail:
 * @STB22X_FRAMED_VIDEO_STATE_ERROR_PAUSED_READY: cause the PAUSED to READY state change to fail:
 * @STB22X_FRAMED_VIDEO_STATE_ERROR_READY_NULL: cause the READY to NULL state change to fail:
 *
 * Possible state change errors for the state-error property.
 */
typedef enum
{
    STB22X_FRAMED_VIDEO_STATE_ERROR_NONE = 0,
    STB22X_FRAMED_VIDEO_STATE_ERROR_NULL_READY,
    STB22X_FRAMED_VIDEO_STATE_ERROR_READY_PAUSED,
    STB22X_FRAMED_VIDEO_STATE_ERROR_PAUSED_PLAYING,
    STB22X_FRAMED_VIDEO_STATE_ERROR_PLAYING_PAUSED,
    STB22X_FRAMED_VIDEO_STATE_ERROR_PAUSED_READY,
    STB22X_FRAMED_VIDEO_STATE_ERROR_READY_NULL
} GstStb22xFramedVideoStateError;

/**
 * Forward declarations.
 */
typedef struct _GstStb22xFramedVideo GstStb22xFramedVideo;
typedef struct _GstStb22xFramedVideoClass GstStb22xFramedVideoClass;

/**
 * GstStb22xFramedVideo:
 *
 * The opaque #GstStb22xFramedVideo data structure.
 */
struct _GstStb22xFramedVideo
{
    /** The sink element.*/
    GstVideoSink		element;
    /** The currently selected codec. */
    GstStb22xFramedVideoSupportedTypes currentCodec;
    /** Are we dumping the output to a file as well? */
    gboolean		dump;
    /** Write data to sink or not.*/
    gboolean		mute;
    /** Output Filename.*/
    gchar  dump_filename[GST_STB22X_FRAMED_VIDEO_FILE_NAME_LENGTH];
    /** File handle for sink*/
    gint    dump_fd;
    gboolean		signal_handoffs;
    GstStb22xFramedVideoStateError state_error;
    /** Sbm sink device name. (iuncluding /dev/)*/
    gchar fullDeviceName[GST_STB22X_FRAMED_VIDEO_FILE_NAME_LENGTH];
    /** File handle for sink*/
    gint    fd;
    /** The meta data we need to write before supplying the data.*/
    phStbEsMetaData_t metaData;
    /** The DSI - needed for H264/DIVX3.*/
    GstBuffer* videoDSI;
    /** Indicator of whether we have sent DSI (One time send only for H264).*/
    gboolean videoDSISent;
    /** H264 specific information to convert from  NAL -> ES for our decoder.*/
    GstBuffer* sps_pps_data;
    GstBuffer* es_code_prefix;
    guint      nal_length;
};

struct _GstStb22xFramedVideoClass
{
    /** Parent class handle.*/
    GstVideoSinkClass parent_class;
    /** */
    GstPadTemplate *sink_template;
    /* signals */
    void (*handoff) (GstElement *element, GstBuffer *buf, GstPad *pad);
    void (*preroll_handoff) (GstElement *element, GstBuffer *buf, GstPad *pad);
};

/**************************************************************
* EXPORTED DATA                                               *
***************************************************************/

/**************************************************************
* EXPORTED FUNCTION PROTOTYPES                                *
***************************************************************/
GType gst_stb22x_framed_video_get_type (void);

#endif /* __GST_STB22X_FRAMED_VIDEO_H__ */
