diff --git a/README.md b/README.md index 9ea5a8614b..d843ac0f8f 100755 --- a/README.md +++ b/README.md @@ -146,6 +146,7 @@ For previous versions, please read: ## V3 changes +* v3.0, 2020-03-12, For [#1630][bug #1630], disable cache for stream changing, and drop dup header. 3.0.128 * v3.0, 2020-03-12, For [#1594][bug #1594], detect and disable daemon for docker. 3.0.127 * v3.0, 2020-03-12, For [#1634][bug #1634], always check status in thread loop. 3.0.126 * v3.0, 2020-03-11, For [#1634][bug #1634], refactor output with datetime for ingest/encoder/exec. 3.0.125 @@ -1666,6 +1667,7 @@ Winlin [bug #1598]: https://github.com/ossrs/srs/issues/1598 [bug #1634]: https://github.com/ossrs/srs/issues/1634 [bug #1594]: https://github.com/ossrs/srs/issues/1594 +[bug #1630]: https://github.com/ossrs/srs/issues/1630 [bug #yyyyyyyyyyyyy]: https://github.com/ossrs/srs/issues/yyyyyyyyyyyyy [exo #828]: https://github.com/google/ExoPlayer/pull/828 diff --git a/trunk/src/app/srs_app_source.cpp b/trunk/src/app/srs_app_source.cpp index f5acb05dad..3473909eb0 100755 --- a/trunk/src/app/srs_app_source.cpp +++ b/trunk/src/app/srs_app_source.cpp @@ -1506,6 +1506,7 @@ void SrsOriginHub::destroy_forwarders() SrsMetaCache::SrsMetaCache() { meta = video = audio = NULL; + previous_video = previous_audio = NULL; vformat = new SrsRtmpFormat(); aformat = new SrsRtmpFormat(); } @@ -1516,6 +1517,13 @@ SrsMetaCache::~SrsMetaCache() } void SrsMetaCache::dispose() +{ + clear(); + srs_freep(previous_video); + srs_freep(previous_audio); +} + +void SrsMetaCache::clear() { srs_freep(meta); srs_freep(video); @@ -1570,6 +1578,28 @@ srs_error_t SrsMetaCache::dumps(SrsConsumer* consumer, bool atc, SrsRtmpJitterAl return err; } +SrsSharedPtrMessage* SrsMetaCache::previous_vsh() +{ + return previous_video; +} + +SrsSharedPtrMessage* SrsMetaCache::previous_ash() +{ + return previous_audio; +} + +void SrsMetaCache::update_previous_vsh() +{ + srs_freep(previous_video); + previous_video = video? video->copy() : NULL; +} + +void SrsMetaCache::update_previous_ash() +{ + srs_freep(previous_audio); + previous_audio = audio? audio->copy() : NULL; +} + srs_error_t SrsMetaCache::update_data(SrsMessageHeader* header, SrsOnMetaDataPacket* metadata, bool& updated) { updated = false; @@ -1636,6 +1666,7 @@ srs_error_t SrsMetaCache::update_ash(SrsSharedPtrMessage* msg) { srs_freep(audio); audio = msg->copy(); + update_previous_ash(); return aformat->on_audio(msg); } @@ -1643,6 +1674,7 @@ srs_error_t SrsMetaCache::update_vsh(SrsSharedPtrMessage* msg) { srs_freep(video); video = msg->copy(); + update_previous_vsh(); return vformat->on_video(msg); } @@ -2138,9 +2170,9 @@ srs_error_t SrsSource::on_audio_imp(SrsSharedPtrMessage* msg) // whether consumer should drop for the duplicated sequence header. bool drop_for_reduce = false; - if (is_sequence_header && meta->ash() && _srs_config->get_reduce_sequence_header(req->vhost)) { - if (meta->ash()->size == msg->size) { - drop_for_reduce = srs_bytes_equals(meta->ash()->payload, msg->payload, msg->size); + if (is_sequence_header && meta->previous_ash() && _srs_config->get_reduce_sequence_header(req->vhost)) { + if (meta->previous_ash()->size == msg->size) { + drop_for_reduce = srs_bytes_equals(meta->previous_ash()->payload, msg->payload, msg->size); srs_warn("drop for reduce sh audio, size=%d", msg->size); } } @@ -2257,9 +2289,9 @@ srs_error_t SrsSource::on_video_imp(SrsSharedPtrMessage* msg) // whether consumer should drop for the duplicated sequence header. bool drop_for_reduce = false; - if (is_sequence_header && meta->vsh() && _srs_config->get_reduce_sequence_header(req->vhost)) { - if (meta->vsh()->size == msg->size) { - drop_for_reduce = srs_bytes_equals(meta->vsh()->payload, msg->payload, msg->size); + if (is_sequence_header && meta->previous_vsh() && _srs_config->get_reduce_sequence_header(req->vhost)) { + if (meta->previous_vsh()->size == msg->size) { + drop_for_reduce = srs_bytes_equals(meta->previous_vsh()->payload, msg->payload, msg->size); srs_warn("drop for reduce sh video, size=%d", msg->size); } } @@ -2415,6 +2447,10 @@ srs_error_t SrsSource::on_publish() // reset the mix queue. mix_queue->clear(); + + // Reset the metadata cache, to make VLC happy when disable/enable stream. + // @see https://github.com/ossrs/srs/issues/1630#issuecomment-597979448 + meta->clear(); // detect the monotonically again. is_monotonically_increase = true; @@ -2450,7 +2486,12 @@ void SrsSource::on_unpublish() // donot clear the sequence header, for it maybe not changed, // when drop dup sequence header, drop the metadata also. gop_cache->clear(); - + + // Reset the metadata cache, to make VLC happy when disable/enable stream. + // @see https://github.com/ossrs/srs/issues/1630#issuecomment-597979448 + meta->update_previous_vsh(); + meta->update_previous_ash(); + srs_trace("cleanup when unpublish"); _can_publish = true; diff --git a/trunk/src/app/srs_app_source.hpp b/trunk/src/app/srs_app_source.hpp index 8cb79f478c..f93bc314d8 100644 --- a/trunk/src/app/srs_app_source.hpp +++ b/trunk/src/app/srs_app_source.hpp @@ -407,8 +407,10 @@ class SrsMetaCache SrsSharedPtrMessage* meta; // The cached video sequence header, for example, sps/pps for h.264. SrsSharedPtrMessage* video; + SrsSharedPtrMessage* previous_video; // The cached audio sequence header, for example, asc for aac. SrsSharedPtrMessage* audio; + SrsSharedPtrMessage* previous_audio; // The format for sequence header. SrsRtmpFormat* vformat; SrsRtmpFormat* aformat; @@ -418,6 +420,8 @@ class SrsMetaCache public: // Dispose the metadata cache. virtual void dispose(); + // For each publishing, clear the metadata cache. + virtual void clear(); public: // Get the cached metadata. virtual SrsSharedPtrMessage* data(); @@ -431,6 +435,13 @@ class SrsMetaCache // @param dm Whether dumps the metadata. // @param ds Whether dumps the sequence header. virtual srs_error_t dumps(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm ag, bool dm, bool ds); +public: + // Previous exists sequence header. + virtual SrsSharedPtrMessage* previous_vsh(); + virtual SrsSharedPtrMessage* previous_ash(); + // Update previous sequence header, drop old one, set to new sequence header. + virtual void update_previous_vsh(); + virtual void update_previous_ash(); public: // Update the cached metadata by packet. virtual srs_error_t update_data(SrsMessageHeader* header, SrsOnMetaDataPacket* metadata, bool& updated); diff --git a/trunk/src/core/srs_core_version3.hpp b/trunk/src/core/srs_core_version3.hpp index 878dd87300..c3a667511f 100644 --- a/trunk/src/core/srs_core_version3.hpp +++ b/trunk/src/core/srs_core_version3.hpp @@ -24,6 +24,6 @@ #ifndef SRS_CORE_VERSION3_HPP #define SRS_CORE_VERSION3_HPP -#define SRS_VERSION3_REVISION 127 +#define SRS_VERSION3_REVISION 128 #endif