incubator-bluesky-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tp...@apache.org
Subject svn commit: r662948 [26/31] - in /incubator/bluesky/NCstu-2.0: ./ autom4te.cache/ include/ intl/ po/ src/ src/.deps/ src/ffmpeg/ src/pic/
Date Wed, 04 Jun 2008 02:48:20 GMT
Propchange: incubator/bluesky/NCstu-2.0/src/en_de_video.cpp
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/bluesky/NCstu-2.0/src/en_de_video.h
URL: http://svn.apache.org/viewvc/incubator/bluesky/NCstu-2.0/src/en_de_video.h?rev=662948&view=auto
==============================================================================
--- incubator/bluesky/NCstu-2.0/src/en_de_video.h (added)
+++ incubator/bluesky/NCstu-2.0/src/en_de_video.h Tue Jun  3 19:48:16 2008
@@ -0,0 +1,710 @@
+//en_de_video.h
+
+// rtp
+#include "fecrtpsession.h"
+
+#ifdef HAVE_1394_CONFIG_H
+//1394 video
+#include "frame.h"
+#include "ieee1394io.h"
+#endif // HAVE_1394_CONFIG_H
+
+#ifndef _KINO_V4L_H
+#define _KINO_V4L_H
+
+#include <vector>
+#include <deque>
+using std::vector;
+using std::deque;
+
+#include <string>
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include <time.h>
+#include <sys/time.h>
+
+#define _DEVICE_H_
+#define _LINUX_TIME_H
+#include <linux/videodev.h>
+
+/** Abstract V4L Structure class. Provides a wrapping for a video4linux struct.
+*/
+
+class V4LStruct
+{
+public:
+	virtual ~V4LStruct() {}
+	virtual void *getStruct() = 0;
+};
+
+/** Abstract V4L Device class.
+*/
+
+class V4LDevice
+{
+public:
+	virtual ~V4LDevice() {}
+	virtual int getHandle() = 0;
+	bool request( int req, V4LStruct *v4l );
+	bool request( int req, void *addr );
+};
+
+/** Wrapping for the V4L capabilities structure.
+*/
+
+class V4LCapability : public V4LStruct
+{
+private:
+	struct video_capability capability;
+
+public:
+	V4LCapability( V4LDevice *device );
+	virtual ~V4LCapability();
+	void *getStruct();
+	char *getName();
+	int getNumberOfChannels();
+	int getNumberOfAudioDevices();
+	int getMinWidth();
+	int getMinHeight();
+	int getMaxWidth();
+	int getMaxHeight();
+	bool canCapture();
+	bool hasTuner();
+	bool hasChromakey();
+	bool hasClipping();
+	bool hasOverwrite();
+	bool hasScaling();
+	bool isMonochrome();
+	bool canSubCapture();
+	void report();
+};
+
+class V4LTuner : public V4LStruct
+{
+private:
+	V4LDevice *device;
+	struct video_tuner tuner;
+
+public:
+	V4LTuner( V4LDevice *device, int index );
+	void *getStruct();
+	void report();
+	int getRangeLow();
+	void setRangeLow( int low );
+	int getRangeHigh();
+	void setRangeHigh( int high );
+	int getFlags();
+	void setFlags( int flags );
+	int getMode();
+	void setMode( int mode );
+	int getSignal();
+};
+
+class V4LChannel : public V4LStruct
+{
+private:
+	V4LDevice *device;
+	struct video_channel channel;
+	vector <V4LTuner *> tuners;
+	V4LTuner *current;
+
+public:
+	V4LChannel( V4LDevice *device, int index );
+	virtual ~V4LChannel();
+	void *getStruct();
+	char *getName();
+	bool setTuner( unsigned int index );
+	unsigned int getNumberOfTuners();
+	V4LTuner *getTuner( unsigned int index );
+	int getSignal();
+	void report();
+};
+
+class V4LFrame : public V4LStruct
+{};
+
+class V4L : public V4LDevice
+{
+	
+private:
+	enum V4LPARA{VideoWidth=320, VideoHeight=240};	
+	
+private:
+	int fd;
+	vector <V4LChannel *> channels;
+	V4LChannel *current;
+	int width;
+	int height;
+	void *map;
+	struct video_mmap frame[ 32 ];
+	int frame_maps;
+	int frame_next;
+	int size;
+	int frames;
+	long long starttime;
+	char *device;
+	char *input;
+	int sample;
+	int fps;
+public:
+	char *audio;
+	V4LCapability *capability;
+	V4L();
+	virtual ~V4L();
+	void setInfo( char *device, char *input, char *audio, int sample );
+	bool openDevice();
+	bool deviceAvailable();
+	int getHandle();
+	unsigned int getNumberOfChannels();
+	V4LChannel *getChannel( unsigned int );
+	bool setChannel( unsigned int channel );
+	unsigned int getNumberOfTuners();
+	V4LTuner *getTuner( unsigned int );
+	bool setTuner( unsigned int tuner );
+	bool setCaptureResolution( int width, int height );
+	int getWidth();
+	int getHeight();
+	void startAudio();
+	void stopAudio();
+	bool initialiseCapture( int format );
+	void *getNextFrame();
+	void stopCapture();
+	int getFrequency();
+	bool setFrequency( int frequency );
+	int getSignal();
+	void report();
+	int mappedMemorySize( bool init = false );
+	int frameSample;
+};
+
+#endif
+
+// Linux sys.
+#include <iostream>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <linux/types.h>
+#include <linux/videodev.h>
+// FFmpeg
+#include <ffmpeg/avcodec.h>
+#include <ffmpeg/avformat.h>
+// Time
+#include <time.h>
+// X11
+#include <X11/Intrinsic.h>
+#include <X11/XWDFile.h>
+// Jthread and JMutex
+#include <jthread.h>
+#include <jmutex.h>
+
+#include "en_de_sendthread.h"
+#include "en_de_screen.h"
+
+
+#if !defined(_EN_DE_VIDEO_H__INCLUDED_)
+#define _EN_DE_VIDEO_H__INCLUDED_
+
+
+typedef void (*VideoPlayback)(uint8_t* videodata, int width, int height);
+
+typedef struct VideoHeader{
+		int width;
+		int height;
+}VideoHeader;
+
+
+//Video encoder.
+class CVEncoder  
+{
+/*	friend class CVDecoder;
+public:
+	static int OpenCapDev();
+private:
+	static int g_hCapDev;
+*/	
+	friend class CVDecoder;
+	friend class CVideoSender;
+	friend class CStuVideoSender;
+		
+private:
+	enum VENCODERBUFSIZE {V_En_OutBufSize = 30*1024};
+	enum VIDEO_CODEC_PARA {V_CODEC_width=320, V_CODEC_height=240,			\
+							V_CODEC_framerate=25, V_CODEC_frame_rate_base=1,	\
+							V_CODEC_gop_size=8,										\
+							V_CODEC_max_b_frames = 1};
+public:
+	bool GetCapSize(int &width, int &height);
+	bool Capture(char **frameaddress);
+	void CloseCap();
+	int EncodeProcess(char * frameaddress, uint8_t * pOutBuf, int nOutsize);
+	bool Init(enum CodecID nCodecID =CODEC_ID_MPEG4);
+	CVEncoder();
+	virtual ~CVEncoder();
+	void GetColorInfo (XImage *image, ColorInfo *ci /* return struct */);
+
+private:
+	int m_bufferIndex;
+	struct video_mmap* m_mmaps;
+	char* m_memoryMap;
+	struct video_mbuf *m_pmemoryBuffer;
+	int m_hDevice;
+	bool InitCapture(int &width, int &height);
+	bool m_bInit;
+	bool m_bInitCap;
+	AVPicture m_pic_rgb;
+//	AVPicture m_pic_yuv;
+	uint8_t *m_pFrameBuf;
+	AVFrame *m_pFrame;
+    AVCodec *m_pCodec ;
+	AVCodecContext *m_pCodecCtx ;
+	int m_width;
+	int m_height;
+	VideoHeader m_VideoHeader;
+};
+
+
+//Video decoder.
+class CVDecoder  
+{
+	friend class CVideoReceiver;
+private:
+	enum VDECODERBUFSIZE {V_De_ExtraHeaderSize = 10000, V_De_SDLBufSize = 512*1024, V_De_INBUF_SIZE = 1024};
+public:
+	CVDecoder();
+	virtual ~CVDecoder();
+public:
+//	enum AVFRAMEDATASIZE_V{ size_v = 100*1024};
+	int DecodeProcess(uint8_t *encodeddata_v, const int encodeddatasize_v);
+	bool Init(int width, int height, enum CodecID nCodecID);
+
+public:
+	bool CreateXImage(Drawable parent, int x, int y, int width, int height);
+	void CloseXImage();
+	void GetColorInfo (XImage *image, ColorInfo *ci /* return struct */);
+
+
+private:
+	
+	void CloseCodec();
+	bool	ResetCodec(const int width, const int height);
+	bool m_bInit;
+    AVCodec *m_pCodec ;
+	AVCodecContext *m_pCodecCtx ;
+	AVFrame *m_pOutFrame;
+	AVPicture pic_rgb;
+//	AVPicture pic_yuv;
+//	uint8_t *m_pSDLBuf;
+	int m_width;
+	int m_height;
+	//for ximage
+	Display *m_display;
+	GC m_gc;
+	Window m_d;
+
+	Window m_win;
+	XImage *m_image;
+	JMutex m_imagemutex;
+	CVEncoder m_encoder;
+	ColorInfo c_info;
+public:
+    static int input_pixfmt;	
+
+};
+
+//video sender.
+class CVideoSender : private JThread
+{
+public:
+	enum VIDEOSENDERMODE {ModeNone=0, ModeCapture=1, ModeTransmit=2};
+private:
+	enum VIDEOSENDBUFSIZE {SendBufSize=25};
+public:
+	CVideoSender();
+	~CVideoSender();
+	bool Init(int nPort);
+	bool AddDestination(const RTPIPv4Address &des);
+	void ClearDestinations();
+	int Start(char* szFile=0, bool bIsRecord=false);
+	void Stop();
+	void SetMode(VIDEOSENDERMODE mode);	
+	bool CreateXImage(Drawable parent, int x, int y, int width, int height);
+	void CloseXImage();
+	void Record(bool bInRecord =true);
+	void GetColorInfo (XImage *image, ColorInfo *ci /* return struct */);
+
+public:
+	bool IsInitialized();
+private:
+	void Playback(uint8_t* videodata, int width, int height);
+	void *Thread();
+	bool stop;
+	JMutex stopmutex;
+private:
+	bool m_bIsRecord;				
+	JMutex m_recordmutex;
+			
+	CVEncoder m_vencoder;
+	uint8_t *m_pOutBuf;
+	FILE* m_hFile;
+//	CFECRtpSession m_fecrtpsession;
+	CSendThread m_sendthread;
+	bool m_bInit;
+	JMutex m_initmutex;
+    
+	VIDEOSENDERMODE m_mode;
+//	VideoPlayback m_playback;
+	JMutex m_modemutex;
+
+	//for ximage
+	Display *m_display;
+	GC m_gc;
+	Window m_win;
+	XImage *m_image;
+	JMutex m_imagemutex;
+	CVEncoder m_encoder;
+	ColorInfo c_info;
+//	int input_pixfmt;	
+
+};
+
+
+
+//stuvideo sender.
+class CStuVideoSender : private JThread
+{
+public:
+	enum STUVIDEOSENDERMODE {ModeNone=0, ModeCapture=1, ModeTransmit=2};
+public:
+	CStuVideoSender();
+	~CStuVideoSender();
+	bool Init(int nPort);
+	bool AddDestination(const RTPIPv4Address &des);
+	void ClearDestinations();
+	int Start(char* szFile=0, bool bIsRecord=false);
+	void Stop();
+	void SetMode(STUVIDEOSENDERMODE mode);	
+	bool CreateXImage(Drawable parent, int x, int y, int width, int height);
+	void CloseXImage();
+
+
+private:
+	void Playback(uint8_t* videodata, int width, int height);
+	void *Thread();
+	bool stop;
+	JMutex stopmutex;
+private:
+	CVEncoder m_vencoder;
+	uint8_t *m_pOutBuf;
+	CFECRtpSession m_fecrtpsession;
+	int m_bInit;
+	STUVIDEOSENDERMODE m_mode;
+	JMutex m_modemutex;
+
+	//for ximage
+	Display *m_display;
+	GC m_gc;
+	Window m_win;
+	XImage *m_image;
+	JMutex m_imagemutex;
+
+};
+
+//video receiver
+
+class CVideoReceiver : public CFECRtpSession  
+{
+public:
+	VideoHeader* pVideo;
+	CVideoReceiver();
+	virtual ~CVideoReceiver();
+
+	bool Init();
+	int Start(int nHostPort);
+	void Stop();
+	
+
+public:
+	bool CreateXImage(Drawable parent, int x, int y, int width, int height);
+	void CloseXImage();
+	
+private:
+	virtual void ProcessFrame(unsigned char* framedata, int framelen);
+
+private:
+	bool m_bInit;
+	CVDecoder m_vdecoder;
+};
+
+
+#ifdef HAVE_1394_CONFIG_H
+//1394 Video encoder.
+class C1394VEncoder  
+{
+
+	friend class C1394VideoSender;
+		
+private:
+	enum _1394_VENCODE_BUFSIZE {V_En_OutBufSize = 400*1024};
+	enum _1394_VIDEO_CODEC_PARA {V_CODEC_framerate=16, V_CODEC_frame_rate_base=1,	\
+							V_CODEC_gop_size=12,									\
+							V_CODEC_max_b_frames = 1};
+public:
+	bool GetCapSize(int &width, int &height);
+	int EncodeProcess(char * frameaddress, uint8_t * pOutBuf, int nOutsize);
+	bool Init(int width, int height, enum CodecID nCodecID =CODEC_ID_MPEG4);
+	C1394VEncoder();
+	virtual ~C1394VEncoder();
+	void GetColorInfo (XImage *image, ColorInfo *ci );
+
+private:
+	bool m_bInit;
+
+//for avcodec
+	AVPicture m_pic_rgb;
+	uint8_t *m_pFrameBuf;
+	AVFrame *m_pFrame;
+    AVCodec *m_pCodec ;
+	AVCodecContext *m_pCodecCtx ;
+	VideoHeader m_VideoHeader;
+};
+
+
+//1394 video sender.
+class C1394VideoSender : private JThread
+{
+public:
+	enum _1394VIDEO_SEND_MODE {ModeNone=0, ModeCapture=1, ModeTransmit=2};
+private:
+	enum _1394VIDEO_SEND_BUFSIZE {SendBufSize=16};
+private:
+	enum _1394VIDEO_SEND_PARA {VideoWidth=320, VideoHeight=240};
+public:
+	C1394VideoSender();
+	~C1394VideoSender();
+	bool Init(int nHostPort);
+	bool AddDestination(const RTPIPv4Address &des);
+	void ClearDestinations();
+	int Start(char* szFile=0, bool bIsRecord=false);
+	void Stop();
+	void SetMode(_1394VIDEO_SEND_MODE mode);	
+	bool CreateXImage(Drawable parent, int x, int y, int width, int height);
+	void CloseXImage();
+	void Record(bool bInRecord =true);
+	void GetColorInfo (XImage *image, ColorInfo *ci );
+    bool IsInitialized();
+
+
+private:
+    void Scale();
+    bool StartCapture();
+    void StopCapture();
+    int Capture(uint8_t** data);
+    bool IsHaved1394Video();
+
+	void Playback(uint8_t* videodata);
+//	void Playback11(uint8_t* videodata);
+	void *Thread();
+	bool stop;
+	JMutex stopmutex;
+private:
+	bool m_bIsRecord;				
+	JMutex m_recordmutex;
+			
+	C1394VEncoder m_vencoder;
+	uint8_t *m_pOutBuf;
+	FILE* m_hFile;
+	CSendThread m_sendthread;
+	bool m_bInit;
+	JMutex m_initmutex;
+	_1394VIDEO_SEND_MODE m_mode;
+	JMutex m_modemutex;
+
+	//for ximage
+	Window m_d;
+	Display *m_display;
+	GC m_gc;
+	Window m_win;
+	XImage *m_image;
+	JMutex m_imagemutex;
+	CVEncoder m_encoder;
+	ColorInfo c_info;
+//	int input_pixfmt;	
+	
+	//for 1394 video.
+	IEEE1394Reader *m_p1394reader;
+	void *m_pCapBuf;
+
+};
+#endif // HAVE_1394_CONFIG_H
+
+
+// V4L Video encoder.
+class CV4LVEncoder  
+{
+
+	friend class CV4LVideoSender;
+	friend class CV4LStuVideoSender;
+		
+private:
+	enum V4L_VENCODE_BUFSIZE {V_En_OutBufSize = 400*1024};
+	enum V4L_VIDEO_CODEC_PARA {V_CODEC_framerate=16, V_CODEC_frame_rate_base=1,	\
+							V_CODEC_gop_size=12,									\
+							V_CODEC_max_b_frames = 1};
+public:
+	bool GetCapSize(int &width, int &height);
+	int EncodeProcess(char * frameaddress, uint8_t * pOutBuf, int nOutsize);
+	bool Init(int width, int height, enum CodecID nCodecID =CODEC_ID_MPEG4);
+	CV4LVEncoder();
+	virtual ~CV4LVEncoder();
+	void GetColorInfo (XImage *image, ColorInfo *ci );
+
+private:
+	bool m_bInit;
+
+//for avcodec
+	AVPicture m_pic_rgb;
+	uint8_t *m_pFrameBuf;
+	AVFrame *m_pFrame;
+    AVCodec *m_pCodec ;
+	AVCodecContext *m_pCodecCtx ;
+	VideoHeader m_VideoHeader;
+};
+
+// V4L video sender.
+class CV4LVideoSender : private JThread
+{
+public:
+	enum V4LVIDEO_SEND_MODE {ModeNone=0, ModeCapture=1, ModeTransmit=2};
+private:
+	enum V4LVIDEO_SEND_BUFSIZE {SendBufSize=16};
+private:
+	enum V4LVIDEO_SEND_PARA {VideoWidth=320, VideoHeight=240};
+public:
+	CV4LVideoSender();
+	~CV4LVideoSender();
+	bool Init(int nHostPort);
+	bool AddDestination(const RTPIPv4Address &des);
+	void ClearDestinations();
+	int Start(char* szFile=0, bool bIsRecord=false);
+	void Stop();
+	void SetMode(V4LVIDEO_SEND_MODE mode);	
+	bool CreateXImage(Drawable parent, int x, int y, int width, int height);
+	void CloseXImage();
+	void Record(bool bInRecord =true);
+	void GetColorInfo (XImage *image, ColorInfo *ci );
+    bool IsInitialized();
+
+
+private:
+    bool OpenVideo();
+    void CloseVideo();
+    int Capture(uint8_t** data);
+    bool IsHavedV4LVideo();
+
+	void Playback(uint8_t* videodata);
+	void *Thread();
+	bool stop;
+	JMutex stopmutex;
+private:
+	bool m_bIsRecord;				
+	JMutex m_recordmutex;
+			
+	CV4LVEncoder m_vencoder;
+	uint8_t *m_pOutBuf;
+	FILE* m_hFile;
+	CSendThread m_sendthread;
+	bool m_bInit;
+	JMutex m_initmutex;
+	V4LVIDEO_SEND_MODE m_mode;
+	JMutex m_modemutex;
+
+	//for ximage
+	Window m_d;
+	Display *m_display;
+	GC m_gc;
+	Window m_win;
+	XImage *m_image;
+	JMutex m_imagemutex;
+	CVEncoder m_encoder;
+	ColorInfo c_info;
+//	int input_pixfmt;	
+	
+	//for V4L video.
+    V4L *m_pV4Ldev;
+//	void *m_pCapBuf;
+
+};
+
+
+
+// V4L video for student sender.
+class CV4LStuVideoSender : private JThread
+{
+public:
+	enum V4LSTUVIDEO_SEND_MODE {ModeNone=0, ModeCapture=1, ModeTransmit=2};
+private:
+	enum V4LSTUVIDEO_SEND_PARA {VideoWidth=320, VideoHeight=240};
+public:
+	CV4LStuVideoSender();
+	~CV4LStuVideoSender();
+	bool Init(int nHostPort);
+	bool AddDestination(const RTPIPv4Address &des);
+	void ClearDestinations();
+	int Start();
+	void Stop();
+	void SetMode(V4LSTUVIDEO_SEND_MODE mode);	
+	bool CreateXImage(Drawable parent, int x, int y, int width, int height);
+	void CloseXImage();
+	void GetColorInfo (XImage *image, ColorInfo *ci );
+    bool IsInitialized();
+
+
+private:
+    bool OpenVideo();
+    void CloseVideo();
+    int Capture(uint8_t** data);
+    bool IsHavedV4LVideo();
+
+	void Playback(uint8_t* videodata);
+	void *Thread();
+	bool stop;
+	JMutex stopmutex;
+private:
+	CV4LVEncoder m_vencoder;
+	uint8_t *m_pOutBuf;
+	bool m_bInit;
+	JMutex m_initmutex;
+	V4LSTUVIDEO_SEND_MODE m_mode;
+	JMutex m_modemutex;
+
+    //for fec transmmiosn.
+	CFECRtpSession m_fecrtpsession;
+	//for ximage
+	Window m_d;
+
+	Display *m_display;
+	GC m_gc;
+	Window m_win;
+	XImage *m_image;
+	JMutex m_imagemutex;
+	CVEncoder m_encoder;
+	ColorInfo c_info;
+//	int input_pixfmt;	
+	
+	//for V4L video.
+    V4L *m_pV4Ldev;
+
+};
+
+#endif // !defined(_EN_DE_VIDEO_H__INCLUDED_)

Propchange: incubator/bluesky/NCstu-2.0/src/en_de_video.h
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/bluesky/NCstu-2.0/src/error.cc
URL: http://svn.apache.org/viewvc/incubator/bluesky/NCstu-2.0/src/error.cc?rev=662948&view=auto
==============================================================================
--- incubator/bluesky/NCstu-2.0/src/error.cc (added)
+++ incubator/bluesky/NCstu-2.0/src/error.cc Tue Jun  3 19:48:16 2008
@@ -0,0 +1,120 @@
+/*
+* error.cc Error handling
+* Copyright (C) 2000 - 2002 Arne Schirmacher <arne@schirmacher.de>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Tag: $Name:  $
+*
+* Change log:
+* 
+* $Log: error.cc,v $
+* Revision 1.4  2003/11/17 00:15:19  ddennedy
+* bump version, remove a couple more strstream, fixup man page
+*
+* Revision 1.3  2003/11/16 22:36:49  ddennedy
+* run make pretty and remove deprecated strstream
+*
+* Revision 1.2  2003/09/17 22:10:12  ddennedy
+* major new features: namely interactive mode and AV/C control
+*
+* Revision 1.1.1.1  2003/02/07 04:08:33  ddennedy
+* initial import of dvgrab
+*
+* Revision 1.1  2002/03/04 19:24:57  arne
+* updated to latest Kino avi code
+*
+*/
+
+#ifdef HAVE_1394_CONFIG_H
+#include "1394_config.h"
+#endif
+
+// C includes
+
+#include <errno.h>
+#include <string.h>
+
+// C++ includes
+
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+
+using std::ostringstream;
+using std::string;
+using std::endl;
+using std::ends;
+
+// local includes
+
+#include "error.h"
+
+void real_fail_neg( int eval, const char *eval_str, const char *func, const char *file, int line )
+{
+	if ( eval < 0 )
+	{
+		string exc;
+		ostringstream sb;
+
+		sb << file << ":" << line << ": In function \"" << func << "\": \"" << eval_str << "\" evaluated to " << eval;
+		if ( errno != 0 )
+			sb << endl << file << ":" << line << ": errno: " << errno << " (" << strerror( errno ) << ")";
+		sb << ends;
+		exc = sb.str();
+		throw exc;
+	}
+}
+
+
+/** error handler for NULL result codes
+ 
+    Whenever this is called with a NULL argument, it will throw an
+    exception. Typically used with functions like malloc() and new().
+ 
+*/
+
+void real_fail_null( const void *eval, const char *eval_str, const char *func, const char *file, int line )
+{
+	if ( eval == NULL )
+	{
+
+		string exc;
+		ostringstream sb;
+
+		sb << file << ":" << line << ": In function \"" << func << "\": " << eval_str << " is NULL" << ends;
+		exc = sb.str();
+		throw exc;
+	}
+}
+
+
+void real_fail_if( bool eval, const char *eval_str, const char *func, const char *file, int line )
+{
+	if ( eval == true )
+	{
+
+		string exc;
+		ostringstream sb;
+
+		sb << file << ":" << line << ": In function \"" << func << "\": condition \"" << eval_str << "\" is true";
+		if ( errno != 0 )
+			sb << endl << file << ":" << line << ": errno: " << errno << " (" << strerror( errno ) << ")";
+		sb << ends;
+		exc = sb.str();
+		throw exc;
+	}
+}

Propchange: incubator/bluesky/NCstu-2.0/src/error.cc
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/bluesky/NCstu-2.0/src/error.h
URL: http://svn.apache.org/viewvc/incubator/bluesky/NCstu-2.0/src/error.h?rev=662948&view=auto
==============================================================================
--- incubator/bluesky/NCstu-2.0/src/error.h (added)
+++ incubator/bluesky/NCstu-2.0/src/error.h Tue Jun  3 19:48:16 2008
@@ -0,0 +1,58 @@
+/*
+* error.h Error handling
+* Copyright (C) 2000 - 2002 Arne Schirmacher <arne@schirmacher.de>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Tag: $Name:  $
+*
+* Change log:
+* 
+* $Log: error.h,v $
+* Revision 1.3  2003/11/16 22:36:49  ddennedy
+* run make pretty and remove deprecated strstream
+*
+* Revision 1.2  2003/09/17 22:10:12  ddennedy
+* major new features: namely interactive mode and AV/C control
+*
+* Revision 1.1.1.1  2003/02/07 04:08:33  ddennedy
+* initial import of dvgrab
+*
+* Revision 1.1  2002/03/04 19:24:57  arne
+* updated to latest Kino avi code
+*
+*/
+
+#ifndef _ERROR_H
+#define _ERROR_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define fail_neg(eval)  real_fail_neg  (eval, #eval, __ASSERT_FUNCTION, __FILE__, __LINE__)
+#define fail_null(eval) real_fail_null (eval, #eval, __ASSERT_FUNCTION, __FILE__, __LINE__)
+#define fail_if(eval)   real_fail_if   (eval, #eval, __ASSERT_FUNCTION, __FILE__, __LINE__)
+
+	void real_fail_neg ( int eval, const char * eval_str, const char * func, const char * file, int line );
+	void real_fail_null ( const void * eval, const char * eval_str, const char * func, const char * file, int line );
+	void real_fail_if ( bool eval, const char * eval_str, const char * func, const char * file, int line );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

Propchange: incubator/bluesky/NCstu-2.0/src/error.h
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/bluesky/NCstu-2.0/src/errorinfo.h
URL: http://svn.apache.org/viewvc/incubator/bluesky/NCstu-2.0/src/errorinfo.h?rev=662948&view=auto
==============================================================================
--- incubator/bluesky/NCstu-2.0/src/errorinfo.h (added)
+++ incubator/bluesky/NCstu-2.0/src/errorinfo.h Tue Jun  3 19:48:16 2008
@@ -0,0 +1,85 @@
+/***************************************************************************
+ *            errorinfo.h
+ *
+ *  Wed Jul 12 09:35:18 2006
+ *  Copyright  2006  zf
+ *  Email
+ ****************************************************************************/
+
+#ifndef _ERRORINFO_H
+#define _ERRORINFO_H
+
+#define  ERROR001 "错误001:与课堂服务中心建立socket连接失败!\n\n"
+#define  ERROR_S001  "提示001:请检查课堂服务中心IP地址,请确认课堂服务中心已启动"
+
+#define  ERROR002 "错误002:与课堂服务中心建立socket连接失败!\n\n"
+#define  ERROR_S002  "提示002:请检查课堂服务中心状态"
+
+#define  ERROR003 "错误003:授课端登录失败!\n\n"
+#define  ERROR_S003  "提示003:请检查课堂服务中心状态,检查登录用户名及密码"
+
+#define  ERROR004 "错误004:发送创建课堂消息失败!\n\n"
+#define  ERROR_S004  "提示004:请检查课堂服务中心状态"
+
+#define  ERROR005 "错误005:创建课堂失败!\n\n"
+#define  ERROR_S005  "提示005:请检查课堂服务中心状态,请确保已启动主DTU"
+
+#define  ERROR006 "错误006:发送取消创建课堂失败!\n\n"
+#define  ERROR_S006  "提示006:请检查课堂服务中心状态"
+
+#define  ERROR007 "错误007:发送获取学生列表消息失败!\n\n"
+#define  ERROR_S007  "提示007:请检查课堂服务中心状态"
+
+#define  ERROR008 "错误008:发送获取学生列表消息失败!\n\n"
+#define  ERROR_S008  "提示008:请检查课堂服务中心状态"
+
+#define  ERROR009 "错误009:发送指定焦点学生消息失败!\n\n"
+#define  ERROR_S009  "提示009:请检查课堂服务中心状态"
+
+#define  ERROR010 "错误010:指定焦点学生失败!\n\n"
+#define  ERROR_S010  "提示010:请检查课堂服务中心状态,请确认该用户仍然登录"
+
+#define  ERROR011 "错误011:发送取消焦点学生消息失败!\n\n"
+#define  ERROR_S011  "提示011:请检查课堂服务中心状态"
+
+#define  ERROR012 "错误012:取消焦点学生失败!\n\n"
+#define  ERROR_S012  "提示012:请检查课堂服务中心状态,请确认该用户没有退出"
+
+#define  ERROR013 "错误013:发送聊天消息失败!\n\n"
+#define  ERROR_S013  "提示013:请检查课堂服务中心状态"
+
+#define  ERROR014 "错误014:数据接收端口填写错误!\n\n"
+#define  ERROR_S014  "提示014:接收焦点学生音频数据端口请填写偶数"
+
+#define  ERROR015 "错误015:数据接收端口填写错误!\n\n"
+#define  ERROR_S015  "提示015:接收焦点学生视频数据端口请填写偶数"
+
+#define  ERROR016 "错误016:接收数据端口填写错误!\n\n"
+#define  ERROR_S016  "提示016:两路数据端口请填写不同值"
+
+#define  ERROR017 "错误017:课堂名填写错误!\n\n"
+#define  ERROR_S017  "提示017:请检查课堂名是否填写,以及名称是否过长"
+
+#define  ERROR018 "错误018:用户名填写错误!\n\n"
+#define  ERROR_S018  "提示018:请检查用户名是否填写,以及名称是否过长"
+
+#define ERROR019 "错误019:禁止聊天失败!\n\n"
+#define ERROR_S019 "提示019:请检查课堂服务中心的状态"
+
+#define ERROR020 "错误020:允许聊天失败! \n\n"
+#define ERROR_S020 "提示020:请检查课堂服务中心的状态"
+
+#define ERROR021 "错误021:没有检测到声卡! \n\n"
+#define ERROR_S021 "提示021:请检查声卡"
+
+#define ERROR022 "错误022:没有检测到视频设备!\n\n"
+#define ERROR_S022 "提示022:请检查视频设备有无插好"
+
+#define ERROR023 "错误023:分辨率过大,不能正常显示!\n\n "
+#define ERROR_S023 "提示023:请将分辨率设定为800*600"
+
+#define ERROR024 "错误023:分辨率过小,不能正常显示!\n\n "
+#define ERROR_S024 "提示023:请将分辨率设定为800*600"
+
+
+#endif

Propchange: incubator/bluesky/NCstu-2.0/src/errorinfo.h
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/bluesky/NCstu-2.0/src/errormessage.h
URL: http://svn.apache.org/viewvc/incubator/bluesky/NCstu-2.0/src/errormessage.h?rev=662948&view=auto
==============================================================================
--- incubator/bluesky/NCstu-2.0/src/errormessage.h (added)
+++ incubator/bluesky/NCstu-2.0/src/errormessage.h Tue Jun  3 19:48:16 2008
@@ -0,0 +1,317 @@
+#include "language_test.h"
+
+
+#ifdef LANGUAGE_EN
+#define  screensize_error "Screen config failure "
+#endif
+#ifdef LANGUAGE_CH
+#define  screensize_error "   屏幕设置失败 "
+#endif
+
+#ifdef LANGUAGE_EN
+#define  screensize_errorms "\n\nPlease set screen as 1024×768 "
+#endif
+#ifdef LANGUAGE_CH
+#define  screensize_errorms "\n\n 请将屏幕设置为1024×768 "
+#endif
+
+
+#ifdef LANGUAGE_EN
+#define  getIP_error "Can't obtain local IP!"
+#endif
+#ifdef LANGUAGE_CH
+#define  getIP_error "     		无法自动获取本机IP地址"
+#endif
+
+#ifdef LANGUAGE_EN
+#define  getIP_errorms "\n\nManual configure please!"
+#endif
+#ifdef LANGUAGE_CH
+#define  getIP_errorms "\n\n请点击高级按钮手动设置"
+#endif
+
+
+#ifdef LANGUAGE_EN
+#define  usename_error "Logon failure"
+#endif
+#ifdef LANGUAGE_CH
+#define  usename_error "     登陆失败! "
+#endif
+
+#ifdef LANGUAGE_EN
+#define  usename_errorms "\n\nNo user name!"
+#endif
+#ifdef LANGUAGE_CH
+#define  usename_errorms "\n\n用户名不能为空"
+#endif
+
+
+#ifdef LANGUAGE_EN
+#define  usename_error1 "Logon failure"
+#endif
+#ifdef LANGUAGE_CH
+#define  usename_error1  "     登陆失败! "
+#endif
+
+#ifdef LANGUAGE_EN
+#define  usename_error1ms "User name too long!\n No more than 10 Chinese characters \nor 30 English characters"
+#endif
+#ifdef LANGUAGE_CH
+#define  usename_error1ms "\n\n用户名过长,请输入少于10个汉字或者30个英文字符"
+#endif
+
+
+#ifdef LANGUAGE_EN
+#define  config_error1 "Receive port error!"
+#endif
+#ifdef LANGUAGE_CH
+#define  config_error1   "     接收端口设置错误    "
+#endif
+
+#ifdef LANGUAGE_EN
+#define  config_error1ms "\nPlease set the port as an \neven number greater than 1024."
+#endif
+#ifdef LANGUAGE_CH
+#define  config_error1ms   "\n\n请将接收基准端口设为大于1024的偶数 "
+#endif
+
+
+#ifdef LANGUAGE_EN
+#define  load_error1 "Logon server failure!"
+#endif
+#ifdef LANGUAGE_CH
+#define  load_error1   "        			登录失败!     "  
+#endif
+
+#ifdef LANGUAGE_EN
+#define  load_error1ms "\nCan't logon server.\nCheck the configuration please."
+#endif
+#ifdef LANGUAGE_CH
+#define  load_error1ms  "\n\n无法连接课堂服务中心,请修改配置参数是否正确"
+#endif
+
+
+#ifdef LANGUAGE_EN
+#define  load_error2 "Can't logon system."
+#endif
+#ifdef LANGUAGE_CH
+#define  load_error2  "      无法登陆系统!      "
+#endif
+
+#ifdef LANGUAGE_EN
+#define  load_error2ms "\nUser name have been used.\nChange another one please!"
+#endif
+#ifdef LANGUAGE_CH
+#define  load_error2ms  " \n\n该用户该用户已经存在,请更换用户名 "
+#endif
+
+
+#ifdef LANGUAGE_EN
+#define  load_error3 "Can't logon system."
+#endif
+#ifdef LANGUAGE_CH
+#define  load_error3  "      无法登陆系统!      "
+#endif
+
+#ifdef LANGUAGE_EN
+#define  load_error3ms "\n\nStudents client overload."
+#endif
+#ifdef LANGUAGE_CH
+#define  load_error3ms  "\n\n听课端人数已满"
+#endif
+
+
+#ifdef LANGUAGE_EN
+#define  load_error4 "Can't logon system."
+#endif
+#ifdef LANGUAGE_CH
+#define  load_error4  " 		无法登陆系统!"
+#endif
+
+#ifdef LANGUAGE_EN
+#define  load_error4ms "\n\nNetwork error.Logon again!"
+#endif
+#ifdef LANGUAGE_CH
+#define  load_error4ms  "\n\n网络出现故障,请重新登陆"
+#endif
+
+
+#ifdef LANGUAGE_EN
+#define  getclasslist_error "Obtain group message error."
+#endif
+#ifdef LANGUAGE_CH
+#define  getclasslist_error  "		获取组消息失败"
+#endif
+
+#ifdef LANGUAGE_EN
+#define  getclasslist_errorms "\nJoin class later \nor logon system again."
+#endif
+#ifdef LANGUAGE_CH
+#define  getclasslist_errorms  "\n\n重新加入课堂或者稍候重新登陆系统"
+#endif
+
+
+#ifdef LANGUAGE_EN
+#define  addclass_error "Join class failure."
+#endif
+#ifdef LANGUAGE_CH
+#define  addclass_error  "				加入课堂失败"
+#endif
+
+#ifdef LANGUAGE_EN
+#define  addclass_errorms "\n\nSelect class again please."
+#endif
+#ifdef LANGUAGE_CH
+#define  addclass_errorms  "\n\n请重新选择课堂"
+#endif
+
+
+#ifdef LANGUAGE_EN
+#define  addclass_error1 "Join class failure."
+#endif
+#ifdef LANGUAGE_CH
+#define  addclass_error1  "				加入课堂失败"
+#endif
+
+#ifdef LANGUAGE_EN
+#define  addclass_error1ms "\nSorry!Too many students \njoin this class.Try later."
+#endif
+#ifdef LANGUAGE_CH
+#define  addclass_error1ms  "\n\n对不起,该课堂人数已满,请稍候再试"
+#endif
+
+
+#ifdef LANGUAGE_EN
+#define  exitclass_error " "
+#endif
+#ifdef LANGUAGE_CH
+#define  exitclass_error  " "
+#endif
+
+#ifdef LANGUAGE_EN
+#define  exitclass_errorms "Quit class failure,try again!"
+#endif
+#ifdef LANGUAGE_CH
+#define  exitclass_errorms  "		退出课堂失败,请重试		"
+#endif
+
+
+#ifdef LANGUAGE_EN
+#define  focus_error1 "Apply for focus failure."
+#endif
+#ifdef LANGUAGE_CH
+#define  focus_error1 "  		申请焦点失败"
+#endif
+
+#ifdef LANGUAGE_EN
+#define  focus_error1ms "\nFocus already exist.\nTry later."
+#endif
+#ifdef LANGUAGE_CH
+#define  focus_error1ms "\n\n已经存在一个焦点,请稍候再试"
+#endif
+
+
+#ifdef LANGUAGE_EN
+#define  focus_error2 "Apply for focus failure."
+#endif
+#ifdef LANGUAGE_CH
+#define  focus_error2 "					申请焦点失败"
+#endif
+
+#ifdef LANGUAGE_EN
+#define  focus_error2ms "\nTeacher client deny.\nTry later."
+#endif
+#ifdef LANGUAGE_CH
+#define  focus_error2ms "\n\n教师端没有同意您的申请,请稍候再试"
+#endif
+
+
+#ifdef LANGUAGE_EN
+#define  killfocus_error "Kill focus failure."
+#endif
+#ifdef LANGUAGE_CH
+#define  killfocus_error "					撤消焦点失败"
+#endif
+
+#ifdef LANGUAGE_EN
+#define  killfocus_errorms "\nCan't get teacher's permit.\nTry later."
+#endif
+#ifdef LANGUAGE_CH
+#define  killfocus_errorms "\n\n您暂时未得到老师的同意撤消焦点,请稍候再试"
+#endif
+
+
+#ifdef LANGUAGE_EN
+#define  getstulist_error "Can't obtain the students list.\nTry again."
+#endif
+#ifdef LANGUAGE_CH
+#define  getstulist_error "无法得到学生列表,请重试"
+#endif
+
+
+#ifdef LANGUAGE_EN
+#define  port_error "Receive port configuration error."
+#endif
+#ifdef LANGUAGE_CH
+#define  port_error  " 基准端口设置错误"
+#endif
+
+#ifdef LANGUAGE_EN
+#define  port_errorms "\nPlease set the port as an \neven number greater than 1024."
+#endif
+#ifdef LANGUAGE_CH
+#define  port_errorms  " \n\n请将基准端口设置为大于1024的偶数"
+#endif
+//#define  screensize_error "   屏幕设置失败 "
+//#define  screensize_errorms "\n\n 请将屏幕设置为1024×768 "
+
+//#define  getIP_error "     		无法自动获取本机IP地址"
+//#define  getIP_errorms "\n\n请点击高级按钮手动设置" 
+
+//#define  usename_error     "     登陆失败! "
+//#define usename_errorms  "\n\n用户名不能为空"
+
+//#define usename_error1 "     登陆失败! "
+//#define usename_error1ms "\n\n用户名过长,请输入少于10个汉字或者30个英文字符"
+
+ 
+ //#define config_error1 "     接收端口设置错误    "
+ //#define config_error1ms " \n\n请将接收基准端口设为大于1024的偶数 "
+ 
+//#define load_error1  "        			登录失败!     "  
+//#define load_error1ms "\n\n无法连接课堂服务中心,请修改配置参数是否正确"
+
+//#define load_error2  "      无法登陆系统!      "
+//#define  load_error2ms   " \n\n该用户该用户已经存在,请更换用户名 "
+
+//#define  load_error3    "		无法登陆系统!"
+//#define  load_error3ms  "\n\n听课端人数已满"
+
+//#define  load_error4    " 		无法登陆系统!"
+//#define  load_error4ms  "\n\n网络出现故障,请重新登陆"
+
+//#define  getclasslist_error   "		获取组消息失败"
+//#define getclasslist_errorms "\n\n重新加入课堂或者稍候重新登陆系统"
+
+//#define addclass_error    "				加入课堂失败"
+//#define  addclass_errorms   "\n\n请重新选择课堂"
+
+//#define addclass_error1 "				加入课堂失败"
+//#define addclass_error1ms "\n\n对不起,该课堂人数已满,请稍候再试"
+
+//#define  exitclass_error "  "
+//#define  exitclass_errorms   "		退出课堂失败,请重试		"
+
+//#define focus_error1 "  		申请焦点失败"
+//#define  focus_error1ms"\n\n已经存在一个焦点,请稍候再试"
+
+//#define  focus_error2  "					申请焦点失败"
+//#define  focus_error2ms "\n\n教师端没有同意您的申请,请稍候再试"
+
+//#define  killfocus_error  "					撤消焦点失败"
+//#define  killfocus_errorms "\n\n您暂时未得到老师的同意撤消焦点,请稍候再试"
+
+//#define  getstulist_error   "无法得到学生列表,请重试"
+
+//#define port_error " 基准端口设置错误"
+//#define port_errorms " \n\n请将基准端口设置为大于1024的偶数"

Propchange: incubator/bluesky/NCstu-2.0/src/errormessage.h
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/bluesky/NCstu-2.0/src/fecrtpsession.cpp
URL: http://svn.apache.org/viewvc/incubator/bluesky/NCstu-2.0/src/fecrtpsession.cpp?rev=662948&view=auto
==============================================================================
--- incubator/bluesky/NCstu-2.0/src/fecrtpsession.cpp (added)
+++ incubator/bluesky/NCstu-2.0/src/fecrtpsession.cpp Tue Jun  3 19:48:16 2008
@@ -0,0 +1,1695 @@
+// fecrtpsession.cpp: implementation of the CFECRtpSession class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include <unistd.h>
+#include "fecrtpsession.h"
+
+// FEC´úÂ벿·Ö [4/8/2002]
+
+/*           $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   FEC´úÂë    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   */
+
+/*
+ GF_BITS:Ö÷ÒªÊÇΪÁ˶¨Òå±àÂë¾ØÕóµÄÁУ¬ÍƼöʹÓÃ8£¬µ«ÊÇÈç¹ûÒªÇó¶Ô±È½Ï´óµÄÊý¾Ý±àÂ룬¿ÉÒÔʹÓÃ16
+ È¡Öµ·¶Î§Îª2£­16
+ */
+#ifndef GF_BITS
+#define GF_BITS  8	// code over GF(2**GF_BITS) - change to suit 
+#endif
+
+#define u_char unsigned char
+#define u_short unsigned short
+#define u_long unsigned long
+
+#define bcmp(a,b,n) memcmp(a,b,n)
+#define bcopy(s, d, siz)        memcpy((d), (s), (siz))
+#define bzero(d, siz)   memset((d), '\0', (siz))
+
+
+
+#define DEB(x)
+#define DDB(x) x
+
+#if (GF_BITS < 2  && GF_BITS >16)
+#error "GF_BITS must be 2 .. 16"
+#endif
+
+#if (GF_BITS <= 8)
+typedef unsigned char gf;
+#else
+typedef unsigned short gf;
+#endif
+
+#define	GF_SIZE ((1 << GF_BITS) - 1)	/* powers of \alpha */
+
+static char *allPp[] = {    /* GF_BITS	polynomial		*/
+    0,		    /*  0	no code			*/
+    0,		    /*  1	no code			*/
+    "111",		    /*  2	1+x+x^2			*/
+    "1101",		    /*  3	1+x+x^3			*/
+    "11001",		    /*  4	1+x+x^4			*/
+    "101001",		    /*  5	1+x^2+x^5		*/
+    "1100001",		    /*  6	1+x+x^6			*/
+    "10010001",		    /*  7	1 + x^3 + x^7		*/
+    "101110001",	    /*  8	1+x^2+x^3+x^4+x^8	*/
+    "1000100001",	    /*  9	1+x^4+x^9		*/
+    "10010000001",	    /* 10	1+x^3+x^10		*/
+    "101000000001",	    /* 11	1+x^2+x^11		*/
+    "1100101000001",	    /* 12	1+x+x^4+x^6+x^12	*/
+    "11011000000001",	    /* 13	1+x+x^3+x^4+x^13	*/
+    "110000100010001",	    /* 14	1+x+x^6+x^10+x^14	*/
+    "1100000000000001",	    /* 15	1+x+x^15		*/
+    "11010000000010001"	    /* 16	1+x+x^3+x^12+x^16	*/
+};
+
+
+static gf gf_exp[2*GF_SIZE];	/* index->poly form conversion table	*/
+static int gf_log[GF_SIZE + 1];	/* Poly->index form conversion table	*/
+static gf inverse[GF_SIZE+1];	/* inverse of field elem.		*/
+
+int modnn(int x)
+{
+    while (x >= GF_SIZE) 
+	{
+		x -= GF_SIZE;
+		x = (x >> GF_BITS) + (x & GF_SIZE);
+    }
+    return x;
+}
+
+#define SWAP(a,b,t) {t tmp; tmp=a; a=b; b=tmp;}
+
+
+#if (GF_BITS <= 8)
+static gf gf_mul_table[GF_SIZE + 1][GF_SIZE + 1];
+
+#define gf_mul(x,y) gf_mul_table[x][y]
+
+#define USE_GF_MULC register gf * __gf_mulc_
+#define GF_MULC0(c) __gf_mulc_ = gf_mul_table[c]
+#define GF_ADDMULC(dst, x) dst ^= __gf_mulc_[x]
+
+static void init_mul_table()
+{
+    int i, j;
+    for (i=0; i< GF_SIZE+1; i++)
+	for (j=0; j< GF_SIZE+1; j++)
+	    gf_mul_table[i][j] = gf_exp[modnn(gf_log[i] + gf_log[j]) ] ;
+
+    for (j=0; j< GF_SIZE+1; j++)
+	    gf_mul_table[0][j] = gf_mul_table[j][0] = 0;
+}
+#else	
+static inline  gf gf_mul(gf x,gf y)
+{
+    if ( (x) == 0 || (y)==0 ) return 0;
+     
+    return gf_exp[gf_log[x] + gf_log[y] ] ;
+}
+#define init_mul_table()
+
+#define USE_GF_MULC register gf * __gf_mulc_
+#define GF_MULC0(c) __gf_mulc_ = &gf_exp[ gf_log[c] ]
+#define GF_ADDMULC(dst, x) { if (x) dst ^= __gf_mulc_[ gf_log[x] ] ; }
+#endif
+
+
+static void* my_malloc(int sz, char *err_string)
+{
+    void *p = malloc( sz );
+    if (p == 0) {	
+    }
+    return p ;
+}
+
+#define NEW_GF_MATRIX(rows, cols) (gf *)my_malloc(rows * cols * sizeof(gf), " ## __LINE__ ## " )
+
+
+static void generate_gf(void)
+{
+    int i;
+    gf mask;
+    char *Pp =  allPp[GF_BITS] ;
+
+    mask = 1;	/* x ** 0 = 1 */
+    gf_exp[GF_BITS] = 0; /* will be updated at the end of the 1st loop */
+    
+    for (i = 0; i < GF_BITS; i++, mask <<= 1 ) 
+	{
+		gf_exp[i] = mask;
+		gf_log[gf_exp[i]] = i;
+		if ( Pp[i] == '1' )
+			gf_exp[GF_BITS] ^= mask;
+    }
+    gf_log[gf_exp[GF_BITS]] = GF_BITS;
+    
+    mask = 1 << (GF_BITS - 1 ) ;
+    for (i = GF_BITS + 1; i < GF_SIZE; i++) 
+	{
+		if (gf_exp[i - 1] >= mask)
+		    gf_exp[i] = gf_exp[GF_BITS] ^ ((gf_exp[i - 1] ^ mask) << 1);
+		else
+		    gf_exp[i] = gf_exp[i - 1] << 1;
+		gf_log[gf_exp[i]] = i;
+    }
+    
+    gf_log[0] =	GF_SIZE ;
+    
+    for (i = 0 ; i < GF_SIZE ; i++)
+	gf_exp[i + GF_SIZE] = gf_exp[i] ;
+
+    
+    inverse[0] = 0 ;
+    inverse[1] = 1;
+    for (i=2; i<=GF_SIZE; i++)
+	inverse[i] = gf_exp[GF_SIZE-gf_log[i]];
+}
+
+
+#define addmul(dst, src, c, sz) \
+    if (c != 0) addmul1(dst, src, c, sz)
+
+#define UNROLL 16 /* 1, 4, 8, 16 */
+static void addmul1(gf *dst1, gf *src1, gf c, int sz)
+{
+    USE_GF_MULC ;
+    register gf *dst = dst1, *src = src1 ;
+    gf *lim = &dst[sz - UNROLL + 1] ;
+
+    GF_MULC0(c) ;
+
+#if (UNROLL > 1) /* unrolling by 8/16 is quite effective on the pentium */
+    for (; dst < lim ; dst += UNROLL, src += UNROLL ) 
+	{
+		GF_ADDMULC( dst[0] , src[0] );
+		GF_ADDMULC( dst[1] , src[1] );
+		GF_ADDMULC( dst[2] , src[2] );
+		GF_ADDMULC( dst[3] , src[3] );
+	#if (UNROLL > 4)
+		GF_ADDMULC( dst[4] , src[4] );
+		GF_ADDMULC( dst[5] , src[5] );
+		GF_ADDMULC( dst[6] , src[6] );
+		GF_ADDMULC( dst[7] , src[7] );
+	#endif
+	#if (UNROLL > 8)
+		GF_ADDMULC( dst[8] , src[8] );
+		GF_ADDMULC( dst[9] , src[9] );
+		GF_ADDMULC( dst[10] , src[10] );
+		GF_ADDMULC( dst[11] , src[11] );
+		GF_ADDMULC( dst[12] , src[12] );
+		GF_ADDMULC( dst[13] , src[13] );
+		GF_ADDMULC( dst[14] , src[14] );
+		GF_ADDMULC( dst[15] , src[15] );
+	#endif
+    }
+#endif
+    lim += UNROLL - 1 ;
+    for (; dst < lim; dst++, src++ )		/* final components */
+	GF_ADDMULC( *dst , *src );
+}
+
+/*
+ * ¾ØÕóÔËËã C = AB  A Ϊ n*k½×¾ØÕó, B Ϊ k*m½×¾ØÕó, C Ϊ n*m½×¾ØÕó
+ */
+static void matmul(gf *a, gf *b, gf *c, int n, int k, int m)
+{
+    int row, col, i ;
+
+    for (row = 0; row < n ; row++) 
+	{
+		for (col = 0; col < m ; col++) 
+		{
+		    gf *pa = &a[ row * k ];
+			gf *pb = &b[ col ];
+			gf acc = 0 ;
+			for (i = 0; i < k ; i++, pa++, pb += m )
+				acc ^= gf_mul( *pa, *pb ) ;
+			c[ row * m + col ] = acc ;
+		}
+    }
+}
+
+#ifdef DEBUG
+static int is_identity(gf *m, int k)
+{
+    int row, col ;
+    for (row=0; row<k; row++)
+	for (col=0; col<k; col++)
+	    if ( (row==col && *m != 1) || (row!=col && *m != 0) )
+			return 0 ;
+	    else
+		m++ ;
+    return 1 ;
+}
+#endif /* debug */
+
+
+DEB( int pivloops=0; int pivswaps=0 ; /* diagnostic */)
+static int invert_mat(gf *src, int k)
+{
+    gf c, *p ;
+    int irow, icol, row, col, i, ix ;
+
+    int error = 1 ;
+    int *indxc = (int *)my_malloc(k*sizeof(int), "indxc");
+
+    int *indxr = (int *)my_malloc(k*sizeof(int), "indxr");
+    int *ipiv = (int *)my_malloc(k*sizeof(int), "ipiv");
+    gf *id_row = NEW_GF_MATRIX(1, k);
+    gf *temp_row = NEW_GF_MATRIX(1, k);
+
+	if ((indxc==0)||(indxr==0)||(id_row==0)||(temp_row==0)||(ipiv==0))
+	{
+		goto fail;
+	}
+
+    bzero(id_row, k*sizeof(gf));
+    DEB( pivloops=0; pivswaps=0 ; /* diagnostic */ )
+
+    for (i = 0; i < k ; i++)
+	ipiv[i] = 0 ;
+
+    for (col = 0; col < k ; col++) {
+		gf *pivot_row ;
+
+		irow = icol = -1 ;
+		if (ipiv[col] != 1 && src[col*k + col] != 0) 
+		{
+		    irow = col ;
+		    icol = col ;
+			goto found_piv ;
+		}
+		for (row = 0 ; row < k ; row++) 
+		{
+			if (ipiv[row] != 1) 
+			{
+				for (ix = 0 ; ix < k ; ix++) 
+				{
+					DEB( pivloops++ ; )
+					if (ipiv[ix] == 0) 
+					{
+						if (src[row*k + ix] != 0) 
+						{
+							irow = row ;
+							icol = ix ;
+							goto found_piv ;
+						}
+					} else if (ipiv[ix] > 1) 
+					{
+						//fprintf(stderr, "singular matrix\n");
+						goto fail ; 
+					}
+				}
+			}
+		}
+		if (icol == -1) 
+		{
+			//fprintf(stderr, "XXX pivot not found!\n");
+			goto fail ;
+		}
+	found_piv:
+		++(ipiv[icol]) ;
+
+	if (irow != icol) 
+	{
+	    for (ix = 0 ; ix < k ; ix++ ) 
+		{
+			SWAP( src[irow*k + ix], src[icol*k + ix], gf) ;
+	    }
+	}
+	indxr[col] = irow ;
+	indxc[col] = icol ;
+	pivot_row = &src[icol*k] ;
+	c = pivot_row[icol] ;
+	if (c == 0) 
+	{
+	    //fprintf(stderr, "singular matrix 2\n");
+	    goto fail ;
+	}
+	if (c != 1 )
+	{ 
+	    DEB( pivswaps++ ; )
+	    c = inverse[ c ] ;
+	    pivot_row[icol] = 1 ;
+	    for (ix = 0 ; ix < k ; ix++ )
+		pivot_row[ix] = gf_mul(c, pivot_row[ix] );
+	}
+	id_row[icol] = 1;
+	if (bcmp(pivot_row, id_row, k*sizeof(gf)) != 0) 
+	{
+	    for (p = src, ix = 0 ; ix < k ; ix++, p += k ) 
+		{
+			if (ix != icol) 
+			{
+			    c = p[icol] ;
+			    p[icol] = 0 ;
+			    addmul(p, pivot_row, c, k );
+			}
+	    }
+	}
+	id_row[icol] = 0;
+    } /* done all columns */
+    for (col = k-1 ; col >= 0 ; col-- ) 
+	{
+		if (indxr[col] <0 || indxr[col] >= k)
+		{
+			goto fail;
+		    //fprintf(stderr, "AARGH, indxr[col] %d\n", indxr[col]);
+		}	
+		else if (indxc[col] <0 || indxc[col] >= k)	
+		{
+			goto fail;
+		    //fprintf(stderr, "AARGH, indxc[col] %d\n", indxc[col]);
+		}
+		else if (indxr[col] != indxc[col] ) 
+		{
+			for (row = 0 ; row < k ; row++ ) 
+			{
+				SWAP( src[row*k + indxr[col]], src[row*k + indxc[col]], gf) ;
+		    }
+		}
+    }
+
+    error = 0 ;
+fail:	
+	if (indxc!=0)	
+		free(indxc);	
+	if (indxr!=0)
+		free(indxr);	
+	if (ipiv!=0)
+		free(ipiv);
+	if (id_row!=0)
+		free(id_row);
+	if (temp_row!=0)
+		free(temp_row);
+    return error ;
+}
+
+int invert_vdm(gf *src, int k)
+{
+    int i, j, row, col ;
+    gf *b, *c, *p;
+    gf t, xx ;
+
+    if (k == 1) 	/* degenerate case, matrix must be p^0 = 1 */
+	return 0 ;
+
+    c = NEW_GF_MATRIX(1, k);
+
+    b = NEW_GF_MATRIX(1, k);
+
+    p = NEW_GF_MATRIX(1, k);
+	if ( (c==0)||(b==0)||(p==0))
+	{
+		if (b==0)
+			free(b);
+		if (c==0)
+			free(c);
+		if (p==0)
+			free(p);
+		return 1;
+	}
+   
+    for ( j=1, i = 0 ; i < k ; i++, j+=k ) 
+	{
+		c[i] = 0 ;
+		p[i] = src[j] ;    /* p[i] */
+    }
+    c[k-1] = p[0] ;	/* really -p(0), but x = -x in GF(2^m) */
+    for (i = 1 ; i < k ; i++ ) {
+	gf p_i = p[i] ; /* see above comment */
+	for (j = k-1  - ( i - 1 ) ; j < k-1 ; j++ )
+	    c[j] ^= gf_mul( p_i, c[j+1] ) ;
+	c[k-1] ^= p_i ;
+    }
+
+    for (row = 0 ; row < k ; row++ ) {
+
+	xx = p[row] ;
+	t = 1 ;
+	b[k-1] = 1 ; /* this is in fact c[k] */
+	for (i = k-2 ; i >= 0 ; i-- ) {
+	    b[i] = c[i+1] ^ gf_mul(xx, b[i+1]) ;
+	    t = gf_mul(xx, t) ^ b[i] ;
+	}
+	for (col = 0 ; col < k ; col++ )
+	    src[col*k + row] = gf_mul(inverse[t], b[col] );
+    }
+    free(c) ;
+    free(b) ;
+    free(p) ;
+    return 0 ;
+}
+
+static int fec_initialized = 0 ;
+static void init_fec()
+{
+
+    generate_gf();
+
+    init_mul_table();
+
+    fec_initialized = 1 ;
+}
+
+
+#define FEC_MAGIC	0xFECC0DEC
+
+struct fec_parms {
+    u_long magic ;
+    int k, n ;		/* parameters of the code */
+    gf *enc_matrix ;
+} ;
+
+void fec_free(struct fec_parms *p)
+{
+    if (p==0 ||
+       p->magic != ( ( (FEC_MAGIC ^ p->k) ^ p->n) ^ (int)(p->enc_matrix)) ) 
+	{
+		//fprintf(stderr, "bad parameters to fec_free\n");
+		return ;
+    }
+    free(p->enc_matrix);
+    free(p);
+}
+
+
+struct fec_parms * fec_new(int k, int n)
+{
+    int row, col ;
+    gf *p, *tmp_m ;	
+
+    struct fec_parms *retval ;
+
+    if (fec_initialized == 0)
+	init_fec();
+
+		
+//	printf("GF_SIZE=%d,  GF_BITS=%d,  1<<GF_BITS=%d\n",GF_SIZE,GF_BITS,1<<GF_BITS);
+
+    if (k > GF_SIZE + 1 || n > GF_SIZE + 1 || k > n ) {
+		return 0 ;
+    }
+
+    retval = (struct fec_parms*)my_malloc(sizeof(struct fec_parms), "new_code");
+	if (retval==0)
+		return 0;
+
+    retval->k = k ;
+    retval->n = n ;
+    retval->enc_matrix = NEW_GF_MATRIX(n, k);
+	if (retval->enc_matrix==0)
+	{
+		free(retval);
+		return 0;
+	}
+		
+    retval->magic = ( ( FEC_MAGIC ^ k) ^ n) ^ (int)(retval->enc_matrix) ;
+    tmp_m = NEW_GF_MATRIX(n, k);
+	if (tmp_m==0)
+	{
+		free(retval->enc_matrix);
+		free(retval);
+		return 0;
+	}
+	
+    
+    tmp_m[0] = 1 ;
+    for (col = 1; col < k ; col++)
+	tmp_m[col] = 0 ;
+    for (p = tmp_m + k, row = 0; row < n-1 ; row++, p += k) {
+	for ( col = 0 ; col < k ; col ++ )
+	    p[col] = gf_exp[modnn(row*col)];
+    }
+
+   if (invert_vdm(tmp_m, k)) /* much faster than invert_mat */
+   {
+   		free(retval->enc_matrix);
+		free(retval);
+		free(tmp_m);
+		return 0;
+   }
+    matmul(tmp_m + k*k, tmp_m, retval->enc_matrix + k*k, n - k, k, k);
+
+    bzero(retval->enc_matrix, k*k*sizeof(gf) );
+    for (p = retval->enc_matrix, col = 0 ; col < k ; col++, p += k+1 )
+	*p = 1 ;
+    free(tmp_m);
+
+    DEB(pr_matrix(retval->enc_matrix, n, k, "encoding_matrix");)
+    return retval ;
+}
+
+
+void fec_encode(struct fec_parms *code, gf *src[], gf *fec, int index, int sz)
+{
+    int i, k = code->k ;
+    gf *p ;
+
+    if (GF_BITS > 8)
+	sz /= 2 ;
+
+    if (index < k)
+         bcopy(src[index], fec, sz*sizeof(gf) ) ;
+    else if (index < code->n) {
+		p = &(code->enc_matrix[index*k] );
+		bzero(fec, sz*sizeof(gf));
+		for (i = 0; i < k ; i++)
+	    addmul(fec, src[i], p[i], sz ) ;
+    } else
+    ;
+
+}
+
+
+static int shuffle(gf *pkt[], int index[], int k)
+{
+    int i;
+
+    for ( i = 0 ; i < k ; ) {
+	if (index[i] >= k || index[i] == i)
+	    i++ ;
+	else {
+	    int c = index[i] ;
+
+	    if (index[c] == c) {		
+			return 1 ;
+	    }
+	    SWAP(index[i], index[c], int) ;
+	    SWAP(pkt[i], pkt[c], gf *) ;
+	}
+    }
+    DEB(
+    for ( i = 0 ; i < k ; i++ ) {
+		if (index[i] < k && index[i] != i) {
+			return 1 ;
+		}
+    }
+    )
+    return 0 ;
+}
+
+static gf* build_decode_matrix(struct fec_parms *code, gf *pkt[], int index[])
+{
+    int i , k = code->k ;
+    gf *p, *matrix = NEW_GF_MATRIX(k, k);
+
+	if (matrix==0)
+	{
+		return 0;
+	}
+    for (i = 0, p = matrix ; i < k ; i++, p += k ) 
+	{
+		if (index[i] < k) 
+		{
+			bzero(p, k*sizeof(gf) );
+			p[i] = 1 ;
+		} else
+		if (index[i] < code->n )
+			bcopy( &(code->enc_matrix[index[i]*k]), p, k*sizeof(gf) ); 
+		else
+		{	
+		    free(matrix) ;
+			return 0 ;
+		}
+    }
+    
+    if (invert_mat(matrix, k)) {    //·µ»Ø0Ϊ³É¹¦,·ñÔòʧ°Ü
+		free(matrix);
+		matrix = 0 ;
+    }    
+    return matrix ;
+}
+
+int fec_decode(struct fec_parms *code, gf *pkt[], int index[], int sz)
+{
+    gf *m_dec ; 
+    gf **new_pkt ;
+    int i,row, col , k = code->k ;
+
+    if (GF_BITS > 8)
+	sz /= 2 ;
+
+    if (shuffle(pkt, index, k))	/* error if true */
+		return 1 ;
+    m_dec = build_decode_matrix(code, pkt, index);
+
+    if (m_dec == 0)
+		return 1 ; /* error */
+
+    new_pkt = (gf **)my_malloc (k * sizeof (gf * ), "new pkt pointers" );
+	if (new_pkt==0)
+	{
+		free(m_dec);
+		return 1;
+	}
+    for (row = 0 ; row < k ; row++ ) {
+		if (index[row] >= k) {
+		    new_pkt[row] = (gf *)my_malloc (sz * sizeof (gf), "new pkt buffer" );
+			if (new_pkt[row]==0)
+			{
+				free(m_dec);
+				for (i=0;i<row;i++)
+				{
+					free(new_pkt[row]);
+				}	
+				free(new_pkt);
+				return 1;
+			}
+			bzero(new_pkt[row], sz * sizeof(gf) ) ;
+			for (col = 0 ; col < k ; col++ )
+			addmul(new_pkt[row], pkt[col], m_dec[row*k + col], sz) ;
+		}
+    }
+
+    for (row = 0 ; row < k ; row++ ) {
+		if (index[row] >= k) {
+			bcopy(new_pkt[row], pkt[row], sz*sizeof(gf));
+			free(new_pkt[row]);
+		}
+    }
+    free(new_pkt);
+    free(m_dec);
+    return 0;
+}
+
+/*           $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   FEC´úÂë    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   */
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CFECRtpSession::CFECRtpSession()
+{
+
+	//init for send.
+	m_nRedundentRate = 1;
+	m_nFrameNo = 0;
+
+	//init for recv.
+//	m_bStartVideoData = false;
+	m_oldVideotimestamp = 0;
+	m_usLatestVideoSeq = 0;
+
+	int i;
+	for(i=0; i<FECLISTSIZE; i++){
+		m_FECListInfo[i].b_isEmpty=true;
+		m_FECListInfo[i].ul_HaveArriveNum=0;
+		m_FECListInfo[i].ul_timestamp=0;
+		m_FECListInfo[i].ul_TotalNeedNum=0;
+	}
+
+}
+
+CFECRtpSession::~CFECRtpSession()
+{
+
+}
+
+
+void CFECRtpSession::OnRTPPacket(RTPPacket *pack, const RTPTime &receivetime, const RTPAddress *senderaddress)
+{
+	FECHEADER*	fec_header;											 //FEC±¨ÎÄÍ·	
+	unsigned char *RecvData;
+	RecvData = pack->GetPayloadData();	 //Ö¸ÕëÀàÐÍת»¯
+	fec_header = (FECHEADER*)RecvData;
+	int Datalen = pack->GetPayloadLength();
+	//TRACE("      ÊÕµ½ÊÓƵ֡ÐòºÅ%d\n",rtp_header->ssrc);	
+	int rtptimestamp = pack->GetTimestamp();
+	int rtpFramNo    = pack->GetExtensionID();
+	
+	if(m_oldVideotimestamp!=0 || m_usLatestVideoSeq!=0){
+		if(rtptimestamp<=m_oldVideotimestamp && rtpFramNo<=m_usLatestVideoSeq){
+			if(m_usLatestVideoSeq-rtpFramNo<=10 && m_oldVideotimestamp-rtptimestamp<=10)
+				return ;
+			
+		} 
+		m_usLatestVideoSeq = 0; 
+		m_oldVideotimestamp = 0;
+	}
+	
+	//ÅжÏÊÇ·ñ¾­¹ýÁËFEC±àÂ룬½øÐÐÏàÓ¦µÄ´¦Àí
+	if(fec_header->FecCoded==0){//δ¾­¹ý±àÂë
+		
+		int nVideoframeNum;
+		bool bIsSameVideoUDP=false;
+		nVideoframeNum =	m_PreSendFrameList.size();
+		//²»Í¬Ö¡µÄʱ´ÁÒ»¶¨²»Ò»Ñù£¬µ«Èç¹ûÒ»Ñù£¬¿ÉÄÜÖ¡Öظ´
+		//µ«ÊÇÈç¹ûÒ»¸öÖ¡ÒÔFEC½øÐÐÁ˱àÂ룬ÿһ֡ÖÐUDP°üµÄʱ´Á¿Ï¶¨Ïàͬ
+		//ÓÃÀ´ÌÞ³ýʱ¼äÏàͬµÄ°ü(¼´ÏàͬµÄUDP°ü)£¬µ«ÊÇÕâ¸ö¿ÉÄÜÐÔ¼¸ºõûÓÐ
+		/*for(int i=0;i<nVideoframeNum;i++)
+		{	
+		FRAMEINFO*	m_pFrame;
+		POSITION pos;
+		pos						=	m_PreSendVideoDataList.FindIndex(i);	
+		m_pFrame				=	m_PreSendVideoDataList.GetAt(pos);
+		if(m_pFrame->ul_timestamp==rtp_header->timestamp)
+		{
+		bIsSameVideoUDP=true;
+		}
+	}*/
+		//¼ÓÈë¸ÃUDP°üÓëÆäËû°ü²»Í¬
+		if(bIsSameVideoUDP==false)
+		{
+			unsigned char* pPacket;
+			pPacket		=	new unsigned char[Datalen];
+			if (pPacket==NULL)
+			{
+				return;
+			}		
+			//¸´ÖƸðü
+			memcpy(pPacket,RecvData,Datalen);
+			//»ñµÃ¸Ã°üµÄÐÅÏ¢
+			FRAMEINFO* pFrameInfo = NULL;
+			pFrameInfo	=	new	FRAMEINFO;
+			
+			if (pFrameInfo==NULL)     
+			{             //·ÖÅäÄÚ´æʧ°Ü
+				delete pPacket;
+				return;
+			}
+			//»ñµÃ¸Ã°üµÄÐÅÏ¢
+			pFrameInfo->FECCoded		=	false;
+			pFrameInfo->ul_timestamp	=	rtptimestamp;
+			pFrameInfo->us_latestseq	=	rtpFramNo;
+			pFrameInfo->l_datalen		=	Datalen-sizeof(FECHEADER);
+			pFrameInfo->pData			=	pPacket+sizeof(FECHEADER);
+			//				m_PreSendVideoDataList.AddTail(pFrameInfo);			
+			m_PreSendFrameList.insert(m_PreSendFrameList.end(), pFrameInfo);
+//			printf("\nnew frame success. FrameNo:%d\n", rtpFramNo);
+			UpdateFrames();
+			//Èç¹û»º³åÇøÒѾ­¿ªÊ¼¶ÁÊý¾Ý,Ôòÿ´Î¶¼ÅжÏÊÇ·ñÓнô½Ó×ŵÄÄÇÒ»Ö¡
+			//ÓÐÔòµã»ð´¥·¢ÉϲãÊý¾Ýµ½´ïʼþ
+			//ÎÞÔò¼ÌÐøµÈ´ýÊý¾Ý				
+			//				if(m_bStartVideoData)
+			//				{
+			//TRACE("ÊÓƵ»º³åÂúºóÒѾ­¿ªÊ¼´¦ÀíÊÓƵÊý¾Ý\n");
+			//					bool m_bIsHaveNext	=	true;
+			//					while(m_bIsHaveNext)
+			//					{
+			//
+			//						int n	=	m_PreSendFrameList.size();
+			//						TRACE("×¼±¸µã»ð %d\n",n);
+			//						m_bIsHaveNext	=	IsHaveNextVideoFrame(n);
+			//					}				
+			//				}
+		}
+	}
+	else{ 
+		if(fec_header->FecCoded==1)//¾­¹ý±àÂë
+		{//7	
+			//ֵΪtimestampµÄFEC°üÒѾ­×é×°³ÉFrame£¬²»´¦Àí¸Ãrtp°ü.
+			FRAMEINFO*	pFrameInfo;
+			FRAMEINFOLIST::iterator itera;
+			for(itera=m_PreSendFrameList.begin(); itera != m_PreSendFrameList.end(); ++itera){
+				pFrameInfo = *itera;
+				if(rtptimestamp==pFrameInfo->ul_timestamp)
+					return;
+			}
+			
+			
+			int i;
+			bool b_isNotAdd	=	true;
+			//¹²ÓÐFECLISTSIZE¸öFEC»º³åÇø
+			for( i=0;i<FECLISTSIZE;i++)
+			{//6
+				if(m_VideoDataList[i].size()!=0)//¶ÓÁзǿÕ
+				{//5
+					//Èç¹ûʱ¼ä´ÁÏàͬ£¬Ôò˵Ã÷¸ÃUDP°üÊDZ¾Ö¡µÄ
+					//ÓÐÒ»¶ÓÁÐÖеÄÊý¾Ýʱ´Á£½ÐÂÀ´Êý¾Ý֡ʱ´Á
+					if(rtptimestamp==m_FECListInfo[i].ul_timestamp)
+					{//4½«¸ÃÊý¾ÝÖ¡¼ÓÈë¸Ã¶ÓÁÐ
+						//################################################################
+						//ÐèÒªÅжÏÊÇ·ñÖظ´µÄÊý¾Ý,UDPÊý¾Ý°ü¿ÉÄÜÖظ´
+						//################################################################
+						b_isNotAdd	=	false;
+						/*È¥µôÊý¾ÝÖظ´Åжϡ£dane modified.
+						unsigned char*	pVideoPacket;
+						bool    bIsSameFECVideoData=false;
+						//ÅжÏÊÇ·ñÓÐÖظ´½ÓÊյİü
+						for(int j=0;j<m_VideoDataList[i].GetCount();j++)
+						{
+						POSITION		pos;
+						pos				=	m_VideoDataList[i].FindIndex(j);							
+						pVideoPacket	=	m_VideoDataList[i].GetAt(pos);
+						RTPHEADER*	    VideoRtp_header;
+						VideoRtp_header	=	(RTPHEADER*)pVideoPacket;
+						//ÓÐÓëÖ®°üÐòºÅÏàͬµÄ
+						if(rtp_header->sequence == VideoRtp_header->sequence)
+						{
+						bIsSameFECVideoData=true;
+						}
+						}
+						*/
+						
+						bool bIsSameFECVideoData = false;
+						//ûÓÐÖظ´½ÓÊյİü
+						if(bIsSameFECVideoData==false)
+						{
+							unsigned char *pPack	=	new unsigned char[Datalen];
+							if (pPack==NULL)
+							{
+								return;
+							}
+							memcpy(pPack,RecvData,Datalen);
+							
+							m_VideoDataList[i].insert(m_VideoDataList[i].end(), (char*)pPack);
+							
+							
+							//Ð޸ĸöÓÁÐVideoFECListInfo
+							m_FECListInfo[i].ul_HaveArriveNum++;
+							
+							//							TRACE("¼ÓÈëFEC¶ÓÁÐ%d  rtp°üʱ¼ä%d  ±¾FEC»º³åÇøÒѵ½´ï%d  Ó¦µ½´ï%d\n",i,rtp_header->timestamp,VideoFECListInfo[i].ul_HaveArriveNum,VideoFECListInfo[i].ul_TotalNeedNum);
+							
+							//ÅжÏÊÇ·ñ·ûºÏ½âÂëÌõ¼þ
+							if(m_FECListInfo[i].ul_HaveArriveNum == m_FECListInfo[i].ul_TotalNeedNum)//·ûºÏ½âÂëÌõ¼þ
+							{//3//½âÂë¹ý³Ì¿ªÊ¼	
+								//TRACE("     ·ûºÏFEC½âÂëÊÓƵ֡ÐòºÅ%d\n",rtp_header->ssrc);
+								//								TRACE("¿ªÊ¼FEC½âÂë%d \n",i);
+								if (FECDecode(&(m_FECListInfo[i]),&m_VideoDataList[i], pack) == 0)
+								{
+//									printf("\nFEC decode success and new frame. FrameNo:%d\n", rtpFramNo);
+									UpdateFrames();
+									//½âÂë³É¹¦
+									//Èç¹û»º³åÇøÒѾ­¿ªÊ¼¶ÁÊý¾Ý,Ôòÿ´Î¶¼ÅжÏÊÇ·ñÓнô½Ó×ŵÄÄÇÒ»Ö¡
+									//ÓÐÔòµã»ð´¥·¢ÉϲãÊý¾Ýµ½´ïʼþ
+									//ÎÞÔò¼ÌÐøµÈ´ýÊý¾Ý	
+									//									if(m_bStartVideoData)
+									//									{
+									//										bool m_bIsHaveNext	=	true;
+									//										while(m_bIsHaveNext)
+									//										{
+									//											int n	=	m_PreSendFrameList.size();
+									//											//TRACE("×¼±¸µã»ð ÐòºÅ%d ¶ÓÁÐ%d Ó¦µ½%d ʵµ½%d \n",rtp_header->sequence,n,VideoFECListInfo[i].ul_TotalNeedNum,VideoFECListInfo[i].ul_HaveArriveNum);
+									//											//										m_bIsHaveNext	=	IsHaveNextVideoFrame(n);
+									//										}				
+									//									}
+								}
+								else
+								{
+									printf("\nFEC decode failed.");
+									//									TRACE("FEC ³ö´í\n");
+								}
+							}
+						}//4
+					}//5					
+				}//6
+			}
+			if(b_isNotAdd)
+			{
+				//				TRACE("UDP°üûÓмÓÈëºÏÊʵĻº³å\n");
+				//¸ÃUDP°üûÓнøÈëºÏÊʵÄFEC»º³å
+				for(i=0;i<FECLISTSIZE;i++)
+				{
+					//Èç¹ûÓÐij¸öFEC»º³åΪ¿Õ£¬¾Í½«Õâ¸öUDP°ü¼ÓÈë½øÈ¥ÐγÉÐÂÖ¡
+					if(m_FECListInfo[i].b_isEmpty)
+					{
+						//						TRACE("ÕÒµ½ÁËÒ»¸ö¿Õ»º³å%d²¢¼ÓÈë\n",i);
+						//½«¸ÃÊý¾ÝÖ¡¼ÓÈë¸Ã¶ÓÁÐ
+						unsigned char *pPack	=	new unsigned char[Datalen];
+						if (pPack==NULL)
+						{
+							return;
+						}
+						memcpy(pPack,RecvData,Datalen);
+						//*pPack		=	*RecvData;
+						m_VideoDataList[i].insert(m_VideoDataList[i].end(), (char*)pPack);
+						//						TRACE("»º³åÇø״̬£¬ÊÇ·ñΪ¿Õ %d \n",m_VideoDataList[i].IsEmpty());
+						//ÐÞ¸ÄÏàÓ¦VideoFECListInfo
+						m_FECListInfo[i].b_isEmpty			=	false;
+						m_FECListInfo[i].ul_HaveArriveNum	=	1;
+						m_FECListInfo[i].ul_timestamp		=	rtptimestamp;
+						//					TRACE("»º³åÇøʱ¼ä¸üÐÂΪ%d \n",VideoFECListInfo[i].ul_timestamp);
+						m_FECListInfo[i].ul_TotalNeedNum		=	fec_header->OriginalK;
+						b_isNotAdd								=	false;	
+						return;
+					}					
+				}
+			}
+			if(b_isNotAdd)
+			{
+				//			TRACE("»¹ÊÇûÓÐÕÒµ½ºÏÊʵĻº³å\n");
+				//¿´¿´ÊÇ·ñij¸öFEC»º³åÒѾ­ÎÞÍû½âÂëÁË
+				ulong time=m_FECListInfo[0].ul_timestamp;
+				int j=0;
+				//²éÕÒ×îÎÞÍûµÄFEC»º³å£¬ÒòΪÓÐÈý¸öFEC»º³å
+				//ÕÒʱ¼ä×îСµÄ
+				for(i=1;i<FECLISTSIZE;i++)
+				{
+					if(m_FECListInfo[i].ul_timestamp<time)
+					{
+						time = m_FECListInfo[i].ul_timestamp;
+						j = i;
+					}
+				}
+				//			TRACE("Çå¿ÕµÚ%d¸öFEC»º³å\n",j);
+				//Çå¿Õ×îÎÞÍûµÄFEC»º³å
+				/*				int iListNum	=	m_VideoDataList[j].GetCount();
+				for(int i=0;i<iListNum;i++)
+				{
+				unsigned char* pPacket;
+				POSITION pos;
+				pos		=	m_VideoDataList[j].FindIndex(i);
+				pPacket	=	m_VideoDataList[j].GetAt(pos);
+				delete pPacket;
+				}
+				m_VideoDataList[j].RemoveAll();
+				*/
+				
+				char*	p;
+				FECDATALIST::iterator itera;
+				for(itera=m_VideoDataList[j].begin(); itera != m_VideoDataList[j].end(); ++itera){
+					p = *itera;
+					delete p;
+					p=0;
+				}
+				m_VideoDataList[j].clear();
+				
+				//Õâ¸öFEC»º³åΪ¿Õ£¬¾Í½«UDP°ü¼ÓÈë½øÈ¥ÐγÉÐÂÖ¡
+				//				InitialVideoFECListInfo(j);
+				//½«¸ÃÊý¾ÝÖ¡¼ÓÈë¸Ã¶ÓÁÐ
+				unsigned char *pPack	=	new unsigned char[Datalen];
+				if (pPack==NULL)
+				{
+					return;
+				}
+				memcpy(pPack,RecvData,Datalen);
+				//*pPack		=	*RecvData;
+				m_VideoDataList[j].insert(m_VideoDataList[j].end(), (char*)pPack);
+				//ÐÞ¸ÄVideoFECListInfo
+				m_FECListInfo[j].b_isEmpty		=	false;
+				m_FECListInfo[j].ul_HaveArriveNum	=	1;
+				m_FECListInfo[j].ul_timestamp		=	rtptimestamp;
+				m_FECListInfo[j].ul_TotalNeedNum	=	fec_header->OriginalK;
+				return;
+			}
+		}
+	}
+	//		printf("\nDo nothing!!!!");
+
+
+//	return;
+	return;		//TRACE("´¦ÀíÍêÒ»´ÎRTP°ü\n");
+
+}
+
+int CFECRtpSession::FECDecode(FECLISTINFO* pFecListInfo,FECDATALIST *pFecDataList, RTPPacket *pack)
+{
+	int			PSize;     //ÿһ¸öÏòÁ¿µÄ³¤¶È
+	int			*ixs;     //½âÂëÇ°µÄ±¨ÎÄÐòºÅÊý×é
+	void		*code;	  //fec½âÂë¾ØÕó
+	unsigned char*	*d_src;	  //ԭʼÊý¾Ý
+
+	unsigned char		* pDataBuf;	
+	ulong	ul_timestamp;    //ʱ´Á
+//	ulong	us_sequence;     //Ö¡ÐòºÅ	
+	unsigned int kCount;   //FEC nk±àÂëµÄKÖµ
+	kCount = pFecListInfo->ul_TotalNeedNum;    //ÐèÒª½âÂëµÄÏòÁ¿Êý,¼´k
+
+	FECHEADER*	fec_header;											 //FEC±¨ÎÄÍ·	
+	unsigned char *RecvData;
+	RecvData = pack->GetPayloadData();	 //Ö¸ÕëÀàÐÍת»¯
+	fec_header = (FECHEADER*)RecvData;
+//	int Datalen = pack->GetPayloadLength();	
+	int rtptimestamp = pack->GetTimestamp();
+	int rtpFramNo    = pack->GetExtensionID();
+
+
+	ul_timestamp	=	rtptimestamp;   //ʱ´Á
+
+	/*$$$$$$$$$$$$$$$$$$$$$$ÕâÀïʹÓÃÁË$$$$$$$$$$$$$$$$$$$$$*/
+
+//	us_sequence		=	rtp_header->frameno;     //Ö¡ÐòºÅ
+	PSize = fec_header->PacketSize;	
+	
+	code = (*fec_new)(fec_header->OriginalK, fec_header->RedunN);		
+	if (code==NULL)
+	{
+		return 1;
+	}
+	ixs			=	new int[kCount];
+	if (ixs==NULL)
+	{
+		fec_free((struct fec_parms *)code);//ÊÍ·ÅÄÚ´æ
+		return 1;
+	}
+	d_src =	new PUCHAR[kCount];						//¶þάÊý×éµÄµÚһάָÕë
+	if (d_src==NULL)
+	{
+		delete ixs;
+		fec_free((struct fec_parms *)code);//ÊÍ·ÅÄÚ´æ
+		return 1;
+	}
+	long		OriginalDataLen;//Ô­À´ÓÐ
+	unsigned int j;
+	for(j=0;j<kCount;j++)
+	{
+		d_src[j]	=	new unsigned char[PSize];   //·ÖÅäk¸ö´óСΪPSizeµÄÖ¸Õë
+		if (d_src[j]==NULL)
+		{
+			delete ixs;
+			fec_free((struct fec_parms *)code);//ÊÍ·ÅÄÚ´æ
+			for (unsigned int ii=0;ii<j;ii++)
+			{
+				delete d_src[ii];
+			}
+			delete d_src;
+			return 1;
+		}
+	}	
+/*
+	for(j=0;j<kCount;j++)												//´´½¨½âÂëԭʼÊý¾Ý£¬¶þάÊý×é
+	{
+		RTPHEADER*		rtp_header1;
+		FECHEADER*		fec_header1;
+		unsigned char*			pPacket;
+		POSITION		pos;
+		pos	= pFecDataList->FindIndex(j);							
+		pPacket	= pFecDataList->GetAt(pos);
+		rtp_header1 = (RTPHEADER*)pPacket;
+		fec_header1	= (FECHEADER*)(pPacket+sizeof(RTPHEADER));
+		PADHEADER* ppad = (PADHEADER*)(pPacket+sizeof(RTPHEADER)+sizeof(FECHEADER));
+		ixs[j] = fec_header1->OrigiCol;							//¸³Öµ
+		memcpy(d_src[j],(unsigned char*)(pPacket+sizeof(RTPHEADER)+sizeof(FECHEADER)),fec_header1->PacketSize);
+		delete pPacket;
+	}
+*/
+	char*	p;
+	FECDATALIST::iterator itera;
+	for(j=0, itera=pFecDataList->begin(); j<kCount && itera != pFecDataList->end(); j++, itera++){
+			FECHEADER*		fec_header1;
+			p = *itera;
+			fec_header1	= (FECHEADER*)(p);
+			//		PADHEADER* ppad = (PADHEADER*)(pPacket+sizeof(RTPHEADER)+sizeof(FECHEADER));
+			ixs[j] = fec_header1->OrigiCol;							//¸³Öµ
+			memcpy(d_src[j],(char*)(p+sizeof(FECHEADER)),fec_header1->PacketSize);
+			delete p;
+	}
+				
+	pFecDataList->clear();
+
+	pFecListInfo->b_isEmpty=true;
+	pFecListInfo->ul_HaveArriveNum=0;
+	pFecListInfo->ul_timestamp=0;
+	pFecListInfo->ul_TotalNeedNum=0;
+
+	int CodeResult = 0;
+	try
+	{
+		CodeResult = fec_decode((struct fec_parms *)code,(unsigned char **)d_src, ixs, PSize);
+	}
+	catch(...)
+	{
+		CodeResult = 1;     //·¢ÉúÒì³£
+	}
+
+	if (CodeResult==0)	//½âÂë,µÈÓÚ0³É¹¦
+	{
+
+		OriginalDataLen	=	GetDataLen(d_src,PSize,kCount);	//µÃµ½Ô­Ê¼Ö¡Êý¾Ý³¤¶È
+		pDataBuf		=	new unsigned char[OriginalDataLen];
+		if (pDataBuf!=NULL)
+		{
+			GetData(pDataBuf,d_src,PSize,kCount);
+
+			FRAMEINFO *pFrameInfo;
+			pFrameInfo	=	new	FRAMEINFO;
+			if (pFrameInfo!=NULL)
+			{
+				pFrameInfo->FECCoded		=	true;
+				pFrameInfo->ul_timestamp	=	ul_timestamp;
+				pFrameInfo->us_latestseq	=	rtpFramNo;
+				pFrameInfo->l_datalen		=	OriginalDataLen;
+				pFrameInfo->pData			=	pDataBuf;	
+
+				m_PreSendFrameList.insert(m_PreSendFrameList.end(), pFrameInfo);
+			}
+		}
+
+		//test
+//		HANDLE hf;
+//		hf = CreateFile("calc.exe", GENERIC_WRITE, 0, 0, CREATE_NEW|TRUNCATE_EXISTING, 0, 0);
+//		unsigned long l, i, t;
+//		l = OriginalDataLen;
+//		i = 0;
+//		t = 0;
+//		while(l>0){
+//			WriteFile(hf, pDataBuf+t, l, &i, 0);
+//			t += i;
+//			l -= i;
+//		}
+//		CloseHandle(hf);
+		//test
+	}
+
+	delete ixs;
+	for(unsigned int i=0;i<kCount;i++)
+	{
+		delete d_src[i];
+	}
+	delete d_src;
+	fec_free((struct fec_parms *)code);//ÊÍ·ÅÄÚ´æ
+		
+	return CodeResult;
+
+}
+
+long CFECRtpSession::GetDataLen(PUCHAR* d_src,long lPacketSize,unsigned int kCount)
+{
+	//long PacketSize;									
+	PADHEADER* pad_header;
+	long OriginalDataLen=0;	
+
+	for(unsigned int i=0;i<kCount;i++)									//½«¶þάÊý×éÖеÄÊý¾Ýת´æpAudioBuf
+	{
+		//ÅжÏÊÇ·ñ¾­¹ýÌî³ä
+		pad_header			=	(PADHEADER*)(d_src[i]);
+		if(pad_header->paddled==0)
+		{	
+			OriginalDataLen	=	OriginalDataLen+lPacketSize-sizeof(PADHEADER);
+		}
+		else if(pad_header->paddled==1)
+		{		
+			OriginalDataLen	=	OriginalDataLen+lPacketSize-sizeof(PADHEADER)-pad_header->padlen;
+		}	
+	}
+	return OriginalDataLen;
+}
+
+void CFECRtpSession::GetData(unsigned char* pData,PUCHAR* d_src,long  lPacketSize,unsigned int kCount)
+{
+	unsigned char*	midbuf;
+	midbuf	=	pData;
+	PADHEADER* pad_header;
+	for(unsigned int i=0;i<kCount;i++)									//½«¶þάÊý×éÖеÄÊý¾Ýת´æpAudioBuf
+	{
+		//ÅжÏÊÇ·ñ¾­¹ýÌî³ä
+		pad_header			=	(PADHEADER*)(d_src[i]);
+		if(pad_header->paddled==0)
+		{
+			memcpy(midbuf,d_src[i]+sizeof(PADHEADER),lPacketSize-sizeof(PADHEADER));
+			midbuf = midbuf+lPacketSize-sizeof(PADHEADER);			
+		}
+		else if(pad_header->paddled==1)
+		{
+			memcpy(midbuf,d_src[i]+sizeof(PADHEADER),lPacketSize-sizeof(PADHEADER)-pad_header->padlen);
+			midbuf = midbuf+lPacketSize-sizeof(PADHEADER)-pad_header->padlen;
+		}	
+	}
+
+}
+
+int CFECRtpSession::GetRtpMaxLen()
+{
+
+	return RtpMaxLen;
+}
+
+
+int CFECRtpSession::SendFECPacket(void *lpData, int datalen, int ndelay /* = 5000*/)
+{
+	int nRtpMaxLen;
+	char *pFECPacket;
+	FECHEADER* fec_header;
+
+	pFECPacket = 0;
+	nRtpMaxLen = GetRtpMaxLen();
+
+	IncrementTimestamp(1);
+	SetDefaultTimestampIncrement(0);
+	m_nFrameNo++;
+	if(datalen+sizeof(FECHEADER) <= nRtpMaxLen){		//Send a FEC packet directly.
+		pFECPacket = new char[datalen+sizeof(FECHEADER)];
+		if(pFECPacket == 0){
+			return -1;
+		}
+		fec_header = (FECHEADER*)pFECPacket;
+		fec_header->FecCoded = 0;     
+		memcpy(pFECPacket+sizeof(FECHEADER),lpData,datalen);  //¿½±´ÐèÒª·¢Ë͵ÄÊý¾Ý
+
+		//rtppacket µÄÀ©Õ¹IDºÅ×÷ΪèåÐòºÅ¡£
+		SendPacketEx(pFECPacket, datalen+sizeof(FECHEADER), m_nFrameNo, 0, 0);
+		delete[] pFECPacket;
+		usleep(ndelay);
+		return 0;
+	} 
+	
+	FECEncodeSend(lpData, datalen, m_nFrameNo, ndelay);
+	return 0;
+}
+
+
+
+int CFECRtpSession::FECEncodeSend(void *pData, 
+								  long datalen,
+								  unsigned int FrameNo, 
+								  int ndelay ) //15000 ´óÖµÈÓÚ2000000£¨Á½ÃëµÄ²ÉÑùÖÜÆÚ£©/(300000(×î´óèå) / 5000£¨°üµÄ´óС£©*) -²É¼¯±àÂëËùºÄʱ¼ä¡£
+{
+	int         SZ;
+	void        *code =0;          //±à½âÂëµÄÖ¸Õë
+	int         kk ;              //ԭʼÊý¾ÝµÄάÊý
+	uchar*      SendData=0;     //ÓÃÀ´¸øRTP²ãÌṩÊý¾ÝµÄÄڴ滺³åÇø
+	FECHEADER*  fec_header;
+	PADHEADER*  pad_header;
+	int         lim = GF_SIZE + 1;    //±àÂëµÄnÖµ
+	int         *ixs = 0 ;           
+	int         redudant,i;          //·¢Ë͵ÄÐòºÅ
+	int         lastpacketlen;
+	uchar       **d_original, **d_src;  //×Ö·û´®¶þάÊý×é
+	
+	//TRACE("½øÈëFEC±àÂ뺯Êý\n");
+	
+	bool CodeResult = true;
+	/*ÎÒ¶ÔÊý¾Ý½øÐжþÖØÈßÓà±àÂë,ÒòΪʵ¼ÊÓ¦ÓÃÖÐ×î¶à¶þÖرàÂë,³¬¹ýÁ˶þÖØÈßÓà¾ÍûÓÐÒâÒåÁË*/
+	
+	SZ = GetRtpMaxLen();   //RTP±¨Îij¤¶È
+	try
+	{
+		kk = datalen/(SZ-sizeof(PADHEADER));
+	}
+	catch(...)
+	{
+		return -1;
+	}
+	if(kk<0)
+		return -1;
+	lastpacketlen = datalen%(SZ-sizeof(PADHEADER));
+	if (lastpacketlen!=0)
+		kk++;     //×îºóÒ»¸ö²»¹»³¤,Ìî³ä	
+	
+	d_original = (uchar**)malloc(kk * sizeof(void *));
+	if (d_original==0)
+		return -2;
+	
+	d_src = (uchar**)malloc(kk * sizeof(void *));
+	if ((d_original==0)||(d_src==0))	
+	{
+		free(d_original);
+		return -3;
+	}
+	for (i=0;i<kk;i++)     //Ö¸Õ븳³õÖµ	
+	{
+		d_original[i] = 0;
+		d_src[i] = 0;
+	}
+	
+	for (i=0; i<kk; i++)
+	{
+		d_original[i] = (uchar*)malloc(SZ);
+		if (d_original[i]==0)
+			goto fail;
+		d_src[i] = (uchar*)malloc(SZ);
+		if (d_src[i]==0)
+			goto fail;
+	}                            //ÓйØfecµÄ´úÂë¿ÉÒÔ¿´fec×÷ÕßдµÄdemo
+	
+	code = (*fec_new)(kk, lim);    //Éú³É±àÂë¾ØÕó
+	if (code==0)     //±àÂë¾ØÕóʧ°Ü	
+	{
+//		TRACE("new fec±àÂëÆ÷ʧ°Ü,³¬³öFECÄÜÁ¦,kk=%d lim=%d\n",kk,lim);
+		goto fail;
+	}
+	
+	ixs = (int*)malloc(kk * sizeof(int));  //·ÖÅäÄÚ´æ¿Õ¼ä,kk¸öÕûÐδóС
+	if (ixs==0)
+		goto fail;
+	
+	SendData = (uchar*)malloc(SZ+sizeof(FECHEADER));
+	if (SendData==0)	
+		goto fail;	
+	
+	for (i=0; i<kk; i++) ixs[i] = kk+i; 	
+	
+	//Ìî³äԭʼÊý¾Ý,¼Çס¼ÓÉÏFECHEADER
+	for (i=0;i<kk;i++)
+	{
+		pad_header = (PADHEADER*)d_original[i];
+		if ((i!=(kk-1))||(lastpacketlen==0))   //ûÓÐÌî³äλ
+		{
+			pad_header->paddled = UNPAD;
+			pad_header->padlen = 0;
+			//¿½±´Êý¾Ý
+			memcpy(d_original[i]+sizeof(PADHEADER),(uchar*)pData+i*(SZ-sizeof(PADHEADER)),SZ-sizeof(PADHEADER));
+		}
+		else    //×îºóÒ»¸öÐèÒªÌî³äλ
+		{
+			pad_header->paddled = ISPAD;
+			pad_header->padlen = SZ-sizeof(PADHEADER)-lastpacketlen;
+			memcpy(d_original[i]+sizeof(PADHEADER),(uchar*)pData+i*(SZ-sizeof(PADHEADER)),lastpacketlen);		
+			memset(d_original[i]+sizeof(PADHEADER)+lastpacketlen, 'A', SZ-sizeof(PADHEADER)-lastpacketlen);
+		}
+	}	
+	
+	/*int maxpacket;
+	if (kk<=MAXFECPACKET/2)
+	maxpacket = kk;
+	else maxpacket = MAXFECPACKET-kk;*/   //·ÀÖ¹³¬³ö·¶Î§
+	
+	//FECºÃÏñ½öÄÜÉú³ÉÒ»·ÝÈßÓà°ü£¬ÒÔΪ×ÅÈç¹ûÊäÈën¸ö°ü£¬×î¶à»ñµÃn¸öÈßÓà°ü!!
+	
+	//¶ª°üÂÊ ÈÏΪ¹À¼ÆÖµ(±£ÊعÀ¼Æ£¬±È½Ï´ó)
+	
+	int maxpacket;
+	
+	if(m_nRedundentRate<=0)
+	{
+		//ûÓÐÈßÓà°ü
+		maxpacket = 0;
+	}
+	else if(m_nRedundentRate > 200)
+	{
+		//»¹ÊÇûÓÐÈßÓà°ü
+		maxpacket = 0;
+	}
+	else if(m_nRedundentRate > 100)
+	{
+		//ÕâÀïµÄÈßÓà¶ÈȡʮλÊý£¬×îÉÙÈßÓà¶ÈÊÇ1
+		//×îÉÙÓÐ1¸öÈßÓà°ü
+		maxpacket = (int)((m_nRedundentRate - 100)*kk/100) + 1;
+		//²»¿ÉÒÔ±Èkk¶à£¬·ñÔòfec»á³ö´í
+		if(maxpacket > kk)
+		{
+			maxpacket = kk;
+		}
+		//²»¿ÉÒÔ³¬¹ýFECµÄÄÜÁ¦£¬×î´ó±àÂë°üÊý
+		if(maxpacket > MAXFECPACKET - kk)
+		{
+			maxpacket = MAXFECPACKET - kk;
+		}
+	}
+	else
+	{
+		//ÓÐÈßÓà°üÁË
+		//ԭʼ°ü±È½ÏÉÙ
+		if(kk < 5)
+		{
+			maxpacket = kk;
+			//²»¿ÉÒÔ³¬¹ýFECµÄÄÜÁ¦£¬×î´ó±àÂë°üÊý
+			if(maxpacket > MAXFECPACKET - kk)
+			{
+				maxpacket = MAXFECPACKET - kk;
+			}
+		}
+		else
+		{
+			//×îÉÙÓÐ5¸öÈßÓà°ü
+			maxpacket = (int)(m_nRedundentRate*kk/100) + 5;
+			//²»¿ÉÒÔ±Èkk¶à£¬·ñÔòfec»á³ö´í
+			if(maxpacket > kk)
+			{
+				maxpacket = kk;
+			}
+			//²»¿ÉÒÔ³¬¹ýFECµÄÄÜÁ¦£¬×î´ó±àÂë°üÊý
+			if(maxpacket > MAXFECPACKET - kk)
+			{
+				maxpacket = MAXFECPACKET - kk;
+			}
+		}
+	}
+	
+	
+	
+//	TRACE("¹²ÓÐ%d¸öԭʼÊý¾Ý°üºÍ%d¸öÈßÓà°ü----------------------\n",kk,maxpacket);
+    for( i = 0 ; i < maxpacket ; i++ )   //²úÉúÒ»·ÝÍêÈ«ÈßÓàÊý¾Ý
+	{
+		try
+		{
+			fec_encode((fec_parms *)code, (unsigned char**)d_original, (unsigned char*)(d_src[i]), ixs[i], SZ );  //±àÂë
+		}
+		catch(...)
+		{
+			CodeResult = false;
+		}
+	}	
+	
+	if (CodeResult==false)
+		goto fail;     //±àÂë´íÎó
+	
+	//¸ù¾Ýµ±Ç°±¨ÎĶªÊ§ÂʺÍԭʼ±¨ÎĵÄάÊý¾ö¶¨·¢ËÍÊý¾ÝµÄÈßÓàÁ¿,º¯Êý°´ÕÕÁõ¾ùÌá³öµÄ¹«Ê½ÊµÏÖ
+	//Cooper:redudantÔÚSkyClassºÍRealClassûÓз´À¡µÄÇé¿öÏ£¬Ê¼ÖÕΪ0
+	//redudant = CompuRedudantN(kk,SendRtp->GetCurrentLostRate(),SendRtp->GetMaxLostRate());	
+	redudant = 0;
+	
+	//½á¹ûµÈÓÚ£­1±íʾµ±Ç°±¨ÎĶªÊ§ÂÊÌ«´ó£¬²»·¢ËÍÈκÎÊý¾Ý,µ«ÊÇÒôƵÊý¾ÝÎÞÂÛÈçºÎ¶¼Òª·¢ËÍ
+	if ( (redudant!=-1))      
+	{
+		for(i=0;i<kk;i++)   //Ê×ÏÈ·¢ËÍ·ÇÈßÓàÊý¾Ý
+		{
+			memset(SendData, 0, SZ+sizeof(FECHEADER));
+			fec_header = (FECHEADER*)SendData;
+			fec_header->FecCoded = FECCODED;   //FEC±àÂë
+			fec_header->OriginalK = kk;
+			fec_header->OrigiCol = i;
+			fec_header->PacketSize = SZ;
+			fec_header->RedunN = lim;
+			memcpy(SendData+sizeof(FECHEADER),d_original[i],SZ);
+			//test 
+//			if(i==1){
+//				memcpy(SendData+sizeof(FECHEADER),d_original[0],SZ);
+//			}
+//			if(i==0){
+//				memcpy(SendData+sizeof(FECHEADER),d_original[1],SZ);
+//			}
+//			if(i==4||i==10||i==11||i==12)
+//				continue;
+			//test
+			SendPacketEx(SendData,SZ+sizeof(FECHEADER), FrameNo, 0, 0);
+			usleep(ndelay);
+		}	
+	}
+	
+	if ( kk>20 )              //ÈËΪÔö¼Ó5Ö¡
+	{                  //Õâ¶Î´úÂëÊǸù¾ÝÆÁÄ»´«Êä¸ÄÔìµÄ,ÒòΪÆÁÄ»Êý¾Ý±È½Ï´ó,Òò´ËÈßÓà¶ÈÒªÇó´óÒ»µã
+		if ( redudant==-1)   //¼ÆËã½á¹ûµÈÓÚ-1ÇÒÊÇÒôƵ
+		{
+			redudant = 1;        //ÒôƵÊý¾ÝÇ¿ÖƵÈÓÚ1
+		}else if (kk>20)   //Ö¡Êý±È½Ï¶à
+		{
+			redudant=+5;	
+		}
+	}
+	
+	if (redudant>=kk)     //²»Òª´«ÊäÌ«¶àÈßÓàÊý¾Ý
+	{
+		redudant = kk;
+	}
+	
+	if (kk+redudant>=MAXFECPACKET)     //ÔÊÐí´«ÊäµÄÿ¸ö±¨ÎĵÄ×î´ó·Ö×éÊý
+		redudant = MAXFECPACKET-kk;
+	
+//	TRACE("ÈßÓàÊý¾Ý°üΪ%d¸ö\n",maxpacket);
+	//ÕâÀï±¾À´ÊÇredudant,µ«reduant²»Æð×÷Óã¬Ö±½Ó¸Ä³Émaxpacket!!
+	for(i=0;i<maxpacket;i++)
+	{
+		//TRACE("×¼±¸·¢Ë͵Ú%d¸öÈßÓàÊý¾Ý°ü\n",i);
+		memset(SendData, 0, SZ+sizeof(FECHEADER));
+		fec_header = (FECHEADER*)SendData;
+		fec_header->FecCoded = FECCODED;   //FEC±àÂë
+		fec_header->OriginalK = kk;
+		fec_header->OrigiCol = kk+i;
+		fec_header->PacketSize = SZ;
+		fec_header->RedunN = lim;
+		memcpy(SendData+sizeof(FECHEADER),d_src[i],SZ);
+
+		//test.
+//		if(i==1)
+		//test.
+		SendPacketEx(SendData,SZ+sizeof(FECHEADER), FrameNo, 0, 0);
+		usleep(ndelay);
+	}
+	
+	//×îºóÐèÒªÊͷűäÁ¿
+	if (SendData!=0)
+		free(SendData);
+	if (code!=0)
+		fec_free((fec_parms *)code);
+	for (i=0; i<kk; i++)
+	{
+		free(d_original[i]);
+		free(d_src[i]);
+	}
+	free(d_original);
+	free(d_src);
+	free(ixs);  
+//	printf("\nFEC encode ok : %d packets\n", kk);
+	return 0;
+fail:	
+	if (SendData!=0)
+		free(SendData);
+	if (code!=0)
+		fec_free((fec_parms *)code);
+	for (i=0; i<kk; i++)
+	{
+		if (d_original[i]!=0)
+			free(d_original[i]);
+		if (d_src[i]!=0)
+			free(d_src[i]);
+	}
+	if (d_original!=0)
+		free(d_original);
+	if (d_src!=0)
+		free(d_src);
+	if (ixs!=0)
+		free(ixs);  
+	return -5;
+}
+
+void CFECRtpSession::UpdateFrames()
+{
+	//Èç¹ûÖ¡»º³åÖÐÓн϶àµÄÖ¡£¬ÔòÊÖ¶¯´¥·¢¡£
+	//´¥·¢Ê±¼ä´Á×îСµÄÄÇÒ»Ö¡Êý¾Ý£¬µ«ÊÇÈç¹ûʱ¼ä´Á×îС
+	//µÄÄÇÒ»Ö¡Êý¾Ý±ÈÉÏÒ»´Î´¥·¢µÄÊý¾ÝµÄʱ¼ä´Á»¹Ð¡£¬
+	//ÄǾÍÅ×ÆúÕâÒ»Ö¡Êý¾Ý£¬²»×öÈκδ¦Àí¡£
+	int framecount;
+	FRAMEINFO * p;
+	FRAMEINFOLIST::iterator itera;
+
+	framecount = m_PreSendFrameList.size();
+	if(framecount==0)
+		return;
+
+
+	
+	for(itera=m_PreSendFrameList.begin(); itera != m_PreSendFrameList.end(); ++itera){
+		p = *itera;
+		m_usLatestVideoSeq = p->us_latestseq; 
+		m_oldVideotimestamp = p->ul_timestamp;
+		ProcessFrame(p->pData, p->l_datalen);		
+		RemoveFrame(p);	
+		p = 0;
+	}
+	m_PreSendFrameList.clear();
+	return ;
+
+
+	//´¦Àí½ô½Ó×ÅÁ¬ÐøµÄÊý¾Ýèå.
+	for(itera=m_PreSendFrameList.begin(); itera != m_PreSendFrameList.end(); ++itera){
+		p = *itera;
+		if(p->us_latestseq == uint16_t(m_usLatestVideoSeq+1)){
+			m_usLatestVideoSeq = p->us_latestseq; 
+			m_oldVideotimestamp = p->ul_timestamp;
+			ProcessFrame(p->pData, p->l_datalen);
+			RemoveFrame(p);	
+			p = 0;
+			m_PreSendFrameList.erase(itera);
+			UpdateFrames();
+			return;
+		}
+	}
+
+	if(framecount<3)
+		return;
+	
+
+	FRAMEINFO *fff;
+	FRAMEINFOLIST::iterator kkk;
+	kkk=m_PreSendFrameList.begin();
+	fff = *kkk;
+	for(itera=kkk; itera != m_PreSendFrameList.end(); ++itera){
+		p = *itera;
+		if(fff->ul_timestamp > p->ul_timestamp){
+			kkk = itera;
+			fff = p;
+		}
+	}
+
+	//±ØÐëÖ±½Ó´¦Àíʱ¼ä×îÀϵÄÒ»èåÊý¾Ý.
+	//ÕâÀï²»ÄÜÉèÖÃÅжÏÊDz»ÊDZÈÔ­ÓеÄʱ¼ä´Á´óÔÚ´¦Àí¡£
+	//ÒòΪºÜÓпÉÄÜ£¬Ê±¼ä´Á½øÐÐÁ˺ܴóµÄ±ä»¯¡£´Ó¶øÒýÆðÔÙÒ²²»ÄÜ´¦ÀíÊý¾Ýèå.
+//	if(m_oldVideotimestamp<fff->ul_timestamp){
+	m_usLatestVideoSeq = fff->us_latestseq; 
+	m_oldVideotimestamp = fff->ul_timestamp;
+	ProcessFrame(fff->pData, fff->l_datalen);
+//	}
+	RemoveFrame(fff);	
+	fff = 0;
+	m_PreSendFrameList.erase(kkk);
+
+	return;
+
+
+
+/*
+	if(m_PreSendFrameList.size()>=FRAMENUM)
+	{
+		FRAMEINFO* m_pFrameInfotoSend;
+		ulong	ul_mintimestamp;
+		//			POSITION PostoDel;		
+		//TRACE("ÏÖÔÚÖ¡»º´æÖеÄÊÓƵ֡Êý:%d\n",FRAMENUM);
+		m_bStartVideoData	=	true;
+		m_pFrameInfotoSend	=	(FRAMEINFO *)*m_PreSendFrameList.begin();
+		ul_mintimestamp		=	m_pFrameInfotoSend->ul_timestamp;
+		FRAMEINFO * p;
+		FRAMEINFOLIST::iterator itera;
+		FRAMEINFOLIST::iterator todel;
+		for(itera=m_PreSendFrameList.begin(); itera != m_PreSendFrameList.end(); ++itera){
+			p = *itera;
+			if(p->ul_timestamp<=ul_mintimestamp)
+			{
+				ul_mintimestamp		=	p->ul_timestamp;
+				m_pFrameInfotoSend	=	p;
+				todel			=	itera;				
+			}			
+		}
+		
+		//TRACE("ÀÏʱ´Á%d\n",m_oldVideotimestamp);
+		//TRACE("    ´ý´¥·¢Ö¡Ê±´Á%d\n",m_pFrameInfotoSend->ul_timestamp);
+		if(m_pFrameInfotoSend->ul_timestamp > m_oldVideotimestamp)
+		{
+			m_oldVideotimestamp	=	m_pFrameInfotoSend->ul_timestamp;
+			m_usLatestVideoSeq	=	m_pFrameInfotoSend->us_latestseq;
+			//TRACE("$$$¸Õ´¥·¢Ö¡µÄÐòºÅΪ%d\n",m_usLatestVideoSeq);
+			///////////////////////////////////дÈÕÖ¾Îļþ	
+			//char tt[100];
+			//sprintf(tt,"                    ÒÑ´¦ÀíÊÓƵ֡ÐòºÅ%d,ʱ´Á%d",m_usLatestVideoSeq,m_oldVideotimestamp);
+			//SaveVideoFrameSeq(tt);
+			
+				
+			//				m_pQOSRecvCtrl->FireOnVideoDataArrive((long)(m_pFrameInfotoSend->pData),m_pFrameInfotoSend->l_datalen,m_oldVideotimestamp);
+		}
+		m_PreSendFrameList.erase(todel);
+		//TRACE("    ÏÖÔÚÖ¡»º´æÖеÄÊÓƵ֡Êý%d\n",m_PreSendVideoDataList.GetCount());
+		if(m_pFrameInfotoSend->FECCoded)
+			delete m_pFrameInfotoSend->pData;
+		else if(!m_pFrameInfotoSend->FECCoded)
+			delete (m_pFrameInfotoSend->pData-sizeof(FECHEADER));
+		delete	m_pFrameInfotoSend;
+		
+		bool m_bIsHaveNext	=	false;
+		while(m_bIsHaveNext)//Èç¹ûÏÂÒ»¸öÖ¡´æÔÚÔòÑ­»·
+		{
+			int n	=	m_PreSendFrameList.size();	
+			//				m_bIsHaveNext=IsHaveNextVideoFrame(n);
+		}
+	}
+*/
+}
+
+void CFECRtpSession::ProcessFrame(unsigned char *recvdata, int recvlen)
+{
+	return;
+	//test
+/*	HANDLE hf;
+	hf = CreateFile("calc.exe", GENERIC_WRITE, 0, 0, CREATE_NEW, 0, 0);
+	unsigned long l, i, t;
+	l = recvlen;
+	i = 0;
+	t = 0;
+	while(l>0){
+		WriteFile(hf, recvdata+t, l, &i, 0);
+		t += i;
+		l -= i;
+	}
+	CloseHandle(hf);
+*/	
+	//test
+}
+
+void CFECRtpSession::RemoveFrame(FRAMEINFO *p)
+{
+	if(p->FECCoded)
+		delete p->pData;
+	else if(!p->FECCoded)
+		delete (p->pData-sizeof(FECHEADER));
+	delete	p;	
+}

Propchange: incubator/bluesky/NCstu-2.0/src/fecrtpsession.cpp
------------------------------------------------------------------------------
    svn:executable = *



Mime
View raw message