From 1abced42eb3997ef9ef675bfe990f7913ea73f2f Mon Sep 17 00:00:00 2001
From: houxiao <houxiao@454eff88-639b-444f-9e54-f578c98de674>
Date: 星期五, 23 十二月 2016 18:34:10 +0800
Subject: [PATCH] add h264 encoder and rtsp server

---
 RtspFace/PL_RTSPServer.cpp |  194 +++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 174 insertions(+), 20 deletions(-)

diff --git a/RtspFace/PL_RTSPServer.cpp b/RtspFace/PL_RTSPServer.cpp
index ad27c00..936b31d 100644
--- a/RtspFace/PL_RTSPServer.cpp
+++ b/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;
 }

--
Gitblit v1.8.0