From 109ffe9a777658936a38d0c146579a67c60a0d17 Mon Sep 17 00:00:00 2001 From: xuxiuxi <xuxiuxi@454eff88-639b-444f-9e54-f578c98de674> Date: 星期四, 11 五月 2017 17:48:48 +0800 Subject: [PATCH] --- RtspFace/PL_RTSPServer.cpp | 221 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 196 insertions(+), 25 deletions(-) diff --git a/RtspFace/PL_RTSPServer.cpp b/RtspFace/PL_RTSPServer.cpp index be0807b..6610e04 100644 --- a/RtspFace/PL_RTSPServer.cpp +++ b/RtspFace/PL_RTSPServer.cpp @@ -1,28 +1,157 @@ #include "PL_RTSPServer.h" +#include "MaterialBuffer.h" +#include "logger.h" -struct PL_RTSPServer_Internal +#include <liveMedia.hh> +#include <BasicUsageEnvironment.hh> + +#include "FFmpegRTSPServer/IEncoder.h" +#include "FFmpegRTSPServer/LiveRTSPServer.h" +#include "FFmpegRTSPServer/FFmpegH264Source.h" +#include "FFmpegRTSPServer/LiveServerMediaSubsession.h" + +class MyEncoderStub; + +struct RTSPServer_Internal { - uint8_t buffer[1920*1080*4]; + uint8_t buffer[1920*1080*3]; size_t buffSize; size_t buffSizeMax; + + RTSPServerConfig config; bool payError; + pthread_t live_daemon_thid; + pthread_mutex_t* frame_mutex; + bool live_daemon_running; - PL_RTSPServer_Internal() : - buffSize(0), buffSizeMax(sizeof(buffer)), - payError(true) + MESAI::LiveRTSPServer * server; + MyEncoderStub * encoderStub; + + RTSPServer_Internal() : + buffSize(0), buffSizeMax(sizeof(buffer)), config(), + payError(true), live_daemon_thid(0), frame_mutex(new pthread_mutex_t), live_daemon_running(false), + server(nullptr), encoderStub(nullptr) { + pthread_mutex_init(frame_mutex, NULL); } - ~PL_RTSPServer_Internal() + ~RTSPServer_Internal() { + if (frame_mutex != nullptr) + { + pthread_mutex_destroy(frame_mutex); + delete frame_mutex; + frame_mutex = nullptr; + } } void reset() { buffSize = 0; + + RTSPServerConfig _config; + config =_config; + 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; + + server = nullptr; + encoderStub = nullptr; } +}; + +class MyEncoderStub : public MESAI::IEncoder +{ +public: + MyEncoderStub(RTSPServer_Internal& _in) : in(_in) + { + } + + virtual ~MyEncoderStub() + { + } + + virtual void setCallbackFunctionFrameIsReady(std::function<void()> func) + { + onFrame = func; + } + + virtual char GetFrame(u_int8_t** FrameBuffer, unsigned int *FrameSize) + { + if (in.buffer == nullptr || in.buffSize <= 0) + { + ReleaseFrame(); + return 0; + } + + uint8_t* pBuffer = in.buffer; + size_t newBufferSize = in.buffSize; + if (in.config.payWithAux) + { + if (newBufferSize <= 4) + { + ReleaseFrame(); + return 0; + } + pBuffer += 4; + newBufferSize -= 4; + } + + *FrameBuffer = pBuffer; + *FrameSize = newBufferSize; + + LOG_DEBUG << "send frame size=" << in.buffSize << std::endl; + } + + virtual char ReleaseFrame() + { + in.buffSize = 0; + + if (in.config.syncDeliverFrame) + { + int ret = pthread_mutex_unlock(in.frame_mutex); + if(ret != 0) + { + LOG_WARN << "pthread_mutex_unlock frame_mutex: " << strerror(ret) << std::endl; + return 0; + } + } + + return 1; + } + + void deliverFrame() + { + // write frame buffer of RTSPServer_Internal::buffer + onFrame(); + + if (in.config.syncDeliverFrame) + { + int ret = pthread_mutex_lock(in.frame_mutex); + if(ret != 0) + { + LOG_WARN << "pthread_mutex_lock frame_mutex: " << strerror(ret) << std::endl; + return; + } + } + } + +private: + RTSPServer_Internal& in; + std::function<void()> onFrame; }; PipeLineElem* create_PL_RTSPServer() @@ -30,52 +159,94 @@ return new PL_RTSPServer; } -PL_RTSPServer::PL_RTSPServer() : internal(new PL_RTSPServer_Internal) +PL_RTSPServer::PL_RTSPServer() : internal(new RTSPServer_Internal) { } PL_RTSPServer::~PL_RTSPServer() { - delete (PL_RTSPServer_Internal*)internal; - internal= nullptr; + delete (RTSPServer_Internal*)internal; + internal = nullptr; +} + +static void* live_daemon_thd(void* arg) +{ + RTSPServer_Internal* in = (RTSPServer_Internal*)arg; + + MyEncoderStub encoder(*in); + in->encoderStub = &encoder; + in->server = new MESAI::LiveRTSPServer(&encoder, 8554, 8080); + + in->live_daemon_running = true; + in->server->run(); // does not return + in->encoderStub = nullptr; + in->live_daemon_running = false; } bool PL_RTSPServer::init(void* args) { - PL_RTSPServer_Internal* in = (PL_RTSPServer_Internal*)internal; + RTSPServer_Internal* in = (RTSPServer_Internal*)internal; in->reset(); + + if (args) + { + RTSPServerConfig* config = (RTSPServerConfig*)args; + in->config = *config; + } + + int ret = pthread_create(&(in->live_daemon_thid), NULL, live_daemon_thd, in); + if(ret != 0) + { + LOG_ERROR << "pthread_create: " << strerror(ret) << std::endl; + return false; + } return true; } void PL_RTSPServer::finit() { - PL_RTSPServer_Internal* in = (PL_RTSPServer_Internal*)internal; - + RTSPServer_Internal* in = (RTSPServer_Internal*)internal; + + pthread_join(in->live_daemon_thid, NULL); } bool PL_RTSPServer::pay(const PipeMaterial& pm) { - PL_RTSPServer_Internal* in = (PL_RTSPServer_Internal*)internal; + RTSPServer_Internal* in = (RTSPServer_Internal*)internal; + + if (pm.buffer == nullptr) + return false; - //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); - + if (pm.type != PipeMaterial::PMT_FRAME) + { + LOG_ERROR << "PL_RTSPServer::pay only support PMT_FRAME" << std::endl; + return false; + } + + if (in->buffSize > 0) + LOG_WARN << "PL_RTSPServer::pay may lost data size=" << in->buffSize << std::endl; + + MB_Frame* frame = (MB_Frame*)pm.buffer; + if (frame->buffer == nullptr) + return false; + memcpy(in->buffer, frame->buffer, frame->buffSize); + in->buffSize = frame->buffSize; + + if (in->encoderStub == nullptr) + return false; + + in->encoderStub->deliverFrame(); return true; } bool PL_RTSPServer::gain(PipeMaterial& pm) { - PL_RTSPServer_Internal* in = (PL_RTSPServer_Internal*)internal; + RTSPServer_Internal* in = (RTSPServer_Internal*)internal; - pm.buffer = in->buffer; - pm.buffSize = in->buffSize; + pm.type = PipeMaterial::PMT_NONE; + pm.buffer = nullptr; + pm.buffSize = 0; pm.former = this; return true; } -- Gitblit v1.8.0