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

---
 RtspFace/live555/testProgs/testOnDemandRTSPServer.hpp |    0 
 RtspFace/PL_RTSPServer.cpp                            |    2 
 RtspFace/live555/testProgs/testH264VideoStreamer.hpp  |  132 ++++++++++++++++++++++++++
 RtspFace/PL_H264Encoder.cpp                           |   86 +++++++++++++++++
 RtspFace/live555/testProgs/testRTSPClient.hpp         |    0 
 RtspFace/PL_RTSPClient.cpp                            |    2 
 RtspFace/PL_H264Encoder.h                             |   24 ++++
 7 files changed, 245 insertions(+), 1 deletions(-)

diff --git a/RtspFace/PL_H264Encoder.cpp b/RtspFace/PL_H264Encoder.cpp
new file mode 100644
index 0000000..ebdfb7f
--- /dev/null
+++ b/RtspFace/PL_H264Encoder.cpp
@@ -0,0 +1,86 @@
+#include "PL_H264Encoder.h"
+
+extern "C"
+{
+	#include <libyuv.h>
+}
+
+struct PL_H264Encoder_Internal
+{
+	uint8_t buffer[1920*1080*4];
+	size_t buffSize;
+	size_t buffSizeMax;
+
+	bool payError;
+	
+	PL_H264Encoder_Internal() : 
+		buffSize(0), buffSizeMax(sizeof(buffer)), 
+		payError(true)
+	{
+	}
+	
+	~PL_H264Encoder_Internal()
+	{
+	}
+	
+	void reset()
+	{
+		buffSize = 0;
+		payError = true;
+	}
+};
+
+PipeLineElem* create_PL_H264Encoder()
+{
+	return new PL_H264Encoder;
+}
+
+PL_H264Encoder::PL_H264Encoder() : internal(new PL_H264Encoder_Internal)
+{
+}
+
+PL_H264Encoder::~PL_H264Encoder()
+{
+	delete (PL_H264Encoder_Internal*)internal;
+	internal= nullptr;
+}
+
+bool PL_H264Encoder::init(void* args)
+{
+	PL_H264Encoder_Internal* in = (PL_H264Encoder_Internal*)internal;
+	in->reset();
+
+	return true;
+}
+
+void PL_H264Encoder::finit()
+{
+	PL_H264Encoder_Internal* in = (PL_H264Encoder_Internal*)internal;
+	
+}
+
+bool PL_H264Encoder::pay(const PipeMaterial& pm)
+{
+	PL_H264Encoder_Internal* in = (PL_H264Encoder_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;
+}
+
+bool PL_H264Encoder::gain(PipeMaterial& pm)
+{
+	PL_H264Encoder_Internal* in = (PL_H264Encoder_Internal*)internal;
+
+	pm.buffer = in->buffer;
+	pm.buffSize = in->buffSize;
+	pm.former = this;
+	return true;
+}
diff --git a/RtspFace/PL_H264Encoder.h b/RtspFace/PL_H264Encoder.h
new file mode 100644
index 0000000..9c85662
--- /dev/null
+++ b/RtspFace/PL_H264Encoder.h
@@ -0,0 +1,24 @@
+#ifndef _PL_H264Encoder_H_
+#define _PL_H264Encoder_H_
+
+#include "PipeLine.h"
+
+class PL_H264Encoder : public PipeLineElem
+{
+public:
+	PL_H264Encoder();
+	virtual ~PL_H264Encoder();
+
+	virtual bool init(void* args);
+	virtual void finit();
+
+	virtual bool pay(const PipeMaterial& pm);
+	virtual bool gain(PipeMaterial& pm);
+	
+private:
+	void* internal;
+};
+
+PipeLineElem* create_PL_H264Encoder();
+
+#endif
diff --git a/RtspFace/PL_RTSPClient.cpp b/RtspFace/PL_RTSPClient.cpp
index 1ed98ee..b83ec88 100644
--- a/RtspFace/PL_RTSPClient.cpp
+++ b/RtspFace/PL_RTSPClient.cpp
@@ -5,7 +5,7 @@
 void rtsp_client_fmtp_callback(void* arg, const char* val);
 void rtsp_client_frame_callback(void* arg, uint8_t* buffer, size_t buffSize);
 void rtsp_client_continue_callback(void* arg);
-#include "testRTSPClient.hpp"
+#include "live555/testProgs/testRTSPClient.hpp"
 
 struct RTSPClient_Internal
 {
diff --git a/RtspFace/PL_RTSPServer.cpp b/RtspFace/PL_RTSPServer.cpp
index be0807b..ad27c00 100644
--- a/RtspFace/PL_RTSPServer.cpp
+++ b/RtspFace/PL_RTSPServer.cpp
@@ -1,5 +1,7 @@
 #include "PL_RTSPServer.h"
 
+#include "testOnDemandRTSPServer.hpp"
+
 struct PL_RTSPServer_Internal
 {
 	uint8_t buffer[1920*1080*4];
diff --git a/RtspFace/live555/testProgs/testH264VideoStreamer.hpp b/RtspFace/live555/testProgs/testH264VideoStreamer.hpp
new file mode 100644
index 0000000..74fe461
--- /dev/null
+++ b/RtspFace/live555/testProgs/testH264VideoStreamer.hpp
@@ -0,0 +1,132 @@
+/**********
+This library is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
+
+This library is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this library; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+**********/
+// Copyright (c) 1996-2017, Live Networks, Inc.  All rights reserved
+// A test program that reads a H.264 Elementary Stream video file
+// and streams it using RTP
+// main program
+//
+// NOTE: For this application to work, the H.264 Elementary Stream video file *must* contain SPS and PPS NAL units,
+// ideally at or near the start of the file.  These SPS and PPS NAL units are used to specify 'configuration' information
+// that is set in the output stream's SDP description (by the RTSP server that is built in to this application).
+// Note also that - unlike some other "*Streamer" demo applications - the resulting stream can be received only using a
+// RTSP client (such as "openRTSP")
+
+#include <liveMedia.hh>
+#include <BasicUsageEnvironment.hh>
+#include <GroupsockHelper.hh>
+
+UsageEnvironment* env;
+char const* inputFileName = "test.264";
+H264VideoStreamFramer* videoSource;
+RTPSink* videoSink;
+
+void play(); // forward
+
+int main(int argc, char** argv) {
+  // Begin by setting up our usage environment:
+  TaskScheduler* scheduler = BasicTaskScheduler::createNew();
+  env = BasicUsageEnvironment::createNew(*scheduler);
+
+  // Create 'groupsocks' for RTP and RTCP:
+  struct in_addr destinationAddress;
+  destinationAddress.s_addr = chooseRandomIPv4SSMAddress(*env);
+  // Note: This is a multicast address.  If you wish instead to stream
+  // using unicast, then you should use the "testOnDemandRTSPServer"
+  // test program - not this test program - as a model.
+
+  const unsigned short rtpPortNum = 18888;
+  const unsigned short rtcpPortNum = rtpPortNum+1;
+  const unsigned char ttl = 255;
+
+  const Port rtpPort(rtpPortNum);
+  const Port rtcpPort(rtcpPortNum);
+
+  Groupsock rtpGroupsock(*env, destinationAddress, rtpPort, ttl);
+  rtpGroupsock.multicastSendOnly(); // we're a SSM source
+  Groupsock rtcpGroupsock(*env, destinationAddress, rtcpPort, ttl);
+  rtcpGroupsock.multicastSendOnly(); // we're a SSM source
+
+  // Create a 'H264 Video RTP' sink from the RTP 'groupsock':
+  OutPacketBuffer::maxSize = 100000;
+  videoSink = H264VideoRTPSink::createNew(*env, &rtpGroupsock, 96);
+
+  // Create (and start) a 'RTCP instance' for this RTP sink:
+  const unsigned estimatedSessionBandwidth = 500; // in kbps; for RTCP b/w share
+  const unsigned maxCNAMElen = 100;
+  unsigned char CNAME[maxCNAMElen+1];
+  gethostname((char*)CNAME, maxCNAMElen);
+  CNAME[maxCNAMElen] = '\0'; // just in case
+  RTCPInstance* rtcp
+  = RTCPInstance::createNew(*env, &rtcpGroupsock,
+			    estimatedSessionBandwidth, CNAME,
+			    videoSink, NULL /* we're a server */,
+			    True /* we're a SSM source */);
+  // Note: This starts RTCP running automatically
+
+  RTSPServer* rtspServer = RTSPServer::createNew(*env, 8554);
+  if (rtspServer == NULL) {
+    *env << "Failed to create RTSP server: " << env->getResultMsg() << "\n";
+    exit(1);
+  }
+  ServerMediaSession* sms
+    = ServerMediaSession::createNew(*env, "testStream", inputFileName,
+		   "Session streamed by \"testH264VideoStreamer\"",
+					   True /*SSM*/);
+  sms->addSubsession(PassiveServerMediaSubsession::createNew(*videoSink, rtcp));
+  rtspServer->addServerMediaSession(sms);
+
+  char* url = rtspServer->rtspURL(sms);
+  *env << "Play this stream using the URL \"" << url << "\"\n";
+  delete[] url;
+
+  // Start the streaming:
+  *env << "Beginning streaming...\n";
+  play();
+
+  env->taskScheduler().doEventLoop(); // does not return
+
+  return 0; // only to prevent compiler warning
+}
+
+void afterPlaying(void* /*clientData*/) {
+  *env << "...done reading from file\n";
+  videoSink->stopPlaying();
+  Medium::close(videoSource);
+  // Note that this also closes the input file that this source read from.
+
+  // Start playing once again:
+  play();
+}
+
+void play() {
+  // Open the input file as a 'byte-stream file source':
+  ByteStreamFileSource* fileSource
+    = ByteStreamFileSource::createNew(*env, inputFileName);
+  if (fileSource == NULL) {
+    *env << "Unable to open file \"" << inputFileName
+         << "\" as a byte-stream file source\n";
+    exit(1);
+  }
+
+  FramedSource* videoES = fileSource;
+
+  // Create a framer for the Video Elementary Stream:
+  videoSource = H264VideoStreamFramer::createNew(*env, videoES);
+
+  // Finally, start playing:
+  *env << "Beginning to read from file...\n";
+  videoSink->startPlaying(*videoSource, afterPlaying, videoSink);
+}
diff --git a/RtspFace/testOnDemandRTSPServer.cpp b/RtspFace/live555/testProgs/testOnDemandRTSPServer.hpp
similarity index 100%
rename from RtspFace/testOnDemandRTSPServer.cpp
rename to RtspFace/live555/testProgs/testOnDemandRTSPServer.hpp
diff --git a/RtspFace/testRTSPClient.hpp b/RtspFace/live555/testProgs/testRTSPClient.hpp
similarity index 100%
rename from RtspFace/testRTSPClient.hpp
rename to RtspFace/live555/testProgs/testRTSPClient.hpp

--
Gitblit v1.8.0