mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
Merge branch v5.0.112 into develop
1. SRT: Fix srt to rtmp crash when sps or pps empty. v5.0.112 (#3323) 2. GB28181: Fix memory overlap for small packets. v5.0.111 (#3315) 3. FLV: Support set default has_av and disable guessing. v5.0.110 (#3311) 4. FLV: Drop packet if header flag is not matched. v5.0.109 (#3306) 5. FLV: Reset has_audio or has_video if only sequence header. (#3310)
This commit is contained in:
commit
2f7e474853
19 changed files with 823 additions and 107 deletions
|
|
@ -2600,7 +2600,8 @@ srs_error_t SrsConfig::check_normal_config()
|
|||
} else if (n == "http_remux") {
|
||||
for (int j = 0; j < (int)conf->directives.size(); j++) {
|
||||
string m = conf->at(j)->name;
|
||||
if (m != "enabled" && m != "mount" && m != "fast_cache") {
|
||||
if (m != "enabled" && m != "mount" && m != "fast_cache" && m != "drop_if_not_match"
|
||||
&& m != "has_audio" && m != "has_video" && m != "guess_has_av") {
|
||||
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal vhost.http_remux.%s of %s", m.c_str(), vhost->arg0().c_str());
|
||||
}
|
||||
}
|
||||
|
|
@ -8241,6 +8242,102 @@ srs_utime_t SrsConfig::get_vhost_http_remux_fast_cache(string vhost)
|
|||
return srs_utime_t(::atof(conf->arg0().c_str()) * SRS_UTIME_SECONDS);
|
||||
}
|
||||
|
||||
bool SrsConfig::get_vhost_http_remux_drop_if_not_match(string vhost)
|
||||
{
|
||||
SRS_OVERWRITE_BY_ENV_BOOL2("srs.vhost.http_remux.drop_if_not_match"); // SRS_VHOST_HTTP_REMUX_DROP_IF_NOT_MATCH
|
||||
|
||||
static bool DEFAULT = true;
|
||||
|
||||
SrsConfDirective* conf = get_vhost(vhost);
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("http_remux");
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("drop_if_not_match");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return SRS_CONF_PERFER_TRUE(conf->arg0());
|
||||
}
|
||||
|
||||
bool SrsConfig::get_vhost_http_remux_has_audio(string vhost)
|
||||
{
|
||||
SRS_OVERWRITE_BY_ENV_BOOL2("srs.vhost.http_remux.has_audio"); // SRS_VHOST_HTTP_REMUX_HAS_AUDIO
|
||||
|
||||
static bool DEFAULT = true;
|
||||
|
||||
SrsConfDirective* conf = get_vhost(vhost);
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("http_remux");
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("has_audio");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return SRS_CONF_PERFER_TRUE(conf->arg0());
|
||||
}
|
||||
|
||||
bool SrsConfig::get_vhost_http_remux_has_video(string vhost)
|
||||
{
|
||||
SRS_OVERWRITE_BY_ENV_BOOL2("srs.vhost.http_remux.has_video"); // SRS_VHOST_HTTP_REMUX_HAS_VIDEO
|
||||
|
||||
static bool DEFAULT = true;
|
||||
|
||||
SrsConfDirective* conf = get_vhost(vhost);
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("http_remux");
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("has_video");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return SRS_CONF_PERFER_TRUE(conf->arg0());
|
||||
}
|
||||
|
||||
bool SrsConfig::get_vhost_http_remux_guess_has_av(string vhost)
|
||||
{
|
||||
SRS_OVERWRITE_BY_ENV_BOOL2("srs.vhost.http_remux.guess_has_av"); // SRS_VHOST_HTTP_REMUX_GUESS_HAS_AV
|
||||
|
||||
static bool DEFAULT = true;
|
||||
|
||||
SrsConfDirective* conf = get_vhost(vhost);
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("http_remux");
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("guess_has_av");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return SRS_CONF_PERFER_TRUE(conf->arg0());
|
||||
}
|
||||
|
||||
string SrsConfig::get_vhost_http_remux_mount(string vhost)
|
||||
{
|
||||
SRS_OVERWRITE_BY_ENV_STRING("srs.vhost.http_remux.mount"); // SRS_VHOST_HTTP_REMUX_MOUNT
|
||||
|
|
|
|||
|
|
@ -1064,6 +1064,14 @@ public:
|
|||
virtual bool get_vhost_http_remux_enabled(SrsConfDirective* vhost);
|
||||
// Get the fast cache duration for http audio live stream.
|
||||
virtual srs_utime_t get_vhost_http_remux_fast_cache(std::string vhost);
|
||||
// Whether drop packet if not match header.
|
||||
bool get_vhost_http_remux_drop_if_not_match(std::string vhost);
|
||||
// Whether stream has audio track.
|
||||
bool get_vhost_http_remux_has_audio(std::string vhost);
|
||||
// Whether stream has video track.
|
||||
bool get_vhost_http_remux_has_video(std::string vhost);
|
||||
// Whether guessing stream about audio or video track
|
||||
bool get_vhost_http_remux_guess_has_av(std::string vhost);
|
||||
// Get the http flv live stream mount point for vhost.
|
||||
// used to generate the flv stream mount path.
|
||||
virtual std::string get_vhost_http_remux_mount(std::string vhost);
|
||||
|
|
|
|||
|
|
@ -1444,8 +1444,9 @@ srs_error_t SrsLazyGbMediaTcpConn::do_cycle()
|
|||
string bytes = srs_string_dumps_hex(b.head(), reserved, 16);
|
||||
srs_trace("PS: Reserved bytes for next loop, pos=%d, left=%d, total=%d, bytes=[%s]",
|
||||
b.pos(), b.left(), b.size(), bytes.c_str());
|
||||
// Copy the bytes left to the start of buffer.
|
||||
b.read_bytes((char*)buffer_, reserved);
|
||||
// Copy the bytes left to the start of buffer. Note that the left(reserved) bytes might be overlapped with
|
||||
// buffer, so we must use memmove not memcpy, see https://github.com/ossrs/srs/issues/3300#issuecomment-1352907075
|
||||
memmove(buffer_, b.head(), reserved);
|
||||
pack_->media_reserved_++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -238,6 +238,9 @@ SrsFlvStreamEncoder::SrsFlvStreamEncoder()
|
|||
{
|
||||
header_written = false;
|
||||
enc = new SrsFlvTransmuxer();
|
||||
has_audio_ = true;
|
||||
has_video_ = true;
|
||||
guess_has_av_ = true;
|
||||
}
|
||||
|
||||
SrsFlvStreamEncoder::~SrsFlvStreamEncoder()
|
||||
|
|
@ -260,7 +263,7 @@ srs_error_t SrsFlvStreamEncoder::write_audio(int64_t timestamp, char* data, int
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if ((err = write_header()) != srs_success) {
|
||||
if ((err = write_header(has_video_, has_audio_)) != srs_success) {
|
||||
return srs_error_wrap(err, "write header");
|
||||
}
|
||||
|
||||
|
|
@ -271,7 +274,7 @@ srs_error_t SrsFlvStreamEncoder::write_video(int64_t timestamp, char* data, int
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if ((err = write_header()) != srs_success) {
|
||||
if ((err = write_header(has_video_, has_audio_)) != srs_success) {
|
||||
return srs_error_wrap(err, "write header");
|
||||
}
|
||||
|
||||
|
|
@ -282,13 +285,33 @@ srs_error_t SrsFlvStreamEncoder::write_metadata(int64_t timestamp, char* data, i
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if ((err = write_header()) != srs_success) {
|
||||
if ((err = write_header(has_video_, has_audio_)) != srs_success) {
|
||||
return srs_error_wrap(err, "write header");
|
||||
}
|
||||
|
||||
return enc->write_metadata(SrsFrameTypeScript, data, size);
|
||||
}
|
||||
|
||||
void SrsFlvStreamEncoder::set_drop_if_not_match(bool v)
|
||||
{
|
||||
enc->set_drop_if_not_match(v);
|
||||
}
|
||||
|
||||
void SrsFlvStreamEncoder::set_has_audio(bool v)
|
||||
{
|
||||
has_audio_ = v;
|
||||
}
|
||||
|
||||
void SrsFlvStreamEncoder::set_has_video(bool v)
|
||||
{
|
||||
has_video_ = v;
|
||||
}
|
||||
|
||||
void SrsFlvStreamEncoder::set_guess_has_av(bool v)
|
||||
{
|
||||
guess_has_av_ = v;
|
||||
}
|
||||
|
||||
bool SrsFlvStreamEncoder::has_cache()
|
||||
{
|
||||
// for flv stream, use gop cache of SrsLiveSource is ok.
|
||||
|
|
@ -305,17 +328,38 @@ srs_error_t SrsFlvStreamEncoder::write_tags(SrsSharedPtrMessage** msgs, int coun
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// Ignore if no messages.
|
||||
if (count <= 0) return err;
|
||||
|
||||
// For https://github.com/ossrs/srs/issues/939
|
||||
if (!header_written) {
|
||||
bool has_video = false;
|
||||
bool has_audio = false;
|
||||
bool has_video = has_audio_; bool has_audio = has_video_;
|
||||
|
||||
for (int i = 0; i < count && (!has_video || !has_audio); i++) {
|
||||
SrsSharedPtrMessage* msg = msgs[i];
|
||||
if (msg->is_video()) {
|
||||
has_video = true;
|
||||
} else if (msg->is_audio()) {
|
||||
has_audio = true;
|
||||
// See https://github.com/ossrs/srs/issues/939#issuecomment-1351385460
|
||||
if (guess_has_av_) {
|
||||
int nn_video_frames = 0; int nn_audio_frames = 0;
|
||||
has_audio = has_video = false;
|
||||
|
||||
// Note that we must iterate all messages to count the audio and video frames.
|
||||
for (int i = 0; i < count; i++) {
|
||||
SrsSharedPtrMessage* msg = msgs[i];
|
||||
if (msg->is_video()) {
|
||||
if (!SrsFlvVideo::sh(msg->payload, msg->size)) nn_video_frames++;
|
||||
has_video = true;
|
||||
} else if (msg->is_audio()) {
|
||||
if (!SrsFlvAudio::sh(msg->payload, msg->size)) nn_audio_frames++;
|
||||
has_audio = true;
|
||||
}
|
||||
}
|
||||
|
||||
// See https://github.com/ossrs/srs/issues/939#issuecomment-1348541733
|
||||
if (nn_video_frames > 0 && nn_audio_frames == 0) {
|
||||
if (has_audio) srs_trace("FLV: Reset has_audio for videos=%d and audios=%d", nn_video_frames, nn_audio_frames);
|
||||
has_audio = false;
|
||||
}
|
||||
if (nn_audio_frames > 0 && nn_video_frames == 0) {
|
||||
if (has_video) srs_trace("FLV: Reset has_video for videos=%d and audios=%d", nn_video_frames, nn_audio_frames);
|
||||
has_video = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -329,6 +373,7 @@ srs_error_t SrsFlvStreamEncoder::write_tags(SrsSharedPtrMessage** msgs, int coun
|
|||
}
|
||||
}
|
||||
|
||||
// Write tags after header is done.
|
||||
return enc->write_tags(msgs, count);
|
||||
}
|
||||
|
||||
|
|
@ -343,7 +388,8 @@ srs_error_t SrsFlvStreamEncoder::write_header(bool has_video, bool has_audio)
|
|||
return srs_error_wrap(err, "write header");
|
||||
}
|
||||
|
||||
srs_trace("FLV: write header audio=%d, video=%d", has_audio, has_video);
|
||||
srs_trace("FLV: write header audio=%d, video=%d, dinm=%d, config=%d/%d/%d", has_audio, has_video,
|
||||
enc->drop_if_not_match(), has_audio_, has_video_, guess_has_av_);
|
||||
}
|
||||
|
||||
return err;
|
||||
|
|
@ -563,12 +609,21 @@ srs_error_t SrsLiveStream::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMess
|
|||
|
||||
string enc_desc;
|
||||
ISrsBufferEncoder* enc = NULL;
|
||||
|
||||
|
||||
srs_assert(entry);
|
||||
bool drop_if_not_match = _srs_config->get_vhost_http_remux_drop_if_not_match(req->vhost);
|
||||
bool has_audio = _srs_config->get_vhost_http_remux_has_audio(req->vhost);
|
||||
bool has_video = _srs_config->get_vhost_http_remux_has_video(req->vhost);
|
||||
bool guess_has_av = _srs_config->get_vhost_http_remux_guess_has_av(req->vhost);
|
||||
|
||||
if (srs_string_ends_with(entry->pattern, ".flv")) {
|
||||
w->header()->set_content_type("video/x-flv");
|
||||
enc_desc = "FLV";
|
||||
enc = new SrsFlvStreamEncoder();
|
||||
((SrsFlvStreamEncoder*)enc)->set_drop_if_not_match(drop_if_not_match);
|
||||
((SrsFlvStreamEncoder*)enc)->set_has_audio(has_audio);
|
||||
((SrsFlvStreamEncoder*)enc)->set_has_video(has_video);
|
||||
((SrsFlvStreamEncoder*)enc)->set_guess_has_av(guess_has_av);
|
||||
} else if (srs_string_ends_with(entry->pattern, ".aac")) {
|
||||
w->header()->set_content_type("audio/x-aac");
|
||||
enc_desc = "AAC";
|
||||
|
|
@ -638,8 +693,9 @@ srs_error_t SrsLiveStream::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMess
|
|||
}
|
||||
|
||||
srs_utime_t mw_sleep = _srs_config->get_mw_sleep(req->vhost);
|
||||
srs_trace("FLV %s, encoder=%s, mw_sleep=%dms, cache=%d, msgs=%d", entry->pattern.c_str(), enc_desc.c_str(),
|
||||
srsu2msi(mw_sleep), enc->has_cache(), msgs.max);
|
||||
srs_trace("FLV %s, encoder=%s, mw_sleep=%dms, cache=%d, msgs=%d, dinm=%d, guess_av=%d/%d/%d",
|
||||
entry->pattern.c_str(), enc_desc.c_str(), srsu2msi(mw_sleep), enc->has_cache(), msgs.max, drop_if_not_match,
|
||||
has_audio, has_video, guess_has_av);
|
||||
|
||||
// TODO: free and erase the disabled entry after all related connections is closed.
|
||||
// TODO: FXIME: Support timeout for player, quit infinite-loop.
|
||||
|
|
|
|||
|
|
@ -68,6 +68,9 @@ class SrsFlvStreamEncoder : public ISrsBufferEncoder
|
|||
private:
|
||||
SrsFlvTransmuxer* enc;
|
||||
bool header_written;
|
||||
bool has_audio_;
|
||||
bool has_video_;
|
||||
bool guess_has_av_;
|
||||
public:
|
||||
SrsFlvStreamEncoder();
|
||||
virtual ~SrsFlvStreamEncoder();
|
||||
|
|
@ -76,6 +79,11 @@ public:
|
|||
virtual srs_error_t write_audio(int64_t timestamp, char* data, int size);
|
||||
virtual srs_error_t write_video(int64_t timestamp, char* data, int size);
|
||||
virtual srs_error_t write_metadata(int64_t timestamp, char* data, int size);
|
||||
public:
|
||||
void set_drop_if_not_match(bool v);
|
||||
void set_has_audio(bool v);
|
||||
void set_has_video(bool v);
|
||||
void set_guess_has_av(bool v);
|
||||
public:
|
||||
virtual bool has_cache();
|
||||
virtual srs_error_t dump_cache(SrsLiveConsumer* consumer, SrsRtmpJitterAlgorithm jitter);
|
||||
|
|
@ -83,7 +91,7 @@ public:
|
|||
// Write the tags in a time.
|
||||
virtual srs_error_t write_tags(SrsSharedPtrMessage** msgs, int count);
|
||||
private:
|
||||
virtual srs_error_t write_header(bool has_video = true, bool has_audio = true);
|
||||
virtual srs_error_t write_header(bool has_video, bool has_audio);
|
||||
};
|
||||
|
||||
// Transmux RTMP to HTTP TS Streaming.
|
||||
|
|
|
|||
|
|
@ -377,6 +377,10 @@ srs_error_t SrsRtmpFromSrtBridge::on_ts_video(SrsTsMessage* msg, SrsBuffer* avs)
|
|||
if ((err = avc->annexb_demux(avs, &frame, &frame_size)) != srs_success) {
|
||||
return srs_error_wrap(err, "demux annexb");
|
||||
}
|
||||
|
||||
if (frame == NULL || frame_size == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// for sps
|
||||
if (avc->is_sps(frame, frame_size)) {
|
||||
|
|
@ -426,6 +430,10 @@ srs_error_t SrsRtmpFromSrtBridge::check_sps_pps_change(SrsTsMessage* msg)
|
|||
return err;
|
||||
}
|
||||
|
||||
if (sps_.empty() || pps_.empty()) {
|
||||
return srs_error_new(ERROR_SRT_TO_RTMP_EMPTY_SPS_PPS, "sps or pps empty");
|
||||
}
|
||||
|
||||
// sps/pps changed, generate new video sh frame and dispatch it.
|
||||
sps_pps_change_ = false;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue