[Live-devel] I can not stream live video with my own framedSource
David Alcaraz Moreno
dalcaraz at eye-cam.com
Tue Dec 4 06:10:23 PST 2012
Hello,
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:
*For init the process in c#:*
service = new
RTPService(Convert.ToInt64(streamInfo.Destination.IP.Address),
Convert.ToInt16(streamInfo.D
estination.uPort), (PlayLoadTypes)1, 7);
while(dontStop){
data = GetData();
service.SetFrames(data);
}
*THE CODE:*
char * ConvertUnsignedToConstChar(unsigned item)
{
ostringstream convert; // stream used for the conversion
convert << item; // insert the textual representation of
'Number' in the characters in the stream
string resultString = convert.str();
return &resultString[0];
}
void afterPlayingFunction(void *clientdata);
OnDemandServerMediaSubsessionMarina::OnDemandServerMediaSubsessionMarina(
UsageEnvironment & env,Boolean reuseFirstSource,portNumBits
initialPortNum,PlayLoadTypes playloadType,unsigned
clientSessionId,struct in_addr destAddr,Port rtpDestPort) :
OnDemandServerMediaSubsession(env,reuseFirstSource,6970)
{
this->playloadType = playloadType;
this->videoSource =
this->createNewStreamSource(clientSessionId,ESTBITRATE);
u_int8_t variable = 255;
this->rtpGroupsock = new Groupsock (env,destAddr,
rtpDestPort,variable);
Port rtpcDestPort(5003);
this->m_pRtcpGroupsock = new Groupsock(env, destAddr,
rtpcDestPort, 255);
unsigned char rtpPayloadTypeIfDynamic = 96;
this->videoSink = this->createNewRTPSink (rtpGroupsock,
rtpPayloadTypeIfDynamic, this->videoSource);
}
void
OnDemandServerMediaSubsessionMarina::setPlayloadType(PlayLoadTypes
playloadType)
{
this->playloadType = playloadType;
}
void
OnDemandServerMediaSubsessionMarina::SetDestination(Destinations *dest,
unsigned clientSessionId)
{
fDestinationsHashTable->Add(ConvertUnsignedToConstChar(clientSessionId),
dest);
}
FramedSource *
OnDemandServerMediaSubsessionMarina::createNewStreamSource (unsigned
clientSessionId, unsigned &estBitrate)
{
//Do not need the params
DeviceParameters params;
return FramedSourceMarina::createNew(this->envir(),params);
}
RTPSink * OnDemandServerMediaSubsessionMarina::createNewRTPSink
(Groupsock *rtpGroupsock, unsigned char rtpPayloadTypeIfDynamic,
FramedSource *inputSource)
{
switch(this->playloadType)
{
case MPEG4:
return MPEG4ESVideoRTPSink::createNew( this->envir(),
rtpGroupsock, rtpPayloadTypeIfDynamic,90000);
break;
case H264:
return H264VideoRTPSink::createNew( this->envir(),
rtpGroupsock, rtpPayloadTypeIfDynamic);
break;
default:
throw;
}
return NULL;
};
RTPService::RTPService(__int64 destAdd, short port,PlayLoadTypes
playloadType,int clientSessionId)
{
struct in_addr destAddr;
destAddr.s_addr = (ULONG)destAdd;
Port rtpDestPort(port);
Port rtpcDestPort(port+1);
this->dest = new Destinations(destAddr,rtpDestPort,rtpcDestPort);
this->start = false;
catcher = gcnew CatchEvent();
catcher->SetCatcher(this);
this->scheduler = BasicTaskScheduler::createNew();
envv = BasicUsageEnvironment::createNew(*scheduler);
portNumBits initialPortNumAux = 55000;
//this->dest = new Destinations();
this->onDemandServerMediaSub = new
OnDemandServerMediaSubsessionMarina(*envv,false,initialPortNumAux,playloadType,clientSessionId,destAddr,rtpDestPort);
unsigned char CNAME[101];
gethostname((char*)CNAME, 100);
CNAME[100] = '\0';
this->rtcp = RTCPInstance::createNew(*envv,
this->onDemandServerMediaSub->rtpGroupsock,1512, CNAME,this->videoSink,
NULL /* we're a server */,True /* we're a SSM source */);
this->videoSource = this->onDemandServerMediaSub->videoSource;
this->videoSink = this->onDemandServerMediaSub->videoSink;
this->onDemandServerMediaSub->SetDestination(this->dest,clientSessionId);
Groupsock *rtpGroupsock =
this->onDemandServerMediaSub->rtpGroupsock;
char const* streamName = "testStream";
this->sms = ServerMediaSession::createNew(*envv, streamName,
streamName,streamName, True);
this->sms->addSubsession((ServerMediaSubsession*)this->onDemandServerMediaSub);
this->sms->addSubsession(PassiveServerMediaSubsession::createNew(*this->videoSink,this->rtcp
));
}
void RTPService::StartStreaming()
{
this->rtspServer = RTSPServer::createNew(*envv, 8554);
rtspServer->addServerMediaSession(sms);
this->start = true;
MPEG4VideoStreamFramer *videoSource1 =
MPEG4VideoStreamFramer::createNew(*envv, this->videoSource);
char* url = this->rtspServer->rtspURL(this->sms);
this->videoSink->startPlaying(*videoSource1,
afterPlayingFunction, this->videoSink);
this->envv->taskScheduler().doEventLoop();
}
void RTPService::StopStreaming()
{
this->start = false;
videoSink->stopPlaying();
}
void RTPService:: SetFrames(FrameData ^ data)
{
FramedSourceMarina * source =
(FramedSourceMarina*)this->videoSource;
source->setFrames(new NativeFrameData(data->data,
data->dataLength));
TaskScheduler* ourScheduler = this->scheduler; //%%% TO BE
WRITTEN %%%
FramedSourceMarina* ourDevice =
(FramedSourceMarina*)this->videoSource; //%%% TO BE WRITTEN %%%
if (ourScheduler != NULL) { // sanity check
ourScheduler->triggerEvent(FramedSourceMarina::eventTriggerId, ourDevice);
}
}
void RTPService::SetIntermediator(Intermediator ^provider)
{
this->provider = provider;
}
/********************************************************/
FramedSourceMarina*
FramedSourceMarina::createNew(UsageEnvironment& env,
DeviceParameters params) {
return new FramedSourceMarina(env, params);
}
EventTriggerId FramedSourceMarina::eventTriggerId = 0;
unsigned FramedSourceMarina::referenceCount = 0;
void FramedSourceMarina::setFrames(NativeFrameData * frame)
{
semaphore->enter();
frames.push(frame);
semaphore->leave();
}
FramedSourceMarina::FramedSourceMarina(UsageEnvironment& env,
DeviceParameters params)
: FramedSource(env), fParams(params) {
semaphore = new CSeccionCritica() ;
if (referenceCount == 0) {
//Nothing todo
}
++referenceCount;
if (eventTriggerId == 0) {
eventTriggerId =
envir().taskScheduler().createEventTrigger(deliverFrame0);
}
}
FramedSourceMarina::~FramedSourceMarina() {
// Any instance-specific 'destruction' (i.e., resetting) of the
device would be done here:
//%%% TO BE WRITTEN %%%
--referenceCount;
if (referenceCount == 0) {
// Any global 'destruction' (i.e., resetting) of the device
would be done here:
//%%% TO BE WRITTEN %%%
// Reclaim our 'event trigger'
envir().taskScheduler().deleteEventTrigger(eventTriggerId);
eventTriggerId = 0;
}
}
void FramedSourceMarina::doGetNextFrame() {
if (!frames.empty() ) {
deliverFrame();
}else
{
handleClosure(this);
return;
}
}
void FramedSourceMarina::deliverFrame0(void* clientData) {
((FramedSourceMarina*)clientData)->deliverFrame();
}
void FramedSourceMarina::deliverFrame() {
semaphore->enter();
NativeFrameData *frameData = (NativeFrameData *)frames.front();
frames.pop();
semaphore->leave();
if (frameData != NULL){
*//the frameData->data is a char * data **
** u_int8_t* newFrameDataStart = (u_int8_t*)frameData->data;*
unsigned newFrameSize = (unsigned)frameData->dataLength;
// Deliver the data here:
if (newFrameSize > fMaxSize) {
fFrameSize = fMaxSize;
fNumTruncatedBytes = newFrameSize - fMaxSize;
} else {
fFrameSize = newFrameSize;
}
gettimeofday(&fPresentationTime, NULL);
unsigned char *ftoAux = new unsigned char[frameData->dataLength];
for(int i = 0;i<frameData->dataLength;i++)
{
ftoAux[i] = frameData->data[i];
}
this->fTo = ftoAux;
//The memmove throws an exception
//memmove(this->fTo, frameData->data, fFrameSize);
FramedSource::afterGetting(this);
}
}
void afterPlayingFunction(void *clientdata)
{
RTPSink *videoSink = (RTPSink*)clientdata;
videoSink->stopPlaying();
};
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.live555.com/pipermail/live-devel/attachments/20121204/f3300209/attachment.html>
More information about the live-devel
mailing list