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