mirror of
https://github.com/ossrs/srs.git
synced 2025-02-15 04:42:04 +00:00
merge from 2.0release
This commit is contained in:
commit
1d57e53910
6 changed files with 62 additions and 49 deletions
|
@ -814,7 +814,9 @@ About the HLS overhead of SRS, we compare the overhead to FLV by remux the HLS t
|
||||||
| 5147kbps | 370s | 195040 | 200280 | 2.68% |
|
| 5147kbps | 370s | 195040 | 200280 | 2.68% |
|
||||||
| 5158kbps | 1327s | 835664 | 858092 | 2.68% |
|
| 5158kbps | 1327s | 835664 | 858092 | 2.68% |
|
||||||
|
|
||||||
The HLS overhead is calc by: (HLS - FLV) / FLV * 100%
|
The HLS overhead is calc by: (HLS - FLV) / FLV * 100%.
|
||||||
|
|
||||||
|
The overhead is larger than this benchmark(48kbps audio is best overhead), for we fix the [#512][bug#512].
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
|
@ -1265,6 +1267,7 @@ Winlin
|
||||||
[bug #59]: https://github.com/simple-rtmp-server/srs/issues/59
|
[bug #59]: https://github.com/simple-rtmp-server/srs/issues/59
|
||||||
[bug #50]: https://github.com/simple-rtmp-server/srs/issues/50
|
[bug #50]: https://github.com/simple-rtmp-server/srs/issues/50
|
||||||
[bug #34]: https://github.com/simple-rtmp-server/srs/issues/34
|
[bug #34]: https://github.com/simple-rtmp-server/srs/issues/34
|
||||||
|
<<<<<<< HEAD
|
||||||
[bug #367]: https://github.com/simple-rtmp-server/srs/issues/367
|
[bug #367]: https://github.com/simple-rtmp-server/srs/issues/367
|
||||||
[bug #319]: https://github.com/simple-rtmp-server/srs/issues/319
|
[bug #319]: https://github.com/simple-rtmp-server/srs/issues/319
|
||||||
[bug #367]: https://github.com/simple-rtmp-server/srs/issues/367
|
[bug #367]: https://github.com/simple-rtmp-server/srs/issues/367
|
||||||
|
@ -1282,6 +1285,10 @@ Winlin
|
||||||
[bug #502]: https://github.com/simple-rtmp-server/srs/issues/502
|
[bug #502]: https://github.com/simple-rtmp-server/srs/issues/502
|
||||||
[bug #467]: https://github.com/simple-rtmp-server/srs/issues/467
|
[bug #467]: https://github.com/simple-rtmp-server/srs/issues/467
|
||||||
[bug #xxxxxxx]: https://github.com/simple-rtmp-server/srs/issues/xxxxxxx
|
[bug #xxxxxxx]: https://github.com/simple-rtmp-server/srs/issues/xxxxxxx
|
||||||
|
=======
|
||||||
|
[bug #512]: https://github.com/simple-rtmp-server/srs/issues/512
|
||||||
|
[bug #xxxxxxxxxx]: https://github.com/simple-rtmp-server/srs/issues/xxxxxxxxxx
|
||||||
|
>>>>>>> 2.0release
|
||||||
|
|
||||||
[r2.0a2]: https://github.com/simple-rtmp-server/srs/releases/tag/v2.0-a2
|
[r2.0a2]: https://github.com/simple-rtmp-server/srs/releases/tag/v2.0-a2
|
||||||
[r2.0a1]: https://github.com/simple-rtmp-server/srs/releases/tag/2.0a1
|
[r2.0a1]: https://github.com/simple-rtmp-server/srs/releases/tag/2.0a1
|
||||||
|
|
|
@ -578,6 +578,7 @@ int SrsHlsMuxer::segment_open(int64_t segment_start_dts)
|
||||||
current->full_path.c_str(), tmp_file.c_str());
|
current->full_path.c_str(), tmp_file.c_str());
|
||||||
|
|
||||||
// set the segment muxer audio codec.
|
// set the segment muxer audio codec.
|
||||||
|
// TODO: FIXME: refine code, use event instead.
|
||||||
if (acodec != SrsCodecAudioReserved1) {
|
if (acodec != SrsCodecAudioReserved1) {
|
||||||
current->muxer->update_acodec(acodec);
|
current->muxer->update_acodec(acodec);
|
||||||
}
|
}
|
||||||
|
@ -646,6 +647,11 @@ int SrsHlsMuxer::update_acodec(SrsCodecAudio ac)
|
||||||
return current->muxer->update_acodec(ac);
|
return current->muxer->update_acodec(ac);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SrsHlsMuxer::pure_audio()
|
||||||
|
{
|
||||||
|
return current && current->muxer && current->muxer->video_codec() == SrsCodecVideoDisabled;
|
||||||
|
}
|
||||||
|
|
||||||
int SrsHlsMuxer::flush_audio(SrsTsCache* cache)
|
int SrsHlsMuxer::flush_audio(SrsTsCache* cache)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
@ -1039,7 +1045,7 @@ int SrsHlsCache::on_sequence_header(SrsHlsMuxer* muxer)
|
||||||
// when the sequence header changed, the stream is not republish.
|
// when the sequence header changed, the stream is not republish.
|
||||||
return muxer->on_sequence_header();
|
return muxer->on_sequence_header();
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsHlsCache::write_audio(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t pts, SrsCodecSample* sample)
|
int SrsHlsCache::write_audio(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t pts, SrsCodecSample* sample)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
@ -1049,25 +1055,6 @@ int SrsHlsCache::write_audio(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// flush if buffer exceed max size.
|
|
||||||
if (cache->audio->payload->length() > SRS_AUTO_HLS_AUDIO_CACHE_SIZE) {
|
|
||||||
if ((ret = muxer->flush_audio(cache)) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: config it.
|
|
||||||
// in ms, audio delay to flush the audios.
|
|
||||||
int64_t audio_delay = SRS_CONF_DEFAULT_AAC_DELAY;
|
|
||||||
// flush if audio delay exceed
|
|
||||||
// cache->audio will be free in flush_audio
|
|
||||||
// so we must check whether it's null ptr.
|
|
||||||
if (cache->audio && pts - cache->audio->start_pts > audio_delay * 90) {
|
|
||||||
if ((ret = muxer->flush_audio(cache)) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// reap when current source is pure audio.
|
// reap when current source is pure audio.
|
||||||
// it maybe changed when stream info changed,
|
// it maybe changed when stream info changed,
|
||||||
// for example, pure audio when start, audio/video when publishing,
|
// for example, pure audio when start, audio/video when publishing,
|
||||||
|
@ -1083,6 +1070,21 @@ int SrsHlsCache::write_audio(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for pure audio, aggregate some frame to one.
|
||||||
|
if (muxer->pure_audio() && cache->audio) {
|
||||||
|
if (pts - cache->audio->start_pts < SRS_CONSTS_HLS_PURE_AUDIO_AGGREGATE) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// directly write the audio frame by frame to ts,
|
||||||
|
// it's ok for the hls overload, or maybe cause the audio corrupt,
|
||||||
|
// which introduced by aggregate the audios to a big one.
|
||||||
|
// @see https://github.com/simple-rtmp-server/srs/issues/512
|
||||||
|
if ((ret = muxer->flush_audio(cache)) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1100,7 +1102,7 @@ int SrsHlsCache::write_video(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t
|
||||||
// do reap ts if any of:
|
// do reap ts if any of:
|
||||||
// a. wait keyframe and got keyframe.
|
// a. wait keyframe and got keyframe.
|
||||||
// b. always reap when not wait keyframe.
|
// b. always reap when not wait keyframe.
|
||||||
if (!muxer->wait_keyframe()|| sample->frame_type == SrsCodecVideoAVCFrameKeyFrame) {
|
if (!muxer->wait_keyframe() || sample->frame_type == SrsCodecVideoAVCFrameKeyFrame) {
|
||||||
// when wait keyframe, there must exists idr frame in sample.
|
// when wait keyframe, there must exists idr frame in sample.
|
||||||
if (!sample->has_idr && muxer->wait_keyframe()) {
|
if (!sample->has_idr && muxer->wait_keyframe()) {
|
||||||
srs_warn("hls: ts starts without IDR, first nalu=%d, idr=%d", sample->first_nalu_type, sample->has_idr);
|
srs_warn("hls: ts starts without IDR, first nalu=%d, idr=%d", sample->first_nalu_type, sample->has_idr);
|
||||||
|
@ -1110,9 +1112,6 @@ int SrsHlsCache::write_video(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t
|
||||||
if ((ret = reap_segment("video", muxer, cache->video->dts)) != ERROR_SUCCESS) {
|
if ((ret = reap_segment("video", muxer, cache->video->dts)) != ERROR_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the video must be flushed, just return.
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -309,6 +309,10 @@ public:
|
||||||
virtual bool is_segment_absolutely_overflow();
|
virtual bool is_segment_absolutely_overflow();
|
||||||
public:
|
public:
|
||||||
virtual int update_acodec(SrsCodecAudio ac);
|
virtual int update_acodec(SrsCodecAudio ac);
|
||||||
|
/**
|
||||||
|
* whether current hls muxer is pure audio mode.
|
||||||
|
*/
|
||||||
|
virtual bool pure_audio();
|
||||||
virtual int flush_audio(SrsTsCache* cache);
|
virtual int flush_audio(SrsTsCache* cache);
|
||||||
virtual int flush_video(SrsTsCache* cache);
|
virtual int flush_video(SrsTsCache* cache);
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -246,12 +246,6 @@ extern int aac_sample_rates[];
|
||||||
#define SRS_SRS_MAX_CODEC_SAMPLE 128
|
#define SRS_SRS_MAX_CODEC_SAMPLE 128
|
||||||
#define SRS_AAC_SAMPLE_RATE_UNSET 15
|
#define SRS_AAC_SAMPLE_RATE_UNSET 15
|
||||||
|
|
||||||
// in ms, for HLS aac flush the audio
|
|
||||||
#define SRS_CONF_DEFAULT_AAC_DELAY 60
|
|
||||||
|
|
||||||
// max PES packets size to flush the video.
|
|
||||||
#define SRS_AUTO_HLS_AUDIO_CACHE_SIZE 128 * 1024
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the FLV/RTMP supported audio sample size.
|
* the FLV/RTMP supported audio sample size.
|
||||||
* Size of each audio sample. This parameter only pertains to
|
* Size of each audio sample. This parameter only pertains to
|
||||||
|
|
|
@ -469,8 +469,11 @@ int SrsTsContext::encode_pes(SrsFileWriter* writer, SrsTsMessage* msg, int16_t p
|
||||||
while (p < end) {
|
while (p < end) {
|
||||||
SrsTsPacket* pkt = NULL;
|
SrsTsPacket* pkt = NULL;
|
||||||
if (p == start) {
|
if (p == start) {
|
||||||
// for pure audio stream, always write pcr.
|
// write pcr according to message.
|
||||||
bool write_pcr = msg->write_pcr;
|
bool write_pcr = msg->write_pcr;
|
||||||
|
|
||||||
|
// for pure audio, always write pcr.
|
||||||
|
// TODO: FIXME: maybe only need to write at begin and end of ts.
|
||||||
if (pure_audio && msg->is_audio()) {
|
if (pure_audio && msg->is_audio()) {
|
||||||
write_pcr = true;
|
write_pcr = true;
|
||||||
}
|
}
|
||||||
|
@ -2772,6 +2775,11 @@ void SrsTSMuxer::close()
|
||||||
writer->close();
|
writer->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SrsCodecVideo SrsTSMuxer::video_codec()
|
||||||
|
{
|
||||||
|
return vcodec;
|
||||||
|
}
|
||||||
|
|
||||||
SrsTsCache::SrsTsCache()
|
SrsTsCache::SrsTsCache()
|
||||||
{
|
{
|
||||||
audio = NULL;
|
audio = NULL;
|
||||||
|
@ -2792,11 +2800,12 @@ int SrsTsCache::cache_audio(SrsAvcAacCodec* codec, int64_t dts, SrsCodecSample*
|
||||||
if (!audio) {
|
if (!audio) {
|
||||||
audio = new SrsTsMessage();
|
audio = new SrsTsMessage();
|
||||||
audio->write_pcr = false;
|
audio->write_pcr = false;
|
||||||
audio->start_pts = dts;
|
audio->dts = audio->pts = audio->start_pts = dts;
|
||||||
}
|
}
|
||||||
|
|
||||||
audio->dts = dts;
|
// TODO: FIXME: refine code.
|
||||||
audio->pts = audio->dts;
|
//audio->dts = dts;
|
||||||
|
//audio->pts = audio->dts;
|
||||||
audio->sid = SrsTsPESStreamIdAudioCommon;
|
audio->sid = SrsTsPESStreamIdAudioCommon;
|
||||||
|
|
||||||
// must be aac or mp3
|
// must be aac or mp3
|
||||||
|
@ -3146,20 +3155,11 @@ int SrsTsEncoder::write_audio(int64_t timestamp, char* data, int size)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// flush if buffer exceed max size.
|
// TODO: FIXME: for pure audio, aggregate some frame to one.
|
||||||
if (cache->audio->payload->length() > SRS_AUTO_HLS_AUDIO_CACHE_SIZE) {
|
|
||||||
return flush_video();
|
// always flush audio frame by frame.
|
||||||
}
|
// @see https://github.com/simple-rtmp-server/srs/issues/512
|
||||||
|
return flush_audio();
|
||||||
// TODO: config it.
|
|
||||||
// in ms, audio delay to flush the audios.
|
|
||||||
int64_t audio_delay = SRS_CONF_DEFAULT_AAC_DELAY;
|
|
||||||
// flush if audio delay exceed
|
|
||||||
if (dts - cache->audio->start_pts > audio_delay * 90) {
|
|
||||||
return flush_audio();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsTsEncoder::write_video(int64_t timestamp, char* data, int size)
|
int SrsTsEncoder::write_video(int64_t timestamp, char* data, int size)
|
||||||
|
|
|
@ -54,6 +54,9 @@ class SrsTsContext;
|
||||||
// Transport Stream packets are 188 bytes in length.
|
// Transport Stream packets are 188 bytes in length.
|
||||||
#define SRS_TS_PACKET_SIZE 188
|
#define SRS_TS_PACKET_SIZE 188
|
||||||
|
|
||||||
|
// the aggregate pure audio for hls, in ts tbn(ms * 90).
|
||||||
|
#define SRS_CONSTS_HLS_PURE_AUDIO_AGGREGATE 720 * 90
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the pid of ts packet,
|
* the pid of ts packet,
|
||||||
* Table 2-3 - PID table, hls-mpeg-ts-iso13818-1.pdf, page 37
|
* Table 2-3 - PID table, hls-mpeg-ts-iso13818-1.pdf, page 37
|
||||||
|
@ -360,6 +363,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* whether the hls stream is pure audio stream.
|
* whether the hls stream is pure audio stream.
|
||||||
*/
|
*/
|
||||||
|
// TODO: FIXME: merge with muxer codec detect.
|
||||||
virtual bool is_pure_audio();
|
virtual bool is_pure_audio();
|
||||||
/**
|
/**
|
||||||
* when PMT table parsed, we know some info about stream.
|
* when PMT table parsed, we know some info about stream.
|
||||||
|
@ -1594,6 +1598,11 @@ public:
|
||||||
* close the writer.
|
* close the writer.
|
||||||
*/
|
*/
|
||||||
virtual void close();
|
virtual void close();
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* get the video codec of ts muxer.
|
||||||
|
*/
|
||||||
|
virtual SrsCodecVideo video_codec();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue