<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
</head>
<body bgcolor="#FFFFFF" text="#000000">
Hello,<br>
I have been 4 weeks trying to stream live video with live555 but I
cannot found the documentation to stream video mpeg4 without a video
file, the problem is that i don't have a file, i have a bytes array
and i have seen the testprogs of live555 but I don't found the
appropiate sample. I have trying to create my own framedsource
subclass,although it seems works in debug mode, does not send data.
this is my code:<br>
<b>For init the process in c#:</b><br>
service = new
RTPService(Convert.ToInt64(streamInfo.Destination.IP.Address),
Convert.ToInt16(streamInfo.D<br>
estination.uPort), (PlayLoadTypes)1, 7);<br>
<br>
while(dontStop){<br>
data = GetData();<br>
service.SetFrames(data);<br>
}<br>
<br>
<b>THE CODE:</b><br>
char * ConvertUnsignedToConstChar(unsigned item)<br>
{<br>
ostringstream convert; // stream used for the conversion<br>
convert << item; // insert the textual
representation of 'Number' in the characters in the stream<br>
string resultString = convert.str();<br>
return &resultString[0];<br>
}<br>
void afterPlayingFunction(void *clientdata);<br>
<br>
OnDemandServerMediaSubsessionMarina::OnDemandServerMediaSubsessionMarina(<br>
UsageEnvironment & env,Boolean
reuseFirstSource,portNumBits initialPortNum,PlayLoadTypes
playloadType,unsigned clientSessionId,struct in_addr destAddr,Port
rtpDestPort) :<br>
OnDemandServerMediaSubsession(env,reuseFirstSource,6970)<br>
{<br>
this->playloadType = playloadType;<br>
this->videoSource =
this->createNewStreamSource(clientSessionId,ESTBITRATE);<br>
u_int8_t variable = 255;<br>
this->rtpGroupsock = new Groupsock (env,destAddr,
rtpDestPort,variable);<br>
Port rtpcDestPort(5003);<br>
this->m_pRtcpGroupsock = new Groupsock(env, destAddr,
rtpcDestPort, 255);<br>
unsigned char rtpPayloadTypeIfDynamic = 96;<br>
this->videoSink = this->createNewRTPSink
(rtpGroupsock, rtpPayloadTypeIfDynamic, this->videoSource);<br>
}<br>
<br>
void
OnDemandServerMediaSubsessionMarina::setPlayloadType(PlayLoadTypes
playloadType)<br>
{<br>
this->playloadType = playloadType;<br>
}<br>
<br>
void
OnDemandServerMediaSubsessionMarina::SetDestination(Destinations
*dest, unsigned clientSessionId)<br>
{<br>
fDestinationsHashTable->Add(ConvertUnsignedToConstChar(clientSessionId),
dest);<br>
}<br>
<br>
<br>
FramedSource *
OnDemandServerMediaSubsessionMarina::createNewStreamSource (unsigned
clientSessionId, unsigned &estBitrate)<br>
{<br>
//Do not need the params<br>
DeviceParameters params;<br>
return
FramedSourceMarina::createNew(this->envir(),params);<br>
}<br>
<br>
RTPSink *
OnDemandServerMediaSubsessionMarina::createNewRTPSink (Groupsock
*rtpGroupsock, unsigned char rtpPayloadTypeIfDynamic, FramedSource
*inputSource)<br>
{ <br>
switch(this->playloadType)<br>
{<br>
case MPEG4:<br>
return MPEG4ESVideoRTPSink::createNew(
this->envir(), rtpGroupsock, rtpPayloadTypeIfDynamic,90000);<br>
break;<br>
case H264:<br>
return H264VideoRTPSink::createNew(
this->envir(), rtpGroupsock, rtpPayloadTypeIfDynamic);<br>
break;<br>
default:<br>
throw; <br>
}<br>
return NULL;<br>
};<br>
<br>
<br>
RTPService::RTPService(__int64 destAdd, short port,PlayLoadTypes
playloadType,int clientSessionId)<br>
{<br>
struct in_addr destAddr; <br>
destAddr.s_addr = (ULONG)destAdd;<br>
Port rtpDestPort(port);<br>
Port rtpcDestPort(port+1);<br>
this->dest = new
Destinations(destAddr,rtpDestPort,rtpcDestPort);<br>
this->start = false;<br>
catcher = gcnew CatchEvent();<br>
catcher->SetCatcher(this);<br>
this->scheduler = BasicTaskScheduler::createNew();<br>
envv = BasicUsageEnvironment::createNew(*scheduler);<br>
portNumBits initialPortNumAux = 55000;<br>
//this->dest = new Destinations();<br>
this->onDemandServerMediaSub = new
OnDemandServerMediaSubsessionMarina(*envv,false,initialPortNumAux,playloadType,clientSessionId,destAddr,rtpDestPort);<br>
unsigned char CNAME[101];<br>
gethostname((char*)CNAME, 100);<br>
CNAME[100] = '\0';<br>
this->rtcp = RTCPInstance::createNew(*envv,
this->onDemandServerMediaSub->rtpGroupsock,1512,
CNAME,this->videoSink, NULL /* we're a server */,True /* we're a
SSM source */);<br>
this->videoSource =
this->onDemandServerMediaSub->videoSource;<br>
this->videoSink =
this->onDemandServerMediaSub->videoSink;<br>
this->onDemandServerMediaSub->SetDestination(this->dest,clientSessionId);<br>
Groupsock *rtpGroupsock =
this->onDemandServerMediaSub->rtpGroupsock;<br>
char const* streamName = "testStream";<br>
this->sms = ServerMediaSession::createNew(*envv,
streamName, streamName,streamName, True);<br>
<br>
this->sms->addSubsession((ServerMediaSubsession*)this->onDemandServerMediaSub);
<br>
this->sms->addSubsession(PassiveServerMediaSubsession::createNew(*this->videoSink,this->rtcp
));<br>
}<br>
<br>
void RTPService::StartStreaming() <br>
{<br>
this->rtspServer = RTSPServer::createNew(*envv, 8554);<br>
rtspServer->addServerMediaSession(sms);<br>
this->start = true;<br>
MPEG4VideoStreamFramer *videoSource1 =
MPEG4VideoStreamFramer::createNew(*envv, this->videoSource);<br>
char* url = this->rtspServer->rtspURL(this->sms);<br>
<br>
this->videoSink->startPlaying(*videoSource1,
afterPlayingFunction, this->videoSink);<br>
<br>
this->envv->taskScheduler().doEventLoop();<br>
<br>
}<br>
<br>
void RTPService::StopStreaming()<br>
{<br>
this->start = false;<br>
videoSink->stopPlaying();<br>
}<br>
<br>
void RTPService:: SetFrames(FrameData ^ data)<br>
{<br>
FramedSourceMarina * source =
(FramedSourceMarina*)this->videoSource;<br>
source->setFrames(new NativeFrameData(data->data,
data->dataLength));<br>
<br>
TaskScheduler* ourScheduler = this->scheduler; //%%% TO
BE WRITTEN %%%<br>
FramedSourceMarina* ourDevice =
(FramedSourceMarina*)this->videoSource; //%%% TO BE WRITTEN %%%<br>
<br>
if (ourScheduler != NULL) { // sanity check<br>
ourScheduler->triggerEvent(FramedSourceMarina::eventTriggerId,
ourDevice);<br>
}<br>
}<br>
<br>
<br>
void RTPService::SetIntermediator(Intermediator ^provider)<br>
{<br>
this->provider = provider;<br>
}<br>
/********************************************************/<br>
<br>
<br>
<br>
FramedSourceMarina*<br>
FramedSourceMarina::createNew(UsageEnvironment& env,<br>
DeviceParameters params) {<br>
return new FramedSourceMarina(env, params);<br>
}<br>
<br>
EventTriggerId FramedSourceMarina::eventTriggerId = 0;<br>
<br>
unsigned FramedSourceMarina::referenceCount = 0;<br>
<br>
void FramedSourceMarina::setFrames(NativeFrameData * frame)<br>
{<br>
semaphore->enter();<br>
frames.push(frame);<br>
semaphore->leave();<br>
}<br>
<br>
FramedSourceMarina::FramedSourceMarina(UsageEnvironment&
env,<br>
DeviceParameters params)<br>
: FramedSource(env), fParams(params) { <br>
semaphore = new CSeccionCritica() ;<br>
if (referenceCount == 0) {<br>
//Nothing todo<br>
}<br>
++referenceCount;<br>
<br>
if (eventTriggerId == 0) {<br>
eventTriggerId =
envir().taskScheduler().createEventTrigger(deliverFrame0);<br>
}<br>
}<br>
<br>
FramedSourceMarina::~FramedSourceMarina() {<br>
// Any instance-specific 'destruction' (i.e., resetting) of
the device would be done here:<br>
//%%% TO BE WRITTEN %%%<br>
<br>
--referenceCount;<br>
if (referenceCount == 0) {<br>
// Any global 'destruction' (i.e., resetting) of the device
would be done here:<br>
//%%% TO BE WRITTEN %%%<br>
<br>
// Reclaim our 'event trigger'<br>
envir().taskScheduler().deleteEventTrigger(eventTriggerId);<br>
eventTriggerId = 0;<br>
}<br>
}<br>
<br>
void FramedSourceMarina::doGetNextFrame() {<br>
if (!frames.empty() ) {<br>
deliverFrame();<br>
}else<br>
{<br>
handleClosure(this);<br>
return;<br>
}<br>
<br>
}<br>
<br>
void FramedSourceMarina::deliverFrame0(void* clientData) {<br>
((FramedSourceMarina*)clientData)->deliverFrame();<br>
}<br>
<br>
void FramedSourceMarina::deliverFrame() {<br>
<br>
semaphore->enter();<br>
NativeFrameData *frameData = (NativeFrameData
*)frames.front(); <br>
frames.pop();<br>
semaphore->leave();<br>
if (frameData != NULL){<br>
<b>//the frameData->data is a char * data </b><b><br>
</b><b> u_int8_t* newFrameDataStart =
(u_int8_t*)frameData->data;</b><br>
unsigned newFrameSize =
(unsigned)frameData->dataLength; <br>
<br>
// Deliver the data here:<br>
if (newFrameSize > fMaxSize) {<br>
fFrameSize = fMaxSize;<br>
fNumTruncatedBytes = newFrameSize - fMaxSize;<br>
} else {<br>
fFrameSize = newFrameSize;<br>
}<br>
gettimeofday(&fPresentationTime, NULL); <br>
unsigned char *ftoAux = new unsigned
char[frameData->dataLength];<br>
for(int i = 0;i<frameData->dataLength;i++)<br>
{<br>
ftoAux[i] = frameData->data[i];<br>
}<br>
this->fTo = ftoAux;<br>
//The memmove throws an exception<br>
//memmove(this->fTo, frameData->data, fFrameSize);<br>
<br>
<br>
FramedSource::afterGetting(this);<br>
}<br>
}<br>
<br>
<br>
void afterPlayingFunction(void *clientdata)<br>
{<br>
RTPSink *videoSink = (RTPSink*)clientdata;<br>
videoSink->stopPlaying();<br>
};<br>
</body>
</html>