1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

For #299, refine the codec info structure.

This commit is contained in:
winlin 2017-02-11 23:09:23 +08:00
parent 5e419c66f8
commit c4a510b834
10 changed files with 574 additions and 298 deletions

View file

@ -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,6 +78,185 @@ string srs_codec_audio2str(SrsCodecAudio codec)
}
}
string srs_codec_audio_samplerate2str(SrsCodecAudioSampleRate v)
{
switch (v) {
case SrsCodecAudioSampleRate5512: return "5512";
case SrsCodecAudioSampleRate11025: return "11025";
case SrsCodecAudioSampleRate22050: return "22050";
case SrsCodecAudioSampleRate44100: return "44100";
default: return "Other";
}
}
SrsFlvCodec::SrsFlvCodec()
{
}
SrsFlvCodec::~SrsFlvCodec()
{
}
bool SrsFlvCodec::video_is_keyframe(char* data, int size)
{
// 2bytes required.
if (size < 1) {
return false;
}
char frame_type = data[0];
frame_type = (frame_type >> 4) & 0x0F;
return frame_type == SrsCodecVideoAVCFrameKeyFrame;
}
bool SrsFlvCodec::video_is_sequence_header(char* data, int size)
{
// sequence header only for h264
if (!video_is_h264(data, size)) {
return false;
}
// 2bytes required.
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;
}
bool SrsFlvCodec::audio_is_sequence_header(char* data, int size)
{
// sequence header only for aac
if (!audio_is_aac(data, size)) {
return false;
}
// 2bytes required.
if (size < 2) {
return false;
}
char aac_packet_type = data[1];
return aac_packet_type == SrsCodecAudioTypeSequenceHeader;
}
bool SrsFlvCodec::video_is_h264(char* data, int size)
{
// 1bytes required.
if (size < 1) {
return false;
}
char codec_id = data[0];
codec_id = codec_id & 0x0F;
return codec_id == SrsCodecVideoAVC;
}
bool SrsFlvCodec::audio_is_aac(char* data, int size)
{
// 1bytes required.
if (size < 1) {
return false;
}
char sound_format = data[0];
sound_format = (sound_format >> 4) & 0x0F;
return sound_format == SrsCodecAudioAAC;
}
bool SrsFlvCodec::video_is_acceptable(char* data, int size)
{
// 1bytes required.
if (size < 1) {
return false;
}
char frame_type = data[0];
char codec_id = frame_type & 0x0f;
frame_type = (frame_type >> 4) & 0x0f;
if (frame_type < 1 || frame_type > 5) {
return false;
}
if (codec_id < 2 || codec_id > 7) {
return false;
}
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) {
case SrsCodecAudioSampleSize16bit: return "16bits";
case SrsCodecAudioSampleSize8bit: return "8bits";
default: return "Other";
}
}
string srs_codec_audio_channels2str(SrsCodecAudioSoundType v)
{
switch (v) {
case SrsCodecAudioSoundTypeStereo: return "Stereo";
case SrsCodecAudioSoundTypeMono: return "Mono";
default: return "Other";
}
}
string srs_codec_avc_nalu2str(SrsAvcNaluType nalu_type)
{
switch (nalu_type) {
case SrsAvcNaluTypeNonIDR: return "NonIDR";
case SrsAvcNaluTypeDataPartitionA: return "DataPartitionA";
case SrsAvcNaluTypeDataPartitionB: return "DataPartitionB";
case SrsAvcNaluTypeDataPartitionC: return "DataPartitionC";
case SrsAvcNaluTypeIDR: return "IDR";
case SrsAvcNaluTypeSEI: return "SEI";
case SrsAvcNaluTypeSPS: return "SPS";
case SrsAvcNaluTypePPS: return "PPS";
case SrsAvcNaluTypeAccessUnitDelimiter: return "AccessUnitDelimiter";
case SrsAvcNaluTypeEOSequence: return "EOSequence";
case SrsAvcNaluTypeEOStream: return "EOStream";
case SrsAvcNaluTypeFilterData: return "FilterData";
case SrsAvcNaluTypeSPSExt: return "SPSExt";
case SrsAvcNaluTypePrefixNALU: return "PrefixNALU";
case SrsAvcNaluTypeSubsetSPS: return "SubsetSPS";
case SrsAvcNaluTypeLayerWithoutPartition: return "LayerWithoutPartition";
case SrsAvcNaluTypeCodedSliceExt: return "CodedSliceExt";
case SrsAvcNaluTypeReserved: default: return "Other";
}
}
string srs_codec_aac_profile2str(SrsAacProfile aac_profile)
{
switch (aac_profile) {
@ -162,193 +341,68 @@ string srs_codec_avc_level2str(SrsAvcLevel level)
}
}
string srs_codec_audio_samplerate2str(SrsCodecAudioSampleRate v)
SrsSample::SrsSample()
{
switch (v) {
case SrsCodecAudioSampleRate5512: return "5512";
case SrsCodecAudioSampleRate11025: return "11025";
case SrsCodecAudioSampleRate22050: return "22050";
case SrsCodecAudioSampleRate44100: return "44100";
default: return "Other";
}
nb_unit = 0;
unit = NULL;
}
/**
* 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()
SrsSample::~SrsSample()
{
}
SrsFlvCodec::~SrsFlvCodec()
SrsCodec::SrsCodec()
{
}
bool SrsFlvCodec::video_is_keyframe(char* data, int size)
SrsCodec::~SrsCodec()
{
// 2bytes required.
if (size < 1) {
return false;
}
char frame_type = data[0];
frame_type = (frame_type >> 4) & 0x0F;
return frame_type == SrsCodecVideoAVCFrameKeyFrame;
}
bool SrsFlvCodec::video_is_sequence_header(char* data, int size)
SrsAudioCodec::SrsAudioCodec()
{
// sequence header only for h264
if (!video_is_h264(data, size)) {
return false;
}
// 2bytes required.
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;
acodec = SrsCodecAudioForbidden;
sound_rate = SrsCodecAudioSampleRateForbidden;
sound_size = SrsCodecAudioSampleSizeForbidden;
sound_type = SrsCodecAudioSoundTypeForbidden;
aac_packet_type = SrsCodecAudioTypeForbidden;
}
bool SrsFlvCodec::audio_is_sequence_header(char* data, int size)
SrsAudioCodec::~SrsAudioCodec()
{
// sequence header only for aac
if (!audio_is_aac(data, size)) {
return false;
}
// 2bytes required.
if (size < 2) {
return false;
}
char aac_packet_type = data[1];
return aac_packet_type == SrsCodecAudioTypeSequenceHeader;
}
bool SrsFlvCodec::video_is_h264(char* data, int size)
SrsCodecFlvTag SrsAudioCodec::codec()
{
// 1bytes required.
if (size < 1) {
return false;
}
char codec_id = data[0];
codec_id = codec_id & 0x0F;
return codec_id == SrsCodecVideoAVC;
return SrsCodecFlvTagAudio;
}
bool SrsFlvCodec::audio_is_aac(char* data, int size)
SrsVideoCodec::SrsVideoCodec()
{
// 1bytes required.
if (size < 1) {
return false;
}
char sound_format = data[0];
sound_format = (sound_format >> 4) & 0x0F;
return sound_format == SrsCodecAudioAAC;
frame_type = SrsCodecVideoAVCFrameForbidden;
avc_packet_type = SrsCodecVideoAVCTypeForbidden;
has_idr = has_aud = has_sps_pps = false;
first_nalu_type = SrsAvcNaluTypeForbidden;
}
bool SrsFlvCodec::video_is_acceptable(char* data, int size)
SrsVideoCodec::~SrsVideoCodec()
{
// 1bytes required.
if (size < 1) {
return false;
}
char frame_type = data[0];
char codec_id = frame_type & 0x0f;
frame_type = (frame_type >> 4) & 0x0f;
if (frame_type < 1 || frame_type > 5) {
return false;
}
if (codec_id < 2 || codec_id > 7) {
return false;
}
return true;
}
string srs_codec_audio_samplesize2str(SrsCodecAudioSampleSize v)
SrsCodecFlvTag SrsVideoCodec::codec()
{
switch (v) {
case SrsCodecAudioSampleSize16bit: return "16bits";
case SrsCodecAudioSampleSize8bit: return "8bits";
default: return "Other";
}
return SrsCodecFlvTagVideo;
}
string srs_codec_audio_channels2str(SrsCodecAudioSoundType v)
SrsFrame::SrsFrame()
{
switch (v) {
case SrsCodecAudioSoundTypeStereo: return "Stereo";
case SrsCodecAudioSoundTypeMono: return "Mono";
default: return "Other";
}
codec = NULL;
nb_samples = 0;
}
string srs_codec_avc_nalu2str(SrsAvcNaluType nalu_type)
{
switch (nalu_type) {
case SrsAvcNaluTypeNonIDR: return "NonIDR";
case SrsAvcNaluTypeDataPartitionA: return "DataPartitionA";
case SrsAvcNaluTypeDataPartitionB: return "DataPartitionB";
case SrsAvcNaluTypeDataPartitionC: return "DataPartitionC";
case SrsAvcNaluTypeIDR: return "IDR";
case SrsAvcNaluTypeSEI: return "SEI";
case SrsAvcNaluTypeSPS: return "SPS";
case SrsAvcNaluTypePPS: return "PPS";
case SrsAvcNaluTypeAccessUnitDelimiter: return "AccessUnitDelimiter";
case SrsAvcNaluTypeEOSequence: return "EOSequence";
case SrsAvcNaluTypeEOStream: return "EOStream";
case SrsAvcNaluTypeFilterData: return "FilterData";
case SrsAvcNaluTypeSPSExt: return "SPSExt";
case SrsAvcNaluTypePrefixNALU: return "PrefixNALU";
case SrsAvcNaluTypeSubsetSPS: return "SubsetSPS";
case SrsAvcNaluTypeLayerWithoutPartition: return "LayerWithoutPartition";
case SrsAvcNaluTypeCodedSliceExt: return "CodedSliceExt";
case SrsAvcNaluTypeReserved: default: return "Other";
}
}
SrsCodecSampleUnit::SrsCodecSampleUnit()
{
size = 0;
bytes = NULL;
}
SrsCodecSampleUnit::~SrsCodecSampleUnit()
SrsFrame::~SrsFrame()
{
srs_freep(codec);
}
SrsCodecSample::SrsCodecSample()
@ -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

View file

@ -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,23 +341,201 @@ 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
* 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,
SrsAvcPayloadFormatAnnexb,
SrsAvcPayloadFormatIbmf,
};
/**
* the aac profile, for ADTS(HLS/TS)
* @see https://github.com/ossrs/srs/issues/310
*/
enum SrsAacProfile
{
SrsAacProfileReserved = 3,
// @see 7.1 Profiles, aac-iso-13818-7.pdf, page 40
SrsAacProfileMain = 0,
SrsAacProfileLC = 1,
SrsAacProfileSSR = 2,
};
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
*/
enum SrsAacObjectType
{
SrsAacObjectTypeReserved = 0,
// Table 1.1 - Audio Object Type definition
// @see @see ISO_IEC_14496-3-AAC-2001.pdf, page 23
SrsAacObjectTypeAacMain = 1,
SrsAacObjectTypeAacLC = 2,
SrsAacObjectTypeAacSSR = 3,
// AAC HE = LC+SBR
SrsAacObjectTypeAacHE = 5,
// AAC HEv2 = LC+SBR+PS
SrsAacObjectTypeAacHEV2 = 29,
};
std::string srs_codec_aac_object2str(SrsAacObjectType aac_object);
// ts/hls/adts audio header profile to RTMP sequence header object type.
SrsAacObjectType srs_codec_aac_ts2rtmp(SrsAacProfile profile);
// RTMP sequence header object type to ts/hls/adts audio header 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.
*/
enum SrsAvcProfile
{
SrsAvcProfileReserved = 0,
// @see ffmpeg, libavcodec/avcodec.h:2713
SrsAvcProfileBaseline = 66,
// FF_PROFILE_H264_CONSTRAINED (1<<9) // 8+1; constraint_set1_flag
// FF_PROFILE_H264_CONSTRAINED_BASELINE (66|FF_PROFILE_H264_CONSTRAINED)
SrsAvcProfileConstrainedBaseline = 578,
SrsAvcProfileMain = 77,
SrsAvcProfileExtended = 88,
SrsAvcProfileHigh = 100,
SrsAvcProfileHigh10 = 110,
SrsAvcProfileHigh10Intra = 2158,
SrsAvcProfileHigh422 = 122,
SrsAvcProfileHigh422Intra = 2170,
SrsAvcProfileHigh444 = 144,
SrsAvcProfileHigh444Predictive = 244,
SrsAvcProfileHigh444Intra = 2192,
};
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.
*/
enum SrsAvcLevel
{
SrsAvcLevelReserved = 0,
SrsAvcLevel_1 = 10,
SrsAvcLevel_11 = 11,
SrsAvcLevel_12 = 12,
SrsAvcLevel_13 = 13,
SrsAvcLevel_2 = 20,
SrsAvcLevel_21 = 21,
SrsAvcLevel_22 = 22,
SrsAvcLevel_3 = 30,
SrsAvcLevel_31 = 31,
SrsAvcLevel_32 = 32,
SrsAvcLevel_4 = 40,
SrsAvcLevel_41 = 41,
SrsAvcLevel_5 = 50,
SrsAvcLevel_51 = 51,
};
std::string srs_codec_avc_level2str(SrsAvcLevel level);
/**
* 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 sample bytes is directly ptr to packet bytes,
* user should never use it when packet destroyed.
*/
int size;
char* bytes;
// The size of unit.
int nb_unit;
// The ptr of unit, user must manage it.
char* unit;
public:
SrsCodecSampleUnit();
virtual ~SrsCodecSampleUnit();
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();
};
/**
@ -435,112 +614,6 @@ public:
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.
*/
enum SrsAvcPayloadFormat
{
SrsAvcPayloadFormatGuess = 0,
SrsAvcPayloadFormatAnnexb,
SrsAvcPayloadFormatIbmf,
};
/**
* the aac profile, for ADTS(HLS/TS)
* @see https://github.com/ossrs/srs/issues/310
*/
enum SrsAacProfile
{
SrsAacProfileReserved = 3,
// @see 7.1 Profiles, aac-iso-13818-7.pdf, page 40
SrsAacProfileMain = 0,
SrsAacProfileLC = 1,
SrsAacProfileSSR = 2,
};
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
*/
enum SrsAacObjectType
{
SrsAacObjectTypeReserved = 0,
// Table 1.1 - Audio Object Type definition
// @see @see ISO_IEC_14496-3-AAC-2001.pdf, page 23
SrsAacObjectTypeAacMain = 1,
SrsAacObjectTypeAacLC = 2,
SrsAacObjectTypeAacSSR = 3,
// AAC HE = LC+SBR
SrsAacObjectTypeAacHE = 5,
// AAC HEv2 = LC+SBR+PS
SrsAacObjectTypeAacHEV2 = 29,
};
std::string srs_codec_aac_object2str(SrsAacObjectType aac_object);
// ts/hls/adts audio header profile to RTMP sequence header object type.
SrsAacObjectType srs_codec_aac_ts2rtmp(SrsAacProfile profile);
// RTMP sequence header object type to ts/hls/adts audio header 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.
*/
enum SrsAvcProfile
{
SrsAvcProfileReserved = 0,
// @see ffmpeg, libavcodec/avcodec.h:2713
SrsAvcProfileBaseline = 66,
// FF_PROFILE_H264_CONSTRAINED (1<<9) // 8+1; constraint_set1_flag
// FF_PROFILE_H264_CONSTRAINED_BASELINE (66|FF_PROFILE_H264_CONSTRAINED)
SrsAvcProfileConstrainedBaseline = 578,
SrsAvcProfileMain = 77,
SrsAvcProfileExtended = 88,
SrsAvcProfileHigh = 100,
SrsAvcProfileHigh10 = 110,
SrsAvcProfileHigh10Intra = 2158,
SrsAvcProfileHigh422 = 122,
SrsAvcProfileHigh422Intra = 2170,
SrsAvcProfileHigh444 = 144,
SrsAvcProfileHigh444Predictive = 244,
SrsAvcProfileHigh444Intra = 2192,
};
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.
*/
enum SrsAvcLevel
{
SrsAvcLevelReserved = 0,
SrsAvcLevel_1 = 10,
SrsAvcLevel_11 = 11,
SrsAvcLevel_12 = 12,
SrsAvcLevel_13 = 13,
SrsAvcLevel_2 = 20,
SrsAvcLevel_21 = 21,
SrsAvcLevel_22 = 22,
SrsAvcLevel_3 = 30,
SrsAvcLevel_31 = 31,
SrsAvcLevel_32 = 32,
SrsAvcLevel_4 = 40,
SrsAvcLevel_41 = 41,
SrsAvcLevel_5 = 50,
SrsAvcLevel_51 = 51,
};
std::string srs_codec_avc_level2str(SrsAvcLevel level);
#if !defined(SRS_EXPORT_LIBRTMP)
/**
* the h264/avc and aac codec, for media stream.
*
@ -682,5 +755,3 @@ private:
#endif
#endif