For #299, refine the codec info structure.

pull/763/head
winlin 8 years ago
parent 5e419c66f8
commit c4a510b834

2
trunk/configure vendored

@ -167,7 +167,7 @@ ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSSLRoot})
MODULE_FILES=("srs_protocol_amf0" "srs_protocol_io" "srs_rtmp_stack"
"srs_rtmp_handshake" "srs_protocol_utility" "srs_rtmp_msg_array" "srs_protocol_stream"
"srs_raw_avc" "srs_rtsp_stack" "srs_http_stack" "srs_protocol_kbps" "srs_protocol_json"
"srs_kafka_stack")
"srs_kafka_stack" "srs_protocol_format")
PROTOCOL_INCS="src/protocol"; MODULE_DIR=${PROTOCOL_INCS} . auto/modules.sh
PROTOCOL_OBJS="${MODULE_OBJS[@]}"
#

@ -116,6 +116,7 @@
3C82802C1BAFF8CC004A1794 /* srs_kafka_stack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C82802A1BAFF8CC004A1794 /* srs_kafka_stack.cpp */; };
3C8CE01E1C3F482100548CC6 /* srs_app_hourglass.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C8CE01D1C3F482100548CC6 /* srs_app_hourglass.cpp */; };
3C9F82221E4ECA8200F5B2D2 /* srs_app_dash.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C9F82201E4ECA8200F5B2D2 /* srs_app_dash.cpp */; };
3C9F82251E4F5D2A00F5B2D2 /* srs_protocol_format.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C9F82231E4F5D2A00F5B2D2 /* srs_protocol_format.cpp */; };
3CA432A81E3F46DD001DA0C6 /* srs_kernel_io.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3CA432A61E3F46DD001DA0C6 /* srs_kernel_io.cpp */; };
3CA432AB1E40AEBC001DA0C6 /* Makefile in Sources */ = {isa = PBXBuildFile; fileRef = 3CA432A91E40AEBC001DA0C6 /* Makefile */; };
3CA432AC1E40AEBC001DA0C6 /* srs_ingest_mp4.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CA432AA1E40AEBC001DA0C6 /* srs_ingest_mp4.c */; };
@ -409,6 +410,8 @@
3C8CE01D1C3F482100548CC6 /* srs_app_hourglass.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_hourglass.cpp; path = ../../../src/app/srs_app_hourglass.cpp; sourceTree = "<group>"; };
3C9F82201E4ECA8200F5B2D2 /* srs_app_dash.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_dash.cpp; path = ../../../src/app/srs_app_dash.cpp; sourceTree = "<group>"; };
3C9F82211E4ECA8200F5B2D2 /* srs_app_dash.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_dash.hpp; path = ../../../src/app/srs_app_dash.hpp; sourceTree = "<group>"; };
3C9F82231E4F5D2A00F5B2D2 /* srs_protocol_format.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_protocol_format.cpp; path = ../../../src/protocol/srs_protocol_format.cpp; sourceTree = "<group>"; };
3C9F82241E4F5D2A00F5B2D2 /* srs_protocol_format.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_protocol_format.hpp; path = ../../../src/protocol/srs_protocol_format.hpp; sourceTree = "<group>"; };
3CA432A61E3F46DD001DA0C6 /* srs_kernel_io.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_kernel_io.cpp; path = ../../../src/kernel/srs_kernel_io.cpp; sourceTree = "<group>"; };
3CA432A71E3F46DD001DA0C6 /* srs_kernel_io.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_kernel_io.hpp; path = ../../../src/kernel/srs_kernel_io.hpp; sourceTree = "<group>"; };
3CA432A91E40AEBC001DA0C6 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; name = Makefile; path = ../../../research/librtmp/Makefile; sourceTree = "<group>"; };
@ -571,6 +574,8 @@
3C82802B1BAFF8CC004A1794 /* srs_kafka_stack.hpp */,
3C12322F1AAE81A400CE8F6C /* srs_protocol_amf0.cpp */,
3C1232301AAE81A400CE8F6C /* srs_protocol_amf0.hpp */,
3C9F82231E4F5D2A00F5B2D2 /* srs_protocol_format.cpp */,
3C9F82241E4F5D2A00F5B2D2 /* srs_protocol_format.hpp */,
3C1232351AAE81A400CE8F6C /* srs_protocol_io.cpp */,
3C1232361AAE81A400CE8F6C /* srs_protocol_io.hpp */,
3C0D422C1B87165900C2508B /* srs_protocol_json.cpp */,
@ -1037,6 +1042,7 @@
3C1232411AAE81A400CE8F6C /* srs_raw_avc.cpp in Sources */,
3C1232491AAE81A400CE8F6C /* srs_protocol_utility.cpp in Sources */,
3C663F191AB0155100286D8B /* srs_publish.c in Sources */,
3C9F82251E4F5D2A00F5B2D2 /* srs_protocol_format.cpp in Sources */,
3C0E1B8D1B0F5ADF003ADEF7 /* srs_http_stack.cpp in Sources */,
3C1232A01AAE81D900CE8F6C /* srs_app_http_client.cpp in Sources */,
3C689F981AB6AAAC00C9CEEE /* key.c in Sources */,

@ -50,6 +50,7 @@ using namespace std;
#include <srs_kernel_ts.hpp>
#include <srs_app_utility.hpp>
#include <srs_app_http_hooks.hpp>
#include <srs_protocol_format.hpp>
// drop the segment when duration of ts too small.
#define SRS_AUTO_HLS_SEGMENT_MIN_DURATION_MS 100
@ -1117,13 +1118,12 @@ SrsHls::SrsHls()
{
req = NULL;
hub = NULL;
format = NULL;
enabled = false;
disposable = false;
last_update_time = 0;
codec = new SrsAvcAacCodec();
sample = new SrsCodecSample();
jitter = new SrsRtmpJitter();
muxer = new SrsHlsMuxer();
@ -1135,8 +1135,6 @@ SrsHls::SrsHls()
SrsHls::~SrsHls()
{
srs_freep(codec);
srs_freep(sample);
srs_freep(jitter);
srs_freep(muxer);
@ -1188,12 +1186,13 @@ int SrsHls::cycle()
return ret;
}
int SrsHls::initialize(SrsOriginHub* h, SrsRequest* r)
int SrsHls::initialize(SrsOriginHub* h, SrsFormat* f, SrsRequest* r)
{
int ret = ERROR_SUCCESS;
hub = h;
req = r;
format = f;
if ((ret = muxer->initialize()) != ERROR_SUCCESS) {
return ret;

@ -36,12 +36,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_kernel_file.hpp>
#include <srs_app_async_call.hpp>
class SrsFormat;
class SrsSharedPtrMessage;
class SrsCodecSample;
class SrsAmf0Object;
class SrsRtmpJitter;
class SrsTSMuxer;
class SrsAvcAacCodec;
class SrsRequest;
class SrsPithyPrint;
class SrsSource;
@ -343,8 +342,7 @@ private:
};
/**
* delivery RTMP stream to HLS(m3u8 and ts),
* SrsHls provides interface with SrsSource.
* Transmux RTMP stream to HLS(m3u8 and ts).
* TODO: FIXME: add utest for hls.
*/
class SrsHls
@ -359,8 +357,7 @@ private:
int64_t last_update_time;
private:
SrsOriginHub* hub;
SrsAvcAacCodec* codec;
SrsCodecSample* sample;
SrsFormat* format;
SrsRtmpJitter* jitter;
SrsPithyPrint* pprint;
/**
@ -387,7 +384,7 @@ public:
/**
* initialize the hls by handler and source.
*/
virtual int initialize(SrsOriginHub* h, SrsRequest* r);
virtual int initialize(SrsOriginHub* h, SrsFormat* f, SrsRequest* r);
/**
* publish stream event, continue to write the m3u8,
* for the muxer object not destroyed.

@ -48,6 +48,7 @@ using namespace std;
#include <srs_protocol_utility.hpp>
#include <srs_app_ng_exec.hpp>
#include <srs_app_dash.hpp>
#include <srs_protocol_format.hpp>
#define CONST_MAX_JITTER_MS 250
#define CONST_MAX_JITTER_MS_NEG -250
@ -853,6 +854,7 @@ SrsOriginHub::SrsOriginHub()
hds = new SrsHds();
#endif
ng_exec = new SrsNgExec();
format = new SrsFormat();
_srs_config->subscribe(this);
}
@ -871,6 +873,7 @@ SrsOriginHub::~SrsOriginHub()
}
srs_freep(ng_exec);
srs_freep(format);
srs_freep(hls);
srs_freep(dash);
srs_freep(dvr);
@ -889,7 +892,11 @@ int SrsOriginHub::initialize(SrsSource* s, SrsRequest* r)
req = r;
source = s;
if ((ret = hls->initialize(this, req)) != ERROR_SUCCESS) {
if ((ret = format->initialize()) != ERROR_SUCCESS) {
return ret;
}
if ((ret = hls->initialize(this, format, req)) != ERROR_SUCCESS) {
return ret;
}
@ -924,10 +931,15 @@ int SrsOriginHub::cycle()
return ret;
}
int SrsOriginHub::on_meta_data(SrsSharedPtrMessage* shared_metadata)
int SrsOriginHub::on_meta_data(SrsSharedPtrMessage* shared_metadata, SrsOnMetaDataPacket* packet)
{
int ret = ERROR_SUCCESS;
if ((ret = format->on_metadata(packet)) != ERROR_SUCCESS) {
srs_error("Codec parse metadata failed, ret=%d", ret);
return ret;
}
// copy to all forwarders
if (true) {
std::vector<SrsForwarder*>::iterator it;
@ -954,6 +966,11 @@ int SrsOriginHub::on_audio(SrsSharedPtrMessage* shared_audio)
SrsSharedPtrMessage* msg = shared_audio;
if ((ret = format->on_audio(msg)) != ERROR_SUCCESS) {
srs_error("Codec parse audio failed, ret=%d", ret);
return ret;
}
if ((ret = hls->on_audio(msg)) != ERROR_SUCCESS) {
// apply the error strategy for hls.
// @see https://github.com/ossrs/srs/issues/264
@ -1027,6 +1044,11 @@ int SrsOriginHub::on_video(SrsSharedPtrMessage* shared_video, bool is_sequence_h
SrsSharedPtrMessage* msg = shared_video;
if ((ret = format->on_video(msg, is_sequence_header)) != ERROR_SUCCESS) {
srs_error("Codec parse video failed, ret=%d", ret);
return ret;
}
if ((ret = hls->on_video(msg, is_sequence_header)) != ERROR_SUCCESS) {
// apply the error strategy for hls.
// @see https://github.com/ossrs/srs/issues/264
@ -2048,7 +2070,7 @@ int SrsSource::on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata
}
// Copy to hub to all utilities.
return hub->on_meta_data(meta->data());
return hub->on_meta_data(meta->data(), metadata);
}
int SrsSource::on_audio(SrsCommonMessage* shared_audio)

@ -38,6 +38,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_app_reload.hpp>
#include <srs_core_performance.hpp>
class SrsFormat;
class SrsConsumer;
class SrsPlayEdge;
class SrsPublishEdge;
@ -421,6 +422,8 @@ private:
// Whether the stream hub is active, or stream is publishing.
bool is_active;
private:
// The format, codec information.
SrsFormat* format;
// hls handler.
SrsHls* hls;
// The DASH encoder.
@ -454,7 +457,7 @@ public:
virtual int cycle();
public:
// When got a parsed metadata.
virtual int on_meta_data(SrsSharedPtrMessage* shared_metadata);
virtual int on_meta_data(SrsSharedPtrMessage* shared_metadata, SrsOnMetaDataPacket* packet);
// When got a parsed audio packet.
virtual int on_audio(SrsSharedPtrMessage* shared_audio);
// When got a parsed video packet.

@ -36,7 +36,7 @@ using namespace std;
string srs_codec_video2str(SrsCodecVideo codec)
{
switch (codec) {
case SrsCodecVideoAVC:
case SrsCodecVideoAVC:
return "H264";
case SrsCodecVideoOn2VP6:
case SrsCodecVideoOn2VP6WithAlphaChannel:
@ -78,90 +78,6 @@ string srs_codec_audio2str(SrsCodecAudio codec)
}
}
string srs_codec_aac_profile2str(SrsAacProfile aac_profile)
{
switch (aac_profile) {
case SrsAacProfileMain: return "Main";
case SrsAacProfileLC: return "LC";
case SrsAacProfileSSR: return "SSR";
default: return "Other";
}
}
string srs_codec_aac_object2str(SrsAacObjectType aac_object)
{
switch (aac_object) {
case SrsAacObjectTypeAacMain: return "Main";
case SrsAacObjectTypeAacHE: return "HE";
case SrsAacObjectTypeAacHEV2: return "HEv2";
case SrsAacObjectTypeAacLC: return "LC";
case SrsAacObjectTypeAacSSR: return "SSR";
default: return "Other";
}
}
SrsAacObjectType srs_codec_aac_ts2rtmp(SrsAacProfile profile)
{
switch (profile) {
case SrsAacProfileMain: return SrsAacObjectTypeAacMain;
case SrsAacProfileLC: return SrsAacObjectTypeAacLC;
case SrsAacProfileSSR: return SrsAacObjectTypeAacSSR;
default: return SrsAacObjectTypeReserved;
}
}
SrsAacProfile srs_codec_aac_rtmp2ts(SrsAacObjectType object_type)
{
switch (object_type) {
case SrsAacObjectTypeAacMain: return SrsAacProfileMain;
case SrsAacObjectTypeAacHE:
case SrsAacObjectTypeAacHEV2:
case SrsAacObjectTypeAacLC: return SrsAacProfileLC;
case SrsAacObjectTypeAacSSR: return SrsAacProfileSSR;
default: return SrsAacProfileReserved;
}
}
string srs_codec_avc_profile2str(SrsAvcProfile profile)
{
switch (profile) {
case SrsAvcProfileBaseline: return "Baseline";
case SrsAvcProfileConstrainedBaseline: return "Baseline(Constrained)";
case SrsAvcProfileMain: return "Main";
case SrsAvcProfileExtended: return "Extended";
case SrsAvcProfileHigh: return "High";
case SrsAvcProfileHigh10: return "High(10)";
case SrsAvcProfileHigh10Intra: return "High(10+Intra)";
case SrsAvcProfileHigh422: return "High(422)";
case SrsAvcProfileHigh422Intra: return "High(422+Intra)";
case SrsAvcProfileHigh444: return "High(444)";
case SrsAvcProfileHigh444Predictive: return "High(444+Predictive)";
case SrsAvcProfileHigh444Intra: return "High(444+Intra)";
default: return "Other";
}
}
string srs_codec_avc_level2str(SrsAvcLevel level)
{
switch (level) {
case SrsAvcLevel_1: return "1";
case SrsAvcLevel_11: return "1.1";
case SrsAvcLevel_12: return "1.2";
case SrsAvcLevel_13: return "1.3";
case SrsAvcLevel_2: return "2";
case SrsAvcLevel_21: return "2.1";
case SrsAvcLevel_22: return "2.2";
case SrsAvcLevel_3: return "3";
case SrsAvcLevel_31: return "3.1";
case SrsAvcLevel_32: return "3.2";
case SrsAvcLevel_4: return "4";
case SrsAvcLevel_41: return "4.1";
case SrsAvcLevel_5: return "5";
case SrsAvcLevel_51: return "5.1";
default: return "Other";
}
}
string srs_codec_audio_samplerate2str(SrsCodecAudioSampleRate v)
{
switch (v) {
@ -173,25 +89,6 @@ string srs_codec_audio_samplerate2str(SrsCodecAudioSampleRate v)
}
}
/**
* the public data, event HLS disable, others can use it.
*/
// 0 = 5.5 kHz = 5512 Hz
// 1 = 11 kHz = 11025 Hz
// 2 = 22 kHz = 22050 Hz
// 3 = 44 kHz = 44100 Hz
int flv_sample_rates[] = {5512, 11025, 22050, 44100};
// the sample rates in the codec,
// in the sequence header.
int aac_sample_rates[] =
{
96000, 88200, 64000, 48000,
44100, 32000, 24000, 22050,
16000, 12000, 11025, 8000,
7350, 0, 0, 0
};
SrsFlvCodec::SrsFlvCodec()
{
}
@ -206,7 +103,7 @@ bool SrsFlvCodec::video_is_keyframe(char* data, int size)
if (size < 1) {
return false;
}
char frame_type = data[0];
frame_type = (frame_type >> 4) & 0x0F;
@ -224,14 +121,14 @@ bool SrsFlvCodec::video_is_sequence_header(char* data, int size)
if (size < 2) {
return false;
}
char frame_type = data[0];
frame_type = (frame_type >> 4) & 0x0F;
char avc_packet_type = data[1];
return frame_type == SrsCodecVideoAVCFrameKeyFrame
&& avc_packet_type == SrsCodecVideoAVCTypeSequenceHeader;
return frame_type == SrsCodecVideoAVCFrameKeyFrame
&& avc_packet_type == SrsCodecVideoAVCTypeSequenceHeader;
}
bool SrsFlvCodec::audio_is_sequence_header(char* data, int size)
@ -257,7 +154,7 @@ bool SrsFlvCodec::video_is_h264(char* data, int size)
if (size < 1) {
return false;
}
char codec_id = data[0];
codec_id = codec_id & 0x0F;
@ -299,6 +196,25 @@ bool SrsFlvCodec::video_is_acceptable(char* data, int size)
return true;
}
/**
* the public data, event HLS disable, others can use it.
*/
// 0 = 5.5 kHz = 5512 Hz
// 1 = 11 kHz = 11025 Hz
// 2 = 22 kHz = 22050 Hz
// 3 = 44 kHz = 44100 Hz
int flv_sample_rates[] = {5512, 11025, 22050, 44100};
// the sample rates in the codec,
// in the sequence header.
int aac_sample_rates[] =
{
96000, 88200, 64000, 48000,
44100, 32000, 24000, 22050,
16000, 12000, 11025, 8000,
7350, 0, 0, 0
};
string srs_codec_audio_samplesize2str(SrsCodecAudioSampleSize v)
{
switch (v) {
@ -341,16 +257,154 @@ string srs_codec_avc_nalu2str(SrsAvcNaluType nalu_type)
}
}
SrsCodecSampleUnit::SrsCodecSampleUnit()
string srs_codec_aac_profile2str(SrsAacProfile aac_profile)
{
switch (aac_profile) {
case SrsAacProfileMain: return "Main";
case SrsAacProfileLC: return "LC";
case SrsAacProfileSSR: return "SSR";
default: return "Other";
}
}
string srs_codec_aac_object2str(SrsAacObjectType aac_object)
{
switch (aac_object) {
case SrsAacObjectTypeAacMain: return "Main";
case SrsAacObjectTypeAacHE: return "HE";
case SrsAacObjectTypeAacHEV2: return "HEv2";
case SrsAacObjectTypeAacLC: return "LC";
case SrsAacObjectTypeAacSSR: return "SSR";
default: return "Other";
}
}
SrsAacObjectType srs_codec_aac_ts2rtmp(SrsAacProfile profile)
{
switch (profile) {
case SrsAacProfileMain: return SrsAacObjectTypeAacMain;
case SrsAacProfileLC: return SrsAacObjectTypeAacLC;
case SrsAacProfileSSR: return SrsAacObjectTypeAacSSR;
default: return SrsAacObjectTypeReserved;
}
}
SrsAacProfile srs_codec_aac_rtmp2ts(SrsAacObjectType object_type)
{
switch (object_type) {
case SrsAacObjectTypeAacMain: return SrsAacProfileMain;
case SrsAacObjectTypeAacHE:
case SrsAacObjectTypeAacHEV2:
case SrsAacObjectTypeAacLC: return SrsAacProfileLC;
case SrsAacObjectTypeAacSSR: return SrsAacProfileSSR;
default: return SrsAacProfileReserved;
}
}
string srs_codec_avc_profile2str(SrsAvcProfile profile)
{
switch (profile) {
case SrsAvcProfileBaseline: return "Baseline";
case SrsAvcProfileConstrainedBaseline: return "Baseline(Constrained)";
case SrsAvcProfileMain: return "Main";
case SrsAvcProfileExtended: return "Extended";
case SrsAvcProfileHigh: return "High";
case SrsAvcProfileHigh10: return "High(10)";
case SrsAvcProfileHigh10Intra: return "High(10+Intra)";
case SrsAvcProfileHigh422: return "High(422)";
case SrsAvcProfileHigh422Intra: return "High(422+Intra)";
case SrsAvcProfileHigh444: return "High(444)";
case SrsAvcProfileHigh444Predictive: return "High(444+Predictive)";
case SrsAvcProfileHigh444Intra: return "High(444+Intra)";
default: return "Other";
}
}
string srs_codec_avc_level2str(SrsAvcLevel level)
{
switch (level) {
case SrsAvcLevel_1: return "1";
case SrsAvcLevel_11: return "1.1";
case SrsAvcLevel_12: return "1.2";
case SrsAvcLevel_13: return "1.3";
case SrsAvcLevel_2: return "2";
case SrsAvcLevel_21: return "2.1";
case SrsAvcLevel_22: return "2.2";
case SrsAvcLevel_3: return "3";
case SrsAvcLevel_31: return "3.1";
case SrsAvcLevel_32: return "3.2";
case SrsAvcLevel_4: return "4";
case SrsAvcLevel_41: return "4.1";
case SrsAvcLevel_5: return "5";
case SrsAvcLevel_51: return "5.1";
default: return "Other";
}
}
SrsSample::SrsSample()
{
nb_unit = 0;
unit = NULL;
}
SrsSample::~SrsSample()
{
}
SrsCodec::SrsCodec()
{
}
SrsCodec::~SrsCodec()
{
}
SrsAudioCodec::SrsAudioCodec()
{
acodec = SrsCodecAudioForbidden;
sound_rate = SrsCodecAudioSampleRateForbidden;
sound_size = SrsCodecAudioSampleSizeForbidden;
sound_type = SrsCodecAudioSoundTypeForbidden;
aac_packet_type = SrsCodecAudioTypeForbidden;
}
SrsAudioCodec::~SrsAudioCodec()
{
}
SrsCodecFlvTag SrsAudioCodec::codec()
{
return SrsCodecFlvTagAudio;
}
SrsVideoCodec::SrsVideoCodec()
{
size = 0;
bytes = NULL;
frame_type = SrsCodecVideoAVCFrameForbidden;
avc_packet_type = SrsCodecVideoAVCTypeForbidden;
has_idr = has_aud = has_sps_pps = false;
first_nalu_type = SrsAvcNaluTypeForbidden;
}
SrsCodecSampleUnit::~SrsCodecSampleUnit()
SrsVideoCodec::~SrsVideoCodec()
{
}
SrsCodecFlvTag SrsVideoCodec::codec()
{
return SrsCodecFlvTagVideo;
}
SrsFrame::SrsFrame()
{
codec = NULL;
nb_samples = 0;
}
SrsFrame::~SrsFrame()
{
srs_freep(codec);
}
SrsCodecSample::SrsCodecSample()
{
clear();
@ -412,8 +466,6 @@ int SrsCodecSample::add_sample_unit(char* bytes, int size)
return ret;
}
#if !defined(SRS_EXPORT_LIBRTMP)
SrsAvcAacCodec::SrsAvcAacCodec()
{
avc_parse_sps = true;
@ -1205,7 +1257,7 @@ int SrsAvcAacCodec::avc_demux_annexb_format(SrsBuffer* stream, SrsCodecSample* s
}
// got the NALU.
if ((ret = sample->add_sample_unit(p, pp - p)) != ERROR_SUCCESS) {
if ((ret = sample->add_sample_unit(p, (int)(pp - p))) != ERROR_SUCCESS) {
srs_error("annexb add video sample failed. ret=%d", ret);
return ret;
}
@ -1271,5 +1323,3 @@ int SrsAvcAacCodec::avc_demux_ibmf_format(SrsBuffer* stream, SrsCodecSample* sam
return ret;
}
#endif

@ -301,6 +301,7 @@ enum SrsAvcNaluType
{
// Unspecified
SrsAvcNaluTypeReserved = 0,
SrsAvcNaluTypeForbidden = 0,
// Coded slice of a non-IDR picture slice_layer_without_partitioning_rbsp( )
SrsAvcNaluTypeNonIDR = 1,
@ -340,106 +341,10 @@ enum SrsAvcNaluType
std::string srs_codec_avc_nalu2str(SrsAvcNaluType nalu_type);
/**
* the codec sample unit.
* for h.264 video packet, a NALU is a sample unit.
* for aac raw audio packet, a NALU is the entire aac raw data.
* for sequence header, it's not a sample unit.
*/
class SrsCodecSampleUnit
{
public:
/**
* the sample bytes is directly ptr to packet bytes,
* user should never use it when packet destroyed.
*/
int size;
char* bytes;
public:
SrsCodecSampleUnit();
virtual ~SrsCodecSampleUnit();
};
/**
* the samples in the flv audio/video packet.
* the sample used to analysis a video/audio packet,
* split the h.264 NALUs to buffers, or aac raw data to a buffer,
* and decode the video/audio specified infos.
*
* the sample unit:
* a video packet codec in h.264 contains many NALUs, each is a sample unit.
* a audio packet codec in aac is a sample unit.
* @remark, the video/audio sequence header is not sample unit,
* all sequence header stores as extra data,
* @see SrsAvcAacCodec.avc_extra_data and SrsAvcAacCodec.aac_extra_data
* @remark, user must clear all samples before decode a new video/audio packet.
*/
class SrsCodecSample
{
public:
/**
* each audio/video raw data packet will dumps to one or multiple buffers,
* the buffers will write to hls and clear to reset.
* generally, aac audio packet corresponding to one buffer,
* where avc/h264 video packet may contains multiple buffer.
*/
int nb_sample_units;
SrsCodecSampleUnit sample_units[SRS_MAX_CODEC_SAMPLE];
public:
/**
* whether the sample is video sample which demux from video packet.
*/
bool is_video;
/**
* CompositionTime, video_file_format_spec_v10_1.pdf, page 78.
* cts = pts - dts, where dts = flvheader->timestamp.
*/
int32_t cts;
public:
// video specified
SrsCodecVideoAVCFrame frame_type;
SrsCodecVideoAVCType avc_packet_type;
// whether sample_units contains IDR frame.
bool has_idr;
// Whether exists AUD NALU.
bool has_aud;
// Whether exists SPS/PPS NALU.
bool has_sps_pps;
// The first nalu type.
SrsAvcNaluType first_nalu_type;
public:
// audio specified
SrsCodecAudio acodec;
// audio aac specified.
SrsCodecAudioSampleRate sound_rate;
SrsCodecAudioSampleSize sound_size;
SrsCodecAudioSoundType sound_type;
SrsCodecAudioType aac_packet_type;
public:
SrsCodecSample();
virtual ~SrsCodecSample();
public:
/**
* clear all samples.
* the sample units never copy the bytes, it directly use the ptr,
* so when video/audio packet is destroyed, the sample must be clear.
* in a word, user must clear sample before demux it.
* @remark demux sample use SrsAvcAacCodec.audio_aac_demux or video_avc_demux.
*/
void clear();
/**
* add the a sample unit, it's a h.264 NALU or aac raw data.
* the sample unit directly use the ptr of packet bytes,
* so user must never use sample unit when packet is destroyed.
* in a word, user must clear sample before demux it.
*/
int add_sample_unit(char* bytes, int size);
};
/**
* the avc payload format, must be ibmf or annexb format.
* we guess by annexb first, then ibmf for the first time,
* and we always use the guessed format for the next time.
*/
* the avc payload format, must be ibmf or annexb format.
* we guess by annexb first, then ibmf for the first time,
* and we always use the guessed format for the next time.
*/
enum SrsAvcPayloadFormat
{
SrsAvcPayloadFormatGuess = 0,
@ -448,9 +353,9 @@ enum SrsAvcPayloadFormat
};
/**
* the aac profile, for ADTS(HLS/TS)
* @see https://github.com/ossrs/srs/issues/310
*/
* the aac profile, for ADTS(HLS/TS)
* @see https://github.com/ossrs/srs/issues/310
*/
enum SrsAacProfile
{
SrsAacProfileReserved = 3,
@ -463,10 +368,10 @@ enum SrsAacProfile
std::string srs_codec_aac_profile2str(SrsAacProfile aac_profile);
/**
* the aac object type, for RTMP sequence header
* for AudioSpecificConfig, @see ISO_IEC_14496-3-AAC-2001.pdf, page 33
* for audioObjectType, @see ISO_IEC_14496-3-AAC-2001.pdf, page 23
*/
* the aac object type, for RTMP sequence header
* for AudioSpecificConfig, @see ISO_IEC_14496-3-AAC-2001.pdf, page 33
* for audioObjectType, @see ISO_IEC_14496-3-AAC-2001.pdf, page 23
*/
enum SrsAacObjectType
{
SrsAacObjectTypeReserved = 0,
@ -489,9 +394,9 @@ SrsAacObjectType srs_codec_aac_ts2rtmp(SrsAacProfile profile);
SrsAacProfile srs_codec_aac_rtmp2ts(SrsAacObjectType object_type);
/**
* the profile for avc/h.264.
* @see Annex A Profiles and levels, ISO_IEC_14496-10-AVC-2003.pdf, page 205.
*/
* the profile for avc/h.264.
* @see Annex A Profiles and levels, ISO_IEC_14496-10-AVC-2003.pdf, page 205.
*/
enum SrsAvcProfile
{
SrsAvcProfileReserved = 0,
@ -515,9 +420,9 @@ enum SrsAvcProfile
std::string srs_codec_avc_profile2str(SrsAvcProfile profile);
/**
* the level for avc/h.264.
* @see Annex A Profiles and levels, ISO_IEC_14496-10-AVC-2003.pdf, page 207.
*/
* the level for avc/h.264.
* @see Annex A Profiles and levels, ISO_IEC_14496-10-AVC-2003.pdf, page 207.
*/
enum SrsAvcLevel
{
SrsAvcLevelReserved = 0,
@ -539,7 +444,175 @@ enum SrsAvcLevel
};
std::string srs_codec_avc_level2str(SrsAvcLevel level);
#if !defined(SRS_EXPORT_LIBRTMP)
/**
* A sample is the unit of frame.
* It's a NALU for H.264.
* It's the whole AAC raw data for AAC.
* @remark Neither SPS/PPS or ASC is sample unit, it's codec sequence header.
*/
class SrsSample
{
public:
// The size of unit.
int nb_unit;
// The ptr of unit, user must manage it.
char* unit;
public:
SrsSample();
virtual ~SrsSample();
};
/**
* The codec is the information of encoder,
* corresponding to the sequence header of FLV,
* parsed to detail info.
*/
class SrsCodec
{
public:
SrsCodec();
virtual ~SrsCodec();
public:
// Get the codec type.
virtual SrsCodecFlvTag codec() = 0;
};
/**
* The audio codec info.
*/
class SrsAudioCodec : public SrsCodec
{
public:
// audio specified
SrsCodecAudio acodec;
// audio aac specified.
SrsCodecAudioSampleRate sound_rate;
SrsCodecAudioSampleSize sound_size;
SrsCodecAudioSoundType sound_type;
SrsCodecAudioType aac_packet_type;
public:
SrsAudioCodec();
virtual ~SrsAudioCodec();
public:
virtual SrsCodecFlvTag codec();
};
/**
* The video codec info.
*/
class SrsVideoCodec : public SrsCodec
{
public:
// video specified
SrsCodecVideoAVCFrame frame_type;
SrsCodecVideoAVCType avc_packet_type;
// whether sample_units contains IDR frame.
bool has_idr;
// Whether exists AUD NALU.
bool has_aud;
// Whether exists SPS/PPS NALU.
bool has_sps_pps;
// The first nalu type.
SrsAvcNaluType first_nalu_type;
public:
SrsVideoCodec();
virtual ~SrsVideoCodec();
public:
virtual SrsCodecFlvTag codec();
};
/**
* A codec frame, consists of a codec and a group of samples.
*/
class SrsFrame
{
public:
// The codec info of frame.
SrsCodec* codec;
// The actual parsed number of samples.
int nb_samples;
// The sampels cache.
SrsSample samples[SRS_MAX_CODEC_SAMPLE];
public:
SrsFrame();
virtual ~SrsFrame();
};
/**
* the samples in the flv audio/video packet.
* the sample used to analysis a video/audio packet,
* split the h.264 NALUs to buffers, or aac raw data to a buffer,
* and decode the video/audio specified infos.
*
* the sample unit:
* a video packet codec in h.264 contains many NALUs, each is a sample unit.
* a audio packet codec in aac is a sample unit.
* @remark, the video/audio sequence header is not sample unit,
* all sequence header stores as extra data,
* @see SrsAvcAacCodec.avc_extra_data and SrsAvcAacCodec.aac_extra_data
* @remark, user must clear all samples before decode a new video/audio packet.
*/
class SrsCodecSample
{
public:
/**
* each audio/video raw data packet will dumps to one or multiple buffers,
* the buffers will write to hls and clear to reset.
* generally, aac audio packet corresponding to one buffer,
* where avc/h264 video packet may contains multiple buffer.
*/
int nb_sample_units;
SrsCodecSampleUnit sample_units[SRS_MAX_CODEC_SAMPLE];
public:
/**
* whether the sample is video sample which demux from video packet.
*/
bool is_video;
/**
* CompositionTime, video_file_format_spec_v10_1.pdf, page 78.
* cts = pts - dts, where dts = flvheader->timestamp.
*/
int32_t cts;
public:
// video specified
SrsCodecVideoAVCFrame frame_type;
SrsCodecVideoAVCType avc_packet_type;
// whether sample_units contains IDR frame.
bool has_idr;
// Whether exists AUD NALU.
bool has_aud;
// Whether exists SPS/PPS NALU.
bool has_sps_pps;
// The first nalu type.
SrsAvcNaluType first_nalu_type;
public:
// audio specified
SrsCodecAudio acodec;
// audio aac specified.
SrsCodecAudioSampleRate sound_rate;
SrsCodecAudioSampleSize sound_size;
SrsCodecAudioSoundType sound_type;
SrsCodecAudioType aac_packet_type;
public:
SrsCodecSample();
virtual ~SrsCodecSample();
public:
/**
* clear all samples.
* the sample units never copy the bytes, it directly use the ptr,
* so when video/audio packet is destroyed, the sample must be clear.
* in a word, user must clear sample before demux it.
* @remark demux sample use SrsAvcAacCodec.audio_aac_demux or video_avc_demux.
*/
void clear();
/**
* add the a sample unit, it's a h.264 NALU or aac raw data.
* the sample unit directly use the ptr of packet bytes,
* so user must never use sample unit when packet is destroyed.
* in a word, user must clear sample before demux it.
*/
int add_sample_unit(char* bytes, int size);
};
/**
* the h264/avc and aac codec, for media stream.
@ -682,5 +755,3 @@ private:
#endif
#endif

@ -0,0 +1,66 @@
/*
The MIT License (MIT)
Copyright (c) 2013-2017 SRS(ossrs)
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 <srs_protocol_format.hpp>
#include <srs_kernel_error.hpp>
#include <srs_kernel_codec.hpp>
#include <srs_rtmp_stack.hpp>
SrsFormat::SrsFormat()
{
audio = video = NULL;
}
SrsFormat::~SrsFormat()
{
srs_freep(audio);
srs_freep(video);
}
int SrsFormat::initialize()
{
return ERROR_SUCCESS;
}
int SrsFormat::on_metadata(SrsOnMetaDataPacket* meta)
{
int ret = ERROR_SUCCESS;
// TODO: FIXME: Try to initialize format from metadata.
return ret;
}
int SrsFormat::on_audio(SrsSharedPtrMessage* shared_audio)
{
int ret = ERROR_SUCCESS;
return ret;
}
int SrsFormat::on_video(SrsSharedPtrMessage* shared_video, bool is_sequence_header)
{
int ret = ERROR_SUCCESS;
return ret;
}

@ -0,0 +1,62 @@
/*
The MIT License (MIT)
Copyright (c) 2013-2017 SRS(ossrs)
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 SRS_PROTOCOL_FORMAT_HPP
#define SRS_PROTOCOL_FORMAT_HPP
/*
#include <srs_protocol_format.hpp>
*/
#include <srs_core.hpp>
class SrsFrame;
class SrsOnMetaDataPacket;
class SrsSharedPtrMessage;
/**
* A codec format, including one or many stream, each stream identified by a frame.
* For example, a typical RTMP stream format, consits of a video and audio frame.
* Maybe some RTMP stream only has a audio stream, for instance, redio application.
*/
class SrsFormat
{
public:
SrsFrame* audio;
SrsFrame* video;
public:
SrsFormat();
virtual ~SrsFormat();
public:
// Initialize the format.
virtual int initialize();
// Initialize the format from metadata, optional.
virtual int on_metadata(SrsOnMetaDataPacket* meta);
// When got a parsed audio packet.
virtual int on_audio(SrsSharedPtrMessage* shared_audio);
// When got a parsed video packet.
virtual int on_video(SrsSharedPtrMessage* shared_video, bool is_sequence_header);
};
#endif
Loading…
Cancel
Save