sdk-hwV1.3/external/eyesee-mpp/system/private/rtsp/IPCProgram/interface/UnicastVideoMediaSubsession...

135 lines
4.5 KiB
C++
Raw Normal View History

2024-05-07 10:09:20 +00:00
/*
* UnicastVideoMediaSubsession.cpp
*
* Created on: 2016830
* Author: liu
*/
#include "UnicastVideoMediaSubsession.h"
#include <iostream>
#include <string.h>
#include <errno.h>
#include "BasicUsageEnvironment.hh"
#include "H264VideoStreamDiscreteFramer.hh"
#include "H265VideoStreamDiscreteFramer.hh"
#include "H264VideoRTPSink.hh"
#include "H265VideoRTPSink.hh"
#include "TinySource.h"
using namespace std;
class BridgeSource: FramedSource {
public:
BridgeSource(UsageEnvironment &env, TinySource &tinySource);
~BridgeSource();
TinySource& getTinySource() {
return _tinySource;
}
private:
virtual void doGetNextFrame();
static void afterGettingFrame(void *clientData, unsigned frameSize, unsigned numTruncatedBytes, struct timeval presentationTime,
unsigned durationInMicroseconds);
void afterGettingFrame1(unsigned frameSize, unsigned numTruncatedBytes, struct timeval presentationTime, unsigned durationInMicroseconds);
private:
TinySource &_tinySource;
};
UnicastVideoMediaSubsession::UnicastVideoMediaSubsession(UsageEnvironment &env, TinySource &tinySource) :
OnDemandServerMediaSubsession(env, true), _tinySource(tinySource) {
}
UnicastVideoMediaSubsession::~UnicastVideoMediaSubsession() {
// _tinySource为外部创建生命周期不归subsession管理
}
UnicastVideoMediaSubsession *UnicastVideoMediaSubsession::createNew(UsageEnvironment &env, TinySource &source) {
return new UnicastVideoMediaSubsession(env, source);
}
FramedSource *UnicastVideoMediaSubsession::createNewStreamSource(unsigned int clientSessionId, unsigned int &estBitrate) {
estBitrate = 1024*1024;
FramedSource *s = NULL;
BridgeSource *source = new BridgeSource(envir(), _tinySource);
if (_tinySource.getPayloadType() == TinySource::PayloadTypeH265) {
s = H265VideoStreamDiscreteFramer::createNew(envir(), (FramedSource*)source);
} else {
s = H264VideoStreamDiscreteFramer::createNew(envir(), (FramedSource*)source);
}
return s;
}
RTPSink *UnicastVideoMediaSubsession::createNewRTPSink(Groupsock *rtpGroupsock, unsigned char rtspPayloadTypeIfDynamic, FramedSource *inputSource) {
#define DYNAMIC_PAYLOAD_TYPE 96
MultiFramedRTPSink *sink = NULL;
string sps, pps, vps;
_tinySource.getSps(sps);
_tinySource.getPps(pps);
_tinySource.getVps(vps);
switch (_tinySource.getPayloadType()) {
case TinySource::PayloadTypeH264:
sink = H264VideoRTPSink::createNew(envir(), rtpGroupsock, DYNAMIC_PAYLOAD_TYPE
, (uint8_t*)sps.c_str(), sps.size()
, (uint8_t*)pps.c_str(), pps.size());
break;
case TinySource::PayloadTypeH265:
sink = H265VideoRTPSink::createNew(envir(), rtpGroupsock, DYNAMIC_PAYLOAD_TYPE
, (uint8_t*)sps.c_str(), sps.size()
, (uint8_t*)pps.c_str(), pps.size()
, (uint8_t*)vps.c_str(), vps.size());
break;
default:
sink = H264VideoRTPSink::createNew(envir(), rtpGroupsock, DYNAMIC_PAYLOAD_TYPE
, (uint8_t*)sps.c_str(), sps.size()
, (uint8_t*)pps.c_str(), pps.size());
break;
}
sink->setOnSendErrorFunc([](void *clientData) {
MultiFramedRTPSink *s = (MultiFramedRTPSink*)clientData;
printf("send rtp data failed! msg:%s\n", strerror(errno));
}, sink);
sink->setComm(_tinySource.getComm());
return sink;
#undef DYNAMIC_PAYLOAD_TYPE
}
/*
* BridgeSource class
*/
BridgeSource::BridgeSource(UsageEnvironment &env, TinySource &tinySource) :
FramedSource(env), _tinySource(tinySource) {
_tinySource.addRef();
}
BridgeSource::~BridgeSource() {
_tinySource.minRef();
}
static void onClose(void *data) {
std::cout << "TinySource is closed! report by [" << __FUNCTION__ << "]" << std::endl;
}
void BridgeSource::afterGettingFrame(void *clientData, unsigned frameSize, unsigned numTruncatedBytes, struct timeval presentationTime,
unsigned durationInMicroseconds) {
BridgeSource *source = (BridgeSource *) clientData;
source->afterGettingFrame1(frameSize, numTruncatedBytes, presentationTime, durationInMicroseconds);
}
void BridgeSource::afterGettingFrame1(unsigned frameSize, unsigned numTruncatedBytes, struct timeval presentationTime,
unsigned durationInMicroseconds) {
fFrameSize = frameSize;
fNumTruncatedBytes = numTruncatedBytes;
fPresentationTime = presentationTime;
fDurationInMicroseconds = durationInMicroseconds;
afterGetting(this);
}
void BridgeSource::doGetNextFrame() {
_tinySource.getNextFrame(fTo, fMaxSize, (FramedSource::afterGettingFunc *) afterGettingFrame, this, onClose, NULL);
}