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

135 lines
4.5 KiB
C++
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* UnicastVideoMediaSubsession.cpp
*
* Created on: 2016年8月30日
* 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);
}