Fix WHIP with transcoding bug. v7.0.92 (#4495)
This commit is contained in:
parent
ca261fe955
commit
10c0b66c0f
|
|
@ -7,6 +7,7 @@ The changelog for SRS.
|
|||
<a name="v7-changes"></a>
|
||||
|
||||
## SRS 7.0 Changelog
|
||||
* v7.0, 2025-09-21, Fix WHIP with transcoding bug. v7.0.92 (#4495)
|
||||
* v7.0, 2025-09-20, Merge [#4504](https://github.com/ossrs/srs/pull/4504): fix rtsp compiling warning. v7.0.91 (#4504)
|
||||
* v7.0, 2025-09-19, Merge [#4503](https://github.com/ossrs/srs/pull/4503): AI: Refine RTMP/SRT/RTC bridge. v7.0.90 (#4503)
|
||||
* v7.0, 2025-09-15, RTC2RTMP: Fix sequence number wraparound assertion crashes. v7.0.89 (#4491)
|
||||
|
|
@ -105,6 +106,7 @@ The changelog for SRS.
|
|||
<a name="v6-changes"></a>
|
||||
|
||||
## SRS 6.0 Changelog
|
||||
* v6.0, 2025-09-21, Fix WHIP with transcoding bug. v6.0.179 (#4495)
|
||||
* v6.0, 2025-09-15, RTC2RTMP: Fix sequence number wraparound assertion crashes. v6.0.177 (#4491)
|
||||
* v6.0, 2025-09-05, RTX: Fix race condition for timer. v6.0.176 (#4470) (#4474)
|
||||
* v6.0, 2025-08-26, Merge [#4451](https://github.com/ossrs/srs/pull/4451): RTC: Fix null pointer crash in RTC2RTMP when start packet is missing. v6.0.175 (#4451)
|
||||
|
|
|
|||
|
|
@ -1869,6 +1869,9 @@ SrsRtcConnection::~SrsRtcConnection()
|
|||
|
||||
srs_freep(req_);
|
||||
srs_freep(pli_epp_);
|
||||
|
||||
// Optional to release the publisher token.
|
||||
publish_token_ = NULL;
|
||||
}
|
||||
|
||||
void SrsRtcConnection::on_before_dispose(ISrsResource *c)
|
||||
|
|
@ -1931,6 +1934,11 @@ string SrsRtcConnection::token()
|
|||
return token_;
|
||||
}
|
||||
|
||||
void SrsRtcConnection::set_publish_token(SrsSharedPtr<SrsStreamPublishToken> publish_token)
|
||||
{
|
||||
publish_token_ = publish_token;
|
||||
}
|
||||
|
||||
ISrsKbpsDelta *SrsRtcConnection::delta()
|
||||
{
|
||||
return networks_->delta();
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ class SrsRtcNetworks;
|
|||
class SrsRtcUdpNetwork;
|
||||
class ISrsRtcNetwork;
|
||||
class SrsRtcTcpNetwork;
|
||||
class SrsStreamPublishToken;
|
||||
|
||||
const uint8_t kSR = 200;
|
||||
const uint8_t kRR = 201;
|
||||
|
|
@ -529,6 +530,7 @@ private:
|
|||
ISrsRequest *req_;
|
||||
SrsSdp remote_sdp_;
|
||||
SrsSdp local_sdp_;
|
||||
SrsSharedPtr<SrsStreamPublishToken> publish_token_;
|
||||
|
||||
private:
|
||||
// twcc handler
|
||||
|
|
@ -561,6 +563,8 @@ public:
|
|||
std::string username();
|
||||
// Get the token for verify this session, for example, when delete session by WHIP API.
|
||||
std::string token();
|
||||
// Set the publish token for this session if publisher.
|
||||
void set_publish_token(SrsSharedPtr<SrsStreamPublishToken> publish_token);
|
||||
|
||||
public:
|
||||
virtual ISrsKbpsDelta *delta();
|
||||
|
|
|
|||
|
|
@ -348,7 +348,7 @@ srs_error_t SrsRtcSessionManager::create_rtc_session(SrsRtcUserConfig *ruc, SrsS
|
|||
if (ruc->publish_ && (err = _srs_stream_publish_tokens->acquire_token(req, publish_token_raw)) != srs_success) {
|
||||
return srs_error_wrap(err, "acquire stream publish token");
|
||||
}
|
||||
SrsUniquePtr<SrsStreamPublishToken> publish_token(publish_token_raw);
|
||||
SrsSharedPtr<SrsStreamPublishToken> publish_token(publish_token_raw);
|
||||
if (publish_token.get()) {
|
||||
srs_trace("stream publish token acquired, type=rtc, url=%s", req->get_stream_url().c_str());
|
||||
}
|
||||
|
|
@ -370,6 +370,11 @@ srs_error_t SrsRtcSessionManager::create_rtc_session(SrsRtcUserConfig *ruc, SrsS
|
|||
return srs_error_wrap(err, "create session");
|
||||
}
|
||||
|
||||
// Update publish token for publisher.
|
||||
if (ruc->publish_) {
|
||||
session->set_publish_token(publish_token);
|
||||
}
|
||||
|
||||
*psession = session;
|
||||
|
||||
return err;
|
||||
|
|
|
|||
|
|
@ -715,9 +715,6 @@ void SrsRtcSource::on_unpublish()
|
|||
|
||||
srs_trace("cleanup when unpublish, created=%u, deliver=%u", is_created_, is_delivering_packets_);
|
||||
|
||||
is_created_ = false;
|
||||
is_delivering_packets_ = false;
|
||||
|
||||
if (!_source_id.empty()) {
|
||||
_pre_source_id = _source_id;
|
||||
}
|
||||
|
|
@ -744,16 +741,20 @@ void SrsRtcSource::on_unpublish()
|
|||
if (consumers_.empty()) {
|
||||
stream_die_at_ = srs_time_now_cached();
|
||||
}
|
||||
|
||||
// Should never change the final state before all cleanup is done.
|
||||
is_created_ = false;
|
||||
is_delivering_packets_ = false;
|
||||
}
|
||||
|
||||
void SrsRtcSource::subscribe(ISrsRtcSourceEventHandler *h)
|
||||
void SrsRtcSource::rtc_source_subscribe(ISrsRtcSourceEventHandler *h)
|
||||
{
|
||||
if (std::find(event_handlers_.begin(), event_handlers_.end(), h) == event_handlers_.end()) {
|
||||
event_handlers_.push_back(h);
|
||||
}
|
||||
}
|
||||
|
||||
void SrsRtcSource::unsubscribe(ISrsRtcSourceEventHandler *h)
|
||||
void SrsRtcSource::rtc_source_unsubscribe(ISrsRtcSourceEventHandler *h)
|
||||
{
|
||||
std::vector<ISrsRtcSourceEventHandler *>::iterator it;
|
||||
it = std::find(event_handlers_.begin(), event_handlers_.end(), h);
|
||||
|
|
|
|||
|
|
@ -310,8 +310,8 @@ public:
|
|||
|
||||
public:
|
||||
// For event handler
|
||||
virtual void subscribe(ISrsRtcSourceEventHandler *h);
|
||||
virtual void unsubscribe(ISrsRtcSourceEventHandler *h);
|
||||
virtual void rtc_source_subscribe(ISrsRtcSourceEventHandler *h);
|
||||
virtual void rtc_source_unsubscribe(ISrsRtcSourceEventHandler *h);
|
||||
|
||||
public:
|
||||
// Get and set the publisher, passed to consumer to process requests such as PLI.
|
||||
|
|
|
|||
|
|
@ -444,9 +444,6 @@ void SrsRtspSource::on_unpublish()
|
|||
|
||||
srs_trace("cleanup when unpublish, created=%u, deliver=%u", is_created_, is_delivering_packets_);
|
||||
|
||||
is_created_ = false;
|
||||
is_delivering_packets_ = false;
|
||||
|
||||
if (!_source_id.empty()) {
|
||||
_pre_source_id = _source_id;
|
||||
}
|
||||
|
|
@ -459,6 +456,10 @@ void SrsRtspSource::on_unpublish()
|
|||
if (consumers_.empty()) {
|
||||
stream_die_at_ = srs_time_now_cached();
|
||||
}
|
||||
|
||||
// Should never change the final state before all cleanup is done.
|
||||
is_created_ = false;
|
||||
is_delivering_packets_ = false;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtspSource::on_rtp(SrsRtpPacket *pkt)
|
||||
|
|
|
|||
|
|
@ -1085,8 +1085,6 @@ void SrsSrtSource::on_unpublish()
|
|||
return;
|
||||
}
|
||||
|
||||
can_publish_ = true;
|
||||
|
||||
SrsStatistic *stat = SrsStatistic::instance();
|
||||
stat->on_stream_close(req_);
|
||||
|
||||
|
|
@ -1099,6 +1097,9 @@ void SrsSrtSource::on_unpublish()
|
|||
if (consumers_.empty()) {
|
||||
stream_die_at_ = srs_time_now_cached();
|
||||
}
|
||||
|
||||
// Should never change the final state before all cleanup is done.
|
||||
can_publish_ = true;
|
||||
}
|
||||
|
||||
srs_error_t SrsSrtSource::on_packet(SrsSrtPacket *packet)
|
||||
|
|
|
|||
|
|
@ -185,6 +185,7 @@ void SrsFastCoroutine::stop()
|
|||
}
|
||||
disposed_ = true;
|
||||
stopping_ = true;
|
||||
stopping_cid_ = _srs_context->get_id();
|
||||
|
||||
interrupt();
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,6 @@
|
|||
|
||||
#define VERSION_MAJOR 6
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_REVISION 177
|
||||
#define VERSION_REVISION 179
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -9,6 +9,6 @@
|
|||
|
||||
#define VERSION_MAJOR 7
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_REVISION 91
|
||||
#define VERSION_REVISION 92
|
||||
|
||||
#endif
|
||||
|
|
@ -1575,8 +1575,8 @@ VOID TEST(AppTest2, RtcSourceOnConsumerDestroyNotifyEventHandlers)
|
|||
|
||||
// Set up source with publish stream and event handlers
|
||||
source->set_publish_stream(publish_stream);
|
||||
source->subscribe(handler1);
|
||||
source->subscribe(handler2);
|
||||
source->rtc_source_subscribe(handler1);
|
||||
source->rtc_source_subscribe(handler2);
|
||||
|
||||
// Create mock consumers
|
||||
MockRtcConsumer *consumer1 = new MockRtcConsumer();
|
||||
|
|
@ -1625,7 +1625,7 @@ VOID TEST(AppTest2, RtcSourceOnConsumerDestroyNoPublishStream)
|
|||
|
||||
// Create mock event handler
|
||||
MockRtcSourceEventHandler *handler = new MockRtcSourceEventHandler();
|
||||
source->subscribe(handler);
|
||||
source->rtc_source_subscribe(handler);
|
||||
|
||||
// Create mock consumer
|
||||
MockRtcConsumer *consumer = new MockRtcConsumer();
|
||||
|
|
@ -1961,12 +1961,12 @@ VOID TEST(AppTest2, RtcSourceSubscribeBasic)
|
|||
EXPECT_EQ(0, (int)source->event_handlers_.size());
|
||||
|
||||
// Subscribe first handler
|
||||
source->subscribe(handler1.get());
|
||||
source->rtc_source_subscribe(handler1.get());
|
||||
EXPECT_EQ(1, (int)source->event_handlers_.size());
|
||||
EXPECT_EQ(handler1.get(), source->event_handlers_[0]);
|
||||
|
||||
// Subscribe second handler
|
||||
source->subscribe(handler2.get());
|
||||
source->rtc_source_subscribe(handler2.get());
|
||||
EXPECT_EQ(2, (int)source->event_handlers_.size());
|
||||
EXPECT_EQ(handler1.get(), source->event_handlers_[0]);
|
||||
EXPECT_EQ(handler2.get(), source->event_handlers_[1]);
|
||||
|
|
@ -1991,18 +1991,18 @@ VOID TEST(AppTest2, RtcSourceSubscribeDuplicateHandler)
|
|||
SrsUniquePtr<MockRtcSourceEventHandler> handler(new MockRtcSourceEventHandler());
|
||||
|
||||
// Subscribe handler first time
|
||||
source->subscribe(handler.get());
|
||||
source->rtc_source_subscribe(handler.get());
|
||||
EXPECT_EQ(1, (int)source->event_handlers_.size());
|
||||
EXPECT_EQ(handler.get(), source->event_handlers_[0]);
|
||||
|
||||
// Subscribe same handler again - should not add duplicate
|
||||
source->subscribe(handler.get());
|
||||
source->rtc_source_subscribe(handler.get());
|
||||
EXPECT_EQ(1, (int)source->event_handlers_.size());
|
||||
EXPECT_EQ(handler.get(), source->event_handlers_[0]);
|
||||
|
||||
// Subscribe same handler multiple times - should still be only one
|
||||
source->subscribe(handler.get());
|
||||
source->subscribe(handler.get());
|
||||
source->rtc_source_subscribe(handler.get());
|
||||
source->rtc_source_subscribe(handler.get());
|
||||
EXPECT_EQ(1, (int)source->event_handlers_.size());
|
||||
EXPECT_EQ(handler.get(), source->event_handlers_[0]);
|
||||
}
|
||||
|
|
@ -2026,12 +2026,12 @@ VOID TEST(AppTest2, RtcSourceSubscribeNullHandler)
|
|||
EXPECT_EQ(0, (int)source->event_handlers_.size());
|
||||
|
||||
// Subscribe null handler - should add it (implementation allows null)
|
||||
source->subscribe(NULL);
|
||||
source->rtc_source_subscribe(NULL);
|
||||
EXPECT_EQ(1, (int)source->event_handlers_.size());
|
||||
EXPECT_EQ(NULL, source->event_handlers_[0]);
|
||||
|
||||
// Subscribe null handler again - should not add duplicate
|
||||
source->subscribe(NULL);
|
||||
source->rtc_source_subscribe(NULL);
|
||||
EXPECT_EQ(1, (int)source->event_handlers_.size());
|
||||
EXPECT_EQ(NULL, source->event_handlers_[0]);
|
||||
}
|
||||
|
|
@ -2060,9 +2060,9 @@ VOID TEST(AppTest2, RtcSourceSubscribeMultipleHandlers)
|
|||
EXPECT_EQ(0, (int)source->event_handlers_.size());
|
||||
|
||||
// Subscribe handlers in order
|
||||
source->subscribe(handler1.get());
|
||||
source->subscribe(handler2.get());
|
||||
source->subscribe(handler3.get());
|
||||
source->rtc_source_subscribe(handler1.get());
|
||||
source->rtc_source_subscribe(handler2.get());
|
||||
source->rtc_source_subscribe(handler3.get());
|
||||
|
||||
// Verify all handlers are subscribed in correct order
|
||||
EXPECT_EQ(3, (int)source->event_handlers_.size());
|
||||
|
|
@ -2071,8 +2071,8 @@ VOID TEST(AppTest2, RtcSourceSubscribeMultipleHandlers)
|
|||
EXPECT_EQ(handler3.get(), source->event_handlers_[2]);
|
||||
|
||||
// Try to subscribe duplicates - should not change the list
|
||||
source->subscribe(handler2.get());
|
||||
source->subscribe(handler1.get());
|
||||
source->rtc_source_subscribe(handler2.get());
|
||||
source->rtc_source_subscribe(handler1.get());
|
||||
EXPECT_EQ(3, (int)source->event_handlers_.size());
|
||||
EXPECT_EQ(handler1.get(), source->event_handlers_[0]);
|
||||
EXPECT_EQ(handler2.get(), source->event_handlers_[1]);
|
||||
|
|
@ -2099,29 +2099,29 @@ VOID TEST(AppTest2, RtcSourceSubscribeUnsubscribeInteraction)
|
|||
SrsUniquePtr<MockRtcSourceEventHandler> handler2(new MockRtcSourceEventHandler());
|
||||
|
||||
// Subscribe both handlers
|
||||
source->subscribe(handler1.get());
|
||||
source->subscribe(handler2.get());
|
||||
source->rtc_source_subscribe(handler1.get());
|
||||
source->rtc_source_subscribe(handler2.get());
|
||||
EXPECT_EQ(2, (int)source->event_handlers_.size());
|
||||
|
||||
// Unsubscribe first handler
|
||||
source->unsubscribe(handler1.get());
|
||||
source->rtc_source_unsubscribe(handler1.get());
|
||||
EXPECT_EQ(1, (int)source->event_handlers_.size());
|
||||
EXPECT_EQ(handler2.get(), source->event_handlers_[0]);
|
||||
|
||||
// Re-subscribe first handler - should be added back
|
||||
source->subscribe(handler1.get());
|
||||
source->rtc_source_subscribe(handler1.get());
|
||||
EXPECT_EQ(2, (int)source->event_handlers_.size());
|
||||
EXPECT_EQ(handler2.get(), source->event_handlers_[0]);
|
||||
EXPECT_EQ(handler1.get(), source->event_handlers_[1]);
|
||||
|
||||
// Unsubscribe all handlers
|
||||
source->unsubscribe(handler1.get());
|
||||
source->unsubscribe(handler2.get());
|
||||
source->rtc_source_unsubscribe(handler1.get());
|
||||
source->rtc_source_unsubscribe(handler2.get());
|
||||
EXPECT_EQ(0, (int)source->event_handlers_.size());
|
||||
|
||||
// Re-subscribe in different order
|
||||
source->subscribe(handler2.get());
|
||||
source->subscribe(handler1.get());
|
||||
source->rtc_source_subscribe(handler2.get());
|
||||
source->rtc_source_subscribe(handler1.get());
|
||||
EXPECT_EQ(2, (int)source->event_handlers_.size());
|
||||
EXPECT_EQ(handler2.get(), source->event_handlers_[0]);
|
||||
EXPECT_EQ(handler1.get(), source->event_handlers_[1]);
|
||||
|
|
@ -2147,8 +2147,8 @@ VOID TEST(AppTest2, RtcSourceSubscribeEventNotification)
|
|||
SrsUniquePtr<MockRtcSourceEventHandler> handler2(new MockRtcSourceEventHandler());
|
||||
|
||||
// Subscribe handlers
|
||||
source->subscribe(handler1.get());
|
||||
source->subscribe(handler2.get());
|
||||
source->rtc_source_subscribe(handler1.get());
|
||||
source->rtc_source_subscribe(handler2.get());
|
||||
|
||||
// Verify initial state
|
||||
EXPECT_EQ(0, handler1->on_unpublish_count_);
|
||||
|
|
@ -2174,11 +2174,11 @@ VOID TEST(AppTest2, RtcSourceSubscribeEventNotification)
|
|||
handler2->on_unpublish_count_ = 0;
|
||||
|
||||
// Subscribe both handlers to the new source
|
||||
source2->subscribe(handler1.get());
|
||||
source2->subscribe(handler2.get());
|
||||
source2->rtc_source_subscribe(handler1.get());
|
||||
source2->rtc_source_subscribe(handler2.get());
|
||||
|
||||
// Unsubscribe handler1
|
||||
source2->unsubscribe(handler1.get());
|
||||
source2->rtc_source_unsubscribe(handler1.get());
|
||||
|
||||
// Verify only handler2 is subscribed now
|
||||
EXPECT_EQ(1, (int)source2->event_handlers_.size());
|
||||
|
|
@ -2255,7 +2255,7 @@ VOID TEST(AppTest2, RtcSourcePublishStreamWithConsumerDestroy)
|
|||
|
||||
// Create a mock event handler
|
||||
SrsUniquePtr<MockRtcSourceEventHandler> handler(new MockRtcSourceEventHandler());
|
||||
source->subscribe(handler.get());
|
||||
source->rtc_source_subscribe(handler.get());
|
||||
|
||||
// Create consumers
|
||||
ISrsRtcConsumer *consumer1 = NULL;
|
||||
|
|
@ -3204,8 +3204,8 @@ VOID TEST(AppTest2, RtcSourceSetStreamCreatedWithEventHandlers)
|
|||
// Create and subscribe event handlers
|
||||
SrsUniquePtr<MockRtcSourceEventHandler> handler1(new MockRtcSourceEventHandler());
|
||||
SrsUniquePtr<MockRtcSourceEventHandler> handler2(new MockRtcSourceEventHandler());
|
||||
source->subscribe(handler1.get());
|
||||
source->subscribe(handler2.get());
|
||||
source->rtc_source_subscribe(handler1.get());
|
||||
source->rtc_source_subscribe(handler2.get());
|
||||
|
||||
// Verify initial state
|
||||
EXPECT_FALSE(source->is_created_);
|
||||
|
|
@ -3242,7 +3242,7 @@ VOID TEST(AppTest2, RtcSourcePublishStreamWithoutConsumerDestroy)
|
|||
|
||||
// Create a mock event handler
|
||||
SrsUniquePtr<MockRtcSourceEventHandler> handler(new MockRtcSourceEventHandler());
|
||||
source->subscribe(handler.get());
|
||||
source->rtc_source_subscribe(handler.get());
|
||||
|
||||
// Create and destroy consumer
|
||||
ISrsRtcConsumer *consumer = NULL;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user