mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-25 20:27:34 +08:00
整理代码,添加265模板代码
This commit is contained in:
parent
27bc19dd64
commit
4cb74454c0
@ -32,7 +32,6 @@
|
||||
#include <functional>
|
||||
#include "Util/util.h"
|
||||
#include "Util/TimeTicker.h"
|
||||
#include "Player/Player.h"
|
||||
#include "Common/MultiMediaSourceMuxer.h"
|
||||
|
||||
using namespace std;
|
||||
|
@ -29,8 +29,8 @@
|
||||
|
||||
#include <mutex>
|
||||
#include <memory>
|
||||
#include "Player/Frame.h"
|
||||
#include "Player/Track.h"
|
||||
#include "Extension/Frame.h"
|
||||
#include "Extension/Track.h"
|
||||
|
||||
using namespace std;
|
||||
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 "Rtmp/amf.h"
|
||||
#include "Player/Track.h"
|
||||
#include "Extension/Track.h"
|
||||
#include "RtspMuxer/RtspSdp.h"
|
||||
#include "RtspMuxer/RtpCodec.h"
|
||||
#include "RtmpMuxer/RtmpCodec.h"
|
@ -40,6 +40,7 @@ namespace mediakit{
|
||||
typedef enum {
|
||||
CodecInvalid = -1,
|
||||
CodecH264 = 0,
|
||||
CodecH265,
|
||||
CodecAAC,
|
||||
CodecMax = 0x7FFF
|
||||
} CodecId;
|
||||
@ -261,106 +262,6 @@ private:
|
||||
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{
|
||||
public:
|
||||
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
|
@ -24,29 +24,33 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SRC_PLAYER_PLAYER_H_
|
||||
#define SRC_PLAYER_PLAYER_H_
|
||||
|
||||
#include <string>
|
||||
#include "Frame.h"
|
||||
#include "H264.h"
|
||||
#include "H264/SPSParser.h"
|
||||
#include "Util/logger.h"
|
||||
using namespace toolkit;
|
||||
|
||||
using namespace std;
|
||||
using namespace mediakit;
|
||||
namespace mediakit{
|
||||
|
||||
unsigned const samplingFrequencyTable[16] = { 96000, 88200,
|
||||
64000, 48000,
|
||||
44100, 32000,
|
||||
24000, 22050,
|
||||
16000, 12000,
|
||||
11025, 8000,
|
||||
7350, 0, 0, 0 };
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
}//namespace mediakit
|
||||
|
||||
|
||||
#endif /* SRC_PLAYER_PLAYER_H_ */
|
@ -24,107 +24,82 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef ZLMEDIAKIT_TRACK_H
|
||||
#define ZLMEDIAKIT_TRACK_H
|
||||
#ifndef ZLMEDIAKIT_H264_H
|
||||
#define ZLMEDIAKIT_H264_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "Frame.h"
|
||||
#include "Util/RingBuffer.h"
|
||||
#include "Rtsp/Rtsp.h"
|
||||
#include "Player.h"
|
||||
using namespace toolkit;
|
||||
#include "Track.h"
|
||||
|
||||
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){}
|
||||
};
|
||||
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);
|
||||
|
||||
/**
|
||||
* 视频通道描述Track类,支持获取宽高fps信息
|
||||
* 264帧类
|
||||
*/
|
||||
class VideoTrack : public Track {
|
||||
class H264Frame : public Frame {
|
||||
public:
|
||||
typedef std::shared_ptr<VideoTrack> Ptr;
|
||||
typedef std::shared_ptr<H264Frame> Ptr;
|
||||
|
||||
TrackType getTrackType() const override { return TrackVideo;};
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回视频高度
|
||||
* @return
|
||||
*/
|
||||
virtual int getVideoHeight() const = 0;
|
||||
TrackType getTrackType() const override{
|
||||
return TrackVideo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回视频宽度
|
||||
* @return
|
||||
*/
|
||||
virtual int getVideoWidth() const = 0;
|
||||
CodecId getCodecId() const override{
|
||||
return CodecH264;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回视频fps
|
||||
* @return
|
||||
*/
|
||||
virtual float getVideoFps() const = 0;
|
||||
bool keyFrame() const override {
|
||||
return type == 5;
|
||||
}
|
||||
public:
|
||||
uint16_t sequence;
|
||||
uint32_t timeStamp;
|
||||
unsigned char type;
|
||||
string buffer;
|
||||
uint32_t iPrefixSize = 4;
|
||||
};
|
||||
|
||||
/**
|
||||
* 音频Track派生类,支持采样率通道数,采用位数信息
|
||||
*/
|
||||
class AudioTrack : public Track {
|
||||
|
||||
class H264FrameNoCopyAble : public FrameNoCopyAble {
|
||||
public:
|
||||
typedef std::shared_ptr<AudioTrack> Ptr;
|
||||
typedef std::shared_ptr<H264FrameNoCopyAble> Ptr;
|
||||
|
||||
TrackType getTrackType() const override { return TrackAudio;};
|
||||
H264FrameNoCopyAble(char *ptr,uint32_t size,uint32_t stamp,int prefixeSize = 4){
|
||||
buffer_ptr = ptr;
|
||||
buffer_size = size;
|
||||
timeStamp = stamp;
|
||||
iPrefixSize = prefixeSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回音频采样率
|
||||
* @return
|
||||
*/
|
||||
virtual int getAudioSampleRate() const = 0;
|
||||
TrackType getTrackType() const override{
|
||||
return TrackVideo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回音频采样位数,一般为16或8
|
||||
* @return
|
||||
*/
|
||||
virtual int getAudioSampleBit() const = 0;
|
||||
CodecId getCodecId() const override{
|
||||
return CodecH264;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回音频通道数
|
||||
* @return
|
||||
*/
|
||||
virtual int getAudioChannel() const = 0;
|
||||
bool keyFrame() const override {
|
||||
return (buffer_ptr[iPrefixSize] & 0x1F) == 5;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 264视频通道
|
||||
*/
|
||||
@ -298,135 +273,8 @@ private:
|
||||
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
|
||||
|
||||
#endif //ZLMEDIAKIT_TRACK_H
|
||||
|
||||
#endif //ZLMEDIAKIT_H264_H
|
@ -24,8 +24,10 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "Frame.h"
|
||||
#include "H265.h"
|
||||
|
||||
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/util.h"
|
||||
#include "Util/NoticeCenter.h"
|
||||
#include "Extension/H264.h"
|
||||
#include "Extension/AAC.h"
|
||||
|
||||
using namespace toolkit;
|
||||
|
||||
namespace mediakit {
|
||||
|
@ -38,7 +38,7 @@
|
||||
#include "Util/TimeTicker.h"
|
||||
#include "Util/TimeTicker.h"
|
||||
#include "Common/MediaSink.h"
|
||||
#include "Player/Track.h"
|
||||
#include "Extension/Track.h"
|
||||
|
||||
using namespace toolkit;
|
||||
|
||||
|
@ -29,7 +29,6 @@
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "Player.h"
|
||||
#include "PlayerBase.h"
|
||||
#include "Rtsp/RtspPlayer.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 <string>
|
||||
#include <functional>
|
||||
#include "Player.h"
|
||||
#include "Network/Socket.h"
|
||||
#include "Util/mini.h"
|
||||
#include "Util/RingBuffer.h"
|
||||
#include "Common/MediaSource.h"
|
||||
#include "Frame.h"
|
||||
#include "Track.h"
|
||||
#include "Extension/Frame.h"
|
||||
#include "Extension/Track.h"
|
||||
using namespace toolkit;
|
||||
|
||||
namespace mediakit {
|
||||
|
@ -24,7 +24,6 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "Player/Player.h"
|
||||
#include "Common/config.h"
|
||||
#include "PlayerProxy.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
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#include <Player/Player.h>
|
||||
#include "AACRtmpCodec.h"
|
||||
|
||||
namespace mediakit{
|
||||
|
@ -28,7 +28,8 @@
|
||||
#define ZLMEDIAKIT_AACRTMPCODEC_H
|
||||
|
||||
#include "RtmpCodec.h"
|
||||
#include "Player/Track.h"
|
||||
#include "Extension/Track.h"
|
||||
#include "Extension/AAC.h"
|
||||
|
||||
namespace mediakit{
|
||||
/**
|
||||
|
@ -28,8 +28,9 @@
|
||||
#define ZLMEDIAKIT_H264RTMPCODEC_H
|
||||
|
||||
#include "RtmpCodec.h"
|
||||
#include "Player/Track.h"
|
||||
#include "Extension/Track.h"
|
||||
#include "Util/ResourcePool.h"
|
||||
#include "Extension/H264.h"
|
||||
using namespace toolkit;
|
||||
|
||||
namespace mediakit{
|
||||
|
@ -28,7 +28,7 @@
|
||||
#define ZLMEDIAKIT_RTMPCODEC_H
|
||||
|
||||
#include "Rtmp/Rtmp.h"
|
||||
#include "Player/Frame.h"
|
||||
#include "Extension/Frame.h"
|
||||
#include "Util/RingBuffer.h"
|
||||
using namespace toolkit;
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
*/
|
||||
|
||||
#include "RtmpDemuxer.h"
|
||||
#include "Common/Factory.h"
|
||||
#include "Extension/Factory.h"
|
||||
|
||||
namespace mediakit {
|
||||
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include <unordered_map>
|
||||
#include "Rtmp/amf.h"
|
||||
#include "Rtmp/Rtmp.h"
|
||||
#include "Player/Player.h"
|
||||
#include "Player/PlayerBase.h"
|
||||
#include "Util/TimeTicker.h"
|
||||
#include "RtmpCodec.h"
|
||||
|
@ -30,9 +30,9 @@
|
||||
#include "RtmpMuxer/H264RtmpCodec.h"
|
||||
#include "RtmpMuxer/AACRtmpCodec.h"
|
||||
#include "Util/base64.h"
|
||||
#include "Player/Track.h"
|
||||
#include "Extension/Track.h"
|
||||
#include "Rtmp/amf.h"
|
||||
#include "Common/Factory.h"
|
||||
#include "Extension/Factory.h"
|
||||
|
||||
namespace mediakit {
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
#define ZLMEDIAKIT_RTMPMUXER_H
|
||||
|
||||
#include "RtmpMetedata.h"
|
||||
#include "Player/Frame.h"
|
||||
#include "Extension/Frame.h"
|
||||
#include "Common/MediaSink.h"
|
||||
|
||||
namespace mediakit{
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include <unordered_map>
|
||||
#include "Common/config.h"
|
||||
#include "Util/util.h"
|
||||
#include "Player/Frame.h"
|
||||
#include "Extension/Frame.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace toolkit;
|
||||
|
@ -28,7 +28,7 @@
|
||||
#define ZLMEDIAKIT_AACRTPCODEC_H
|
||||
|
||||
#include "RtpCodec.h"
|
||||
|
||||
#include "Extension/AAC.h"
|
||||
namespace mediakit{
|
||||
/**
|
||||
* aac rtp转adts类
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
#include "RtpCodec.h"
|
||||
#include "Util/ResourcePool.h"
|
||||
#include "Extension/H264.h"
|
||||
using namespace toolkit;
|
||||
|
||||
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 "Util/base64.h"
|
||||
#include "H264/SPSParser.h"
|
||||
#include "Common/Factory.h"
|
||||
#include "Extension/Factory.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -29,7 +29,6 @@
|
||||
|
||||
#include <unordered_map>
|
||||
#include "Rtsp/Rtsp.h"
|
||||
#include "Player/Player.h"
|
||||
#include "Player/PlayerBase.h"
|
||||
#include "Util/TimeTicker.h"
|
||||
#include "RtspMuxer/RtpCodec.h"
|
||||
|
@ -25,7 +25,7 @@
|
||||
*/
|
||||
|
||||
#include "RtspMuxer.h"
|
||||
#include "Common/Factory.h"
|
||||
#include "Extension/Factory.h"
|
||||
|
||||
namespace mediakit {
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
#define ZLMEDIAKIT_RTSPMUXER_H
|
||||
|
||||
#include "RtspSdp.h"
|
||||
#include "Player/Frame.h"
|
||||
#include "Extension/Frame.h"
|
||||
#include "Common/MediaSink.h"
|
||||
|
||||
namespace mediakit{
|
||||
|
@ -24,7 +24,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#include "RtspSdp.h"
|
||||
#include "Common/Factory.h"
|
||||
#include "Extension/Factory.h"
|
||||
|
||||
namespace mediakit{
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
#include "RtspMuxer/H264RtpCodec.h"
|
||||
#include "RtspMuxer/AACRtpCodec.h"
|
||||
#include "Util/base64.h"
|
||||
#include "Player/Track.h"
|
||||
#include "Extension/Track.h"
|
||||
|
||||
namespace mediakit {
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user