mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-29 14:45:55 +08:00
整理代码,添加265模板代码
This commit is contained in:
parent
27bc19dd64
commit
4cb74454c0
@ -32,7 +32,6 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include "Util/util.h"
|
#include "Util/util.h"
|
||||||
#include "Util/TimeTicker.h"
|
#include "Util/TimeTicker.h"
|
||||||
#include "Player/Player.h"
|
|
||||||
#include "Common/MultiMediaSourceMuxer.h"
|
#include "Common/MultiMediaSourceMuxer.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -29,8 +29,8 @@
|
|||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "Player/Frame.h"
|
#include "Extension/Frame.h"
|
||||||
#include "Player/Track.h"
|
#include "Extension/Track.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace toolkit;
|
using namespace toolkit;
|
||||||
|
120
src/Extension/AAC.cpp
Normal file
120
src/Extension/AAC.cpp
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 xiongziliang <771730766@qq.com>
|
||||||
|
*
|
||||||
|
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "AAC.h"
|
||||||
|
|
||||||
|
namespace mediakit{
|
||||||
|
|
||||||
|
void writeAdtsHeader(const AACFrame &hed, uint8_t *pcAdts) {
|
||||||
|
pcAdts[0] = (hed.syncword >> 4 & 0xFF); //8bit
|
||||||
|
pcAdts[1] = (hed.syncword << 4 & 0xF0); //4 bit
|
||||||
|
pcAdts[1] |= (hed.id << 3 & 0x08); //1 bit
|
||||||
|
pcAdts[1] |= (hed.layer << 1 & 0x06); //2bit
|
||||||
|
pcAdts[1] |= (hed.protection_absent & 0x01); //1 bit
|
||||||
|
|
||||||
|
pcAdts[2] = (hed.profile << 6 & 0xC0); // 2 bit
|
||||||
|
pcAdts[2] |= (hed.sf_index << 2 & 0x3C); //4bit
|
||||||
|
pcAdts[2] |= (hed.private_bit << 1 & 0x02); //1 bit
|
||||||
|
pcAdts[2] |= (hed.channel_configuration >> 2 & 0x03); //1 bit
|
||||||
|
|
||||||
|
pcAdts[3] = (hed.channel_configuration << 6 & 0xC0); // 2 bit
|
||||||
|
pcAdts[3] |= (hed.original << 5 & 0x20); //1 bit
|
||||||
|
pcAdts[3] |= (hed.home << 4 & 0x10); //1 bit
|
||||||
|
pcAdts[3] |= (hed.copyright_identification_bit << 3 & 0x08); //1 bit
|
||||||
|
pcAdts[3] |= (hed.copyright_identification_start << 2 & 0x04); //1 bit
|
||||||
|
pcAdts[3] |= (hed.aac_frame_length >> 11 & 0x03); //2 bit
|
||||||
|
|
||||||
|
pcAdts[4] = (hed.aac_frame_length >> 3 & 0xFF); //8 bit
|
||||||
|
|
||||||
|
pcAdts[5] = (hed.aac_frame_length << 5 & 0xE0); //3 bit
|
||||||
|
pcAdts[5] |= (hed.adts_buffer_fullness >> 6 & 0x1F); //5 bit
|
||||||
|
|
||||||
|
pcAdts[6] = (hed.adts_buffer_fullness << 2 & 0xFC); //6 bit
|
||||||
|
pcAdts[6] |= (hed.no_raw_data_blocks_in_frame & 0x03); //2 bit
|
||||||
|
}
|
||||||
|
string makeAdtsConfig(const uint8_t *pcAdts){
|
||||||
|
if (!(pcAdts[0] == 0xFF && (pcAdts[1] & 0xF0) == 0xF0)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
// Get and check the 'profile':
|
||||||
|
unsigned char profile = (pcAdts[2] & 0xC0) >> 6; // 2 bits
|
||||||
|
if (profile == 3) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get and check the 'sampling_frequency_index':
|
||||||
|
unsigned char sampling_frequency_index = (pcAdts[2] & 0x3C) >> 2; // 4 bits
|
||||||
|
if (samplingFrequencyTable[sampling_frequency_index] == 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get and check the 'channel_configuration':
|
||||||
|
unsigned char channel_configuration = ((pcAdts[2] & 0x01) << 2)
|
||||||
|
| ((pcAdts[3] & 0xC0) >> 6); // 3 bits
|
||||||
|
|
||||||
|
unsigned char audioSpecificConfig[2];
|
||||||
|
unsigned char const audioObjectType = profile + 1;
|
||||||
|
audioSpecificConfig[0] = (audioObjectType << 3) | (sampling_frequency_index >> 1);
|
||||||
|
audioSpecificConfig[1] = (sampling_frequency_index << 7) | (channel_configuration << 3);
|
||||||
|
return string((char *)audioSpecificConfig,2);
|
||||||
|
}
|
||||||
|
void makeAdtsHeader(const string &strAudioCfg,AACFrame &adts) {
|
||||||
|
uint8_t cfg1 = strAudioCfg[0];
|
||||||
|
uint8_t cfg2 = strAudioCfg[1];
|
||||||
|
|
||||||
|
int audioObjectType;
|
||||||
|
int sampling_frequency_index;
|
||||||
|
int channel_configuration;
|
||||||
|
|
||||||
|
audioObjectType = cfg1 >> 3;
|
||||||
|
sampling_frequency_index = ((cfg1 & 0x07) << 1) | (cfg2 >> 7);
|
||||||
|
channel_configuration = (cfg2 & 0x7F) >> 3;
|
||||||
|
|
||||||
|
adts.syncword = 0x0FFF;
|
||||||
|
adts.id = 0;
|
||||||
|
adts.layer = 0;
|
||||||
|
adts.protection_absent = 1;
|
||||||
|
adts.profile = audioObjectType - 1;
|
||||||
|
adts.sf_index = sampling_frequency_index;
|
||||||
|
adts.private_bit = 0;
|
||||||
|
adts.channel_configuration = channel_configuration;
|
||||||
|
adts.original = 0;
|
||||||
|
adts.home = 0;
|
||||||
|
adts.copyright_identification_bit = 0;
|
||||||
|
adts.copyright_identification_start = 0;
|
||||||
|
adts.aac_frame_length = 7;
|
||||||
|
adts.adts_buffer_fullness = 2047;
|
||||||
|
adts.no_raw_data_blocks_in_frame = 0;
|
||||||
|
}
|
||||||
|
void getAACInfo(const AACFrame &adts,int &iSampleRate,int &iChannel){
|
||||||
|
iSampleRate = samplingFrequencyTable[adts.sf_index];
|
||||||
|
iChannel = adts.channel_configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
}//namespace mediakit
|
||||||
|
|
||||||
|
|
266
src/Extension/AAC.h
Normal file
266
src/Extension/AAC.h
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 xiongziliang <771730766@qq.com>
|
||||||
|
*
|
||||||
|
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ZLMEDIAKIT_AAC_H
|
||||||
|
#define ZLMEDIAKIT_AAC_H
|
||||||
|
|
||||||
|
#include "Frame.h"
|
||||||
|
#include "Track.h"
|
||||||
|
|
||||||
|
namespace mediakit{
|
||||||
|
|
||||||
|
class AACFrame;
|
||||||
|
|
||||||
|
unsigned const samplingFrequencyTable[16] = { 96000, 88200,
|
||||||
|
64000, 48000,
|
||||||
|
44100, 32000,
|
||||||
|
24000, 22050,
|
||||||
|
16000, 12000,
|
||||||
|
11025, 8000,
|
||||||
|
7350, 0, 0, 0 };
|
||||||
|
|
||||||
|
void makeAdtsHeader(const string &strAudioCfg,AACFrame &adts);
|
||||||
|
void writeAdtsHeader(const AACFrame &adts, uint8_t *pcAdts) ;
|
||||||
|
string makeAdtsConfig(const uint8_t *pcAdts);
|
||||||
|
void getAACInfo(const AACFrame &adts,int &iSampleRate,int &iChannel);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* aac帧,包含adts头
|
||||||
|
*/
|
||||||
|
class AACFrame : public Frame {
|
||||||
|
public:
|
||||||
|
typedef std::shared_ptr<AACFrame> Ptr;
|
||||||
|
|
||||||
|
char *data() const override{
|
||||||
|
return (char *)buffer;
|
||||||
|
}
|
||||||
|
uint32_t size() const override {
|
||||||
|
return aac_frame_length;
|
||||||
|
}
|
||||||
|
uint32_t stamp() const override {
|
||||||
|
return timeStamp;
|
||||||
|
}
|
||||||
|
uint32_t prefixSize() const override{
|
||||||
|
return iPrefixSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
TrackType getTrackType() const override{
|
||||||
|
return TrackAudio;
|
||||||
|
}
|
||||||
|
|
||||||
|
CodecId getCodecId() const override{
|
||||||
|
return CodecAAC;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool keyFrame() const override {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
unsigned int syncword; //12 bslbf 同步字The bit string ‘1111 1111 1111’,说明一个ADTS帧的开始
|
||||||
|
unsigned int id; //1 bslbf MPEG 标示符, 设置为1
|
||||||
|
unsigned int layer; //2 uimsbf Indicates which layer is used. Set to ‘00’
|
||||||
|
unsigned int protection_absent; //1 bslbf 表示是否误码校验
|
||||||
|
unsigned int profile; //2 uimsbf 表示使用哪个级别的AAC,如01 Low Complexity(LC)--- AACLC
|
||||||
|
unsigned int sf_index; //4 uimsbf 表示使用的采样率下标
|
||||||
|
unsigned int private_bit; //1 bslbf
|
||||||
|
unsigned int channel_configuration; //3 uimsbf 表示声道数
|
||||||
|
unsigned int original; //1 bslbf
|
||||||
|
unsigned int home; //1 bslbf
|
||||||
|
//下面的为改变的参数即每一帧都不同
|
||||||
|
unsigned int copyright_identification_bit; //1 bslbf
|
||||||
|
unsigned int copyright_identification_start; //1 bslbf
|
||||||
|
unsigned int aac_frame_length; // 13 bslbf 一个ADTS帧的长度包括ADTS头和raw data block
|
||||||
|
unsigned int adts_buffer_fullness; //11 bslbf 0x7FF 说明是码率可变的码流
|
||||||
|
//no_raw_data_blocks_in_frame 表示ADTS帧中有number_of_raw_data_blocks_in_frame + 1个AAC原始帧.
|
||||||
|
//所以说number_of_raw_data_blocks_in_frame == 0
|
||||||
|
//表示说ADTS帧中有一个AAC数据块并不是说没有。(一个AAC原始帧包含一段时间内1024个采样及相关数据)
|
||||||
|
unsigned int no_raw_data_blocks_in_frame; //2 uimsfb
|
||||||
|
unsigned char buffer[2 * 1024 + 7];
|
||||||
|
uint16_t sequence;
|
||||||
|
uint32_t timeStamp;
|
||||||
|
uint32_t iPrefixSize = 7;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
class AACFrameNoCopyAble : public FrameNoCopyAble {
|
||||||
|
public:
|
||||||
|
typedef std::shared_ptr<AACFrameNoCopyAble> Ptr;
|
||||||
|
|
||||||
|
AACFrameNoCopyAble(char *ptr,uint32_t size,uint32_t stamp,int prefixeSize = 7){
|
||||||
|
buffer_ptr = ptr;
|
||||||
|
buffer_size = size;
|
||||||
|
timeStamp = stamp;
|
||||||
|
iPrefixSize = prefixeSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
TrackType getTrackType() const override{
|
||||||
|
return TrackAudio;
|
||||||
|
}
|
||||||
|
|
||||||
|
CodecId getCodecId() const override{
|
||||||
|
return CodecAAC;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool keyFrame() const override {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* aac音频通道
|
||||||
|
*/
|
||||||
|
class AACTrack : public AudioTrack{
|
||||||
|
public:
|
||||||
|
typedef std::shared_ptr<AACTrack> Ptr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 延后获取adts头信息
|
||||||
|
* 在随后的inputFrame中获取adts头信息
|
||||||
|
*/
|
||||||
|
AACTrack(){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造aac类型的媒体
|
||||||
|
* @param aac_cfg aac两个字节的配置信息
|
||||||
|
*/
|
||||||
|
AACTrack(const string &aac_cfg){
|
||||||
|
if(aac_cfg.size() != 2){
|
||||||
|
throw std::invalid_argument("adts配置必须为2个字节");
|
||||||
|
}
|
||||||
|
_cfg = aac_cfg;
|
||||||
|
parseAacCfg(_cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造aac类型的媒体
|
||||||
|
* @param adts_header adts头,7个字节
|
||||||
|
* @param adts_header_len adts头长度,不少于7个字节
|
||||||
|
*/
|
||||||
|
AACTrack(const char *adts_header,int adts_header_len = 7){
|
||||||
|
if(adts_header_len < 7){
|
||||||
|
throw std::invalid_argument("adts头必须不少于7个字节");
|
||||||
|
}
|
||||||
|
_cfg = makeAdtsConfig((uint8_t*)adts_header);
|
||||||
|
parseAacCfg(_cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造aac类型的媒体
|
||||||
|
* @param aac_frame_with_adts 带adts头的aac帧
|
||||||
|
*/
|
||||||
|
AACTrack(const Frame::Ptr &aac_frame_with_adts){
|
||||||
|
if(aac_frame_with_adts->getCodecId() != CodecAAC || aac_frame_with_adts->prefixSize() < 7){
|
||||||
|
throw std::invalid_argument("必须输入带adts头的aac帧");
|
||||||
|
}
|
||||||
|
_cfg = makeAdtsConfig((uint8_t*)aac_frame_with_adts->data());
|
||||||
|
parseAacCfg(_cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取aac两个字节的配置
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
const string &getAacCfg() const{
|
||||||
|
return _cfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回编码类型
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
CodecId getCodecId() const override{
|
||||||
|
return CodecAAC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在获取aac_cfg前是无效的Track
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
bool ready() override {
|
||||||
|
return !_cfg.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回音频采样率
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int getAudioSampleRate() const override{
|
||||||
|
return _sampleRate;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 返回音频采样位数,一般为16或8
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int getAudioSampleBit() const override{
|
||||||
|
return _sampleBit;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 返回音频通道数
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int getAudioChannel() const override{
|
||||||
|
return _channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输入数据帧,并获取aac_cfg
|
||||||
|
* @param frame 数据帧
|
||||||
|
*/
|
||||||
|
void inputFrame(const Frame::Ptr &frame) override{
|
||||||
|
if(_cfg.empty() && frame->prefixSize() >= 7){
|
||||||
|
//7个字节的adts头
|
||||||
|
_cfg = makeAdtsConfig(reinterpret_cast<const uint8_t *>(frame->data()));
|
||||||
|
parseAacCfg(_cfg);
|
||||||
|
}
|
||||||
|
AudioTrack::inputFrame(frame);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* 解析2个字节的aac配置
|
||||||
|
* @param aac_cfg
|
||||||
|
*/
|
||||||
|
void parseAacCfg(const string &aac_cfg){
|
||||||
|
AACFrame aacFrame;
|
||||||
|
makeAdtsHeader(aac_cfg,aacFrame);
|
||||||
|
getAACInfo(aacFrame,_sampleRate,_channel);
|
||||||
|
}
|
||||||
|
Track::Ptr clone() override {
|
||||||
|
return std::make_shared<std::remove_reference<decltype(*this)>::type >(*this);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
string _cfg;
|
||||||
|
int _sampleRate = 0;
|
||||||
|
int _sampleBit = 16;
|
||||||
|
int _channel = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}//namespace mediakit
|
||||||
|
|
||||||
|
|
||||||
|
#endif //ZLMEDIAKIT_AAC_H
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "Rtmp/amf.h"
|
#include "Rtmp/amf.h"
|
||||||
#include "Player/Track.h"
|
#include "Extension/Track.h"
|
||||||
#include "RtspMuxer/RtspSdp.h"
|
#include "RtspMuxer/RtspSdp.h"
|
||||||
#include "RtspMuxer/RtpCodec.h"
|
#include "RtspMuxer/RtpCodec.h"
|
||||||
#include "RtmpMuxer/RtmpCodec.h"
|
#include "RtmpMuxer/RtmpCodec.h"
|
@ -40,6 +40,7 @@ namespace mediakit{
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
CodecInvalid = -1,
|
CodecInvalid = -1,
|
||||||
CodecH264 = 0,
|
CodecH264 = 0,
|
||||||
|
CodecH265,
|
||||||
CodecAAC,
|
CodecAAC,
|
||||||
CodecMax = 0x7FFF
|
CodecMax = 0x7FFF
|
||||||
} CodecId;
|
} CodecId;
|
||||||
@ -261,106 +262,6 @@ private:
|
|||||||
map<void *,FrameWriterInterface::Ptr> _delegateMap;
|
map<void *,FrameWriterInterface::Ptr> _delegateMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 264帧类
|
|
||||||
*/
|
|
||||||
class H264Frame : public Frame {
|
|
||||||
public:
|
|
||||||
typedef std::shared_ptr<H264Frame> Ptr;
|
|
||||||
|
|
||||||
char *data() const override{
|
|
||||||
return (char *)buffer.data();
|
|
||||||
}
|
|
||||||
uint32_t size() const override {
|
|
||||||
return buffer.size();
|
|
||||||
}
|
|
||||||
uint32_t stamp() const override {
|
|
||||||
return timeStamp;
|
|
||||||
}
|
|
||||||
uint32_t prefixSize() const override{
|
|
||||||
return iPrefixSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
TrackType getTrackType() const override{
|
|
||||||
return TrackVideo;
|
|
||||||
}
|
|
||||||
|
|
||||||
CodecId getCodecId() const override{
|
|
||||||
return CodecH264;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool keyFrame() const override {
|
|
||||||
return type == 5;
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
uint16_t sequence;
|
|
||||||
uint32_t timeStamp;
|
|
||||||
unsigned char type;
|
|
||||||
string buffer;
|
|
||||||
uint32_t iPrefixSize = 4;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* aac帧,包含adts头
|
|
||||||
*/
|
|
||||||
class AACFrame : public Frame {
|
|
||||||
public:
|
|
||||||
typedef std::shared_ptr<AACFrame> Ptr;
|
|
||||||
|
|
||||||
char *data() const override{
|
|
||||||
return (char *)buffer;
|
|
||||||
}
|
|
||||||
uint32_t size() const override {
|
|
||||||
return aac_frame_length;
|
|
||||||
}
|
|
||||||
uint32_t stamp() const override {
|
|
||||||
return timeStamp;
|
|
||||||
}
|
|
||||||
uint32_t prefixSize() const override{
|
|
||||||
return iPrefixSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
TrackType getTrackType() const override{
|
|
||||||
return TrackAudio;
|
|
||||||
}
|
|
||||||
|
|
||||||
CodecId getCodecId() const override{
|
|
||||||
return CodecAAC;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool keyFrame() const override {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
unsigned int syncword; //12 bslbf 同步字The bit string ‘1111 1111 1111’,说明一个ADTS帧的开始
|
|
||||||
unsigned int id; //1 bslbf MPEG 标示符, 设置为1
|
|
||||||
unsigned int layer; //2 uimsbf Indicates which layer is used. Set to ‘00’
|
|
||||||
unsigned int protection_absent; //1 bslbf 表示是否误码校验
|
|
||||||
unsigned int profile; //2 uimsbf 表示使用哪个级别的AAC,如01 Low Complexity(LC)--- AACLC
|
|
||||||
unsigned int sf_index; //4 uimsbf 表示使用的采样率下标
|
|
||||||
unsigned int private_bit; //1 bslbf
|
|
||||||
unsigned int channel_configuration; //3 uimsbf 表示声道数
|
|
||||||
unsigned int original; //1 bslbf
|
|
||||||
unsigned int home; //1 bslbf
|
|
||||||
//下面的为改变的参数即每一帧都不同
|
|
||||||
unsigned int copyright_identification_bit; //1 bslbf
|
|
||||||
unsigned int copyright_identification_start; //1 bslbf
|
|
||||||
unsigned int aac_frame_length; // 13 bslbf 一个ADTS帧的长度包括ADTS头和raw data block
|
|
||||||
unsigned int adts_buffer_fullness; //11 bslbf 0x7FF 说明是码率可变的码流
|
|
||||||
//no_raw_data_blocks_in_frame 表示ADTS帧中有number_of_raw_data_blocks_in_frame + 1个AAC原始帧.
|
|
||||||
//所以说number_of_raw_data_blocks_in_frame == 0
|
|
||||||
//表示说ADTS帧中有一个AAC数据块并不是说没有。(一个AAC原始帧包含一段时间内1024个采样及相关数据)
|
|
||||||
unsigned int no_raw_data_blocks_in_frame; //2 uimsfb
|
|
||||||
unsigned char buffer[2 * 1024 + 7];
|
|
||||||
uint16_t sequence;
|
|
||||||
uint32_t timeStamp;
|
|
||||||
uint32_t iPrefixSize = 7;
|
|
||||||
} ;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class FrameNoCopyAble : public Frame{
|
class FrameNoCopyAble : public Frame{
|
||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<FrameNoCopyAble> Ptr;
|
typedef std::shared_ptr<FrameNoCopyAble> Ptr;
|
||||||
@ -384,53 +285,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class H264FrameNoCopyAble : public FrameNoCopyAble {
|
|
||||||
public:
|
|
||||||
typedef std::shared_ptr<H264FrameNoCopyAble> Ptr;
|
|
||||||
|
|
||||||
H264FrameNoCopyAble(char *ptr,uint32_t size,uint32_t stamp,int prefixeSize = 4){
|
|
||||||
buffer_ptr = ptr;
|
|
||||||
buffer_size = size;
|
|
||||||
timeStamp = stamp;
|
|
||||||
iPrefixSize = prefixeSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
TrackType getTrackType() const override{
|
|
||||||
return TrackVideo;
|
|
||||||
}
|
|
||||||
|
|
||||||
CodecId getCodecId() const override{
|
|
||||||
return CodecH264;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool keyFrame() const override {
|
|
||||||
return (buffer_ptr[iPrefixSize] & 0x1F) == 5;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class AACFrameNoCopyAble : public FrameNoCopyAble {
|
|
||||||
public:
|
|
||||||
typedef std::shared_ptr<AACFrameNoCopyAble> Ptr;
|
|
||||||
|
|
||||||
AACFrameNoCopyAble(char *ptr,uint32_t size,uint32_t stamp,int prefixeSize = 7){
|
|
||||||
buffer_ptr = ptr;
|
|
||||||
buffer_size = size;
|
|
||||||
timeStamp = stamp;
|
|
||||||
iPrefixSize = prefixeSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
TrackType getTrackType() const override{
|
|
||||||
return TrackAudio;
|
|
||||||
}
|
|
||||||
|
|
||||||
CodecId getCodecId() const override{
|
|
||||||
return CodecAAC;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool keyFrame() const override {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} ;
|
|
||||||
|
|
||||||
|
|
||||||
}//namespace mediakit
|
}//namespace mediakit
|
@ -24,29 +24,33 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SRC_PLAYER_PLAYER_H_
|
|
||||||
#define SRC_PLAYER_PLAYER_H_
|
|
||||||
|
|
||||||
#include <string>
|
#include "H264.h"
|
||||||
#include "Frame.h"
|
#include "H264/SPSParser.h"
|
||||||
|
#include "Util/logger.h"
|
||||||
|
using namespace toolkit;
|
||||||
|
|
||||||
using namespace std;
|
namespace mediakit{
|
||||||
using namespace mediakit;
|
|
||||||
|
|
||||||
unsigned const samplingFrequencyTable[16] = { 96000, 88200,
|
bool getAVCInfo(const string& strSps,int &iVideoWidth, int &iVideoHeight, float &iVideoFps) {
|
||||||
64000, 48000,
|
return getAVCInfo(strSps.data(),strSps.size(),iVideoWidth,iVideoHeight,iVideoFps);
|
||||||
44100, 32000,
|
}
|
||||||
24000, 22050,
|
bool getAVCInfo(const char * sps,int sps_len,int &iVideoWidth, int &iVideoHeight, float &iVideoFps){
|
||||||
16000, 12000,
|
T_GetBitContext tGetBitBuf;
|
||||||
11025, 8000,
|
T_SPS tH264SpsInfo;
|
||||||
7350, 0, 0, 0 };
|
memset(&tGetBitBuf,0,sizeof(tGetBitBuf));
|
||||||
|
memset(&tH264SpsInfo,0,sizeof(tH264SpsInfo));
|
||||||
|
tGetBitBuf.pu8Buf = (uint8_t*)sps + 1;
|
||||||
|
tGetBitBuf.iBufSize = sps_len - 1;
|
||||||
|
if(0 != h264DecSeqParameterSet((void *) &tGetBitBuf, &tH264SpsInfo)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
h264GetWidthHeight(&tH264SpsInfo, &iVideoWidth, &iVideoHeight);
|
||||||
|
h264GeFramerate(&tH264SpsInfo, &iVideoFps);
|
||||||
|
//ErrorL << iVideoWidth << " " << iVideoHeight << " " << iVideoFps;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void makeAdtsHeader(const string &strAudioCfg,AACFrame &adts);
|
}//namespace mediakit
|
||||||
void writeAdtsHeader(const AACFrame &adts, uint8_t *pcAdts) ;
|
|
||||||
string makeAdtsConfig(const uint8_t *pcAdts);
|
|
||||||
void getAACInfo(const AACFrame &adts,int &iSampleRate,int &iChannel);
|
|
||||||
bool getAVCInfo(const string &strSps,int &iVideoWidth, int &iVideoHeight, float &iVideoFps);
|
|
||||||
bool getAVCInfo(const char * sps,int sps_len,int &iVideoWidth, int &iVideoHeight, float &iVideoFps);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* SRC_PLAYER_PLAYER_H_ */
|
|
@ -24,106 +24,81 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ZLMEDIAKIT_TRACK_H
|
#ifndef ZLMEDIAKIT_H264_H
|
||||||
#define ZLMEDIAKIT_TRACK_H
|
#define ZLMEDIAKIT_H264_H
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
#include "Frame.h"
|
#include "Frame.h"
|
||||||
#include "Util/RingBuffer.h"
|
#include "Track.h"
|
||||||
#include "Rtsp/Rtsp.h"
|
|
||||||
#include "Player.h"
|
|
||||||
using namespace toolkit;
|
|
||||||
|
|
||||||
namespace mediakit{
|
namespace mediakit{
|
||||||
|
|
||||||
|
bool getAVCInfo(const string &strSps,int &iVideoWidth, int &iVideoHeight, float &iVideoFps);
|
||||||
|
bool getAVCInfo(const char * sps,int sps_len,int &iVideoWidth, int &iVideoHeight, float &iVideoFps);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 媒体通道描述类,也支持帧输入输出
|
* 264帧类
|
||||||
*/
|
*/
|
||||||
class Track : public FrameRingInterfaceDelegate , public CodecInfo{
|
class H264Frame : public Frame {
|
||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<Track> Ptr;
|
typedef std::shared_ptr<H264Frame> Ptr;
|
||||||
Track(){}
|
|
||||||
|
|
||||||
virtual ~Track(){}
|
char *data() const override{
|
||||||
|
return (char *)buffer.data();
|
||||||
|
}
|
||||||
|
uint32_t size() const override {
|
||||||
|
return buffer.size();
|
||||||
|
}
|
||||||
|
uint32_t stamp() const override {
|
||||||
|
return timeStamp;
|
||||||
|
}
|
||||||
|
uint32_t prefixSize() const override{
|
||||||
|
return iPrefixSize;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
TrackType getTrackType() const override{
|
||||||
* 是否准备好,准备好才能获取譬如sps pps等信息
|
return TrackVideo;
|
||||||
* @return
|
}
|
||||||
*/
|
|
||||||
virtual bool ready() = 0;
|
|
||||||
|
|
||||||
/**
|
CodecId getCodecId() const override{
|
||||||
* 克隆接口,用于复制本对象用
|
return CodecH264;
|
||||||
* 在调用该接口时只会复制派生类的信息
|
}
|
||||||
* 环形缓存和代理关系不能拷贝,否则会关系紊乱
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
virtual Track::Ptr clone() = 0;
|
|
||||||
|
|
||||||
/**
|
bool keyFrame() const override {
|
||||||
* 复制拷贝,只能拷贝派生类的信息,
|
return type == 5;
|
||||||
* 环形缓存和代理关系不能拷贝,否则会关系紊乱
|
}
|
||||||
* @param that
|
public:
|
||||||
*/
|
uint16_t sequence;
|
||||||
Track(const Track &that){}
|
uint32_t timeStamp;
|
||||||
|
unsigned char type;
|
||||||
|
string buffer;
|
||||||
|
uint32_t iPrefixSize = 4;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* 视频通道描述Track类,支持获取宽高fps信息
|
class H264FrameNoCopyAble : public FrameNoCopyAble {
|
||||||
*/
|
|
||||||
class VideoTrack : public Track {
|
|
||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<VideoTrack> Ptr;
|
typedef std::shared_ptr<H264FrameNoCopyAble> Ptr;
|
||||||
|
|
||||||
TrackType getTrackType() const override { return TrackVideo;};
|
H264FrameNoCopyAble(char *ptr,uint32_t size,uint32_t stamp,int prefixeSize = 4){
|
||||||
|
buffer_ptr = ptr;
|
||||||
|
buffer_size = size;
|
||||||
|
timeStamp = stamp;
|
||||||
|
iPrefixSize = prefixeSize;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
TrackType getTrackType() const override{
|
||||||
* 返回视频高度
|
return TrackVideo;
|
||||||
* @return
|
}
|
||||||
*/
|
|
||||||
virtual int getVideoHeight() const = 0;
|
|
||||||
|
|
||||||
/**
|
CodecId getCodecId() const override{
|
||||||
* 返回视频宽度
|
return CodecH264;
|
||||||
* @return
|
}
|
||||||
*/
|
|
||||||
virtual int getVideoWidth() const = 0;
|
|
||||||
|
|
||||||
/**
|
bool keyFrame() const override {
|
||||||
* 返回视频fps
|
return (buffer_ptr[iPrefixSize] & 0x1F) == 5;
|
||||||
* @return
|
}
|
||||||
*/
|
|
||||||
virtual float getVideoFps() const = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* 音频Track派生类,支持采样率通道数,采用位数信息
|
|
||||||
*/
|
|
||||||
class AudioTrack : public Track {
|
|
||||||
public:
|
|
||||||
typedef std::shared_ptr<AudioTrack> Ptr;
|
|
||||||
|
|
||||||
TrackType getTrackType() const override { return TrackAudio;};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回音频采样率
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
virtual int getAudioSampleRate() const = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回音频采样位数,一般为16或8
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
virtual int getAudioSampleBit() const = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回音频通道数
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
virtual int getAudioChannel() const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 264视频通道
|
* 264视频通道
|
||||||
@ -298,135 +273,8 @@ private:
|
|||||||
H264Frame::Ptr _ppsFrame;
|
H264Frame::Ptr _ppsFrame;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* aac音频通道
|
|
||||||
*/
|
|
||||||
class AACTrack : public AudioTrack{
|
|
||||||
public:
|
|
||||||
typedef std::shared_ptr<AACTrack> Ptr;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 延后获取adts头信息
|
|
||||||
* 在随后的inputFrame中获取adts头信息
|
|
||||||
*/
|
|
||||||
AACTrack(){}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造aac类型的媒体
|
|
||||||
* @param aac_cfg aac两个字节的配置信息
|
|
||||||
*/
|
|
||||||
AACTrack(const string &aac_cfg){
|
|
||||||
if(aac_cfg.size() != 2){
|
|
||||||
throw std::invalid_argument("adts配置必须为2个字节");
|
|
||||||
}
|
|
||||||
_cfg = aac_cfg;
|
|
||||||
parseAacCfg(_cfg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造aac类型的媒体
|
|
||||||
* @param adts_header adts头,7个字节
|
|
||||||
* @param adts_header_len adts头长度,不少于7个字节
|
|
||||||
*/
|
|
||||||
AACTrack(const char *adts_header,int adts_header_len = 7){
|
|
||||||
if(adts_header_len < 7){
|
|
||||||
throw std::invalid_argument("adts头必须不少于7个字节");
|
|
||||||
}
|
|
||||||
_cfg = makeAdtsConfig((uint8_t*)adts_header);
|
|
||||||
parseAacCfg(_cfg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造aac类型的媒体
|
|
||||||
* @param aac_frame_with_adts 带adts头的aac帧
|
|
||||||
*/
|
|
||||||
AACTrack(const Frame::Ptr &aac_frame_with_adts){
|
|
||||||
if(aac_frame_with_adts->getCodecId() != CodecAAC || aac_frame_with_adts->prefixSize() < 7){
|
|
||||||
throw std::invalid_argument("必须输入带adts头的aac帧");
|
|
||||||
}
|
|
||||||
_cfg = makeAdtsConfig((uint8_t*)aac_frame_with_adts->data());
|
|
||||||
parseAacCfg(_cfg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取aac两个字节的配置
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
const string &getAacCfg() const{
|
|
||||||
return _cfg;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回编码类型
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
CodecId getCodecId() const override{
|
|
||||||
return CodecAAC;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 在获取aac_cfg前是无效的Track
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
bool ready() override {
|
|
||||||
return !_cfg.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回音频采样率
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
int getAudioSampleRate() const override{
|
|
||||||
return _sampleRate;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 返回音频采样位数,一般为16或8
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
int getAudioSampleBit() const override{
|
|
||||||
return _sampleBit;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 返回音频通道数
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
int getAudioChannel() const override{
|
|
||||||
return _channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 输入数据帧,并获取aac_cfg
|
|
||||||
* @param frame 数据帧
|
|
||||||
*/
|
|
||||||
void inputFrame(const Frame::Ptr &frame) override{
|
|
||||||
if(_cfg.empty() && frame->prefixSize() >= 7){
|
|
||||||
//7个字节的adts头
|
|
||||||
_cfg = makeAdtsConfig(reinterpret_cast<const uint8_t *>(frame->data()));
|
|
||||||
parseAacCfg(_cfg);
|
|
||||||
}
|
|
||||||
AudioTrack::inputFrame(frame);
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* 解析2个字节的aac配置
|
|
||||||
* @param aac_cfg
|
|
||||||
*/
|
|
||||||
void parseAacCfg(const string &aac_cfg){
|
|
||||||
AACFrame aacFrame;
|
|
||||||
makeAdtsHeader(aac_cfg,aacFrame);
|
|
||||||
getAACInfo(aacFrame,_sampleRate,_channel);
|
|
||||||
}
|
|
||||||
Track::Ptr clone() override {
|
|
||||||
return std::make_shared<std::remove_reference<decltype(*this)>::type >(*this);
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
string _cfg;
|
|
||||||
int _sampleRate = 0;
|
|
||||||
int _sampleBit = 16;
|
|
||||||
int _channel = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
}//namespace mediakit
|
}//namespace mediakit
|
||||||
|
|
||||||
#endif //ZLMEDIAKIT_TRACK_H
|
|
||||||
|
#endif //ZLMEDIAKIT_H264_H
|
@ -24,8 +24,10 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Frame.h"
|
#include "H265.h"
|
||||||
|
|
||||||
namespace mediakit{
|
namespace mediakit{
|
||||||
|
|
||||||
}
|
|
||||||
|
}//namespace mediakit
|
||||||
|
|
104
src/Extension/H265.h
Normal file
104
src/Extension/H265.h
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 xiongziliang <771730766@qq.com>
|
||||||
|
*
|
||||||
|
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef ZLMEDIAKIT_H265_H
|
||||||
|
#define ZLMEDIAKIT_H265_H
|
||||||
|
|
||||||
|
#include "Frame.h"
|
||||||
|
#include "Track.h"
|
||||||
|
|
||||||
|
namespace mediakit{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 265帧类
|
||||||
|
*/
|
||||||
|
class H265Frame : public Frame {
|
||||||
|
public:
|
||||||
|
typedef std::shared_ptr<H265Frame> Ptr;
|
||||||
|
|
||||||
|
char *data() const override{
|
||||||
|
return (char *)buffer.data();
|
||||||
|
}
|
||||||
|
uint32_t size() const override {
|
||||||
|
return buffer.size();
|
||||||
|
}
|
||||||
|
uint32_t stamp() const override {
|
||||||
|
return timeStamp;
|
||||||
|
}
|
||||||
|
uint32_t prefixSize() const override{
|
||||||
|
return iPrefixSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
TrackType getTrackType() const override{
|
||||||
|
return TrackVideo;
|
||||||
|
}
|
||||||
|
|
||||||
|
CodecId getCodecId() const override{
|
||||||
|
return CodecH265;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool keyFrame() const override {
|
||||||
|
return type == 5;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
uint16_t sequence;
|
||||||
|
uint32_t timeStamp;
|
||||||
|
unsigned char type;
|
||||||
|
string buffer;
|
||||||
|
uint32_t iPrefixSize = 4;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class H265FrameNoCopyAble : public FrameNoCopyAble {
|
||||||
|
public:
|
||||||
|
typedef std::shared_ptr<H265FrameNoCopyAble> Ptr;
|
||||||
|
|
||||||
|
H265FrameNoCopyAble(char *ptr,uint32_t size,uint32_t stamp,int prefixeSize = 4){
|
||||||
|
buffer_ptr = ptr;
|
||||||
|
buffer_size = size;
|
||||||
|
timeStamp = stamp;
|
||||||
|
iPrefixSize = prefixeSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
TrackType getTrackType() const override{
|
||||||
|
return TrackVideo;
|
||||||
|
}
|
||||||
|
|
||||||
|
CodecId getCodecId() const override{
|
||||||
|
return CodecH265;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool keyFrame() const override {
|
||||||
|
return (buffer_ptr[iPrefixSize] & 0x1F) == 5;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}//namespace mediakit
|
||||||
|
|
||||||
|
|
||||||
|
#endif //ZLMEDIAKIT_H265_H
|
130
src/Extension/Track.h
Normal file
130
src/Extension/Track.h
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 xiongziliang <771730766@qq.com>
|
||||||
|
*
|
||||||
|
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ZLMEDIAKIT_TRACK_H
|
||||||
|
#define ZLMEDIAKIT_TRACK_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include "Frame.h"
|
||||||
|
#include "Util/RingBuffer.h"
|
||||||
|
#include "Rtsp/Rtsp.h"
|
||||||
|
using namespace toolkit;
|
||||||
|
|
||||||
|
namespace mediakit{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 媒体通道描述类,也支持帧输入输出
|
||||||
|
*/
|
||||||
|
class Track : public FrameRingInterfaceDelegate , public CodecInfo{
|
||||||
|
public:
|
||||||
|
typedef std::shared_ptr<Track> Ptr;
|
||||||
|
Track(){}
|
||||||
|
|
||||||
|
virtual ~Track(){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否准备好,准备好才能获取譬如sps pps等信息
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual bool ready() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 克隆接口,用于复制本对象用
|
||||||
|
* 在调用该接口时只会复制派生类的信息
|
||||||
|
* 环形缓存和代理关系不能拷贝,否则会关系紊乱
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual Track::Ptr clone() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制拷贝,只能拷贝派生类的信息,
|
||||||
|
* 环形缓存和代理关系不能拷贝,否则会关系紊乱
|
||||||
|
* @param that
|
||||||
|
*/
|
||||||
|
Track(const Track &that){}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频通道描述Track类,支持获取宽高fps信息
|
||||||
|
*/
|
||||||
|
class VideoTrack : public Track {
|
||||||
|
public:
|
||||||
|
typedef std::shared_ptr<VideoTrack> Ptr;
|
||||||
|
|
||||||
|
TrackType getTrackType() const override { return TrackVideo;};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回视频高度
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual int getVideoHeight() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回视频宽度
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual int getVideoWidth() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回视频fps
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual float getVideoFps() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 音频Track派生类,支持采样率通道数,采用位数信息
|
||||||
|
*/
|
||||||
|
class AudioTrack : public Track {
|
||||||
|
public:
|
||||||
|
typedef std::shared_ptr<AudioTrack> Ptr;
|
||||||
|
|
||||||
|
TrackType getTrackType() const override { return TrackAudio;};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回音频采样率
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual int getAudioSampleRate() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回音频采样位数,一般为16或8
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual int getAudioSampleBit() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回音频通道数
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual int getAudioChannel() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}//namespace mediakit
|
||||||
|
|
||||||
|
#endif //ZLMEDIAKIT_TRACK_H
|
@ -34,6 +34,9 @@
|
|||||||
#include "Util/mini.h"
|
#include "Util/mini.h"
|
||||||
#include "Util/util.h"
|
#include "Util/util.h"
|
||||||
#include "Util/NoticeCenter.h"
|
#include "Util/NoticeCenter.h"
|
||||||
|
#include "Extension/H264.h"
|
||||||
|
#include "Extension/AAC.h"
|
||||||
|
|
||||||
using namespace toolkit;
|
using namespace toolkit;
|
||||||
|
|
||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
#include "Util/TimeTicker.h"
|
#include "Util/TimeTicker.h"
|
||||||
#include "Util/TimeTicker.h"
|
#include "Util/TimeTicker.h"
|
||||||
#include "Common/MediaSink.h"
|
#include "Common/MediaSink.h"
|
||||||
#include "Player/Track.h"
|
#include "Extension/Track.h"
|
||||||
|
|
||||||
using namespace toolkit;
|
using namespace toolkit;
|
||||||
|
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "Player.h"
|
|
||||||
#include "PlayerBase.h"
|
#include "PlayerBase.h"
|
||||||
#include "Rtsp/RtspPlayer.h"
|
#include "Rtsp/RtspPlayer.h"
|
||||||
#include "Rtmp/RtmpPlayer.h"
|
#include "Rtmp/RtmpPlayer.h"
|
||||||
|
@ -1,135 +0,0 @@
|
|||||||
/*
|
|
||||||
* MIT License
|
|
||||||
*
|
|
||||||
* Copyright (c) 2016 xiongziliang <771730766@qq.com>
|
|
||||||
*
|
|
||||||
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include "Player.h"
|
|
||||||
#include "H264/SPSParser.h"
|
|
||||||
#include "Util/logger.h"
|
|
||||||
using namespace toolkit;
|
|
||||||
|
|
||||||
void writeAdtsHeader(const AACFrame &hed, uint8_t *pcAdts) {
|
|
||||||
pcAdts[0] = (hed.syncword >> 4 & 0xFF); //8bit
|
|
||||||
pcAdts[1] = (hed.syncword << 4 & 0xF0); //4 bit
|
|
||||||
pcAdts[1] |= (hed.id << 3 & 0x08); //1 bit
|
|
||||||
pcAdts[1] |= (hed.layer << 1 & 0x06); //2bit
|
|
||||||
pcAdts[1] |= (hed.protection_absent & 0x01); //1 bit
|
|
||||||
|
|
||||||
pcAdts[2] = (hed.profile << 6 & 0xC0); // 2 bit
|
|
||||||
pcAdts[2] |= (hed.sf_index << 2 & 0x3C); //4bit
|
|
||||||
pcAdts[2] |= (hed.private_bit << 1 & 0x02); //1 bit
|
|
||||||
pcAdts[2] |= (hed.channel_configuration >> 2 & 0x03); //1 bit
|
|
||||||
|
|
||||||
pcAdts[3] = (hed.channel_configuration << 6 & 0xC0); // 2 bit
|
|
||||||
pcAdts[3] |= (hed.original << 5 & 0x20); //1 bit
|
|
||||||
pcAdts[3] |= (hed.home << 4 & 0x10); //1 bit
|
|
||||||
pcAdts[3] |= (hed.copyright_identification_bit << 3 & 0x08); //1 bit
|
|
||||||
pcAdts[3] |= (hed.copyright_identification_start << 2 & 0x04); //1 bit
|
|
||||||
pcAdts[3] |= (hed.aac_frame_length >> 11 & 0x03); //2 bit
|
|
||||||
|
|
||||||
pcAdts[4] = (hed.aac_frame_length >> 3 & 0xFF); //8 bit
|
|
||||||
|
|
||||||
pcAdts[5] = (hed.aac_frame_length << 5 & 0xE0); //3 bit
|
|
||||||
pcAdts[5] |= (hed.adts_buffer_fullness >> 6 & 0x1F); //5 bit
|
|
||||||
|
|
||||||
pcAdts[6] = (hed.adts_buffer_fullness << 2 & 0xFC); //6 bit
|
|
||||||
pcAdts[6] |= (hed.no_raw_data_blocks_in_frame & 0x03); //2 bit
|
|
||||||
}
|
|
||||||
string makeAdtsConfig(const uint8_t *pcAdts){
|
|
||||||
if (!(pcAdts[0] == 0xFF && (pcAdts[1] & 0xF0) == 0xF0)) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
// Get and check the 'profile':
|
|
||||||
unsigned char profile = (pcAdts[2] & 0xC0) >> 6; // 2 bits
|
|
||||||
if (profile == 3) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get and check the 'sampling_frequency_index':
|
|
||||||
unsigned char sampling_frequency_index = (pcAdts[2] & 0x3C) >> 2; // 4 bits
|
|
||||||
if (samplingFrequencyTable[sampling_frequency_index] == 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get and check the 'channel_configuration':
|
|
||||||
unsigned char channel_configuration = ((pcAdts[2] & 0x01) << 2)
|
|
||||||
| ((pcAdts[3] & 0xC0) >> 6); // 3 bits
|
|
||||||
|
|
||||||
unsigned char audioSpecificConfig[2];
|
|
||||||
unsigned char const audioObjectType = profile + 1;
|
|
||||||
audioSpecificConfig[0] = (audioObjectType << 3) | (sampling_frequency_index >> 1);
|
|
||||||
audioSpecificConfig[1] = (sampling_frequency_index << 7) | (channel_configuration << 3);
|
|
||||||
return string((char *)audioSpecificConfig,2);
|
|
||||||
}
|
|
||||||
void makeAdtsHeader(const string &strAudioCfg,AACFrame &adts) {
|
|
||||||
uint8_t cfg1 = strAudioCfg[0];
|
|
||||||
uint8_t cfg2 = strAudioCfg[1];
|
|
||||||
|
|
||||||
int audioObjectType;
|
|
||||||
int sampling_frequency_index;
|
|
||||||
int channel_configuration;
|
|
||||||
|
|
||||||
audioObjectType = cfg1 >> 3;
|
|
||||||
sampling_frequency_index = ((cfg1 & 0x07) << 1) | (cfg2 >> 7);
|
|
||||||
channel_configuration = (cfg2 & 0x7F) >> 3;
|
|
||||||
|
|
||||||
adts.syncword = 0x0FFF;
|
|
||||||
adts.id = 0;
|
|
||||||
adts.layer = 0;
|
|
||||||
adts.protection_absent = 1;
|
|
||||||
adts.profile = audioObjectType - 1;
|
|
||||||
adts.sf_index = sampling_frequency_index;
|
|
||||||
adts.private_bit = 0;
|
|
||||||
adts.channel_configuration = channel_configuration;
|
|
||||||
adts.original = 0;
|
|
||||||
adts.home = 0;
|
|
||||||
adts.copyright_identification_bit = 0;
|
|
||||||
adts.copyright_identification_start = 0;
|
|
||||||
adts.aac_frame_length = 7;
|
|
||||||
adts.adts_buffer_fullness = 2047;
|
|
||||||
adts.no_raw_data_blocks_in_frame = 0;
|
|
||||||
}
|
|
||||||
void getAACInfo(const AACFrame &adts,int &iSampleRate,int &iChannel){
|
|
||||||
iSampleRate = samplingFrequencyTable[adts.sf_index];
|
|
||||||
iChannel = adts.channel_configuration;
|
|
||||||
}
|
|
||||||
bool getAVCInfo(const string& strSps,int &iVideoWidth, int &iVideoHeight, float &iVideoFps) {
|
|
||||||
return getAVCInfo(strSps.data(),strSps.size(),iVideoWidth,iVideoHeight,iVideoFps);
|
|
||||||
}
|
|
||||||
bool getAVCInfo(const char * sps,int sps_len,int &iVideoWidth, int &iVideoHeight, float &iVideoFps){
|
|
||||||
T_GetBitContext tGetBitBuf;
|
|
||||||
T_SPS tH264SpsInfo;
|
|
||||||
memset(&tGetBitBuf,0,sizeof(tGetBitBuf));
|
|
||||||
memset(&tH264SpsInfo,0,sizeof(tH264SpsInfo));
|
|
||||||
tGetBitBuf.pu8Buf = (uint8_t*)sps + 1;
|
|
||||||
tGetBitBuf.iBufSize = sps_len - 1;
|
|
||||||
if(0 != h264DecSeqParameterSet((void *) &tGetBitBuf, &tH264SpsInfo)){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
h264GetWidthHeight(&tH264SpsInfo, &iVideoWidth, &iVideoHeight);
|
|
||||||
h264GeFramerate(&tH264SpsInfo, &iVideoFps);
|
|
||||||
//ErrorL << iVideoWidth << " " << iVideoHeight << " " << iVideoFps;
|
|
||||||
return true;
|
|
||||||
}
|
|
@ -31,13 +31,12 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include "Player.h"
|
|
||||||
#include "Network/Socket.h"
|
#include "Network/Socket.h"
|
||||||
#include "Util/mini.h"
|
#include "Util/mini.h"
|
||||||
#include "Util/RingBuffer.h"
|
#include "Util/RingBuffer.h"
|
||||||
#include "Common/MediaSource.h"
|
#include "Common/MediaSource.h"
|
||||||
#include "Frame.h"
|
#include "Extension/Frame.h"
|
||||||
#include "Track.h"
|
#include "Extension/Track.h"
|
||||||
using namespace toolkit;
|
using namespace toolkit;
|
||||||
|
|
||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Player/Player.h"
|
|
||||||
#include "Common/config.h"
|
#include "Common/config.h"
|
||||||
#include "PlayerProxy.h"
|
#include "PlayerProxy.h"
|
||||||
#include "Util/mini.h"
|
#include "Util/mini.h"
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#include <Player/Player.h>
|
|
||||||
#include "AACRtmpCodec.h"
|
#include "AACRtmpCodec.h"
|
||||||
|
|
||||||
namespace mediakit{
|
namespace mediakit{
|
||||||
|
@ -28,7 +28,8 @@
|
|||||||
#define ZLMEDIAKIT_AACRTMPCODEC_H
|
#define ZLMEDIAKIT_AACRTMPCODEC_H
|
||||||
|
|
||||||
#include "RtmpCodec.h"
|
#include "RtmpCodec.h"
|
||||||
#include "Player/Track.h"
|
#include "Extension/Track.h"
|
||||||
|
#include "Extension/AAC.h"
|
||||||
|
|
||||||
namespace mediakit{
|
namespace mediakit{
|
||||||
/**
|
/**
|
||||||
|
@ -28,8 +28,9 @@
|
|||||||
#define ZLMEDIAKIT_H264RTMPCODEC_H
|
#define ZLMEDIAKIT_H264RTMPCODEC_H
|
||||||
|
|
||||||
#include "RtmpCodec.h"
|
#include "RtmpCodec.h"
|
||||||
#include "Player/Track.h"
|
#include "Extension/Track.h"
|
||||||
#include "Util/ResourcePool.h"
|
#include "Util/ResourcePool.h"
|
||||||
|
#include "Extension/H264.h"
|
||||||
using namespace toolkit;
|
using namespace toolkit;
|
||||||
|
|
||||||
namespace mediakit{
|
namespace mediakit{
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#define ZLMEDIAKIT_RTMPCODEC_H
|
#define ZLMEDIAKIT_RTMPCODEC_H
|
||||||
|
|
||||||
#include "Rtmp/Rtmp.h"
|
#include "Rtmp/Rtmp.h"
|
||||||
#include "Player/Frame.h"
|
#include "Extension/Frame.h"
|
||||||
#include "Util/RingBuffer.h"
|
#include "Util/RingBuffer.h"
|
||||||
using namespace toolkit;
|
using namespace toolkit;
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "RtmpDemuxer.h"
|
#include "RtmpDemuxer.h"
|
||||||
#include "Common/Factory.h"
|
#include "Extension/Factory.h"
|
||||||
|
|
||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "Rtmp/amf.h"
|
#include "Rtmp/amf.h"
|
||||||
#include "Rtmp/Rtmp.h"
|
#include "Rtmp/Rtmp.h"
|
||||||
#include "Player/Player.h"
|
|
||||||
#include "Player/PlayerBase.h"
|
#include "Player/PlayerBase.h"
|
||||||
#include "Util/TimeTicker.h"
|
#include "Util/TimeTicker.h"
|
||||||
#include "RtmpCodec.h"
|
#include "RtmpCodec.h"
|
||||||
|
@ -30,9 +30,9 @@
|
|||||||
#include "RtmpMuxer/H264RtmpCodec.h"
|
#include "RtmpMuxer/H264RtmpCodec.h"
|
||||||
#include "RtmpMuxer/AACRtmpCodec.h"
|
#include "RtmpMuxer/AACRtmpCodec.h"
|
||||||
#include "Util/base64.h"
|
#include "Util/base64.h"
|
||||||
#include "Player/Track.h"
|
#include "Extension/Track.h"
|
||||||
#include "Rtmp/amf.h"
|
#include "Rtmp/amf.h"
|
||||||
#include "Common/Factory.h"
|
#include "Extension/Factory.h"
|
||||||
|
|
||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#define ZLMEDIAKIT_RTMPMUXER_H
|
#define ZLMEDIAKIT_RTMPMUXER_H
|
||||||
|
|
||||||
#include "RtmpMetedata.h"
|
#include "RtmpMetedata.h"
|
||||||
#include "Player/Frame.h"
|
#include "Extension/Frame.h"
|
||||||
#include "Common/MediaSink.h"
|
#include "Common/MediaSink.h"
|
||||||
|
|
||||||
namespace mediakit{
|
namespace mediakit{
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "Common/config.h"
|
#include "Common/config.h"
|
||||||
#include "Util/util.h"
|
#include "Util/util.h"
|
||||||
#include "Player/Frame.h"
|
#include "Extension/Frame.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace toolkit;
|
using namespace toolkit;
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#define ZLMEDIAKIT_AACRTPCODEC_H
|
#define ZLMEDIAKIT_AACRTPCODEC_H
|
||||||
|
|
||||||
#include "RtpCodec.h"
|
#include "RtpCodec.h"
|
||||||
|
#include "Extension/AAC.h"
|
||||||
namespace mediakit{
|
namespace mediakit{
|
||||||
/**
|
/**
|
||||||
* aac rtp转adts类
|
* aac rtp转adts类
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#include "RtpCodec.h"
|
#include "RtpCodec.h"
|
||||||
#include "Util/ResourcePool.h"
|
#include "Util/ResourcePool.h"
|
||||||
|
#include "Extension/H264.h"
|
||||||
using namespace toolkit;
|
using namespace toolkit;
|
||||||
|
|
||||||
namespace mediakit{
|
namespace mediakit{
|
||||||
|
265
src/RtspMuxer/H265RtpCodec.cpp
Normal file
265
src/RtspMuxer/H265RtpCodec.cpp
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 xiongziliang <771730766@qq.com>
|
||||||
|
*
|
||||||
|
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "H265RtpCodec.h"
|
||||||
|
|
||||||
|
namespace mediakit{
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned forbidden_zero_bit :1;
|
||||||
|
unsigned nal_ref_idc :2;
|
||||||
|
unsigned type :5;
|
||||||
|
} NALU;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned S :1;
|
||||||
|
unsigned E :1;
|
||||||
|
unsigned R :1;
|
||||||
|
unsigned type :5;
|
||||||
|
} FU;
|
||||||
|
|
||||||
|
bool MakeNalu(uint8_t in, NALU &nal) {
|
||||||
|
nal.forbidden_zero_bit = in >> 7;
|
||||||
|
if (nal.forbidden_zero_bit) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
nal.nal_ref_idc = (in & 0x60) >> 5;
|
||||||
|
nal.type = in & 0x1f;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool MakeFU(uint8_t in, FU &fu) {
|
||||||
|
fu.S = in >> 7;
|
||||||
|
fu.E = (in >> 6) & 0x01;
|
||||||
|
fu.R = (in >> 5) & 0x01;
|
||||||
|
fu.type = in & 0x1f;
|
||||||
|
if (fu.R != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
H265RtpDecoder::H265RtpDecoder() {
|
||||||
|
_h265frame = obtainFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
H265Frame::Ptr H265RtpDecoder::obtainFrame() {
|
||||||
|
//从缓存池重新申请对象,防止覆盖已经写入环形缓存的对象
|
||||||
|
auto frame = ResourcePoolHelper<H265Frame>::obtainObj();
|
||||||
|
frame->buffer.clear();
|
||||||
|
frame->iPrefixSize = 4;
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool H265RtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) {
|
||||||
|
key_pos = decodeRtp(rtp);
|
||||||
|
RtpCodec::inputRtp(rtp, key_pos);
|
||||||
|
return key_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
|
||||||
|
/**
|
||||||
|
* h265帧类型
|
||||||
|
* Type==1:P/B frame
|
||||||
|
* Type==5:IDR frame
|
||||||
|
* Type==6:SEI frame
|
||||||
|
* Type==7:SPS frame
|
||||||
|
* Type==8:PPS frame
|
||||||
|
*/
|
||||||
|
|
||||||
|
const uint8_t *frame = (uint8_t *) rtppack->payload + rtppack->offset;
|
||||||
|
int length = rtppack->length - rtppack->offset;
|
||||||
|
NALU nal;
|
||||||
|
MakeNalu(*frame, nal);
|
||||||
|
|
||||||
|
if (nal.type >= 0 && nal.type < 24) {
|
||||||
|
//a full frame
|
||||||
|
_h265frame->buffer.assign("\x0\x0\x0\x1", 4);
|
||||||
|
_h265frame->buffer.append((char *)frame, length);
|
||||||
|
_h265frame->type = nal.type;
|
||||||
|
_h265frame->timeStamp = rtppack->timeStamp;
|
||||||
|
_h265frame->sequence = rtppack->sequence;
|
||||||
|
auto isIDR = _h265frame->type == 5;
|
||||||
|
onGetH265(_h265frame);
|
||||||
|
return (isIDR); //i frame
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nal.type == 28) {
|
||||||
|
//FU-A
|
||||||
|
FU fu;
|
||||||
|
MakeFU(frame[1], fu);
|
||||||
|
if (fu.S == 1) {
|
||||||
|
//FU-A start
|
||||||
|
char tmp = (nal.forbidden_zero_bit << 7 | nal.nal_ref_idc << 5 | fu.type);
|
||||||
|
_h265frame->buffer.assign("\x0\x0\x0\x1", 4);
|
||||||
|
_h265frame->buffer.push_back(tmp);
|
||||||
|
_h265frame->buffer.append((char *)frame + 2, length - 2);
|
||||||
|
_h265frame->type = fu.type;
|
||||||
|
_h265frame->timeStamp = rtppack->timeStamp;
|
||||||
|
_h265frame->sequence = rtppack->sequence;
|
||||||
|
return (_h265frame->type == 5); //i frame
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rtppack->sequence != (uint16_t)(_h265frame->sequence + 1)) {
|
||||||
|
_h265frame->buffer.clear();
|
||||||
|
WarnL << "丢包,帧废弃:" << rtppack->sequence << "," << _h265frame->sequence;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_h265frame->sequence = rtppack->sequence;
|
||||||
|
if (fu.E == 1) {
|
||||||
|
//FU-A end
|
||||||
|
_h265frame->buffer.append((char *)frame + 2, length - 2);
|
||||||
|
_h265frame->timeStamp = rtppack->timeStamp;
|
||||||
|
auto isIDR = _h265frame->type == 5;
|
||||||
|
onGetH265(_h265frame);
|
||||||
|
return isIDR;
|
||||||
|
}
|
||||||
|
//FU-A mid
|
||||||
|
_h265frame->buffer.append((char *)frame + 2, length - 2);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
WarnL << "不支持的rtp类型:" << nal.type << " " << rtppack->sequence;
|
||||||
|
return false;
|
||||||
|
// 29 FU-B 单NAL单元B模式
|
||||||
|
// 24 STAP-A 单一时间的组合包
|
||||||
|
// 25 STAP-B 单一时间的组合包
|
||||||
|
// 26 MTAP16 多个时间的组合包
|
||||||
|
// 27 MTAP24 多个时间的组合包
|
||||||
|
// 0 udef
|
||||||
|
// 30 udef
|
||||||
|
// 31 udef
|
||||||
|
}
|
||||||
|
|
||||||
|
void H265RtpDecoder::onGetH265(const H265Frame::Ptr &frame) {
|
||||||
|
//写入环形缓存
|
||||||
|
RtpCodec::inputFrame(frame);
|
||||||
|
_h265frame = obtainFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
H265RtpEncoder::H265RtpEncoder(uint32_t ui32Ssrc,
|
||||||
|
uint32_t ui32MtuSize,
|
||||||
|
uint32_t ui32SampleRate,
|
||||||
|
uint8_t ui8PlayloadType,
|
||||||
|
uint8_t ui8Interleaved) :
|
||||||
|
RtpInfo(ui32Ssrc,
|
||||||
|
ui32MtuSize,
|
||||||
|
ui32SampleRate,
|
||||||
|
ui8PlayloadType,
|
||||||
|
ui8Interleaved) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void H265RtpEncoder::inputFrame(const Frame::Ptr &frame) {
|
||||||
|
RtpCodec::inputFrame(frame);
|
||||||
|
|
||||||
|
GET_CONFIG_AND_REGISTER(uint32_t,cycleMS,Rtp::kCycleMS);
|
||||||
|
auto pcData = frame->data() + frame->prefixSize();
|
||||||
|
auto uiStamp = frame->stamp();
|
||||||
|
auto iLen = frame->size() - frame->prefixSize();
|
||||||
|
|
||||||
|
uiStamp %= cycleMS;
|
||||||
|
int iSize = _ui32MtuSize - 2;
|
||||||
|
if (iLen > iSize) { //超过MTU
|
||||||
|
const unsigned char s_e_r_Start = 0x80;
|
||||||
|
const unsigned char s_e_r_Mid = 0x00;
|
||||||
|
const unsigned char s_e_r_End = 0x40;
|
||||||
|
//获取帧头数据,1byte
|
||||||
|
unsigned char naluType = *((unsigned char *) pcData) & 0x1f; //获取NALU的5bit 帧类型
|
||||||
|
|
||||||
|
unsigned char nal_ref_idc = *((unsigned char *) pcData) & 0x60; //获取NALU的2bit 帧重要程度 00 可以丢 11不能丢
|
||||||
|
//nal_ref_idc = 0x60;
|
||||||
|
//组装FU-A帧头数据 2byte
|
||||||
|
unsigned char f_nri_type = nal_ref_idc + 28;//F为0 1bit,nri上面获取到2bit,28为FU-A分片类型5bit
|
||||||
|
unsigned char s_e_r_type = naluType;
|
||||||
|
bool bFirst = true;
|
||||||
|
bool mark = false;
|
||||||
|
int nOffset = 1;
|
||||||
|
while (!mark) {
|
||||||
|
if (iLen < nOffset + iSize) { //是否拆分结束
|
||||||
|
iSize = iLen - nOffset;
|
||||||
|
mark = true;
|
||||||
|
s_e_r_type = s_e_r_End + naluType;
|
||||||
|
} else {
|
||||||
|
if (bFirst == true) {
|
||||||
|
s_e_r_type = s_e_r_Start + naluType;
|
||||||
|
bFirst = false;
|
||||||
|
} else {
|
||||||
|
s_e_r_type = s_e_r_Mid + naluType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memcpy(_aucSectionBuf, &f_nri_type, 1);
|
||||||
|
memcpy(_aucSectionBuf + 1, &s_e_r_type, 1);
|
||||||
|
memcpy(_aucSectionBuf + 2, (unsigned char *) pcData + nOffset, iSize);
|
||||||
|
nOffset += iSize;
|
||||||
|
makeH265Rtp(_aucSectionBuf, iSize + 2, mark, uiStamp);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
makeH265Rtp(pcData, iLen, true, uiStamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void H265RtpEncoder::makeH265Rtp(const void* data, unsigned int len, bool mark, uint32_t uiStamp) {
|
||||||
|
uint16_t ui16RtpLen = len + 12;
|
||||||
|
uint32_t ts = htonl((_ui32SampleRate / 1000) * uiStamp);
|
||||||
|
uint16_t sq = htons(_ui16Sequence);
|
||||||
|
uint32_t sc = htonl(_ui32Ssrc);
|
||||||
|
|
||||||
|
auto rtppkt = ResourcePoolHelper<RtpPacket>::obtainObj();
|
||||||
|
unsigned char *pucRtp = rtppkt->payload;
|
||||||
|
pucRtp[0] = '$';
|
||||||
|
pucRtp[1] = _ui8Interleaved;
|
||||||
|
pucRtp[2] = ui16RtpLen >> 8;
|
||||||
|
pucRtp[3] = ui16RtpLen & 0x00FF;
|
||||||
|
pucRtp[4] = 0x80;
|
||||||
|
pucRtp[5] = (mark << 7) | _ui8PlayloadType;
|
||||||
|
memcpy(&pucRtp[6], &sq, 2);
|
||||||
|
memcpy(&pucRtp[8], &ts, 4);
|
||||||
|
//ssrc
|
||||||
|
memcpy(&pucRtp[12], &sc, 4);
|
||||||
|
//playload
|
||||||
|
memcpy(&pucRtp[16], data, len);
|
||||||
|
|
||||||
|
rtppkt->PT = _ui8PlayloadType;
|
||||||
|
rtppkt->interleaved = _ui8Interleaved;
|
||||||
|
rtppkt->mark = mark;
|
||||||
|
rtppkt->length = len + 16;
|
||||||
|
rtppkt->sequence = _ui16Sequence;
|
||||||
|
rtppkt->timeStamp = uiStamp;
|
||||||
|
rtppkt->ssrc = _ui32Ssrc;
|
||||||
|
rtppkt->type = TrackVideo;
|
||||||
|
rtppkt->offset = 16;
|
||||||
|
|
||||||
|
uint8_t type = ((uint8_t *) (data))[0] & 0x1F;
|
||||||
|
RtpCodec::inputRtp(rtppkt,type == 7);
|
||||||
|
_ui16Sequence++;
|
||||||
|
_ui32TimeStamp = uiStamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
}//namespace mediakit
|
104
src/RtspMuxer/H265RtpCodec.h
Normal file
104
src/RtspMuxer/H265RtpCodec.h
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 xiongziliang <771730766@qq.com>
|
||||||
|
*
|
||||||
|
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ZLMEDIAKIT_H265RTPCODEC_H
|
||||||
|
#define ZLMEDIAKIT_H265RTPCODEC_H
|
||||||
|
|
||||||
|
#include "RtpCodec.h"
|
||||||
|
#include "Util/ResourcePool.h"
|
||||||
|
#include "Extension/H265.h"
|
||||||
|
|
||||||
|
using namespace toolkit;
|
||||||
|
|
||||||
|
namespace mediakit{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* h265 rtp解码类
|
||||||
|
*/
|
||||||
|
class H265RtpDecoder : public RtpCodec , public ResourcePoolHelper<H265Frame> {
|
||||||
|
public:
|
||||||
|
typedef std::shared_ptr<H265RtpDecoder> Ptr;
|
||||||
|
|
||||||
|
H265RtpDecoder();
|
||||||
|
~H265RtpDecoder() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输入265 rtp包
|
||||||
|
* @param rtp rtp包
|
||||||
|
* @param key_pos 此参数忽略之
|
||||||
|
*/
|
||||||
|
bool inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = true) override;
|
||||||
|
|
||||||
|
TrackType getTrackType() const override{
|
||||||
|
return TrackVideo;
|
||||||
|
}
|
||||||
|
|
||||||
|
CodecId getCodecId() const override{
|
||||||
|
return CodecH265;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
bool decodeRtp(const RtpPacket::Ptr &rtp);
|
||||||
|
void onGetH265(const H265Frame::Ptr &frame);
|
||||||
|
H265Frame::Ptr obtainFrame();
|
||||||
|
private:
|
||||||
|
H265Frame::Ptr _h265frame;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 265 rtp打包类
|
||||||
|
*/
|
||||||
|
class H265RtpEncoder : public H265RtpDecoder ,public RtpInfo{
|
||||||
|
public:
|
||||||
|
typedef std::shared_ptr<H265RtpEncoder> Ptr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ui32Ssrc ssrc
|
||||||
|
* @param ui32MtuSize mtu大小
|
||||||
|
* @param ui32SampleRate 采样率,强制为90000
|
||||||
|
* @param ui8PlayloadType pt类型
|
||||||
|
* @param ui8Interleaved rtsp interleaved
|
||||||
|
*/
|
||||||
|
H265RtpEncoder(uint32_t ui32Ssrc,
|
||||||
|
uint32_t ui32MtuSize = 1400,
|
||||||
|
uint32_t ui32SampleRate = 90000,
|
||||||
|
uint8_t ui8PlayloadType = 96,
|
||||||
|
uint8_t ui8Interleaved = TrackVideo * 2);
|
||||||
|
~H265RtpEncoder() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输入265帧
|
||||||
|
* @param frame 帧数据,必须
|
||||||
|
*/
|
||||||
|
void inputFrame(const Frame::Ptr &frame) override;
|
||||||
|
private:
|
||||||
|
void makeH265Rtp(const void *pData, unsigned int uiLen, bool bMark, uint32_t uiStamp);
|
||||||
|
private:
|
||||||
|
unsigned char _aucSectionBuf[1600];
|
||||||
|
};
|
||||||
|
|
||||||
|
}//namespace mediakit{
|
||||||
|
|
||||||
|
#endif //ZLMEDIAKIT_H265RTPCODEC_H
|
@ -29,7 +29,7 @@
|
|||||||
#include "RtspDemuxer.h"
|
#include "RtspDemuxer.h"
|
||||||
#include "Util/base64.h"
|
#include "Util/base64.h"
|
||||||
#include "H264/SPSParser.h"
|
#include "H264/SPSParser.h"
|
||||||
#include "Common/Factory.h"
|
#include "Extension/Factory.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "Rtsp/Rtsp.h"
|
#include "Rtsp/Rtsp.h"
|
||||||
#include "Player/Player.h"
|
|
||||||
#include "Player/PlayerBase.h"
|
#include "Player/PlayerBase.h"
|
||||||
#include "Util/TimeTicker.h"
|
#include "Util/TimeTicker.h"
|
||||||
#include "RtspMuxer/RtpCodec.h"
|
#include "RtspMuxer/RtpCodec.h"
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "RtspMuxer.h"
|
#include "RtspMuxer.h"
|
||||||
#include "Common/Factory.h"
|
#include "Extension/Factory.h"
|
||||||
|
|
||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#define ZLMEDIAKIT_RTSPMUXER_H
|
#define ZLMEDIAKIT_RTSPMUXER_H
|
||||||
|
|
||||||
#include "RtspSdp.h"
|
#include "RtspSdp.h"
|
||||||
#include "Player/Frame.h"
|
#include "Extension/Frame.h"
|
||||||
#include "Common/MediaSink.h"
|
#include "Common/MediaSink.h"
|
||||||
|
|
||||||
namespace mediakit{
|
namespace mediakit{
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#include "RtspSdp.h"
|
#include "RtspSdp.h"
|
||||||
#include "Common/Factory.h"
|
#include "Extension/Factory.h"
|
||||||
|
|
||||||
namespace mediakit{
|
namespace mediakit{
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
#include "RtspMuxer/H264RtpCodec.h"
|
#include "RtspMuxer/H264RtpCodec.h"
|
||||||
#include "RtspMuxer/AACRtpCodec.h"
|
#include "RtspMuxer/AACRtpCodec.h"
|
||||||
#include "Util/base64.h"
|
#include "Util/base64.h"
|
||||||
#include "Player/Track.h"
|
#include "Extension/Track.h"
|
||||||
|
|
||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user