// Copyright 2019 Fuzhou Rockchip Electronics Co., Ltd. All rights reserved.
|
// Use of this source code is governed by a BSD-style license that can be
|
// found in the LICENSE file.
|
|
#include "simple_server_media_subsession.hh"
|
#include "SimpleRTPSink.hh"
|
#ifndef _MPEG2_TRANSPORT_STREAM_FRAMER_HH
|
#include "MPEG2TransportStreamFramer.hh"
|
#endif
|
#include "media_type.h"
|
#include "utils.h"
|
|
namespace easymedia
|
{
|
|
SIMPLEServerMediaSubsession* SIMPLEServerMediaSubsession::createNew(UsageEnvironment& env,
|
Live555MediaInput& wisInput,
|
unsigned samplingFrequency,
|
unsigned numChannels, std::string audioFormat,
|
unsigned bitrate)
|
{
|
return new SIMPLEServerMediaSubsession(env, wisInput, samplingFrequency, numChannels, audioFormat, bitrate);
|
}
|
|
SIMPLEServerMediaSubsession::SIMPLEServerMediaSubsession(UsageEnvironment& env, Live555MediaInput& mediaInput,
|
unsigned samplingFrequency, unsigned numChannels,
|
std::string audioFormat, unsigned bitrate)
|
: OnDemandServerMediaSubsession(env, True /*reuse the first source*/), fMediaInput(mediaInput),
|
fSamplingFrequency(samplingFrequency), fNumChannels(numChannels), fAudioFormat(audioFormat), fbitrate(bitrate)
|
{
|
}
|
|
SIMPLEServerMediaSubsession::~SIMPLEServerMediaSubsession()
|
{
|
LOG_FILE_FUNC_LINE();
|
}
|
|
FramedSource* SIMPLEServerMediaSubsession::createNewStreamSource(unsigned /*clientSessionId*/, unsigned& estBitrate)
|
{
|
LOG_FILE_FUNC_LINE();
|
estBitrate = (fbitrate + 500) / 1000; // kbps
|
if (fAudioFormat == MUXER_MPEG_TS || fAudioFormat == MUXER_MPEG_PS) {
|
return fMediaInput.muxerSource();
|
}
|
return fMediaInput.audioSource();
|
}
|
|
RTPSink* SIMPLEServerMediaSubsession::createNewRTPSink(Groupsock* rtpGroupsock,
|
unsigned char rtpPayloadTypeIfDynamic,
|
FramedSource* inputSource)
|
{
|
if (!inputSource) {
|
LOG("inputSource is not ready, can not create new rtp sink\n");
|
return NULL;
|
}
|
char const* mimeType = NULL;
|
SimpleRTPSink* rtpsink = NULL;
|
unsigned char payloadFormatCode = rtpPayloadTypeIfDynamic; // by default, unless a static RTP payload type
|
// can be used
|
|
if (fAudioFormat == MUXER_MPEG_TS || fAudioFormat == MUXER_MPEG_PS) {
|
setVideoRTPSinkBufferSize();
|
} else {
|
setAudioRTPSinkBufferSize();
|
}
|
if (fAudioFormat == AUDIO_G711U) {
|
mimeType = "PCMU";
|
if (fSamplingFrequency == 8000 && fNumChannels == 1) {
|
payloadFormatCode = 0; // a static RTP payload type
|
}
|
} else if (fAudioFormat == AUDIO_G711A) {
|
mimeType = "PCMA";
|
if (fSamplingFrequency == 8000 && fNumChannels == 1) {
|
payloadFormatCode = 8; // a static RTP payload type
|
}
|
} else if (fAudioFormat == AUDIO_G726) {
|
if (fbitrate / 1000 == 16) {
|
mimeType = "G726-16";
|
} else if (fbitrate / 1000 == 24) {
|
mimeType = "G726-24";
|
} else if (fbitrate / 1000 == 32) {
|
mimeType = "G726-32";
|
} else if (fbitrate / 1000 == 40) {
|
mimeType = "G726-40";
|
}
|
}
|
if (fAudioFormat == MUXER_MPEG_TS) {
|
rtpsink = SimpleRTPSink::createNew(envir(), rtpGroupsock, 33, 90000, "video", "MP2T", 1, True,
|
False /*no 'M' bit*/);
|
// maxPacketSize < MTU
|
// 12 bytes is the size of the RTP header
|
// 188 TRANSPORT_PACKET_SIZE
|
unsigned maxPacketSize = 12 + 188 * 7;
|
rtpsink->setPacketSizes(1000, maxPacketSize);
|
} else if (fAudioFormat == MUXER_MPEG_PS) {
|
rtpsink = SimpleRTPSink::createNew(envir(), rtpGroupsock, payloadFormatCode, 90000, "video", "MP2P", 1,
|
True, False /*no 'M' bit*/);
|
} else if (mimeType != NULL) {
|
|
rtpsink = SimpleRTPSink::createNew(envir(), rtpGroupsock, payloadFormatCode, fSamplingFrequency, "audio",
|
mimeType, fNumChannels);
|
}
|
setVideoRTPSinkBufferSize();
|
return rtpsink;
|
}
|
|
// std::mutex SIMPLEServerMediaSubsession::kMutex;
|
void SIMPLEServerMediaSubsession::startStream(
|
unsigned clientSessionId, void* streamToken, TaskFunc* rtcpRRHandler, void* rtcpRRHandlerClientData,
|
unsigned short& rtpSeqNum, unsigned& rtpTimestamp,
|
ServerRequestAlternativeByteHandler* serverRequestAlternativeByteHandler,
|
void* serverRequestAlternativeByteHandlerClientData)
|
{
|
OnDemandServerMediaSubsession::startStream(clientSessionId, streamToken, rtcpRRHandler, rtcpRRHandlerClientData,
|
rtpSeqNum, rtpTimestamp, serverRequestAlternativeByteHandler,
|
serverRequestAlternativeByteHandlerClientData);
|
// kMutex.lock();
|
if (kSessionIdList.empty()) {
|
fMediaInput.Start(envir());
|
}
|
if (fMediaInput.GetStartAudioStreamCallback() != NULL) {
|
fMediaInput.GetStartAudioStreamCallback()();
|
}
|
LOG("%s - clientSessionId: 0x%08x\n", __func__, clientSessionId);
|
kSessionIdList.push_back(clientSessionId);
|
// kMutex.unlock();
|
}
|
void SIMPLEServerMediaSubsession::deleteStream(unsigned clientSessionId, void*& streamToken)
|
{
|
// kMutex.lock();
|
LOG("%s - clientSessionId: 0x%08x\n", __func__, clientSessionId);
|
kSessionIdList.remove(clientSessionId);
|
if (kSessionIdList.empty()) {
|
fMediaInput.Stop(envir());
|
}
|
// kMutex.unlock();
|
OnDemandServerMediaSubsession::deleteStream(clientSessionId, streamToken);
|
}
|
|
} // namespace easymedia
|