houxiao
2016-12-23 1abced42eb3997ef9ef675bfe990f7913ea73f2f
RtspFace/PL_RTSPServer.cpp
@@ -1,29 +1,123 @@
#include "PL_RTSPServer.h"
#include "testOnDemandRTSPServer.hpp"
#include <liveMedia.hh>
#include <BasicUsageEnvironment.hh>
class MyH264FramedSource : public FramedSource
{
public:
   static MyH264FramedSource* createNew(UsageEnvironment& env);
protected:
   MyH264FramedSource(UsageEnvironment& env)
   virtual ~MyH264FramedSource()
   // overide FramedSource
   virtual void doGetNextFrame()
   {
      // deliverFrame
      //if (fFrameSize > 0)
      //{
      //   // send Frame to the consumer
      //   FramedSource::afterGetting(this);
      //}
      // isCurrentlyAwaitingData
         //if (frame->m_size > fMaxSize)
         //{
         //   fFrameSize = fMaxSize;
         //   fNumTruncatedBytes = frame->m_size - fMaxSize;
         //}
         //else
         //{
         //   fFrameSize = frame->m_size;
         //}
      //memcpy(fTo, frame->m_buffer, fFrameSize);
      //if (fFrameSize > 0)
      //   FramedSource::afterGetting(this);
   }
   virtual void doStopGettingFrames()
   {
      FramedSource::doStopGettingFrames();
   }
};
struct PL_RTSPServer_Internal
{
   uint8_t buffer[1920*1080*4];
   size_t buffSize;
   size_t buffSizeMax;
   //uint8_t buffer[1920*1080*4];
   //size_t buffSize;
   //size_t buffSizeMax;
   bool payError;
   pthread_t live_daemon_thid;
   pthread_mutex_t* frame_mutex;
   bool live_daemon_running;
   UsageEnvironment* env;
   // To make the second and subsequent client for each stream reuse the same
   // input stream as the first client (rather than playing the file from the
   // start for each client), change the following "False" to "True":
   Boolean reuseFirstSource;
   // To stream *only* MPEG-1 or 2 video "I" frames
   // (e.g., to reduce network bandwidth),
   // change the following "False" to "True":
   Boolean iFramesOnly;
   UserAuthenticationDatabase* authDB;
   RTSPServer* rtspServer;//#todo delete
   char descriptionString[1024];
   
   PL_RTSPServer_Internal() : 
      buffSize(0), buffSizeMax(sizeof(buffer)),
      payError(true)
      //buffSize(0), buffSizeMax(sizeof(buffer)),
      payError(true), live_daemon_thid(0), frame_mutex(nullptr), live_daemon_running(false),
      env(nullptr), reuseFirstSource(False), iFramesOnly(False), authDB(nullptr),
      rtspServer(nullptr);
   {
      pthread_mutex_init(frame_mutex, NULL);
   }
   
   ~PL_RTSPServer_Internal()
   {
      if (frame_mutex != nullptr)
      {
         pthread_mutex_destroy(frame_mutex);
         delete frame_mutex;
         frame_mutex = nullptr;
      }
   }
   
   void reset()
   {
      buffSize = 0;
      //buffSize = 0;
      payError = true;
      if (frame_mutex != nullptr)
      {
         pthread_mutex_destroy(frame_mutex);
         delete frame_mutex;
         frame_mutex = nullptr;
      }
      frame_mutex = new pthread_mutex_t;
      pthread_mutex_init(frame_mutex, NULL);
      live_daemon_thid = 0;
      live_daemon_running = false;
      env = nullptr;
      reuseFirstSource = False;
      iFramesOnly = False;
      authDB = nullptr;
      rtspServer = nullptr;
      strcpy(descriptionString, "Session streamed by \"testOnDemandRTSPServer\"");
   }
};
@@ -42,32 +136,92 @@
   internal= nullptr;
}
void* live_daemon_thd(void* arg)
{
   RTSPClient_Internal* in = (RTSPClient_Internal*)arg;
   // Begin by setting up our usage environment:
   TaskScheduler* scheduler = BasicTaskScheduler::createNew();
   in->env = BasicUsageEnvironment::createNew(*scheduler);
#ifdef ACCESS_CONTROL
   // To implement client access control to the RTSP server, do the following:
   in->authDB = new UserAuthenticationDatabase;
   in->authDB->addUserRecord("username1", "password1"); // replace these with real strings
   // Repeat the above with each <username>, <password> that you wish to allow
   // access to the server.
#endif
   // Create the RTSP server:
   in->rtspServer = RTSPServer::createNew(*env, 8554, authDB);
   if (rtspServer == NULL)
   {
      *(in->env) << "Failed to create RTSP server: " << env->getResultMsg() << "\n";
      return;
   }
   // Set up each of the possible streams that can be served by the
   // RTSP server.  Each such stream is implemented using a
   // "ServerMediaSession" object, plus one or more
   // "ServerMediaSubsession" objects for each audio/video substream.
    char const* streamName = "plH264Encoder";
    ServerMediaSession* sms = ServerMediaSession::createNew(*(in->env), streamName, streamName, in->descriptionString);
    sms->addSubsession(MyH264FramedSource::createNew(*(in->env), in));
    in->rtspServer->addServerMediaSession(sms);
   // announceStream
   char* url = rtspServer->rtspURL(sms);
   *(in->env) << "\n\"" << streamName << "\" stream, from the file \"" << inputFileName << "\"\n";
   *(in->env) << "Play this stream using the URL \"" << url << "\"\n";
   delete[] url;
   // Also, attempt to create a HTTP server for RTSP-over-HTTP tunneling.
   // Try first with the default HTTP port (80), and then with the alternative HTTP
   // port numbers (8000 and 8080).
   if (rtspServer->setUpTunnelingOverHTTP(80))
      *(in->env) << "\n(We use port " << rtspServer->httpServerPortNum() << " for optional RTSP-over-HTTP tunneling.)\n";
   else
      *(in->env) << "\n(RTSP-over-HTTP tunneling is not available.)\n";
   in->live_daemon_running = true;
   env->taskScheduler().doEventLoop(); // does not return
   in->live_daemon_running = false;
}
bool PL_RTSPServer::init(void* args)
{
   PL_RTSPServer_Internal* in = (PL_RTSPServer_Internal*)internal;
   in->reset();
   int ret = pthread_mutex_lock(in->frame_mutex);
   if(ret != 0)
   {
      printf("pthread_mutex_lock frame_mutex: %s/n", strerror(ret));
      return false;
   }
   ret = pthread_create(&(in->live_daemon_thid), NULL, live_daemon_thd, in);
   if(ret != 0)
   {
      printf("pthread_create: %s/n", strerror(ret));
      return false;
   }
   return true;
}
void PL_RTSPServer::finit()
{
   PL_RTSPServer_Internal* in = (PL_RTSPServer_Internal*)internal;
   RTSPClient_Internal* in = (RTSPClient_Internal*)internal;
   
   pthread_join(in->live_daemon_thid, NULL);
}
bool PL_RTSPServer::pay(const PipeMaterial& pm)
{
   PL_RTSPServer_Internal* in = (PL_RTSPServer_Internal*)internal;
   //in->buffer readly
   //static size_t f=0;
   //char fname[50];
   //sprintf(fname, "%u.bgra", ++f);
   //FILE * pFile = fopen (fname,"wb");
   //fwrite (in->buffer , sizeof(char), in->buffSize, pFile);
   //fclose(pFile);
   return true;
}
@@ -76,8 +230,8 @@
{
   PL_RTSPServer_Internal* in = (PL_RTSPServer_Internal*)internal;
   pm.buffer = in->buffer;
   pm.buffSize = in->buffSize;
   pm.buffer = nullptr;
   pm.buffSize = 0;
   pm.former = this;
   return true;
}