Update of /cvsroot/pure-data/externals/pidip/include In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21968/include
Added Files: pdp_mp4audiosource.h pdp_mp4audiosync.h pdp_mp4config.h pdp_mp4configset.h pdp_mp4playermedia.h pdp_mp4playersession.h pdp_mp4player~.h pdp_mp4rtpbytestream.h pdp_mp4videosource.h pdp_mp4videosync.h Log Message: New in PiDiP 0.12.13
--- NEW FILE: pdp_mp4audiosource.h --- /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is MPEG4IP. * * The Initial Developer of the Original Code is Cisco Systems Inc. * Portions created by Cisco Systems Inc. are * Copyright (C) Cisco Systems Inc. 2000, 2001. All Rights Reserved. * * Contributor(s): * Dave Mackie dmackie@cisco.com * Bill May wmay@cisco.com * * Adapted for PD/PDP by Yves Degoyon (ydegoyon@free.fr) */
#ifndef __PDP_MP4AUDIOSOURCE__ #define __PDP_MP4AUDIOSOURCE__
#include <sys/types.h> #include <sys/ioctl.h> #include <linux/soundcard.h>
#include "media_source.h" #include "audio_encoder.h"
class CPDPAudioSource : public CMediaSource { public: CPDPAudioSource(CLiveConfig *pConfig);
~CPDPAudioSource() { free(m_pcmFrameBuffer); }
bool IsDone() { return false; }
float GetProgress() { return 0.0; }
void CPDPAudioSource::DoStart();
void CPDPAudioSource::DoStop();
void ProcessAudio(u_int8_t* pcmBuffer, u_int32_t pcmBufferSize);
protected: int ThreadMain();
bool Init();
protected: int m_maxPasses; Timestamp m_prevTimestamp; int m_audioOssMaxBufferSize; int m_audioOssMaxBufferFrames; Timestamp *m_timestampOverflowArray; size_t m_timestampOverflowArrayIndex; u_int8_t* m_pcmFrameBuffer; u_int32_t m_pcmFrameSize; uint32_t m_channelsConfigured; };
#endif /* __PDP_MP4AUDIOSOURCE__ */
--- NEW FILE: pdp_mp4playermedia.h --- /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is MPEG4IP. * * The Initial Developer of the Original Code is Cisco Systems Inc. * Portions created by Cisco Systems Inc. are * Copyright (C) Cisco Systems Inc. 2000, 2001. All Rights Reserved. * * Contributor(s): * Bill May wmay@cisco.com * * Adapted to PD/PDP by Yves Degoyon (ydegoyon@free.fr) */
/* * player_media.h - provides CPlayerMedia class, which defines the * interface to a particular media steam. */
#ifndef __PLAYER_MEDIA_H__ #define __PLAYER_MEDIA_H__
#include <SDL.h> #include <SDL_thread.h> #include <sdp/sdp.h> #include <rtsp/rtsp_client.h> #include <rtp/rtp.h> #include "our_bytestream.h" #include "our_msg_queue.h" #include "codec_plugin.h"
class CPlayerSession; class CPDPAudioSync; class CPDPVideoSync; class C2ConsecIpPort; class COurInByteStream; class CRtpByteStreamBase;
class CPlayerMedia { public: CPlayerMedia(CPlayerSession *p); ~CPlayerMedia(); /* API routine - create - for RTP stream */ int create_streaming(media_desc_t *sdp_media, char *errmsg, uint32_t errlen, int on_demand, int use_rtsp, int media_number_in_session); /* API routine - create - where we provide the bytestream */ int create(COurInByteStream *b, int is_video, char *errmsg = NULL, uint32_t errlen = 0, int streaming = 0); /* API routine - play, pause */ int do_play(double start_time_offset, char *errmsg, uint32_t errlen); int do_pause(void); int is_video(void) { return (m_is_video); }; double get_max_playtime(void); /* API routine - interface for decoding start/continue */ void start_decoding(void); void bytestream_primed(void); /* API routine - ip port information */ uint16_t get_our_port (void) { return m_our_port; }; void set_server_port (uint16_t port) { m_server_port = port; }; uint16_t get_server_port (void) { return m_server_port; };
media_desc_t *get_sdp_media_desc (void) { return m_media_info; }; void set_source_addr (char *s) { if (m_source_addr != NULL) free(m_source_addr); m_source_addr = s; } const char *get_source_addr(void); CPlayerMedia *get_next (void) { return m_next; }; void set_next (CPlayerMedia *newone) { m_next = newone; }; int decode_thread(void);
/* Public RTP routines - receive thread, callback, and routines to * pass information from rtsp to rtp byte stream */ int recv_thread(void); void recv_callback(struct rtp *session, rtp_event *e); void set_rtp_ssrc (uint32_t ssrc) { m_rtp_ssrc = ssrc; m_rtp_ssrc_set = TRUE;}; void set_rtp_base_ts(uint32_t time); void set_rtp_base_seq(uint16_t seq);
void set_video_sync(CPDPVideoSync *p) {m_video_sync = p;}; void set_audio_sync(CPDPAudioSync *p) {m_audio_sync = p;};
const video_info_t *get_video_info (void) { return m_video_info; }; const audio_info_t *get_audio_info (void) { return m_audio_info; };
int create_video_plugin(const codec_plugin_t *p, const char *compressor, int profile, int type, format_list_t *sdp_media, video_info_t *video, const uint8_t *user_data, uint32_t userdata_size); int create_audio_plugin(const codec_plugin_t *p, const char *compressor, int profile, int type, format_list_t *sdp_media, audio_info_t *audio, const uint8_t *user_data, uint32_t userdata_size); void set_plugin_data (const codec_plugin_t *p, codec_data_t *d, video_vft_t *v, audio_vft_t *a); int get_plugin_status(char *buffer, uint32_t buflen); void set_user_data (const uint8_t *udata, int length) { m_user_data = udata; m_user_data_size = length; } rtsp_session_t *get_rtsp_session(void) { return m_rtsp_session; }; void rtp_init_tcp(void); void rtp_periodic(void); void rtp_start(void); void rtp_end(void); int rtp_receive_packet(unsigned char interleaved, struct rtp_packet *, int len); int rtcp_send_packet(uint8_t *buffer, int buflen); int get_rtp_media_number (void) { return m_rtp_media_number_in_session; }; void syncronize_rtp_bytestreams(rtcp_sync_t *sync); private: int create_common(int is_video, char *errmsg, uint32_t errlen); void wait_on_bytestream(void); int m_streaming; int m_is_video; int m_paused; CPlayerMedia *m_next; CPlayerSession *m_parent; media_desc_t *m_media_info; format_list_t *m_media_fmt; // format currently running. rtsp_session_t *m_rtsp_session; C2ConsecIpPort *m_ports; in_port_t m_our_port; in_port_t m_server_port; char *m_source_addr;
time_t m_start_time; int m_stream_ondemand; int m_sync_time_set; uint64_t m_sync_time_offset; uint32_t m_rtptime_tickpersec; double m_play_start_time; // Receive thread variables SDL_Thread *m_recv_thread;
/************************************************************************* * RTP variables - used to pass info to the bytestream *************************************************************************/ int m_rtp_ondemand; int m_rtp_use_rtsp; int m_rtp_media_number_in_session; int m_rtp_buffering; struct rtp *m_rtp_session; CRtpByteStreamBase *m_rtp_byte_stream; CMsgQueue m_rtp_msg_queue;
rtp_packet *m_head, *m_tail; uint32_t m_rtp_queue_len;
// from rtsp... int m_rtp_ssrc_set; uint32_t m_rtp_ssrc; int m_rtsp_base_ts_received; uint32_t m_rtp_base_ts; int m_rtsp_base_seq_received; uint16_t m_rtp_base_seq;
int determine_payload_type_from_rtp(void); void create_rtp_byte_stream(uint8_t payload, uint64_t tps, format_list_t *fmt); void clear_rtp_packets(void);
// from rtcp, for broadcast, in case we get an RTCP before we determine // the payload type uint32_t m_rtcp_ntp_frac; uint32_t m_rtcp_ntp_sec; uint32_t m_rtcp_rtp_ts; int m_rtcp_received;
volatile int m_rtp_inited;
/************************************************************************* * Decoder thread variables *************************************************************************/ SDL_Thread *m_decode_thread; volatile int m_decode_thread_waiting; SDL_sem *m_decode_thread_sem;
const codec_plugin_t *m_plugin; codec_data_t *m_plugin_data;
// State change variable CMsgQueue m_decode_msg_queue; // Private routines int process_rtsp_transport(char *transport); CPDPAudioSync *m_audio_sync; CPDPVideoSync *m_video_sync; void parse_decode_message(int &thread_stop, int &decoding); COurInByteStream *m_byte_stream; video_info_t *m_video_info; audio_info_t *m_audio_info;
const uint8_t *m_user_data; int m_user_data_size;
};
int pdp_process_rtsp_rtpinfo(char *rtpinfo, CPlayerSession *session, CPlayerMedia *media);
extern audio_vft_t audio_vft; extern video_vft_t video_vft;
#define media_message(loglevel, fmt...) message(loglevel, "media", fmt)
#endif
--- NEW FILE: pdp_mp4rtpbytestream.h --- /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is MPEG4IP. * * The Initial Developer of the Original Code is Cisco Systems Inc. * Portions created by Cisco Systems Inc. are * Copyright (C) Cisco Systems Inc. 2000, 2001. All Rights Reserved. * * Contributor(s): * Bill May wmay@cisco.com */ /* * player_rtp_bytestream.h - provides an RTP bytestream for the codecs * to access */
#ifndef __RTP_BYTESTREAM_H__ #define __RTP_BYTESTREAM_H__ 1 #include "our_bytestream.h" #include "player_util.h" #include "rtp/rtp.h" #include <SDL.h> #include <SDL_thread.h> #include <sdp/sdp.h>
class CRtpByteStreamBase : public COurInByteStream { public: CRtpByteStreamBase(const char *name, format_list_t *fmt, unsigned int rtp_pt, int ondemand, uint64_t tickpersec, rtp_packet **head, rtp_packet **tail, int rtp_seq_set, uint16_t rtp_base_seq, int rtp_ts_set, uint32_t rtp_base_ts, int rtcp_received, uint32_t ntp_frac, uint32_t ntp_sec, uint32_t rtp_ts);
~CRtpByteStreamBase(); int eof (void) { return m_eof; }; virtual void reset(void) { player_debug_message("rtp bytestream reset"); init(); m_buffering = 0; m_base_ts_set = 0; m_rtp_base_seq_set = 0;
}; void set_skip_on_advance (uint32_t bytes_to_skip) { m_skip_on_advance_bytes = bytes_to_skip; }; double get_max_playtime (void) { if (m_fmt->media->media_range.have_range) { return m_fmt->media->media_range.range_end; } else if (m_fmt->media->parent->session_range.have_range) { return m_fmt->media->parent->session_range.range_end; } return 0.0; };
// various routines for RTP interface. void set_rtp_base_ts(uint32_t t, uint64_t value = 0) { m_base_ts_set = true; m_base_rtp_ts = t; m_base_ts = value; }; void set_rtp_base_seq(uint16_t s) { m_rtp_base_seq_set = true; m_rtp_base_seq = s; }; int can_skip_frame (void) { return 1; } ; void set_wallclock_offset (uint64_t wclock, uint32_t rtp_ts); int rtp_ready (void) { return true; }; void recv_callback(struct rtp *session, rtp_event *e); virtual void flush_rtp_packets(void); int recv_task(int waiting); uint32_t get_last_rtp_timestamp (void) {return m_rtptime_last; }; void remove_packet_rtp_queue(rtp_packet *pak, int free); void pause(void); void set_sync(CPlayerSession *psptr);
void syncronize(rtcp_sync_t *sync); protected: bool check_seq (uint16_t seq); void set_last_seq(uint16_t seq); void init(void); // Make sure all classes call this to calculate real time. uint64_t rtp_ts_to_msec(uint32_t rtp_ts, uint64_t uts, uint64_t &wrap_offset); rtp_packet *m_head, *m_tail; int m_offset_in_pak; uint32_t m_skip_on_advance_bytes; uint32_t m_ts; uint64_t m_total; bool m_base_ts_set; uint32_t m_base_rtp_ts; uint64_t m_base_ts; bool m_rtp_base_seq_set; uint16_t m_rtp_base_seq; uint64_t m_timescale; int m_stream_ondemand; uint64_t m_wrap_offset; bool m_rtcp_received; uint64_t m_rtcp_ts; uint32_t m_rtcp_rtp_ts; uint64_t m_wallclock_offset_wrap; void calculate_wallclock_offset_from_rtcp(uint32_t ntp_frac, uint32_t ntp_sec, uint32_t rtp_ts); SDL_mutex *m_rtp_packet_mutex; int m_buffering; uint64_t m_rtp_buffer_time; unsigned int m_rtp_pt; virtual int check_rtp_frame_complete_for_payload_type(void); virtual void rtp_done_buffering(void) {}; uint32_t m_rtptime_last; int m_recvd_pak; int m_recvd_pak_timeout; uint64_t m_recvd_pak_timeout_time; uint64_t m_last_realtime; format_list_t *m_fmt; int m_eof; int m_rtpinfo_set_from_pak; uint16_t m_next_seq; bool m_have_first_pak_ts; uint64_t m_first_pak_ts; uint32_t m_first_pak_rtp_ts; CPlayerSession *m_psptr; bool m_have_sync_info; rtcp_sync_t m_sync_info; };
class CRtpByteStream : public CRtpByteStreamBase { public: CRtpByteStream(const char *name, format_list_t *fmt, unsigned int rtp_pt, int ondemand, uint64_t tickpersec, rtp_packet **head, rtp_packet **tail, int rtp_seq_set, uint16_t rtp_base_seq, int rtp_ts_set, uint32_t rtp_base_ts, int rtcp_received, uint32_t ntp_frac, uint32_t ntp_sec, uint32_t rtp_ts); ~CRtpByteStream(); uint64_t start_next_frame(uint8_t **buffer, uint32_t *buflen, void **userdata); int skip_next_frame(uint64_t *ts, int *havesync, uint8_t **buffer, uint32_t *buflen, void **userdata = NULL); void used_bytes_for_frame(uint32_t bytes); int have_no_data(void); void flush_rtp_packets(void); void reset(void); protected: uint8_t *m_buffer; uint32_t m_buffer_len; uint32_t m_buffer_len_max; uint32_t m_bytes_used; };
class CAudioRtpByteStream : public CRtpByteStream { public: CAudioRtpByteStream(unsigned int rtp_pt, format_list_t *fmt, int ondemand, uint64_t tickpersec, rtp_packet **head, rtp_packet **tail, int rtp_seq_set, uint16_t rtp_base_seq, int rtp_ts_set, uint32_t rtp_base_ts, int rtcp_received, uint32_t ntp_frac, uint32_t ntp_sec, uint32_t rtp_ts); ~CAudioRtpByteStream(); int have_no_data(void); int check_rtp_frame_complete_for_payload_type(void); uint64_t start_next_frame(uint8_t **buffer, uint32_t *buflen, void **userdata); void reset(void); private: rtp_packet *m_working_pak; }; int add_rtp_packet_to_queue(rtp_packet *pak, rtp_packet **head, rtp_packet **tail, const char *name); #endif
--- NEW FILE: pdp_mp4audiosync.h --- /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is MPEG4IP. * * The Initial Developer of the Original Code is Cisco Systems Inc. * Portions created by Cisco Systems Inc. are * Copyright (C) Cisco Systems Inc. 2000, 2001. All Rights Reserved. * * Contributor(s): * Bill May wmay@cisco.com * * Adapted to PD/PDP by Yves Degoyon (ydegoyon@free.fr) */
/* * audio.h - provides a class that interfaces between the codec and * the SDL audio application. Will provide for volume, buffering, * syncronization */
#ifndef __PDP_MP4AUDIOSYNC__ #define __PDP_MP4AUDIOSYNC__
#include "audio.h" #include "pdp_mp4player~.h"
#define DECODE_BUFFERS_MAX 32
class CPDPAudioSync : public CAudioSync { public: CPDPAudioSync(CPlayerSession *psptr, t_pdp_mp4player *pdp_father); ~CPDPAudioSync(void); // APIs from codec uint8_t *get_audio_buffer(void); void filled_audio_buffer(uint64_t ts, int resync); void set_config(int freq, int channels, int format, uint32_t max_buffer_size); void set_eof(void); void load_audio_buffer(uint8_t *from, uint32_t bytes, uint64_t ts, int resync);
// APIs from sync task int initialize_audio(int have_video); int is_audio_ready(uint64_t &disptime); uint64_t check_audio_sync(uint64_t current_time, int &have_eof); void play_audio(void); void audio_callback(Uint8 *stream, int len); void flush_sync_buffers(void); void flush_decode_buffers(void);
// Initialization, other APIs void set_wait_sem(SDL_sem *p) { }; //m_audio_waiting = p; } ; void set_volume(int volume);
private: void audio_convert_data(void *from, uint32_t len); volatile int m_dont_fill; uint64_t m_buffer_ts; uint32_t m_buffer_offset_on; uint32_t m_buffer_size; uint32_t m_fill_index, m_play_index; volatile int m_buffer_filled[DECODE_BUFFERS_MAX]; uint64_t m_buffer_time[DECODE_BUFFERS_MAX]; uint64_t m_last_fill_timestamp; uint64_t m_play_time; SDL_AudioSpec m_obtained; uint8_t *m_sample_buffer[DECODE_BUFFERS_MAX]; int m_config_set; int m_audio_initialized; int m_freq; int m_channels; int m_format; int m_resync_required; int m_audio_paused; int m_consec_no_buffers; volatile int m_audio_waiting_buffer; int m_use_SDL_delay; uint32_t m_resync_buffer; SDL_sem *m_audio_waiting; uint32_t m_skipped_buffers; uint32_t m_didnt_fill_buffers; int m_first_time; int m_first_filled; uint32_t m_msec_per_frame; uint64_t m_buffer_latency; int m_consec_wrong_latency; int64_t m_wrong_latency_total; int m_volume; int m_do_sync; int m_load_audio_do_next_resync; uint32_t m_sample_size; uint32_t m_play_sample_index; uint32_t m_samples_loaded; uint32_t m_bytes_per_sample; uint64_t m_loaded_next_ts; int m_silence; void *m_convert_buffer; t_pdp_mp4player *m_father; };
CPDPAudioSync *pdp_create_audio_sync(CPlayerSession *, t_pdp_mp4player *pdp_father);
#endif
--- NEW FILE: pdp_mp4videosync.h --- /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is MPEG4IP. * * The Initial Developer of the Original Code is Cisco Systems Inc. * Portions created by Cisco Systems Inc. are * Copyright (C) Cisco Systems Inc. 2000, 2001. All Rights Reserved. * * Contributor(s): * Bill May wmay@cisco.com * video aspect ratio by: * Peter Maersk-Moller peter@maersk-moller.net * * Adapted for PD/PDP by Yves Degoyon (ydegoyon@free.fr) */
/* * video.h - contains the interface class between the codec and the video * display hardware. */
#ifndef __PDP_MP4VIDEOSYNC__ #define __PDP_MP4VIDEOSYNC__
#include "video.h" #include "pdp_mp4player~.h"
class CPDPVideoSync : public CVideoSync { public: CPDPVideoSync(CPlayerSession *psptr, t_pdp_mp4player *pdp_father); ~CPDPVideoSync(void); int initialize_video(const char *name); // from sync task int is_video_ready(uint64_t &disptime); // from sync task int64_t play_video_at(uint64_t current_time, // from sync task int &have_eof); int get_video_buffer(uint8_t **y, uint8_t **u, uint8_t **v); void filled_video_buffers(uint64_t time); void set_video_frame(const uint8_t *y, // from codec const uint8_t *u, const uint8_t *v, int m_pixelw_y, int m_pixelw_uv, uint64_t time); void config (int w, int h); // from codec void set_wait_sem (SDL_sem *p) { m_decode_sem = p; }; // from set up void flush_decode_buffers(void); // from decoder task in response to stop void flush_sync_buffers(void); // from sync task in response to stop void play_video(void); private: int m_video_bpp; int m_video_scale; int m_fullscreen; unsigned int m_width, m_height; int m_video_initialized; int m_config_set; int m_paused; int m_double_width; volatile int m_have_data; SDL_Surface *m_screen; SDL_Overlay *m_image; SDL_Rect m_dstrect; uint32_t m_fill_index, m_play_index; int m_decode_waiting; volatile int m_buffer_filled[MAX_VIDEO_BUFFERS]; uint8_t *m_y_buffer[MAX_VIDEO_BUFFERS]; uint8_t *m_u_buffer[MAX_VIDEO_BUFFERS]; uint8_t *m_v_buffer[MAX_VIDEO_BUFFERS]; uint64_t m_play_this_at[MAX_VIDEO_BUFFERS]; int m_dont_fill; int m_pixel_width; int m_pixel_height; int m_max_width; int m_max_height; t_pdp_mp4player *m_father; };
CPDPVideoSync *pdp_create_video_sync(CPlayerSession *psptr, t_pdp_mp4player *pdp_father);
#endif
--- NEW FILE: pdp_mp4configset.h --- /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is MPEG4IP. * * The Initial Developer of the Original Code is Cisco Systems Inc. * Portions created by Cisco Systems Inc. are * Copyright (C) Cisco Systems Inc. 2000, 2001. All Rights Reserved. * * Contributor(s): * Dave Mackie dmackie@cisco.com * Bill May wmay@cisco.com * * Adapted for PD/PDP by Yves Degoyon (ydegoyon@free.fr) */
#ifndef __CONFIG_SET_H__ #define __CONFIG_SET_H__
#include <mpeg4ip.h>
#ifndef CONFIG_SAFETY #define CONFIG_SAFETY 1 #endif
typedef u_int32_t config_integer_t;
typedef u_int16_t config_index_t;
enum ConfigException { CONFIG_ERR_INAME, CONFIG_ERR_TYPE, CONFIG_ERR_MEMORY, };
// TBD type specific exception info and printing utility class CConfigException { public: CConfigException(ConfigException e) { type = e; fprintf( stderr, "pdp_mp4configset : exception : type : %d\n", e ); } ConfigException type; };
#define CONFIG_MAX_STRLEN 255
// TBD weld this in, and throw exception inline char* stralloc(const char* src) { char* dst = (char*)malloc(strlen(src)+1); if (dst) { strcpy(dst, src); } return dst; }
enum ConfigType { CONFIG_TYPE_UNDEFINED, CONFIG_TYPE_INTEGER, CONFIG_TYPE_BOOL, CONFIG_TYPE_STRING, CONFIG_TYPE_FLOAT };
union UConfigValue { UConfigValue(void) { m_svalue = NULL; } UConfigValue(config_integer_t ivalue) { m_ivalue = ivalue; } UConfigValue(bool bvalue) { m_bvalue = bvalue; } UConfigValue(char* svalue) { m_svalue = svalue; } UConfigValue(float fvalue) { m_fvalue = fvalue; }
config_integer_t m_ivalue; bool m_bvalue; char* m_svalue; float m_fvalue; };
struct SConfigVariable { config_index_t *m_iName; const char* m_sName; ConfigType m_type; UConfigValue m_defaultValue; UConfigValue m_value;
const char* ToAscii() { static char sBuf[CONFIG_MAX_STRLEN+3]; switch (m_type) { case CONFIG_TYPE_INTEGER: sprintf(sBuf, "%d", m_value.m_ivalue); return sBuf; case CONFIG_TYPE_BOOL: sprintf(sBuf, "%d", m_value.m_bvalue); return sBuf; case CONFIG_TYPE_STRING: if (strchr(m_value.m_svalue, ' ')) { sBuf[0] = '"'; strncpy(&sBuf[1], m_value.m_svalue, CONFIG_MAX_STRLEN); strcpy(&sBuf[ MIN(strlen(m_value.m_svalue), CONFIG_MAX_STRLEN)+1], """); } return m_value.m_svalue; case CONFIG_TYPE_FLOAT: sprintf(sBuf, "%f", m_value.m_fvalue); return sBuf; default: return ""; } }
bool FromAscii(const char* s) { switch (m_type) { case CONFIG_TYPE_INTEGER: return (sscanf(s, " %i ", &m_value.m_ivalue) == 1); case CONFIG_TYPE_BOOL: // OPTION could add "yes/no", "true/false" if (sscanf(s, " %u ", &m_value.m_ivalue) != 1) { return false; } m_value.m_bvalue = m_value.m_ivalue ? true : false; return true; case CONFIG_TYPE_STRING: // N.B. assuming m_svalue has been alloc'ed { size_t len = strlen(s); free(m_value.m_svalue); if (*s == '"' && s[len] == '"') { m_value.m_svalue = strdup(s + 1); m_value.m_svalue[len - 1] = '\0'; } else { m_value.m_svalue = strdup(s); } if (m_value.m_svalue == NULL) { throw new CConfigException(CONFIG_ERR_MEMORY); } return true; } case CONFIG_TYPE_FLOAT: return (sscanf(s, " %f ", &m_value.m_fvalue) == 1); default: return false; } }
void SetToDefault(void) { switch (m_type) { case CONFIG_TYPE_INTEGER: m_value.m_ivalue = m_defaultValue.m_ivalue; break; case CONFIG_TYPE_BOOL: m_value.m_bvalue = m_defaultValue.m_bvalue; break; case CONFIG_TYPE_STRING: // free(m_value.m_svalue); m_value.m_svalue = stralloc(m_defaultValue.m_svalue); if (m_value.m_svalue == NULL) { throw new CConfigException(CONFIG_ERR_MEMORY); } break; case CONFIG_TYPE_FLOAT: m_value.m_fvalue = m_defaultValue.m_fvalue; break; default: break; } }
bool IsValueDefault(void) { switch (m_type) { case CONFIG_TYPE_INTEGER: return m_value.m_ivalue == m_defaultValue.m_ivalue; case CONFIG_TYPE_BOOL: return m_value.m_bvalue == m_defaultValue.m_bvalue; case CONFIG_TYPE_STRING: return (strcmp(m_value.m_svalue, m_defaultValue.m_svalue) == 0); case CONFIG_TYPE_FLOAT: return m_value.m_fvalue == m_defaultValue.m_fvalue; default: return false; } } void CleanUpConfig(void) { if (m_type == CONFIG_TYPE_STRING) { CHECK_AND_FREE(m_value.m_svalue); } } };
struct SUnknownConfigVariable { struct SUnknownConfigVariable *next; char *value; };
class CConfigSet { public: CConfigSet(SConfigVariable* variables, config_index_t numVariables, const char* defaultFileName) { uint32_t size; m_fileName = NULL; m_debug = false; m_variables = variables; m_numVariables = numVariables; size = sizeof(SConfigVariable) * numVariables; m_variables = (SConfigVariable*)malloc(size);
memcpy(m_variables, variables, size); m_defaultFileName = strdup(defaultFileName); SetToDefaults(); m_unknown_head = NULL; };
~CConfigSet() { free(m_fileName); for (config_index_t i = 0; i < m_numVariables; i++) { m_variables[i].CleanUpConfig(); } free(m_variables); m_variables = NULL; SUnknownConfigVariable *ptr = m_unknown_head; while (ptr != NULL) { m_unknown_head = ptr->next; free(ptr->value); free(ptr); ptr = m_unknown_head; } CHECK_AND_FREE(m_defaultFileName); }
void InitializeIndexes(void) { for (config_index_t ix = 0; ix < m_numVariables; ix++) { *m_variables[ix].m_iName = ix; } }
void AddConfigVariables (SConfigVariable* vars, config_index_t numVariables) { config_index_t start = m_numVariables; uint32_t size = sizeof(SConfigVariable) * (m_numVariables + numVariables); m_variables = (SConfigVariable*)realloc(m_variables, size); memcpy(&m_variables[m_numVariables], vars, numVariables * sizeof(SConfigVariable)); m_numVariables += numVariables; SetToDefaults(start); }
const char* GetFileName() { return m_fileName; }
inline void CheckIName(config_index_t iName) { if (iName >= m_numVariables) { throw new CConfigException(CONFIG_ERR_INAME); } if (*m_variables[iName].m_iName != iName) { throw new CConfigException(CONFIG_ERR_INAME); } }
inline void CheckIntegerType(config_index_t iName) { if (m_variables[iName].m_type != CONFIG_TYPE_INTEGER) { throw new CConfigException(CONFIG_ERR_TYPE); } }
inline void CheckBoolType(config_index_t iName) { if (m_variables[iName].m_type != CONFIG_TYPE_BOOL) { throw new CConfigException(CONFIG_ERR_TYPE); } }
inline void CheckStringType(config_index_t iName) { if (m_variables[iName].m_type != CONFIG_TYPE_STRING) { throw new CConfigException(CONFIG_ERR_TYPE); } }
inline void CheckFloatType(config_index_t iName) { if (m_variables[iName].m_type != CONFIG_TYPE_FLOAT) { throw new CConfigException(CONFIG_ERR_TYPE); } }
inline bool IsDefault (const config_index_t iName) { #if CONFIG_SAFETY CheckIName(iName); CheckIntegerType(iName); #endif return m_variables[iName].IsValueDefault(); };
inline config_integer_t GetIntegerValue(const config_index_t iName) { #if CONFIG_SAFETY CheckIName(iName); CheckIntegerType(iName); #endif return m_variables[iName].m_value.m_ivalue; }
inline void SetIntegerValue(const config_index_t iName, config_integer_t ivalue) { #if CONFIG_SAFETY CheckIName(iName); CheckIntegerType(iName); #endif m_variables[iName].m_value.m_ivalue = ivalue; }
inline bool GetBoolValue(const config_index_t iName) { #if CONFIG_SAFETY CheckIName(iName); CheckBoolType(iName); #endif return m_variables[iName].m_value.m_bvalue;; }
inline void SetBoolValue(const config_index_t iName, bool bvalue) { #if CONFIG_SAFETY CheckIName(iName); CheckBoolType(iName); #endif m_variables[iName].m_value.m_bvalue = bvalue; }
inline char* GetStringValue(const config_index_t iName) { #if CONFIG_SAFETY CheckIName(iName); CheckStringType(iName); #endif return m_variables[iName].m_value.m_svalue; }
inline void SetStringValue(const config_index_t iName, const char* svalue) { printf ( "setting variable : %d to : %s\n", iName, svalue ); #if CONFIG_SAFETY CheckIName(iName); CheckStringType(iName); #endif if (svalue == m_variables[iName].m_value.m_svalue) { return; } // free(m_variables[iName].m_value.m_svalue); m_variables[iName].m_value.m_svalue = stralloc(svalue); if (m_variables[iName].m_value.m_svalue == NULL) { throw new CConfigException(CONFIG_ERR_MEMORY); } }
inline float GetFloatValue(const config_index_t iName) { #if CONFIG_SAFETY CheckIName(iName); CheckFloatType(iName); #endif return m_variables[iName].m_value.m_fvalue; }
inline void SetFloatValue(const config_index_t iName, float fvalue) { #if CONFIG_SAFETY CheckIName(iName); CheckFloatType(iName); #endif m_variables[iName].m_value.m_fvalue = fvalue; }
void SetToDefaults(int start = 0) { for (config_index_t i = start; i < m_numVariables; i++) { m_variables[i].SetToDefault(); } }
void SetToDefault(const config_index_t iName) { m_variables[iName].SetToDefault(); }
void ProcessLine (char *line) { // comment if (line[0] == '#') { return; } char* s = line; while (*s != '\0') s++; s--; while (isspace(*s)) { *s = '\0'; s--; } s = line;
SConfigVariable* var = FindByName(strsep(&s, "=")); if (var == NULL || s == NULL) { if (s != NULL) { *(s - 1) = '='; // restore seperation character SUnknownConfigVariable *ptr; ptr = MALLOC_STRUCTURE(SUnknownConfigVariable); ptr->next = m_unknown_head; ptr->value = strdup(line); m_unknown_head = ptr; } if (m_debug) { fprintf(stderr, "bad config line %s\n", s); } return; } if (!var->FromAscii(s)) { if (m_debug) { fprintf(stderr, "bad config value in line %s\n", s); } } }
bool ReadFromFile(const char* fileName) { free(m_fileName); m_fileName = stralloc(fileName); FILE* pFile = fopen(fileName, "r"); if (pFile == NULL) { if (m_debug) { fprintf(stderr, "couldn't open file %s\n", fileName); } return false; } char line[256]; while (fgets(line, sizeof(line), pFile)) { ProcessLine(line); } fclose(pFile); return true; }
bool WriteToFile(const char* fileName, bool allValues = false) { FILE* pFile = fopen(fileName, "w"); config_index_t i; SConfigVariable *var; SUnknownConfigVariable *ptr;
if (pFile == NULL) { if (m_debug) { fprintf(stderr, "couldn't open file %s\n", fileName); } return false; } for (i = 0; i < m_numVariables; i++) { var = &m_variables[i]; if (allValues || !var->IsValueDefault()) { fprintf(pFile, "%s=%s\n", var->m_sName, var->ToAscii()); } } ptr = m_unknown_head; while (ptr != NULL) { fprintf(pFile, "%s\n", ptr->value); ptr = ptr->next; } fclose(pFile); return true; }
bool ReadDefaultFile(void) { return ReadFromFile(m_defaultFileName); } bool WriteDefaultFile(void) { return WriteToFile(m_defaultFileName); }
void SetDebug(bool debug = true) { m_debug = debug; }
protected: SConfigVariable* FindByName(const char* sName) { for (config_index_t i = 0; i < m_numVariables; i++) { if (!strcasecmp(sName, m_variables[i].m_sName)) { return &m_variables[i]; } } return NULL; };
protected: SConfigVariable* m_variables; config_index_t m_numVariables; const char* m_defaultFileName; bool m_debug; char* m_fileName; SUnknownConfigVariable *m_unknown_head; };
// To define configuration variables - first DECLARE_CONFIG in a // .h file. Then in either a C++ or h file, define a static array // of configuration variables using CONFIG_BOOL, CONFIG_FLOAT, CONFIG_INT // or CONFIG_STRING. You can include the .h anywhere you use the variable - // in a .cpp, you must include the .h file with DECLARE_CONFIG_VARIABLES // defined before the .h file. Note - if you're already including mp4live.h, // you need to #define the DECLARE_CONFIG_VARIABLES after the include. // // Note - you want to add the config variables BEFORE the ReadFromFile // call #ifdef DECLARE_CONFIG_VARIABLES #define DECLARE_CONFIG(a) config_index_t (a); #else #define DECLARE_CONFIG(a) extern config_index_t (a); #endif
#define CONFIG_BOOL(var, name, defval) \ { &(var), (name), CONFIG_TYPE_BOOL, (defval), } #define CONFIG_FLOAT(var, name, defval) \ { &(var), (name), CONFIG_TYPE_FLOAT,(float) (defval), } #define CONFIG_INT(var, name, defval) \ { &(var), (name), CONFIG_TYPE_INTEGER,(config_integer_t) (defval), } #define CONFIG_STRING(var, name, defval) \ { &(var), (name), CONFIG_TYPE_STRING, (defval), }
#endif /* __CONFIG_SET_H__ */
--- NEW FILE: pdp_mp4config.h --- /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is MPEG4IP. * * The Initial Developer of the Original Code is Cisco Systems Inc. * Portions created by Cisco Systems Inc. are * Copyright (C) Cisco Systems Inc. 2000, 2001. All Rights Reserved. * * Contributor(s): * Dave Mackie dmackie@cisco.com * Bill May wmay@cisco.com * * Adapted for PD/PDP by Yves Degoyon (ydegoyon@free.fr) */
#ifndef __LIVE_CONFIG_H__ #define __LIVE_CONFIG_H__
#include <sys/types.h> #include <linux/videodev.h>
#include "pdp_mp4configset.h"
#include "media_time.h" #include "video_util_tv.h"
#define FILE_SOURCE "FILE" #define URL_SOURCE "URL"
#define AUDIO_SOURCE_OSS "OSS" #define AUDIO_SOURCE_PDP "PDP"
#define AUDIO_ENCODER_FAAC "faac" #define AUDIO_ENCODER_LAME "lame" #define AUDIO_ENCODING_NONE "None" #define AUDIO_ENCODING_PCM16 "PCM16" #define AUDIO_ENCODING_MP3 "MP3" #define AUDIO_ENCODING_AAC "AAC" #define AUDIO_ENCODING_AC3 "AC3" #define AUDIO_ENCODING_VORBIS "VORBIS"
#define VIDEO_SOURCE_V4L "V4L" #define VIDEO_SOURCE_PDP "PDP"
#define VIDEO_ENCODER_FFMPEG "ffmpeg" #define VIDEO_ENCODER_DIVX "divx" #define VIDEO_ENCODER_H26L "h26l" #define VIDEO_ENCODER_XVID "xvid" #define VIDEO_ENCODER_H261 "h261"
#define VIDEO_ENCODING_NONE "None" #define VIDEO_ENCODING_YUV12 "YUV12" #define VIDEO_ENCODING_MPEG2 "MPEG2" #define VIDEO_ENCODING_MPEG4 "MPEG4" #define VIDEO_ENCODING_H26L "H26L" #define VIDEO_ENCODING_H261 "H261"
#define VIDEO_NTSC_FRAME_RATE ((float)29.97) #define VIDEO_PAL_FRAME_RATE ((float)25.00)
#define VIDEO_STD_ASPECT_RATIO ((float)1.33) // standard 4:3 #define VIDEO_LB1_ASPECT_RATIO ((float)2.35) // typical "widescreen" format #define VIDEO_LB2_ASPECT_RATIO ((float)1.85) // alternate widescreen format #define VIDEO_LB3_ASPECT_RATIO ((float)1.78) // hdtv 16:9
#define MP3_MPEG1_SAMPLES_PER_FRAME 1152 // for MPEG-1 bitrates #define MP3_MPEG2_SAMPLES_PER_FRAME 576 // for MPEG-2 bitrates
#define VIDEO_SIGNAL_PAL 0 #define VIDEO_SIGNAL_NTSC 1 #define VIDEO_SIGNAL_SECAM 2
DECLARE_CONFIG(CONFIG_APP_REAL_TIME); DECLARE_CONFIG(CONFIG_APP_REAL_TIME_SCHEDULER); DECLARE_CONFIG(CONFIG_APP_DURATION); DECLARE_CONFIG(CONFIG_APP_DURATION_UNITS); DECLARE_CONFIG(CONFIG_APP_FILE_0); DECLARE_CONFIG(CONFIG_APP_FILE_1); DECLARE_CONFIG(CONFIG_APP_FILE_2); DECLARE_CONFIG(CONFIG_APP_FILE_3); DECLARE_CONFIG(CONFIG_APP_FILE_4); DECLARE_CONFIG(CONFIG_APP_FILE_5); DECLARE_CONFIG(CONFIG_APP_FILE_6); DECLARE_CONFIG(CONFIG_APP_FILE_7); DECLARE_CONFIG(CONFIG_APP_DEBUG); DECLARE_CONFIG(CONFIG_APP_LOGLEVEL); DECLARE_CONFIG(CONFIG_APP_SIGNAL_HALT);
DECLARE_CONFIG(CONFIG_AUDIO_ENABLE); DECLARE_CONFIG(CONFIG_AUDIO_SOURCE_TYPE); DECLARE_CONFIG(CONFIG_AUDIO_SOURCE_NAME); DECLARE_CONFIG(CONFIG_AUDIO_MIXER_NAME); DECLARE_CONFIG(CONFIG_AUDIO_INPUT_NAME); DECLARE_CONFIG(CONFIG_AUDIO_SOURCE_TRACK); DECLARE_CONFIG(CONFIG_AUDIO_CHANNELS); DECLARE_CONFIG(CONFIG_AUDIO_SAMPLE_RATE); DECLARE_CONFIG(CONFIG_AUDIO_BIT_RATE_KBPS); DECLARE_CONFIG(CONFIG_AUDIO_BIT_RATE); DECLARE_CONFIG(CONFIG_AUDIO_ENCODING); DECLARE_CONFIG(CONFIG_AUDIO_ENCODER); DECLARE_CONFIG(CONFIG_AUDIO_OSS_USE_SMALL_FRAGS); DECLARE_CONFIG(CONFIG_AUDIO_OSS_FRAGMENTS); DECLARE_CONFIG(CONFIG_AUDIO_OSS_FRAG_SIZE);
DECLARE_CONFIG(CONFIG_VIDEO_ENABLE); DECLARE_CONFIG(CONFIG_VIDEO_SOURCE_TYPE); DECLARE_CONFIG(CONFIG_VIDEO_SOURCE_NAME); DECLARE_CONFIG(CONFIG_VIDEO_INPUT); DECLARE_CONFIG(CONFIG_VIDEO_SIGNAL); DECLARE_CONFIG(CONFIG_VIDEO_TUNER); DECLARE_CONFIG(CONFIG_VIDEO_CHANNEL_LIST_INDEX); DECLARE_CONFIG(CONFIG_VIDEO_CHANNEL_INDEX); DECLARE_CONFIG(CONFIG_VIDEO_SOURCE_TRACK); DECLARE_CONFIG(CONFIG_VIDEO_PREVIEW); DECLARE_CONFIG(CONFIG_VIDEO_RAW_PREVIEW); DECLARE_CONFIG(CONFIG_VIDEO_ENCODED_PREVIEW); DECLARE_CONFIG(CONFIG_VIDEO_ENCODER); DECLARE_CONFIG(CONFIG_VIDEO_ENCODING); DECLARE_CONFIG(CONFIG_VIDEO_RAW_WIDTH); DECLARE_CONFIG(CONFIG_VIDEO_RAW_HEIGHT); DECLARE_CONFIG(CONFIG_VIDEO_ASPECT_RATIO); DECLARE_CONFIG(CONFIG_VIDEO_FRAME_RATE); DECLARE_CONFIG(CONFIG_VIDEO_KEY_FRAME_INTERVAL); DECLARE_CONFIG(CONFIG_VIDEO_BIT_RATE); DECLARE_CONFIG(CONFIG_VIDEO_PROFILE_ID); DECLARE_CONFIG(CONFIG_VIDEO_BRIGHTNESS); DECLARE_CONFIG(CONFIG_VIDEO_HUE); DECLARE_CONFIG(CONFIG_VIDEO_COLOR); DECLARE_CONFIG(CONFIG_VIDEO_CONTRAST); DECLARE_CONFIG(CONFIG_VIDEO_TIMEBITS); DECLARE_CONFIG(CONFIG_V4L_CACHE_TIMESTAMP); DECLARE_CONFIG(CONFIG_VIDEO_H261_QUALITY); DECLARE_CONFIG(CONFIG_VIDEO_H261_QUALITY_ADJ_FRAMES); DECLARE_CONFIG(CONFIG_VIDEO_CAP_BUFF_COUNT);
DECLARE_CONFIG(CONFIG_RECORD_ENABLE); DECLARE_CONFIG(CONFIG_RECORD_RAW_AUDIO); DECLARE_CONFIG(CONFIG_RECORD_RAW_VIDEO); DECLARE_CONFIG(CONFIG_RECORD_ENCODED_AUDIO); DECLARE_CONFIG(CONFIG_RECORD_ENCODED_VIDEO); DECLARE_CONFIG(CONFIG_RECORD_MP4_FILE_NAME); DECLARE_CONFIG(CONFIG_RECORD_MP4_HINT_TRACKS); DECLARE_CONFIG(CONFIG_RECORD_MP4_OVERWRITE); DECLARE_CONFIG(CONFIG_RECORD_MP4_OPTIMIZE);
DECLARE_CONFIG(CONFIG_RTP_ENABLE); DECLARE_CONFIG(CONFIG_RTP_DEST_ADDRESS); // for video DECLARE_CONFIG(CONFIG_RTP_AUDIO_DEST_PORT); DECLARE_CONFIG(CONFIG_RTP_VIDEO_DEST_PORT); DECLARE_CONFIG(CONFIG_RTP_RECV_BUFFER_TIME); DECLARE_CONFIG(CONFIG_RTP_PAYLOAD_SIZE); DECLARE_CONFIG(CONFIG_RTP_MCAST_TTL); DECLARE_CONFIG(CONFIG_RTP_DISABLE_TS_OFFSET); DECLARE_CONFIG(CONFIG_RTP_USE_SSM); DECLARE_CONFIG(CONFIG_SDP_FILE_NAME); DECLARE_CONFIG(CONFIG_RTP_AUDIO_DEST_ADDRESS); DECLARE_CONFIG(CONFIG_RTP_USE_MP3_PAYLOAD_14); DECLARE_CONFIG(CONFIG_RTP_NO_B_RR_0); DECLARE_CONFIG(CONFIG_RAW_ENABLE); DECLARE_CONFIG(CONFIG_RAW_PCM_FILE_NAME); DECLARE_CONFIG(CONFIG_RAW_PCM_FIFO); DECLARE_CONFIG(CONFIG_RAW_YUV_FILE_NAME); DECLARE_CONFIG(CONFIG_RAW_YUV_FIFO);
#ifdef DECLARE_CONFIG_VARIABLES static SConfigVariable PdpConfigVariables[] = {
CONFIG_BOOL(CONFIG_APP_REAL_TIME, "isRealTime", true), CONFIG_BOOL(CONFIG_APP_REAL_TIME_SCHEDULER, "useRealTimeScheduler", true), CONFIG_INT(CONFIG_APP_DURATION, "duration", 1), CONFIG_INT(CONFIG_APP_DURATION_UNITS, "durationUnits", 60),
CONFIG_STRING(CONFIG_APP_FILE_0, "file0", ""), CONFIG_STRING(CONFIG_APP_FILE_1, "file1", ""), CONFIG_STRING(CONFIG_APP_FILE_2, "file2", ""), CONFIG_STRING(CONFIG_APP_FILE_3, "file3", ""), CONFIG_STRING(CONFIG_APP_FILE_4, "file4", ""), CONFIG_STRING(CONFIG_APP_FILE_5, "file5", ""), CONFIG_STRING(CONFIG_APP_FILE_6, "file6", ""), CONFIG_STRING(CONFIG_APP_FILE_7, "file7", ""),
CONFIG_BOOL(CONFIG_APP_DEBUG, "debug", false), CONFIG_INT(CONFIG_APP_LOGLEVEL, "logLevel", 0), CONFIG_STRING(CONFIG_APP_SIGNAL_HALT, "signalHalt", "sighup"),
// AUDIO
CONFIG_BOOL(CONFIG_AUDIO_ENABLE, "audioEnable", true), CONFIG_STRING(CONFIG_AUDIO_SOURCE_TYPE, "audioSourceType", AUDIO_SOURCE_PDP), CONFIG_STRING(CONFIG_AUDIO_SOURCE_NAME, "audioDevice", "/dev/dsp"), CONFIG_STRING(CONFIG_AUDIO_MIXER_NAME, "audioMixer", "/dev/mixer"), CONFIG_STRING(CONFIG_AUDIO_INPUT_NAME, "audioInput", "mix"),
CONFIG_INT(CONFIG_AUDIO_SOURCE_TRACK, "audioSourceTrack", 0), CONFIG_INT(CONFIG_AUDIO_CHANNELS, "audioChannels", 2), CONFIG_INT(CONFIG_AUDIO_SAMPLE_RATE, "audioSampleRate", 44100), CONFIG_INT(CONFIG_AUDIO_BIT_RATE_KBPS, "audioBitRate", 128), CONFIG_INT(CONFIG_AUDIO_BIT_RATE, "audioBitRateBps", 128000), CONFIG_STRING(CONFIG_AUDIO_ENCODING, "audioEncoding", AUDIO_ENCODING_AAC), CONFIG_STRING(CONFIG_AUDIO_ENCODER, "audioEncoder", AUDIO_ENCODER_FAAC),
CONFIG_BOOL(CONFIG_AUDIO_OSS_USE_SMALL_FRAGS, "audioOssUseSmallFrags", true), CONFIG_INT(CONFIG_AUDIO_OSS_FRAGMENTS, "audioOssFragments", 128), CONFIG_INT(CONFIG_AUDIO_OSS_FRAG_SIZE, "audioOssFragSize", 8),
// VIDEO
CONFIG_BOOL(CONFIG_VIDEO_ENABLE, "videoEnable", true), CONFIG_STRING(CONFIG_VIDEO_SOURCE_TYPE, "videoSourceType", VIDEO_SOURCE_PDP), CONFIG_STRING(CONFIG_VIDEO_SOURCE_NAME, "videoDevice", "/dev/video0"), CONFIG_INT(CONFIG_VIDEO_INPUT, "videoInput", 1), CONFIG_INT(CONFIG_VIDEO_SIGNAL, "videoSignal", VIDEO_SIGNAL_NTSC),
CONFIG_INT(CONFIG_VIDEO_TUNER, "videoTuner", -1), CONFIG_INT(CONFIG_VIDEO_CHANNEL_LIST_INDEX, "videoChannelListIndex", 0), CONFIG_INT(CONFIG_VIDEO_CHANNEL_INDEX, "videoChannelIndex", 1),
CONFIG_INT(CONFIG_VIDEO_SOURCE_TRACK, "videoSourceTrack", 0),
CONFIG_BOOL(CONFIG_VIDEO_PREVIEW, "videoPreview", true), CONFIG_BOOL(CONFIG_VIDEO_RAW_PREVIEW, "videoRawPreview", false), CONFIG_BOOL(CONFIG_VIDEO_ENCODED_PREVIEW, "videoEncodedPreview", true),
CONFIG_STRING(CONFIG_VIDEO_ENCODER, "videoEncoder", VIDEO_ENCODER_XVID), CONFIG_STRING(CONFIG_VIDEO_ENCODING, "videoEncoding", VIDEO_ENCODING_MPEG4),
CONFIG_INT(CONFIG_VIDEO_RAW_WIDTH, "videoRawWidth", 320), CONFIG_INT(CONFIG_VIDEO_RAW_HEIGHT, "videoRawHeight", 240), CONFIG_FLOAT(CONFIG_VIDEO_ASPECT_RATIO, "videoAspectRatio", VIDEO_STD_ASPECT_RATIO), CONFIG_FLOAT(CONFIG_VIDEO_FRAME_RATE, "videoFrameRate", VIDEO_PAL_FRAME_RATE), CONFIG_FLOAT(CONFIG_VIDEO_KEY_FRAME_INTERVAL, "videoKeyFrameInterval", 2.0),
CONFIG_INT(CONFIG_VIDEO_BIT_RATE, "videoBitRate", 128), CONFIG_INT(CONFIG_VIDEO_PROFILE_ID, "videoProfileId", MPEG4_SP_L3),
CONFIG_INT(CONFIG_VIDEO_BRIGHTNESS, "videoBrightness", 50), CONFIG_INT(CONFIG_VIDEO_HUE, "videoHue", 50), CONFIG_INT(CONFIG_VIDEO_COLOR, "videoColor", 50), CONFIG_INT(CONFIG_VIDEO_CONTRAST, "videoContrast", 50),
CONFIG_INT(CONFIG_VIDEO_TIMEBITS, "videoTimebits", 0),
CONFIG_BOOL(CONFIG_V4L_CACHE_TIMESTAMP, "videoTimestampCache", true), CONFIG_INT(CONFIG_VIDEO_H261_QUALITY, "videoH261Quality", 10), CONFIG_INT(CONFIG_VIDEO_H261_QUALITY_ADJ_FRAMES, "videoH261QualityAdjFrames", 8),
CONFIG_INT(CONFIG_VIDEO_CAP_BUFF_COUNT, "videoCaptureBuffersCount", 16),
// RECORD CONFIG_BOOL(CONFIG_RECORD_ENABLE, "recordEnable", true), CONFIG_BOOL(CONFIG_RECORD_RAW_AUDIO, "recordRawAudio", false), CONFIG_BOOL(CONFIG_RECORD_RAW_VIDEO, "recordRawVideo", false), CONFIG_BOOL(CONFIG_RECORD_ENCODED_AUDIO, "recordEncodedAudio", true), CONFIG_BOOL(CONFIG_RECORD_ENCODED_VIDEO, "recordEncodedVideo", true),
CONFIG_STRING(CONFIG_RECORD_MP4_FILE_NAME, "recordMp4File", "capture.mp4"), CONFIG_BOOL(CONFIG_RECORD_MP4_HINT_TRACKS, "recordMp4HintTracks", true), CONFIG_BOOL(CONFIG_RECORD_MP4_OVERWRITE, "recordMp4Overwrite", true), CONFIG_BOOL(CONFIG_RECORD_MP4_OPTIMIZE, "recordMp4Optimize", false),
// RTP
CONFIG_BOOL(CONFIG_RTP_ENABLE, "rtpEnable", true), CONFIG_STRING(CONFIG_RTP_DEST_ADDRESS, "rtpDestAddress", "127.0.0.1"), CONFIG_STRING(CONFIG_RTP_AUDIO_DEST_ADDRESS, "audioRtpDestAddress", "127.0.0.1"),
CONFIG_INT(CONFIG_RTP_AUDIO_DEST_PORT, "rtpAudioDestPort", 8000), CONFIG_INT(CONFIG_RTP_VIDEO_DEST_PORT, "rtpVideoDestPort", 7070),
CONFIG_INT(CONFIG_RTP_PAYLOAD_SIZE, "rtpPayloadSize", 1460), CONFIG_INT(CONFIG_RTP_MCAST_TTL, "rtpMulticastTtl", 15),
CONFIG_BOOL(CONFIG_RTP_DISABLE_TS_OFFSET, "rtpDisableTimestampOffset", false), CONFIG_BOOL(CONFIG_RTP_USE_SSM, "rtpUseSingleSourceMulticast", false),
CONFIG_STRING(CONFIG_SDP_FILE_NAME, "sdpFile", "capture.sdp"),
CONFIG_BOOL(CONFIG_RTP_USE_MP3_PAYLOAD_14, "rtpUseMp4RtpPayload14", false), CONFIG_BOOL(CONFIG_RTP_NO_B_RR_0, "rtpNoBRR0", false),
// RAW sink
CONFIG_BOOL(CONFIG_RAW_ENABLE, "rawEnable", false), CONFIG_STRING(CONFIG_RAW_PCM_FILE_NAME, "rawAudioFile", "capture.pcm"), CONFIG_BOOL(CONFIG_RAW_PCM_FIFO, "rawAudioUseFifo", false),
CONFIG_STRING(CONFIG_RAW_YUV_FILE_NAME, "rawVideoFile", "capture.yuv"), CONFIG_BOOL(CONFIG_RAW_YUV_FIFO, "rawVideoUseFifo", false)
}; #endif
// forward declarations class CVideoCapabilities; class CAudioCapabilities; class CLiveConfig;
// some configuration utility routines void GenerateMpeg4VideoConfig(CLiveConfig* pConfig); bool GenerateSdpFile(CLiveConfig* pConfig); struct session_desc_t;
session_desc_t *createSdpDescription(CLiveConfig *pConfig, char *sAudioDestAddr, char *sVideoDestAddr, int ttl, bool allow_rtcp, int video_port, int audio_port);
class CLiveConfig : public CConfigSet { public: CLiveConfig(SConfigVariable* variables, config_index_t numVariables, const char* defaultFileName);
~CLiveConfig();
// recalculate derived values void Update(); void UpdateFileHistory(const char* fileName); void UpdateVideo(); void CalculateVideoFrameSize(); void UpdateAudio(); void UpdateRecord();
bool IsOneSource(); bool IsCaptureVideoSource(); bool IsCaptureAudioSource(); bool IsFileVideoSource(); bool IsFileAudioSource();
bool SourceRawVideo() { return false; }
bool SourceRawAudio() { return false; }
public: // command line configuration bool m_appAutomatic;
// derived, shared video configuration CVideoCapabilities* m_videoCapabilities; bool m_videoEncode; u_int32_t m_videoPreviewWindowId; u_int16_t m_videoWidth; u_int16_t m_videoHeight; u_int16_t m_videoMaxWidth; u_int16_t m_videoMaxHeight; u_int32_t m_ySize; u_int32_t m_uvSize; u_int32_t m_yuvSize; bool m_videoNeedRgbToYuv; u_int16_t m_videoMpeg4ConfigLength; u_int8_t* m_videoMpeg4Config; u_int32_t m_videoMaxVopSize; u_int8_t m_videoTimeIncrBits;
// derived, shared audio configuration CAudioCapabilities* m_audioCapabilities; bool m_audioEncode;
// derived, shared file configuration u_int64_t m_recordEstFileSize; };
#endif /* __LIVE_CONFIG_H__ */
--- NEW FILE: pdp_mp4videosource.h --- /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is MPEG4IP. * * The Initial Developer of the Original Code is Cisco Systems Inc. * Portions created by Cisco Systems Inc. are * Copyright (C) Cisco Systems Inc. 2000, 2001. All Rights Reserved. * * Contributor(s): * Dave Mackie dmackie@cisco.com * Bill May wmay@cisco.com * * Adapted for PD/PDP by Yves Degoyon (ydegoyon@free.fr) */
#ifndef __PDP_MP4VIDEOSOURCE__ #define __PDP_MP4VIDEOSOURCE__
#include <sys/types.h> #include <sys/ioctl.h> #include <linux/videodev.h>
#include "media_source.h" #include "video_encoder.h"
class CPDPVideoSource : public CMediaSource { public: CPDPVideoSource() : CMediaSource() { m_videoMap = NULL; m_videoFrameMap = NULL; }
bool IsDone() { return false; }
float GetProgress() { return 0.0; }
void ProcessVideo(u_int8_t *pY, u_int8_t *pU, u_int8_t *pV);
void DoStart(void);
void DoStop(void);
protected: int ThreadMain(void);
bool Init(void);
int8_t StartTimeStamp(Timestamp &frameTimestamp);
bool EndTimeStamp(int8_t frameNumber);
Timestamp CalculateVideoTimestampFromFrames (uint64_t frame) { double duration = frame; duration *= TimestampTicks; duration /= m_videoSrcFrameRate; return m_videoCaptureStartTimestamp + (Timestamp)duration; } protected: u_int8_t m_maxPasses;
struct video_mbuf m_videoMbuf; void* m_videoMap; struct video_mmap* m_videoFrameMap; Timestamp m_videoCaptureStartTimestamp; uint64_t m_videoFrames; Duration m_videoSrcFrameDuration; int8_t m_captureHead; int8_t m_encodeHead; float m_videoSrcFrameRate; uint64_t *m_videoFrameMapFrame; Timestamp *m_videoFrameMapTimestamp; uint64_t m_lastVideoFrameMapFrameLoaded; Timestamp m_lastVideoFrameMapTimestampLoaded; bool m_cacheTimestamp; };
#endif /* __PDP_MP4VIDEOSOURCE__ */
--- NEW FILE: pdp_mp4player~.h ---
#ifndef __PDP_MP4PLAYER__ #define __PDP_MP4PLAYER__
struct pdp_mp4player_struct; typedef struct pdp_mp4player_struct t_pdp_mp4player;
#include "pdp.h" #include "yuv.h" #include <pthread.h> #include <stdio.h> #include <unistd.h> #include <math.h> #include <time.h> #include <sys/time.h> #include <sys/resource.h> #include "pdp_mp4playersession.h" #include "pdp_mp4playermedia.h" #include "pdp_mp4videosync.h" #include "pdp_mp4audiosync.h" #include "media_utils.h" #include "codec_plugin_private.h" #include "our_config_file.h" #include "player_util.h" #include <rtp/debug.h> #include <libhttp/http.h>
/* mpeg4ip includes taken from the source tree ( not exported ) */ #include <mp4.h> #undef DECLARE_CONFIG_VARIABLES #include "config_set.h"
#undef CONFIG_BOOL #define CONFIG_BOOL(var, name, defval) \ { &(var), (name), CONFIG_TYPE_BOOL, (defval), (defval) } #undef CONFIG_FLOAT #define CONFIG_FLOAT(var, name, defval) \ { &(var), (name), CONFIG_TYPE_FLOAT,(float) (defval), (float) (defval) } #undef CONFIG_INT #define CONFIG_INT(var, name, defval) \ { &(var), (name), CONFIG_TYPE_INTEGER,(config_integer_t) (defval), (config_integer_t)(defval) } #undef CONFIG_STRING #define CONFIG_STRING(var, name, defval) \ { &(var), (name), CONFIG_TYPE_STRING, (defval), (defval) }
#include "pdp_mp4config.h"
#undef DECLARE_CONFIG_VARIABLES #ifndef debug_message #define debug_message post #endif #include "rtp_transmitter.h" #include "pdp_mp4videosource.h" #include "pdp_mp4audiosource.h"
#define DEFAULT_CHANNELS 1 #define MIN_PRIORITY -20 #define DEFAULT_PRIORITY 0 #define MAX_PRIORITY 20
#define VIDEO_BUFFER_SIZE (1024*1024) #define MAX_AUDIO_PACKET_SIZE (128 * 1024) #define MIN_AUDIO_SIZE (64 * 1024) #define AUDIO_PACKET_SIZE (2*1152)
typedef struct pdp_mp4player_struct { t_object x_obj; t_float x_f;
t_int x_packet0; t_int x_dropped;
t_pdp *x_header; short int *x_data; t_int x_vwidth; t_int x_vheight; t_int x_vsize;
t_outlet *x_pdp_out; // output decoded pdp packets t_outlet *x_outlet_left; // left audio output t_outlet *x_outlet_right; // right audio output t_outlet *x_outlet_streaming; // indicates the action of streaming t_outlet *x_outlet_nbframes; // number of frames emitted t_outlet *x_outlet_framerate; // real framerate
char *x_url; t_int x_rtpovertcp; // flag to bypass certain firewalls (tcp mode) t_int x_streaming; // streaming flag t_int x_nbframes; // number of frames emitted t_int x_framerate; // framerate t_int x_samplerate; // audio sample rate t_int x_audiochannels; // audio channels t_int x_audioon; // enough audio data to start playing struct timeval x_starttime; // streaming starting time t_int x_cursec; // current second t_int x_secondcount; // number of frames received in the current second pthread_t x_decodechild;// stream decoding thread t_int x_priority; // priority of decoding thread t_int x_newpicture; // flag indicating a new picture
/* audio structures */ t_int x_audio; // flag to activate the decoding of audio short x_audio_buf[4*MAX_AUDIO_PACKET_SIZE]; /* buffer for audio from stream*/ short x_audio_in[4*MAX_AUDIO_PACKET_SIZE]; /* buffer for resampled PCM audio */ t_int x_audioin_position; // writing position for incoming audio
/* mpeg4hippies structures */ CPlayerSession *x_psession; CMsgQueue x_queue; SDL_sem *x_psem; t_int x_decodingstate; // internal decoding state
} t_pdp_mp4player;
#endif
--- NEW FILE: pdp_mp4playersession.h --- /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is MPEG4IP. * * The Initial Developer of the Original Code is Cisco Systems Inc. * Portions created by Cisco Systems Inc. are * Copyright (C) Cisco Systems Inc. 2000, 2001. All Rights Reserved. * * Contributor(s): * Bill May wmay@cisco.com * video aspect ratio by: * Peter Maersk-Moller peter @maersk-moller.net * * Adapted for PD/PDP by Yves Degoyon (ydegoyon@free.fr) * */
/* * pdp_mp4playersession.h - provides definitions for a CPlayerSession. * CPlayerSession is the base class that provides a combination audio/video * stream/file playback. * This class should be the main interface between any outside functionality * and the player window. */
#ifndef __PDP_MP4PLAYERSESSION_H__ #define __PDP_MP4PLAYERSESSION_H__
struct rtcp_sync_t; typedef struct rtcp_sync_t rtcp_sync_t;
#include <rtsp/rtsp_client.h> #include <sdp/sdp.h> #include "our_msg_queue.h" #include "ip_port.h" #include "pdp_mp4player~.h"
class CPlayerMedia; class CPDPAudioSync; class CPDPVideoSync;
typedef enum { SESSION_PAUSED, SESSION_BUFFERING, SESSION_PLAYING, SESSION_DONE } session_state_t;
typedef struct rtcp_sync_t { uint64_t first_pak_ts; uint64_t rtcp_ts; uint32_t first_pak_rtp_ts; uint32_t rtcp_rtp_ts; uint64_t timescale; } rtcp_sync_t;
typedef void (*media_close_callback_f)(void *);
class CPlayerSession { public: /* * API routine - create player session. */ CPlayerSession(CMsgQueue *master_queue, SDL_sem *master_sem, const char *name, t_pdp_mp4player *pdp_father); /* * API routine - destroy session - free all sub-structures, cleans * up rtsp, etc */ ~CPlayerSession(); /* * API routine - create a rtsp session with the url. After that, you * need to associate media */ int create_streaming_broadcast(session_desc_t *sdp, char *ermsg, uint32_t errlen); int create_streaming_ondemand(const char *url, char *errmsg, uint32_t errlen, int use_rtp_tcp); /* * API routine - play at time. If start_from_begin is FALSE, start_time * and we're paused, it will continue from where it left off. */ int play_all_media(int start_from_begin = FALSE, double start_time = 0.0, char *errmsg = NULL, uint32_t errlen = 0); /* * API routine - pause */ int pause_all_media(void); /* * API routine for media set up - associate a created * media with the session. */ void add_media(CPlayerMedia *m); /* * API routine - returns sdp info for streamed session */ session_desc_t *get_sdp_info (void) { return m_sdp_info;} ; rtsp_client_t *get_rtsp_client (void) { return m_rtsp_client; }; /* * API routine - after setting up media, need to set up sync thread */ void set_up_sync_thread(void); CPDPVideoSync *set_up_video_sync(void); CPDPAudioSync *set_up_audio_sync(void); /* * API routine - get the current time */ uint64_t get_playing_time (void) { if (m_streaming && session_is_seekable() == 0) { return (m_current_time - m_first_time_played); } return (m_current_time); }; /* * API routine - get max play time */ double get_max_time (void); /* * Other API routines */ int session_has_audio(void); int session_has_video(void); void set_audio_volume(int volume); int get_audio_volume(void) { return m_audio_volume; }; void session_set_seekable (int seekable) { m_seekable = seekable; }; int session_is_seekable (void) { return (m_seekable); }; session_state_t get_session_state(void) { return (m_session_state); } void set_media_close_callback (media_close_callback_f mccf, void *mccd) { m_media_close_callback = mccf; m_media_close_callback_data = mccd; } int session_is_network (int &on_demand, int &rtp_over_rtsp) { if (m_streaming == 0) { return 0; } if (m_seekable) { on_demand = 1; rtp_over_rtsp = m_rtp_over_rtsp; } else { on_demand = 0; rtp_over_rtsp = 0; } return 1; } /* * Non-API routines - used for c interfaces, for sync task APIs. */ void wake_sync_thread (void) { SDL_SemPost(m_sync_sem); } int send_sync_thread_a_message(uint32_t msgval, unsigned char *msg = NULL, uint32_t msg_len = 0) { return (m_sync_thread_msg_queue.send_message(msgval, msg, msg_len, m_sync_sem)); }; int sync_thread(int state); uint64_t get_current_time(void); void audio_is_ready (uint64_t latency, uint64_t time); void adjust_start_time(int64_t delta); int session_control_is_aggregate (void) { return m_session_control_is_aggregate; }; void set_session_control (int is_aggregate) { m_session_control_is_aggregate = is_aggregate; } CPlayerMedia *rtsp_url_to_media (const char *url); int set_session_desc(int line, const char *desc); const char *get_session_desc(int line); void streaming_media_set_up(void) { m_streaming_media_set_up = 1; }; CIpPort **get_unused_ip_port_ptr(void) { return &m_unused_ports; }; void syncronize_rtp_bytestreams(rtcp_sync_t *sync); private: int process_msg_queue(int state); int sync_thread_init(void); int sync_thread_wait_sync(void); int sync_thread_wait_audio(void); int sync_thread_playing(void); int sync_thread_paused(void); int sync_thread_done(void); const char *m_session_name; const char *m_content_base; int m_paused; int m_streaming; uint64_t m_current_time; // current time playing uint64_t m_start; uint64_t m_latency; int m_clock_wrapped; uint64_t m_play_start_time; session_desc_t *m_sdp_info; rtsp_client_t *m_rtsp_client; CPlayerMedia *m_my_media; CPDPAudioSync *m_audio_sync; CPDPVideoSync *m_video_sync; SDL_Thread *m_sync_thread; SDL_sem *m_sync_sem; CMsgQueue *m_master_msg_queue; SDL_sem *m_master_msg_queue_sem; CMsgQueue m_sync_thread_msg_queue; range_desc_t *m_range; int m_session_control_is_aggregate; int m_waiting_for_audio; int m_audio_volume; int m_screen_scale; int m_fullscreen; int m_pixel_height; int m_pixel_width; int m_seekable; volatile int m_sync_pause_done; session_state_t m_session_state; int m_hardware_error; #define SESSION_DESC_COUNT 4 const char *m_session_desc[SESSION_DESC_COUNT]; media_close_callback_f m_media_close_callback; void *m_media_close_callback_data; int m_streaming_media_set_up; CIpPort *m_unused_ports; int m_rtp_over_rtsp; uint64_t m_first_time_played; bool m_have_audio_rtcp_sync; rtcp_sync_t m_audio_rtcp_sync; t_pdp_mp4player *m_father; };
int pdp_sync_thread(void *data);
#endif