--- /dev/null
+/*\r
+ * GPAC - Multimedia Framework C SDK\r
+ *\r
+ * Copyright (c) Jean Le Feuvre 2000-2005 \r
+ * All rights reserved\r
+ *\r
+ * This file is part of GPAC / modules interfaces\r
+ *\r
+ * GPAC is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU Lesser General Public License as published by\r
+ * the Free Software Foundation; either version 2, or (at your option)\r
+ * any later version.\r
+ * \r
+ * GPAC is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU Lesser General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; see the file COPYING. If not, write to\r
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. \r
+ *\r
+ */\r
+\r
+#ifndef _GF_SERVICE_H_\r
+#define _GF_SERVICE_H_\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/*for SL, ESD and OD*/\r
+#include <gpac/mpeg4_odf.h>\r
+#include <gpac/download.h>\r
+\r
+/*handle to service*/\r
+typedef struct _net_service GF_ClientService;\r
+\r
+/*handle to channel*/\r
+typedef void *LPNETCHANNEL;\r
+\r
+enum\r
+{\r
+ /*channel control, app->module. Note that most modules don't need to handle pause/resume/set_speed*/\r
+ GF_NET_CHAN_PLAY,\r
+ GF_NET_CHAN_STOP,\r
+ GF_NET_CHAN_PAUSE,\r
+ GF_NET_CHAN_RESUME,\r
+ GF_NET_CHAN_SET_SPEED,\r
+ /*channel configuration, app->module*/\r
+ GF_NET_CHAN_CONFIG,\r
+ /*channel duration, app<->module (in case duration is not known at setup)*/\r
+ GF_NET_CHAN_DURATION,\r
+ /*channel buffer, app->module*/\r
+ GF_NET_CHAN_BUFFER,\r
+ /*channel buffer query, app<-module*/\r
+ GF_NET_CHAN_BUFFER_QUERY,\r
+ /*retrieves DSI from channel (DSI may be caried by net with a != value than OD), app->module*/\r
+ GF_NET_CHAN_GET_DSI,\r
+ /*set media padding for all AUs fetched (pull mode only). \r
+ If not supported the channel will have to run in push mode. app->module*/\r
+ GF_NET_CHAN_SET_PADDING,\r
+ /*sets input channel to pull mode if possible, app->module*/\r
+ GF_NET_CHAN_SET_PULL,\r
+ /*query channel capability to pause/resume and seek(play from an arbitrary range)\r
+ a non-interactive channel doesn't have to handle SET_SPEED, PAUSE and RESUME commands but can \r
+ still work in pull mode*/\r
+ GF_NET_CHAN_INTERACTIVE,\r
+ /*map net time (OTB) to media time (up only) - this is needed by some signaling protocols when the \r
+ real play range is not the requested one */\r
+ GF_NET_CHAN_MAP_TIME,\r
+ /*reconfiguration of channel comming from network (up only) - this is used to override the SL config\r
+ if it differs from the one specified at config*/\r
+ GF_NET_CHAN_RECONFIG,\r
+ /*signal channel is ISMACryp'ted (net->term only)*/\r
+ GF_NET_CHAN_DRM_CFG,\r
+ \r
+ /*retrieves ESD for channel - net->term only, for cache configuration*/\r
+ GF_NET_CHAN_GET_ESD,\r
+ /*retrieves visual PAR as indicated in container if any*/\r
+ GF_NET_CHAN_GET_PIXEL_AR,\r
+ \r
+ /*service buffer query (for all channels running in service), app<-module*/\r
+ GF_NET_BUFFER_QUERY,\r
+ /*retrieves network stats for service/channel; app->module*/\r
+ GF_NET_GET_STATS,\r
+ /*retrieves whether service can be cached (rtp, http streaming radios, etc) or not. No associated struct*/\r
+ GF_NET_IS_CACHABLE,\r
+\r
+ /*sets info for service - net->term only*/\r
+ GF_NET_SERVICE_INFO,\r
+ /*checks if there is an audio stream in the service - term->net only*/\r
+ GF_NET_SERVICE_HAS_AUDIO,\r
+};\r
+\r
+/*channel command for all commands that don't need params:\r
+GF_NET_CHAN_SET_PULL: module shall return GF_OK or GF_NOT_SUPPORTED\r
+GF_NET_CHAN_INTERACTIVE: module shall return GF_OK or GF_NOT_SUPPORTED\r
+*/\r
+typedef struct\r
+{\r
+ /*command type*/\r
+ u32 command_type;\r
+ /*channel*/\r
+ LPNETCHANNEL on_channel;\r
+} GF_NetComBase;\r
+\r
+/*GF_NET_CHAN_PLAY, GF_NET_CHAN_SET_SPEED*/\r
+typedef struct\r
+{\r
+ u32 command_type;\r
+ LPNETCHANNEL on_channel;\r
+ /*params for GF_NET_CHAN_PLAY, ranges in sec - if range is <0, then it is ignored (eg [2, -1] with speed>0 means 2 +oo) */\r
+ Double start_range, end_range;\r
+ /*params for GF_NET_CHAN_PLAY and GF_NET_CHAN_SPEED*/\r
+ Double speed;\r
+} GF_NetComPlay;\r
+\r
+\r
+/*GF_NET_CHAN_CONFIG, GF_NET_CHAN_RECONFIG\r
+channel config may happen as soon as the channel is open, even if the module hasn't acknowledge creation\r
+channel config can also be used from network to app, with GF_NET_CHAN_RECONFIG type - only the SL config is then used\r
+*/\r
+typedef struct\r
+{\r
+ u32 command_type;\r
+ LPNETCHANNEL on_channel;\r
+\r
+ /*SL config of the stream as delivered in OD (app->channel) or by network (channel->app)*/\r
+ GF_SLConfig sl_config; \r
+ /*stream priority packet drops are more tolerable if low priority - app->channel only*/\r
+ u32 priority;\r
+ /*sync ID: all channels with the same sync ID run on the same timeline, thus the module should \r
+ try to match this - note this may not be possible (typically RTP/RTSP)*/\r
+ u32 sync_id;\r
+ /*audio frame duration and sample rate if any - this is needed by some RTP payload*/\r
+ u32 frame_duration, sample_rate;\r
+} GF_NetComConfig;\r
+\r
+/*GF_NET_CHAN_BUFFER, GF_NET_CHAN_BUFFER_QUERY*/\r
+typedef struct\r
+{\r
+ u32 command_type;\r
+ LPNETCHANNEL on_channel;\r
+ /*the recommended buffering limits in ms - this depends on the modules preferences and on the service \r
+ type (multicast, vod, ...) - below buffer_min the stream will pause if possible until buffer_max is reached\r
+ note the app will fill in default values before querying*/\r
+ u32 min, max;\r
+ /*only used with GF_NET_CHAN_BUFFER_QUERY - amount of media in decoding buffer, in ms*/\r
+ u32 occupancy;\r
+} GF_NetComBuffer;\r
+\r
+/*GF_NET_CHAN_DURATION*/\r
+typedef struct\r
+{\r
+ u32 command_type;\r
+ LPNETCHANNEL on_channel;\r
+ /*duration in sec*/\r
+ Double duration;\r
+} GF_NetComDuration;\r
+\r
+/*GF_NET_CHAN_GET_DSI*/\r
+typedef struct\r
+{\r
+ u32 command_type;\r
+ LPNETCHANNEL on_channel;\r
+ /*carries specific info for codec - data shall be allocated by service and is freed by user*/\r
+ char *dsi;\r
+ u32 dsi_len;\r
+} GF_NetComGetDSI;\r
+\r
+/*GF_NET_CHAN_SET_PADDING*/\r
+typedef struct\r
+{\r
+ u32 command_type;\r
+ LPNETCHANNEL on_channel;\r
+ u32 padding_bytes;\r
+} GF_NetComPadding;\r
+\r
+/*GF_NET_CHAN_MAP_TIME*/\r
+typedef struct\r
+{\r
+ u32 command_type;\r
+ LPNETCHANNEL on_channel;\r
+ /*MediaTime at this timestamp*/\r
+ Double media_time;\r
+ /*TS where mapping is done (in SL TS resolution)*/\r
+ u64 timestamp;\r
+ /*specifies whether decoder input data shall be discarded or only have its timing updated*/\r
+ Bool reset_buffers;\r
+} GF_NetComMapTime;\r
+\r
+/*GF_NET_CHAN_ISMACRYP_CFG*/\r
+typedef struct\r
+{\r
+ u32 command_type;\r
+ LPNETCHANNEL on_channel;\r
+\r
+\r
+ /*per channel, regardless of DRM schemes (ISMA, OMA, )*/\r
+ u32 scheme_version;\r
+ u32 scheme_type;\r
+ const char *scheme_uri;\r
+ const char *kms_uri;\r
+ /*OMA DRM info*/\r
+ const char *contentID;\r
+ u32 oma_drm_crypt_type;\r
+ Bool oma_drm_use_pad, oma_drm_use_hdr;\r
+ const char *oma_drm_textual_headers;\r
+ u32 oma_drm_textual_headers_len;\r
+\r
+ /*SHA-1 file hash*/\r
+ u8 hash[20];\r
+} GF_NetComDRMConfig;\r
+\r
+/*GF_NET_CHAN_GET_ESD*/\r
+typedef struct\r
+{\r
+ u32 command_type;\r
+ LPNETCHANNEL on_channel;\r
+ const GF_ESD *esd;\r
+ Bool is_iod_stream;\r
+} GF_NetComGetESD;\r
+\r
+/*GF_NET_GET_STATS\r
+Notes\r
+1: only channels using network must reply. All channels fetching data through a \r
+file downloader (cf below) shall NOT answer, the app manages downloader bandwidth internally.\r
+2: BANDWIDTH USED BY SIGNALING PROTOCOL IS IGNORED IN GPAC\r
+*/\r
+typedef struct __netstatcom\r
+{\r
+ u32 command_type;\r
+ /*MAY BE NULL, in which case the module must fill in ONLY the control channel part. This\r
+ is not used yet, but could be with a protocol using a single control socket for N media channels.*/\r
+ LPNETCHANNEL on_channel;\r
+ /*percentage of packet loss from network. This cannot be figured out by the app since there is no\r
+ one-to-one mapping between the protocol packets and the final SL packet (cf RTP payloads)*/\r
+ Float pck_loss_percentage;\r
+ /*channel port, control channel port if any (eg RTCP)*/\r
+ u16 port, ctrl_port;\r
+ /*bandwidth used by channel & its control channel if any (both up and down) - expressed in bits per second*/\r
+ u32 bw_up, bw_down, ctrl_bw_down, ctrl_bw_up;\r
+ /*set to 0 if channel is not part of a multiplex. Otherwise set to the multiplex port, and \r
+ above port info shall be identifiers in the multiplex - note that multiplexing overhead is ignored \r
+ in GPAC for the current time*/\r
+ u16 multiplex_port;\r
+} GF_NetComStats;\r
+\r
+/*GF_NET_CHAN_GET_PIXEL_AR*/\r
+typedef struct\r
+{\r
+ u32 command_type;\r
+ LPNETCHANNEL on_channel;\r
+ u32 hSpacing, vSpacing;\r
+} GF_NetComPixelAR;\r
+\r
+/*GF_NET_SERVICE_INFO*/\r
+typedef struct __netinfocom\r
+{\r
+ u32 command_type;\r
+ /*currently NULL only*/\r
+ LPNETCHANNEL on_channel;\r
+ /*packed trackNumber(16 bits)/totaltrack(16 bits)*/\r
+ u32 track_info;\r
+ u32 genre;\r
+ const char *album;\r
+ const char *artist;\r
+ const char *comment;\r
+ const char *composer;\r
+ const char *name;\r
+ const char *writer;\r
+} GF_NetComInfo;\r
+\r
+/*GF_NET_CHAN_GET_PIXEL_AR*/\r
+typedef struct\r
+{\r
+ u32 command_type;\r
+ char *base_url;\r
+} GF_NetComHasAudio;\r
+\r
+typedef union __netcommand\r
+{\r
+ u32 command_type;\r
+ GF_NetComBase base;\r
+ GF_NetComPlay play;\r
+ GF_NetComConfig cfg;\r
+ GF_NetComBuffer buffer;\r
+ GF_NetComDuration duration;\r
+ GF_NetComGetDSI get_dsi;\r
+ GF_NetComPadding pad;\r
+ GF_NetComMapTime map_time;\r
+ GF_NetComStats net_stats;\r
+ GF_NetComDRMConfig drm_cfg;\r
+ GF_NetComGetESD cache_esd;\r
+ GF_NetComInfo info;\r
+ GF_NetComPixelAR par;\r
+ GF_NetComHasAudio audio;\r
+} GF_NetworkCommand;\r
+\r
+/*\r
+ network modules\r
+*/\r
+\r
+/*interface name and version for input service*/\r
+#define GF_NET_CLIENT_INTERFACE GF_4CC('G', 'I', 'S', 0x01)\r
+\r
+typedef struct _netinterface\r
+{\r
+ /* interface declaration*/\r
+ GF_DECL_MODULE_INTERFACE\r
+\r
+ /*retuns 1 if module can process this URL, 0 otherwise. This is only called when the file extension/mimeType cannot be\r
+ retrieved in the cfg file, otherwise the mime type/file ext is used to load service. Typically a module would \r
+ register its mime types in this function (cf gf_term_register_mime_type below)\r
+ */\r
+ Bool (*CanHandleURL)(struct _netinterface *, const char *url);\r
+\r
+ /*connects the service to the desired URL - the service handle is used for callbacks. \r
+ Only one service can be connected to a loaded interface.\r
+ */\r
+ GF_Err (*ConnectService) (struct _netinterface *, GF_ClientService *serv, const char *url);\r
+\r
+ /*disconnects service - the module is no longer used after this call - if immediate_shutdown is set the module\r
+ shall not attempt to get confirmation from remote side, it will be deleted right away\r
+ \r
+ NOTE: depending on how the client/server exchange is happening, it may happen that the CloseService is called\r
+ in the same context as a reply from your module. This can result into deadlocks if you're using threads. \r
+ You should therefore only try to destroy threads used in the interface shutdown process, which is guarantee\r
+ to be in a different context call.\r
+ */\r
+ GF_Err (*CloseService) (struct _netinterface *);\r
+\r
+ /*retrieves service decsriptor (expressed as an MPEG4 OD/IOD) for accessing this service \r
+ descriptor is allocated by plugin and destroyed by user\r
+ the IOD shall refer to the service attached to the module\r
+ @expect_type is a hint in case the service regenerates an IOD. It indicates whether the entry point expected is \r
+ INLINE, BIFS animation stream, video, audio or input sensor.\r
+ @sub_url: indicates fetching of an IOD for a given object in the service.\r
+ Only used for services handling the optional CanHandleURLInService below\r
+ NULL for main service\r
+ service extension for sub-service (cf CanHandleURLInService below). For ex,\r
+ "rtsp://myserver/file.mp4/ES_ID=3" and "rtsp://myserver/file.mp4/ES_ID=4" \r
+ or "file.avi#audio" and "file.avi#video".In this case a partial IOD for the desired object is expected\r
+ Note: once a service is acknowledged as connected, this function must be executed synchronously\r
+ The service can return NULL for a descriptor:\r
+ * if the expected media type is a single media, this means the media couldn't be found\r
+ * if the expected media type is a scene, this means the terminalk shall create and manage the scene\r
+ */\r
+ GF_Descriptor *(*GetServiceDescriptor) (struct _netinterface *, u32 expect_type, const char *sub_url);\r
+ \r
+\r
+ /*sends command to the service / channel - cf command structure*/\r
+ GF_Err (*ServiceCommand) (struct _netinterface *, GF_NetworkCommand *com);\r
+\r
+ /*data channel setup - url is either\r
+ "ES_ID=ID" where ID is the stream ID in this service\r
+ or a control string depending on the service/stream. The URL is first used to load a module able to handle it, \r
+ so the module has no redirection to handle\r
+ */\r
+ GF_Err (*ConnectChannel) (struct _netinterface *, LPNETCHANNEL channel, const char *url, Bool upstream);\r
+ /*teardown of data channel*/\r
+ GF_Err (*DisconnectChannel) (struct _netinterface *, LPNETCHANNEL channel);\r
+\r
+ /*optional - fetch MPEG4 data from channel - data shall not be duplicated and must be released at ReleaseData\r
+ SL info shall be written to provided header - if the data is a real SL packet the flag sl_compressed shall be \r
+ set to signal the app this is a full SL pdu (@out_sl_hdr is then ignored)\r
+ set to NULL if not supported\r
+ */\r
+ GF_Err (*ChannelGetSLP) (struct _netinterface *, LPNETCHANNEL channel, char **out_data_ptr, u32 *out_data_size, GF_SLHeader *out_sl_hdr, Bool *sl_compressed, GF_Err *out_reception_status, Bool *is_new_data);\r
+\r
+ /*optional - release SLP data allocated on channel by the previous call, if any\r
+ set to NULL if not supported*/\r
+ GF_Err (*ChannelReleaseSLP) (struct _netinterface *, LPNETCHANNEL channel);\r
+\r
+ /*this is needed for modules to query other modules, the typical case being 2 ESD URLs pointing to the \r
+ same media (audio and video streams in an RTSP session). This is always used on loaded modules but \r
+ doesn't have to be declared*/\r
+ Bool (*CanHandleURLInService)(struct _netinterface *, const char *url);\r
+\r
+/*private*/\r
+ void *priv;\r
+} GF_InputService;\r
+\r
+/*callback functions - these can be linked with non-LGPL modules*/\r
+/*message from service - error is set if error*/\r
+void gf_term_on_message(GF_ClientService *service, GF_Err error, const char *message);\r
+/*to call on service (if channel is NULL) or channel connect completed*/\r
+void gf_term_on_connect(GF_ClientService *service, LPNETCHANNEL ns, GF_Err response);\r
+/*to call on service (if channel is NULL) or channel disconnect completed*/\r
+void gf_term_on_disconnect(GF_ClientService *service, LPNETCHANNEL ns, GF_Err response);\r
+/* acknowledgement of service command - service commands handle both services and channels\r
+Most of the time commands are NOT acknowledged, typical acknowledgement are needed for setup and control\r
+with remote servers. \r
+command can also be triggered from the service (QoS, broadcast announcements)\r
+cf above for command usage\r
+*/\r
+void gf_term_on_command(GF_ClientService *service, GF_NetworkCommand *com, GF_Err response);\r
+/*to call when data packet is received. \r
+@data, data_size: data received\r
+@hdr: uncompressed SL header passed with data for stream sync - if not present then data shall be a valid SL packet \r
+ (header + PDU). Note that using an SLConfig resulting in an empty GF_SLHeader allows sending raw data directly\r
+@reception_status: data reception status. To signal end of stream, set this to GF_EOS\r
+*/\r
+void gf_term_on_sl_packet(GF_ClientService *service, LPNETCHANNEL ns, char *data, u32 data_size, GF_SLHeader *hdr, GF_Err reception_status);\r
+/*returns URL associated with service (so that you don't need to store it)*/\r
+const char *gf_term_get_service_url(GF_ClientService *service);\r
+\r
+/*adds a new media from network. !! The media descriptor is then owned/destroyed by the term!!\r
+media_desc: object descriptor for the new media. May be NULL to force scene rebuilt.\r
+no_scene_check: specifies if the scene description shall be rebuilt or not.\r
+*/\r
+void gf_term_add_media(GF_ClientService *service, GF_Descriptor *media_desc, Bool no_scene_update);\r
+\r
+\r
+/*check if @fileExt extension is supported for given mimeType, and if associated with module. If mimeType not registered, register it for given module*/\r
+Bool gf_term_check_extension(GF_InputService *ifce, const char *mimeType, const char *extList, const char *description, const char *fileExt);\r
+/*register mime types & file extensions - most modules should only need the check version above*/\r
+void gf_term_register_mime_type(GF_InputService *ifce, const char *mimeType, const char *extList, const char *description);\r
+\r
+GF_InputService *gf_term_get_service_interface(GF_ClientService *service);\r
+\r
+/*file downloading - can and MUST be used by any module (regardless of license) in order not to interfere \r
+with net management*/\r
+/*creates a new downloading session in the given service - if url is relative, it will be interpreted through\r
+the service URL*/\r
+GF_DownloadSession * gf_term_download_new(GF_ClientService *service, const char *url, u32 flags, gf_dm_user_io user_io, void *cbk);\r
+/*closes the downloading session*/\r
+void gf_term_download_del(GF_DownloadSession * dnload);\r
+/*send progress and connection messages to user...*/\r
+void gf_term_download_update_stats(GF_DownloadSession * sess);\r
+\r
+\r
+/*MPEG-4 media cache interface name*/\r
+#define GF_STREAMING_MEDIA_CACHE GF_4CC('G', 'M', 'C', 0x01)\r
+\r
+typedef struct _cacheinterface\r
+{\r
+ /* interface declaration*/\r
+ GF_DECL_MODULE_INTERFACE\r
+\r
+ /*opens media cache at given place - extension is handled by cache module\r
+ @serv: service owning cache (eg, where to send data when requested)\r
+ @keep_existing_files: don't overwrite previously recorded sessions*/\r
+ GF_Err (*Open)(struct _cacheinterface *, GF_ClientService *serv, const char *location_and_name, Bool keep_existing_files);\r
+ /*closes media cache, delete file(s) if desired*/\r
+ GF_Err (*Close)(struct _cacheinterface *, Bool delete_cache);\r
+ /*writes data to cache. data is always a complete AU as reconstructed by gpac core\r
+ If first time data is written, user should query channel desc through service commands*/\r
+ GF_Err (*Write)(struct _cacheinterface *, LPNETCHANNEL ch, char *data, u32 data_size, GF_SLHeader *sl_hdr);\r
+\r
+ /*same as reader, except they MUST be provided - in other words, only PULL mode is supported for cache\r
+ at the current time*/\r
+ GF_Err (*ServiceCommand) (struct _cacheinterface *, GF_NetworkCommand *com);\r
+ GF_Err (*ChannelGetSLP) (struct _cacheinterface *, LPNETCHANNEL channel, char **out_data_ptr, u32 *out_data_size, GF_SLHeader *out_sl_hdr, Bool *sl_compressed, GF_Err *out_reception_status, Bool *is_new_data);\r
+ GF_Err (*ChannelReleaseSLP) (struct _cacheinterface *, LPNETCHANNEL channel);\r
+\r
+ /*module private*/\r
+ void *priv;\r
+} GF_StreamingCache;\r
+\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /*_GF_SERVICE_H_*/\r