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();
    };
_______________________________________________
live-devel mailing list
live-devel@lists.live555.com
http://lists.live555.com/mailman/listinfo/live-devel

Reply via email to