/*
 * 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.
 */
/*****************************************************************************/
/* Copyright (c) 2010 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   20091203    mpage       First Version
--------------------------------------------------------------------------------
    For consistency and standardisation retain the Section Separators.
*/

#ifndef STB_MEDIA_DEMUX_H
#define STB_MEDIA_DEMUX_H

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

/**************************************************************
* EXPORTED MACROS                                             *
***************************************************************/

/** Maximum filename length, used for outputFileNamePrefix in stbMediaDemux_Create(). */
#define STB_MEDIA_DEMUX_MAX_FILENAME_LENGTH             (1024)

/** GENERAL ERRORS. */
#define STB_MEDIA_DEMUX_ERR_GENERAL_BASE                (0x0)
/** No error - OK. */
#define STB_MEDIA_DEMUX_ERR_OK                          (STB_MEDIA_DEMUX_ERR_GENERAL_BASE | 0x0)
/** No further instances available. */
#define STB_MEDIA_DEMUX_ERR_NO_INSTANCES                (STB_MEDIA_DEMUX_ERR_GENERAL_BASE | 0x1)
/** Callback function is NULL. */
#define STB_MEDIA_DEMUX_ERR_NULL_CALLBACK               (STB_MEDIA_DEMUX_ERR_GENERAL_BASE | 0x2)
/** Instance passed is invalid. */
#define STB_MEDIA_DEMUX_ERR_INVALID_INSTANCE            (STB_MEDIA_DEMUX_ERR_GENERAL_BASE | 0x3)
/** The demux container format is not recognised. */
#define STB_MEDIA_DEMUX_ERR_UNRECOGNISED_CONTAINER      (STB_MEDIA_DEMUX_ERR_GENERAL_BASE | 0x4)
/** The demux can't work out the duration of the clip. */
#define STB_MEDIA_DEMUX_ERR_DURATION_UNAVAILABLE        (STB_MEDIA_DEMUX_ERR_GENERAL_BASE | 0x5)
/** The demux seek failed. */
#define STB_MEDIA_DEMUX_ERR_SEEK                        (STB_MEDIA_DEMUX_ERR_GENERAL_BASE | 0x6)
/** The demux trick command (ffwd, rewind) failed. */
#define STB_MEDIA_DEMUX_ERR_TRICK                       (STB_MEDIA_DEMUX_ERR_GENERAL_BASE | 0x7)

/** ALLOCATION ERRORS. */
#define STB_MEDIA_DEMUX_ERR_ALLOC_BASE                  (0x10)
/** The GStreamer main loop allocation failed. */
#define STB_MEDIA_DEMUX_ERR_ALLOC_MAINLOOP              (STB_MEDIA_DEMUX_ERR_ALLOC_BASE)
/** The GStreamer pipeline allocation failed. */
#define STB_MEDIA_DEMUX_ERR_ALLOC_PIPELINE              (STB_MEDIA_DEMUX_ERR_ALLOC_BASE | 0x1)
/** The GStreamer bus allocation failed. */
#define STB_MEDIA_DEMUX_ERR_ALLOC_BUS                   (STB_MEDIA_DEMUX_ERR_ALLOC_BASE | 0x2)
/** The graph source allocation failed. */
#define STB_MEDIA_DEMUX_ERR_ALLOC_SOURCE                (STB_MEDIA_DEMUX_ERR_ALLOC_BASE | 0x3)
/** The graph demux allocation failed. */
#define STB_MEDIA_DEMUX_ERR_ALLOC_DEMUX                 (STB_MEDIA_DEMUX_ERR_ALLOC_BASE | 0x4)
/** The graph audio sink allocation failed. */
#define STB_MEDIA_DEMUX_ERR_ALLOC_AUDIO_SINK            (STB_MEDIA_DEMUX_ERR_ALLOC_BASE | 0x5)
/** The graph video sink allocation failed. */
#define STB_MEDIA_DEMUX_ERR_ALLOC_VIDEO_SINK            (STB_MEDIA_DEMUX_ERR_ALLOC_BASE | 0x6)
/** The graph framer allocation failed. */
#define STB_MEDIA_DEMUX_ERR_ALLOC_FRAMER                (STB_MEDIA_DEMUX_ERR_ALLOC_BASE | 0x7)
/** The main loop thread allocation failed. */
#define STB_MEDIA_DEMUX_ERR_ALLOC_MAIN_LOOP_THREAD      (STB_MEDIA_DEMUX_ERR_ALLOC_BASE | 0x8)
/** The sync object allocation failed. */
#define STB_MEDIA_DEMUX_ERR_ALLOC_SYNC_OBJECT           (STB_MEDIA_DEMUX_ERR_ALLOC_BASE | 0x9)
/** The audio queue allocation failed. */
#define STB_MEDIA_DEMUX_ERR_ALLOC_AUDIO_QUEUE           (STB_MEDIA_DEMUX_ERR_ALLOC_BASE | 0xA)
/** The video queue allocation failed. */
#define STB_MEDIA_DEMUX_ERR_ALLOC_VIDEO_QUEUE           (STB_MEDIA_DEMUX_ERR_ALLOC_BASE | 0xB)
/** The pre source allocation failed. */
#define STB_MEDIA_DEMUX_ERR_ALLOC_SOURCE_QUEUE          (STB_MEDIA_DEMUX_ERR_ALLOC_BASE | 0xC)

/** LINK ERRORS. */
#define STB_MEDIA_DEMUX_ERR_LINK_BASE                   (0x20)
/** Source to demux link error. */
#define STB_MEDIA_DEMUX_ERR_LINK_SOURCE_DEMUX           (STB_MEDIA_DEMUX_ERR_LINK_BASE)
/** Demux to audio link error. */
#define STB_MEDIA_DEMUX_ERR_LINK_DEMUX_AUDIO            (STB_MEDIA_DEMUX_ERR_LINK_BASE | 0x1)
/** Demux to video link error. */
#define STB_MEDIA_DEMUX_ERR_LINK_DEMUX_VIDEO            (STB_MEDIA_DEMUX_ERR_LINK_BASE | 0x2)
/** Audio queue to sink link error. */
#define STB_MEDIA_DEMUX_ERR_LINK_AUDIO_QUEUE_SINK       (STB_MEDIA_DEMUX_ERR_LINK_BASE | 0x3)
/** Video queue to sink link error. */
#define STB_MEDIA_DEMUX_ERR_LINK_VIDEO_QUEUE_SINK       (STB_MEDIA_DEMUX_ERR_LINK_BASE | 0x4)
/** Pre source to source link error. */
#define STB_MEDIA_DEMUX_ERR_LINK_SOURCE_QUEUE           (STB_MEDIA_DEMUX_ERR_LINK_BASE | 0x5)

/** STATE CHANGE ERRORS. */
#define STB_MEDIA_DEMUX_ERR_STATE_BASE                  (0x30)
/** Source state change error. */
#define STB_MEDIA_DEMUX_ERR_STATE_PIPELINE              (STB_MEDIA_DEMUX_ERR_STATE_BASE)
/** Source state change error. */
#define STB_MEDIA_DEMUX_ERR_STATE_SOURCE                (STB_MEDIA_DEMUX_ERR_STATE_BASE | 0x1)
/** Demux state change error. */
#define STB_MEDIA_DEMUX_ERR_STATE_DEMUX                 (STB_MEDIA_DEMUX_ERR_STATE_BASE | 0x2)
/** Audio sink state change error. */
#define STB_MEDIA_DEMUX_ERR_STATE_AUDIO                 (STB_MEDIA_DEMUX_ERR_STATE_BASE | 0x3)
/** Video sink state change error. */
#define STB_MEDIA_DEMUX_ERR_STATE_VIDEO                 (STB_MEDIA_DEMUX_ERR_STATE_BASE | 0x4)
/** Pre source state change error. */
#define STB_MEDIA_DEMUX_ERR_STATE_SOURCE_QUEUE          (STB_MEDIA_DEMUX_ERR_STATE_BASE | 0x5)

/**************************************************************
* EXPORTED TYPES                                              *
***************************************************************/

/** Media demux instance. */
typedef unsigned int stbMediaDemux_t;

/** Media demux error. */
typedef unsigned int stbMediaDemux_Error_t;

/** Codec types. */
typedef enum
{
    stbMediaDemux_CodecType_None = 0,

    /** Video. */
    stbMediaDemux_CodecType_VideoMPEG1,
    stbMediaDemux_CodecType_VideoMPEG2,
    stbMediaDemux_CodecType_VideoMPEG4,
    stbMediaDemux_CodecType_VideoH263,
    stbMediaDemux_CodecType_VideoH264,
    stbMediaDemux_CodecType_VideoDIVX3,
    stbMediaDemux_CodecType_VideoWMV,
    stbMediaDemux_CodecType_VideoVP6,

    /** Audio. */
    stbMediaDemux_CodecType_AudioMP1,
    stbMediaDemux_CodecType_AudioMP2,
    stbMediaDemux_CodecType_AudioMP3,
    stbMediaDemux_CodecType_AudioMPEG2,
    stbMediaDemux_CodecType_AudioAAC,
    stbMediaDemux_CodecType_AudioAC3,
    stbMediaDemux_CodecType_AudioDTS,
    stbMediaDemux_CodecType_AudioWMA,
    stbMediaDemux_CodecType_AudioLPCM,

    stbMediaDemux_CodecType_Guard
} stbMediaDemux_CodecType_t;

/** Demux commands. */
typedef enum
{
    stbMediaDemux_CommandType_None = 0,
    /** Command Start, pData is NULL. */
    stbMediaDemux_CommandType_Start,
    /** Command Stop, pData is NULL. */
    stbMediaDemux_CommandType_Stop,
    /** Command GetDuration. Returns Duration in seconds, pData should be unsigned int*. */
    stbMediaDemux_CommandType_GetDuration,
    /** Command GetDuration. Returns Position in seconds, pData should be unsigned int*. */
    stbMediaDemux_CommandType_GetPosition,
    stbMediaDemux_CommandType_Seek,
    stbMediaDemux_CommandType_FastForward,
    stbMediaDemux_CommandType_Rewind,
    stbMediaDemux_CommandType_Guard
} stbMediaDemux_CommandType_t;

/** Demux oommand structure. */
typedef struct stbMediaCommand
{
    /** Command. */
    stbMediaDemux_CommandType_t type;
    /** Additional data. */
    void* pData;
} stbMediaDemux_Command_t;

/** Media demux container type. */
typedef enum
{
    stbMediaDemux_Type_None = 0,
    stbMediaDemux_Type_AVI,
    stbMediaDemux_Type_QT,
    stbMediaDemux_Type_MPEGPS,
    stbMediaDemux_Type_MPEGTS,
    stbMediaDemux_Type_FLV,
    stbMediaDemux_Type_MKV,
    stbMediaDemux_Type_ASF,
    stbMediaDemux_Type_Guard
} stbMediaDemux_Type_t;

/** Codec information. Passed back with a stbMediaDemux_Event_CodecIdentified event. */
typedef struct stbMediaDemux_CodecInfo
{
    /** Codec type. */
    stbMediaDemux_CodecType_t codecType;
    /** Filename being used for output of this codec (storage is only valid during the callback). */
    char* pOutputFilename;
} stbMediaDemux_CodecInfo_t;

/** Media demux events. */
typedef enum
{
    /** Codec identified. pEventData points to a . */
    stbMediaDemux_Event_CodecIdentified = 0,
    /** End of stream. pEventData is NULL. */
    stbMediaDemux_Event_EndOfStream,
    /** Error. pEventData should be cast to a stbMediaDemux_Error_t. */
    stbMediaDemux_Event_Error
} stbMediaDemux_Event_t;

/** Generic event callback function.
    @param userData IN User specified data to identify instance.
    @param event IN The event.
    @param pEventData IN Associated event data (see stbMediaDemux_Event_t description for details).
*/
typedef void (*stbMediaDemux_EventCallback_t)(unsigned int userData, stbMediaDemux_Event_t event, void* pEventData);

/**************************************************************
* EXPORTED FUNCTIONS                                          *
***************************************************************/

/******************************************************************************************************/
/** Creates an instance of a media demux.
    @param url          IN  The source URL (file://<path and filename>, http://<path and filename> etc.).
                            Must be no longer than STB_MEDIA_DEMUX_MAX_FILENAME_LENGTH.
    @param demuxType    IN  The type of demux to invoke. If None is specified, GStreamer will attempt
                            to work out the container itself.
    @param detectionTimeout IN Timeout in seconds to wait for codec detection.
    @param pEventCallbackFunc IN  Callback func.
    @param userData     IN  Passed back with callback.
    @param pDemux       OUT The returned media demux pointer.
    @return @see stbMediaDemux_Error_t
*/
extern stbMediaDemux_Error_t stbMediaDemux_Create(char* url,
                                                  stbMediaDemux_Type_t demuxType,
                                                  unsigned int detectionTimeout,
                                                  stbMediaDemux_EventCallback_t pEventCallbackFunc,
                                                  unsigned int userData,
                                                  stbMediaDemux_t* pDemux);

/******************************************************************************************************/
/** Destroys an instance of a media demux.
    @param demux        IN  The media demux.
    @return @see stbMediaDemux_Error_t
*/
extern stbMediaDemux_Error_t stbMediaDemux_Destroy(stbMediaDemux_t demux);

/******************************************************************************************************/
/** Inputs a command into an instance of a media demux.
    @param demux        IN  The media demux.
    @param pCommand     IN  The command structure.
    @return @see stbMediaDemux_Error_t
*/
extern stbMediaDemux_Error_t stbMediaDemux_Command(stbMediaDemux_t demux, stbMediaDemux_Command_t* pCommand);

#endif /* STB_MEDIA_DEMUX_H */

