[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Ccrtp-devel] There is bug when use multi RTP session of ccRTP!
From: |
Seven Pham |
Subject: |
[Ccrtp-devel] There is bug when use multi RTP session of ccRTP! |
Date: |
Fri, 27 May 2005 09:58:41 +0700 |
Hi all,
I use the ccRTP to transfer the audio and video stream. I am stick in
a bug. i have spent a lot of time to fix it. But I still can not pass
it. This is my problem:
My application have 2 stream: audio stream and video stream.I use 2
thread for them. One for send/receiv audio, one for send/receive
video. They can send/receive both audio and video stream. But They
were killed(or application was segmentation fault) after about 5
minutes for streaming. if i stop one stream audio or video and use
only one stream, it can send/receive well.This is the way that i use
multi session of ccRTP:
+ For Audio stream:
class AudioRtpRTX : public Thread, public TimerPort {
public:
AudioRtpRTX (SipCall *, AudioDrivers *, Manager *, bool, int);
~AudioRtpRTX();
virtual void run ();
private:
SipCall *ca;
AudioDrivers *audioDevice;
RTPSession *sessionSend;
RTPSession *sessionRecv;
SymmetricRTPSession *session;
Manager *manager;
bool sym;
int line;
};
sessionSend and sessionRecv were created as the following source code:
InetHostAddress local_ip("0.0.0.0");
sessionRecv = new RTPSession (local_ip,
getLocalAudioPort(ca));//local audio port is 7070
sessionSend = new RTPSession (local_ip);
And this is the run() function of the thread:
void AudioRtpRTX::run(void)
{
int gran = 160;
int prev_ts= 0;
AudioCodec *ac=NULL;
unsigned char *data_to_send;
short *data_mute;
short *data_from_mic;
int i, compSize, timestamp;
int expandedSize;
short *data_for_speakers = NULL;
int numFrames = 0;
data_for_speakers = (short *)malloc(2048 *sizeof(short));
data_from_mic = (short *)malloc(1024 *sizeof( short));
data_to_send = (unsigned char *)malloc(1024 * sizeof( unsigned char));
data_mute = (short *)malloc(1024 * sizeof( short));
InetHostAddress remote_ip(ca->remote_sdp_audio_ip);
printf("Enter thread AudioRtpRTX:)-Mode %d\n", sym);
//Init the Audio codec, use g711 audio codec
ac = AudioCodec_new();
if (!remote_ip) {
printf("RTX: IP address is not correct!\n");
this->exit();
} else {
printf("RTX: Connected to %s:%d",
ca->remote_sdp_audio_ip, ca->remote_sdp_audio_port);
}
sym = 0;
// Initialization
if (!sym) {
sessionRecv->setSchedulingTimeout (10000);
sessionRecv->setExpireTimeout(1000000);
sessionSend->setSchedulingTimeout(10000);
sessionSend->setExpireTimeout(1000000);
}
if (!sym) {
//remote_sdp_audio_port is 7070
if (!sessionSend->addDestination (remote_ip,
(unsigned short)
ca->remote_sdp_audio_port)) {
printf("RTX send: could not connect to port %d",
ca->remote_sdp_audio_port);
this->exit();
} else {
printf("RTP(Send): Added destination %s:%d",
remote_ip.getHostname(),
(unsigned short)
ca->remote_sdp_audio_port);
}
sessionRecv->setPayloadFormat(StaticPayloadFormat(sptPCMU));
sessionSend->setPayloadFormat(StaticPayloadFormat(sptPCMU));
setCancel(cancelImmediate);
sessionSend->setMark(TRUE);
sessionSend->setSessionBandwidth(4000000);
}
timestamp = 0;
#ifdef SET_TIMER
// TODO: get frameSize from user config
int frameSize = 20; // 20ms frames
TimerPort::setTimer(frameSize);
#endif
// start running the packet queue scheduler.
if (!sym) {
sessionRecv->startRunning();
sessionSend->startRunning();
cout << "The RTP queueRV is ";
if( sessionRecv->isActive() )
cout << "active." << endl;
else
cout << "not active." << endl;
cout << "The RTP queueSend is ";
if( sessionSend->isActive() )
cout << "active." << endl;
else
cout << "not active." << endl;
}
while (ca->enable_audio != -1)
{
////////////////////////////
// Send session
////////////////////////////
if (!manager->mute)
{
i = AudioDrivers_readBuffer_with_data
(audioDevice, data_from_mic, 320);
}
// Encode acquired audio sample
compSize = codecEncode (
0,
data_to_send,
data_from_mic, i);
// Send encoded audio sample
if (!sym)
{
sessionSend->putData(timestamp, data_to_send,compSize);
}
timestamp += compSize;
//Recv session
////////////////////////////
{
const AppDataUnit* adu = NULL;
int loop = 0;
Thread::sleep(5); // in msec.
if (!sym)
{
adu =
sessionRecv->getData(sessionRecv->getFirstTimestamp());
if(adu)
{
//decode the encode data
expandedSize = codecDecode (
0,
data_for_speakers,
(unsigned
char*)adu->getData(),adu->getSize());
// Write decoded data to sound device
AudioBuffer_resize(&manager->audiodriver[line]->audio_buf,
expandedSize);
AudioBuffer_setData
(&manager->audiodriver[line]->audio_buf, data_for_speakers);
i = AudioDrivers_writeBuffer_with_data
(audioDevice, data_for_speakers, expandedSize);
delete adu;
}
}
// Let's wait for the next transmit cycle
#ifdef SET_TIMER
Thread::sleep(TimerPort::getTimer());
TimerPort::incTimer(frameSize); // 'frameSize' ms
#endif
}
free(data_for_speakers);
free(data_from_mic);
free( data_mute);
free( data_to_send);
this->exit();
}
If i define SET_TIMER, the quality of the audio will be very bad
+ For video stream:
The RTP session send/receive for the video stream is like the RTP
session of the audio stream:
class VideoRtpRTX : public Thread, public TimerPort {
public:
VideoRtpRTX (SipCall *, VideoDrivers *, Manager *, bool, int);
~VideoRtpRTX();
virtual void run ();
private:
SipCall *ca;
VideoDrivers *videoDevice;
RTPSession *sessionSend;
RTPSession *sessionRecv;
SymmetricRTPSession *session;
Manager *manager;
bool sym;
int line;
};
sessionSend and sessionRecv were created as the following source code:
InetHostAddress local_ip("0.0.0.0");
sessionRecv = new RTPSession (local_ip,
getLocalVideoPort(ca));//local video port is 7072
sessionSend = new RTPSession (local_ip);
And this is the run function of the thread:
void VideoRtpRTX::run(void)
{
#define PIC_WIDTH 176
##define PIC_HEIGHT 144
#define FRAME_SIZE (PIC_WIDTH*PIC_HEIGHT*3/2) //frame size of
the YUV picture
unsigned char *data_to_send;
unsigned char *data_compressed;
unsigned char *data_from_wc;
unsigned char *data_for_lcd = NULL;
// TODO: get frameSize from user config
int frameSize = 100; // 100ms frames
unsigned long numFrames = 0;
InetHostAddress remote_ip(ca->remote_sdp_audio_ip);
data_for_lcd = (unsigned char *)malloc(FRAME_SIZE);
data_from_wc = (unsigned char *)malloc(FRAME_SIZE);
data_to_send = (unsigned char *)malloc(FRAME_SIZE);
data_compressed = (unsigned char *)malloc(FRAME_SIZE);
printf("Enter thread VideoRtpRTX\n");
sym = 0;
// Initialization
if (!sym) {
sessionRecv->setSchedulingTimeout(120000);
sessionRecv->setExpireTimeout(12000000);
sessionSend->setSchedulingTimeout(120000);
sessionSend->setExpireTimeout(12000000);
}
if (!sym) {
if (!sessionSend->addDestination (remote_ip,
(unsigned
short)ca->remote_sdp_video_port)) {
//remote_sdp_video_port is 7072
printf("RTX send: could not connect to port %d",
ca->remote_sdp_video_port);
free(data_for_lcd);
free(data_from_wc);
free( data_compressed);
free( data_to_send);
this->exit();
} else {
printf("RTP(Send): Added destination %s:%d\n",
remote_ip.getHostname(),
(unsigned
short)ca->remote_sdp_video_port);
}
sessionRecv->setPayloadFormat(DynamicPayloadFormat(
ca->video_payload, 90000));
sessionSend->setPayloadFormat(DynamicPayloadFormat(
ca->video_payload, 90000));
//video_payload is 96
setCancel(cancelImmediate);
sessionSend->setMark(true);
sessionSend->setSessionBandwidth(4000000);
}
TimerPort::setTimer(frameSize);//100ms
// start running the packet queue scheduler.
if (!sym) {
sessionRecv->startRunning();
sessionSend->startRunning();
cout << "The RTP queueRV is ";
if( sessionRecv->isActive() )
cout << "active." << endl;
else
cout << "not active." << endl;
cout << "The RTP queueSend is ";
if( sessionSend->isActive() )
cout << "active." << endl;
else
cout << "not active." << endl;
}
int packetsPerSecond = 10;
uint16 tstampInc = sessionSend->getCurrentRTPClockRate() /
packetsPerSecond;
while(ca->enable_video != -1)
{
////////////////////////////
// Send session
////////////////////////////
//Read one frame YUV from a file into the data_from_wc buffer
int i = readVideoFrame(data_from_wc, FRAME_SIZE);
if( i>0 )
{
//right now, i use the XVID codec bitrate 40000, 10fps
#ifdef ADD_CODEC
int complen;
int keyframe = -1;
complen = VideoEncImage(data_from_wc, i,
data_to_send, keyframe);
if(complen<0)
{
printf("encode fail");
continue;
}
#endif
// send an RTP packet
if(!sym)
{
Thread::sleep(2);
#ifdef ADD_CODEC
sessionSend->putData(numFrames*tstampInc, data_to_send, complen);
numFrames++;
#else
sessionSend->putData(numFrames*tstampInc, data_from_wc,FRAME_SIZE);
numFrames++;
#endif
}else{ //end of file, close and reopen the file
closeVideoInput();
openVideoInput(VIDEOFILE);
}
////////////////////////////
// Recv session
////////////////////////////
const AppDataUnit* adu = NULL;
Thread::sleep(5); // in msec.
if (!sym) {
adu =
sessionRecv->getData(sessionRecv->getFirstTimestamp());
}
if (adu)
{
int decomplen;
#ifdef ADD_CODEC
//decode the frame and write it to frame buffer
decomplen = VideoDecImage((unsigned
char*)adu->getData(), data_for_lcd, adu->getSize());
usleep(2);
if(decomplen<0){
printf("decode video image fail\n");
delete adu;
continue;
}
#endif
//convert the yuv420p to rgb565
int bytes = 2;//rgb565
unsigned char* convm = (unsigned
char*)malloc(PIC_WIDTH*PIC_HEIGHT*bytes);
if(convm)
{
#ifdef ADD_CODEC
v4l_yuv420p2rgb (convm, (unsigned
char*)data_for_lcd,PIC_WIDTH, PIC_HEIGHT, bytes*8);
#else
v4l_yuv420p2rgb (convm, (unsigned
char*)adu->getData(),PIC_WIDTH, PIC_HEIGHT, bytes*8);
#endif
//display it to frame buffer
displayVideo((short*)convm);
free(convm);
}
else
{
printf("Can not allocate memory\n");
}
delete adu;
}
Thread::sleep(TimerPort::getTimer());
TimerPort::incTimer(frameSize);
}
printf("Quit the video Thread Send/Recv\n");
free(data_for_lcd);
free(data_from_wc);
free( data_compressed);
free( data_to_send);
}
Do you find any problem? please give me your idea. Thanks!
--
--------------Seven Pham----------------
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Ccrtp-devel] There is bug when use multi RTP session of ccRTP!,
Seven Pham <=