[PD-cvs] externals/pidip/include pdp_mp4audiosource.h,NONE,1.1 pdp_mp4audiosync.h,NONE,1.1 pdp_mp4config.h,NONE,1.1 pdp_mp4configset.h,NONE,1.1 pdp_mp4playermedia.h,NONE,1.1 pdp_mp4playersession.h,NONE,1.1 pdp_mp4player~.h,NONE,1.1 pdp_mp4rtpbytestream.h,NONE,1.1 pdp_mp4videosource.h,NONE,1.1 pdp_mp4videosync.h,NONE,1.1

Yves Degoyon sevyves at users.sourceforge.net
Tue Mar 30 04:59:57 CEST 2004


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 at cisco.com
 *		Bill May 		wmay at cisco.com
 *
 * Adapted for PD/PDP by Yves Degoyon (ydegoyon at 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 at cisco.com
 *
 * Adapted to PD/PDP by Yves Degoyon (ydegoyon at 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 at 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 at cisco.com
 *
 * Adapted to PD/PDP by Yves Degoyon (ydegoyon at 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 at cisco.com
 *              video aspect ratio by:
 *              Peter Maersk-Moller peter at maersk-moller.net
 *
 * Adapted for PD/PDP by Yves Degoyon (ydegoyon at 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 at cisco.com
 *		Bill May 		wmay at cisco.com
 *
 * Adapted for PD/PDP by Yves Degoyon (ydegoyon at 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 at cisco.com
 *		Bill May 		wmay at cisco.com
 *
 * Adapted for PD/PDP by Yves Degoyon (ydegoyon at 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 at cisco.com
 *        Bill May         wmay at cisco.com
 *
 * Adapted for PD/PDP by Yves Degoyon (ydegoyon at 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 at cisco.com
 *              video aspect ratio by:
 *              Peter Maersk-Moller peter @maersk-moller.net
 *              
 * Adapted for PD/PDP by Yves Degoyon (ydegoyon at 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





More information about the Pd-cvs mailing list