[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