mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
fix #133, support push rtsp to srs. 2.0.120.
This commit is contained in:
parent
a954040d29
commit
9d233db27e
11 changed files with 670 additions and 80 deletions
|
@ -279,58 +279,12 @@ int SrsAvcAacCodec::audio_aac_demux(char* data, int size, SrsCodecSample* sample
|
|||
srs_freep(aac_extra_data);
|
||||
aac_extra_data = new char[aac_extra_size];
|
||||
memcpy(aac_extra_data, stream->data() + stream->pos(), aac_extra_size);
|
||||
}
|
||||
|
||||
// only need to decode the first 2bytes:
|
||||
// audioObjectType, aac_profile, 5bits.
|
||||
// samplingFrequencyIndex, aac_sample_rate, 4bits.
|
||||
// channelConfiguration, aac_channels, 4bits
|
||||
if (!stream->require(2)) {
|
||||
ret = ERROR_HLS_DECODE_ERROR;
|
||||
srs_error("audio codec decode aac sequence header failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
u_int8_t profile_ObjectType = stream->read_1bytes();
|
||||
u_int8_t samplingFrequencyIndex = stream->read_1bytes();
|
||||
|
||||
aac_channels = (samplingFrequencyIndex >> 3) & 0x0f;
|
||||
samplingFrequencyIndex = ((profile_ObjectType << 1) & 0x0e) | ((samplingFrequencyIndex >> 7) & 0x01);
|
||||
profile_ObjectType = (profile_ObjectType >> 3) & 0x1f;
|
||||
|
||||
// set the aac sample rate.
|
||||
aac_sample_rate = samplingFrequencyIndex;
|
||||
|
||||
// the profile = object_id + 1
|
||||
// @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 78,
|
||||
// Table 1. A.9 ¨C MPEG-2 Audio profiles and MPEG-4 Audio object types
|
||||
aac_profile = profile_ObjectType + 1;
|
||||
|
||||
// the valid aac profile:
|
||||
// MPEG-2 profile
|
||||
// Main profile (ID == 1)
|
||||
// Low Complexity profile (LC) (ID == 2)
|
||||
// Scalable Sampling Rate profile (SSR) (ID == 3)
|
||||
// (reserved) (ID == 4)
|
||||
// @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 78,
|
||||
// Table 1. A.9 ¨C MPEG-2 Audio profiles and MPEG-4 Audio object types
|
||||
if (aac_profile > 4) {
|
||||
ret = ERROR_HLS_DECODE_ERROR;
|
||||
srs_error("audio codec decode aac sequence header failed, "
|
||||
"adts object=%d invalid. ret=%d", profile_ObjectType, ret);
|
||||
return ret;
|
||||
// demux the sequence header.
|
||||
if ((ret = audio_aac_sequence_header_demux(aac_extra_data, aac_extra_size)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: FIXME: to support aac he/he-v2, see: ngx_rtmp_codec_parse_aac_header
|
||||
// @see: https://github.com/winlinvip/nginx-rtmp-module/commit/3a5f9eea78fc8d11e8be922aea9ac349b9dcbfc2
|
||||
//
|
||||
// donot force to LC, @see: https://github.com/winlinvip/simple-rtmp-server/issues/81
|
||||
// the source will print the sequence header info.
|
||||
//if (aac_profile > 3) {
|
||||
// Mark all extended profiles as LC
|
||||
// to make Android as happy as possible.
|
||||
// @see: ngx_rtmp_hls_parse_aac_header
|
||||
//aac_profile = 1;
|
||||
//}
|
||||
} else if (aac_packet_type == SrsCodecAudioTypeRawData) {
|
||||
// ensure the sequence header demuxed
|
||||
if (aac_extra_size <= 0 || !aac_extra_data) {
|
||||
|
@ -403,6 +357,68 @@ int SrsAvcAacCodec::audio_mp3_demux(char* data, int size, SrsCodecSample* sample
|
|||
return ret;
|
||||
}
|
||||
|
||||
int SrsAvcAacCodec::audio_aac_sequence_header_demux(char* data, int size)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
if ((ret = stream->initialize(data, size)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// only need to decode the first 2bytes:
|
||||
// audioObjectType, aac_profile, 5bits.
|
||||
// samplingFrequencyIndex, aac_sample_rate, 4bits.
|
||||
// channelConfiguration, aac_channels, 4bits
|
||||
if (!stream->require(2)) {
|
||||
ret = ERROR_HLS_DECODE_ERROR;
|
||||
srs_error("audio codec decode aac sequence header failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
u_int8_t profile_ObjectType = stream->read_1bytes();
|
||||
u_int8_t samplingFrequencyIndex = stream->read_1bytes();
|
||||
|
||||
aac_channels = (samplingFrequencyIndex >> 3) & 0x0f;
|
||||
samplingFrequencyIndex = ((profile_ObjectType << 1) & 0x0e) | ((samplingFrequencyIndex >> 7) & 0x01);
|
||||
profile_ObjectType = (profile_ObjectType >> 3) & 0x1f;
|
||||
|
||||
// set the aac sample rate.
|
||||
aac_sample_rate = samplingFrequencyIndex;
|
||||
|
||||
// the profile = object_id + 1
|
||||
// @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 78,
|
||||
// Table 1. A.9 ¨C MPEG-2 Audio profiles and MPEG-4 Audio object types
|
||||
aac_profile = profile_ObjectType + 1;
|
||||
|
||||
// the valid aac profile:
|
||||
// MPEG-2 profile
|
||||
// Main profile (ID == 1)
|
||||
// Low Complexity profile (LC) (ID == 2)
|
||||
// Scalable Sampling Rate profile (SSR) (ID == 3)
|
||||
// (reserved) (ID == 4)
|
||||
// @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 78,
|
||||
// Table 1. A.9 ¨C MPEG-2 Audio profiles and MPEG-4 Audio object types
|
||||
if (aac_profile > 4) {
|
||||
ret = ERROR_HLS_DECODE_ERROR;
|
||||
srs_error("audio codec decode aac sequence header failed, "
|
||||
"adts object=%d invalid. ret=%d", profile_ObjectType, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// TODO: FIXME: to support aac he/he-v2, see: ngx_rtmp_codec_parse_aac_header
|
||||
// @see: https://github.com/winlinvip/nginx-rtmp-module/commit/3a5f9eea78fc8d11e8be922aea9ac349b9dcbfc2
|
||||
//
|
||||
// donot force to LC, @see: https://github.com/winlinvip/simple-rtmp-server/issues/81
|
||||
// the source will print the sequence header info.
|
||||
//if (aac_profile > 3) {
|
||||
// Mark all extended profiles as LC
|
||||
// to make Android as happy as possible.
|
||||
// @see: ngx_rtmp_hls_parse_aac_header
|
||||
//aac_profile = 1;
|
||||
//}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsAvcAacCodec::video_avc_demux(char* data, int size, SrsCodecSample* sample)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
|
|
@ -475,6 +475,11 @@ public:
|
|||
* demux the h.264 NALUs to sampe units.
|
||||
*/
|
||||
virtual int video_avc_demux(char* data, int size, SrsCodecSample* sample);
|
||||
public:
|
||||
/**
|
||||
* directly demux the sequence header, without RTMP packet header.
|
||||
*/
|
||||
virtual int audio_aac_sequence_header_demux(char* data, int size);
|
||||
private:
|
||||
/**
|
||||
* when avc packet type is SrsCodecVideoAVCTypeSequenceHeader,
|
||||
|
|
|
@ -147,6 +147,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define ERROR_RTP_HEADER_CORRUPT 2044
|
||||
#define ERROR_RTP_TYPE96_CORRUPT 2045
|
||||
#define ERROR_RTP_TYPE97_CORRUPT 2046
|
||||
#define ERROR_RTSP_AUDIO_CONFIG 2047
|
||||
//
|
||||
// system control message,
|
||||
// not an error, but special control logic.
|
||||
|
|
|
@ -621,3 +621,41 @@ char* srs_av_base64_encode(char* out, int out_size, const u_int8_t* in, int in_s
|
|||
return ret;
|
||||
}
|
||||
|
||||
#define SPACE_CHARS " \t\r\n"
|
||||
|
||||
int av_toupper(int c)
|
||||
{
|
||||
if (c >= 'a' && c <= 'z') {
|
||||
c ^= 0x20;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
int ff_hex_to_data(u_int8_t* data, const char* p)
|
||||
{
|
||||
int c, len, v;
|
||||
|
||||
len = 0;
|
||||
v = 1;
|
||||
for (;;) {
|
||||
p += strspn(p, SPACE_CHARS);
|
||||
if (*p == '\0')
|
||||
break;
|
||||
c = av_toupper((unsigned char) *p++);
|
||||
if (c >= '0' && c <= '9')
|
||||
c = c - '0';
|
||||
else if (c >= 'A' && c <= 'F')
|
||||
c = c - 'A' + 10;
|
||||
else
|
||||
break;
|
||||
v = (v << 4) | c;
|
||||
if (v & 0x100) {
|
||||
if (data)
|
||||
data[len] = v;
|
||||
len++;
|
||||
v = 1;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
|
|
|
@ -115,5 +115,12 @@ extern char* srs_av_base64_encode(char* out, int out_size, const u_int8_t* in, i
|
|||
*/
|
||||
#define SRS_AV_BASE64_SIZE(x) (((x)+2) / 3 * 4 + 1)
|
||||
|
||||
/**
|
||||
* convert hex string to data.
|
||||
* for example, p=config='139056E5A0'
|
||||
* output hex to data={0x13, 0x90, 0x56, 0xe5, 0xa0}
|
||||
*/
|
||||
extern int ff_hex_to_data(u_int8_t* data, const char* p);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue