Compare commits
2 Commits
develop
...
7.0release
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
133f66afba | ||
|
|
386a3768df |
|
|
@ -10,7 +10,7 @@
|
||||||
[](https://hub.docker.com/r/ossrs/srs/tags)
|
[](https://hub.docker.com/r/ossrs/srs/tags)
|
||||||
[](https://codecov.io/gh/ossrs/srs)
|
[](https://codecov.io/gh/ossrs/srs)
|
||||||
|
|
||||||
SRS/8.0 ([Free](https://ossrs.io/lts/en-us/product#release-80)) is a simple, high-efficiency, and real-time video server,
|
SRS/7.0 ([Kai](https://ossrs.io/lts/en-us/product#release-70)) is a simple, high-efficiency, and real-time video server,
|
||||||
supporting RTMP/WebRTC/HLS/HTTP-FLV/SRT/MPEG-DASH/GB28181, Linux/macOS, X86_64/ARMv7/AARCH64/M1/RISCV/LOONGARCH/MIPS,
|
supporting RTMP/WebRTC/HLS/HTTP-FLV/SRT/MPEG-DASH/GB28181, Linux/macOS, X86_64/ARMv7/AARCH64/M1/RISCV/LOONGARCH/MIPS,
|
||||||
with codec support for H.264, H.265, AV1, VP9, AAC, Opus, and G.711,
|
with codec support for H.264, H.265, AV1, VP9, AAC, Opus, and G.711,
|
||||||
and essential [features](trunk/doc/Features.md#features).
|
and essential [features](trunk/doc/Features.md#features).
|
||||||
|
|
|
||||||
|
|
@ -136,21 +136,12 @@ func newSettings() *settings {
|
||||||
|
|
||||||
// The chunk stream which transport a message once.
|
// The chunk stream which transport a message once.
|
||||||
type chunkStream struct {
|
type chunkStream struct {
|
||||||
format formatType
|
format formatType
|
||||||
cid chunkID
|
cid chunkID
|
||||||
header messageHeader
|
header messageHeader
|
||||||
message *message
|
message *message
|
||||||
count uint64
|
count uint64
|
||||||
|
extendedTimestamp bool
|
||||||
// Whether the chunk carries an extended timestamp, set when the (delta) timestamp in
|
|
||||||
// the message header equals 0xffffff. Type-3 continuation chunks inherit this from the
|
|
||||||
// preceding Type-0/1/2 chunk.
|
|
||||||
hasExtendedTimestamp bool
|
|
||||||
// The raw value last read from the extended timestamp field. Kept separately from
|
|
||||||
// header.Timestamp (the accumulated message timestamp) so we can both detect Type-3
|
|
||||||
// chunks that omit the extended timestamp and use it as a delta for fmt=1/2 chunks.
|
|
||||||
// See readMessageHeader.
|
|
||||||
extendedTimestamp uint32
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newChunkStream() *chunkStream {
|
func newChunkStream() *chunkStream {
|
||||||
|
|
@ -549,7 +540,29 @@ func (v *protocol) readMessageHeader(ctx context.Context, chunk *chunkStream, fo
|
||||||
// 0x00ffffff), this value MUST be 16777215, and the 'extended
|
// 0x00ffffff), this value MUST be 16777215, and the 'extended
|
||||||
// timestamp header' MUST be present. Otherwise, this value SHOULD be
|
// timestamp header' MUST be present. Otherwise, this value SHOULD be
|
||||||
// the entire delta.
|
// the entire delta.
|
||||||
chunk.hasExtendedTimestamp = uint64(chunk.header.timestampDelta) >= extendedTimestamp
|
chunk.extendedTimestamp = uint64(chunk.header.timestampDelta) >= extendedTimestamp
|
||||||
|
if !chunk.extendedTimestamp {
|
||||||
|
// Extended timestamp: 0 or 4 bytes
|
||||||
|
// This field MUST be sent when the normal timsestamp is set to
|
||||||
|
// 0xffffff, it MUST NOT be sent if the normal timestamp is set to
|
||||||
|
// anything else. So for values less than 0xffffff the normal
|
||||||
|
// timestamp field SHOULD be used in which case the extended timestamp
|
||||||
|
// MUST NOT be present. For values greater than or equal to 0xffffff
|
||||||
|
// the normal timestamp field MUST NOT be used and MUST be set to
|
||||||
|
// 0xffffff and the extended timestamp MUST be sent.
|
||||||
|
if format == formatType0 {
|
||||||
|
// 6.1.2.1. Type 0
|
||||||
|
// For a type-0 chunk, the absolute timestamp of the message is sent
|
||||||
|
// here.
|
||||||
|
chunk.header.Timestamp = uint64(chunk.header.timestampDelta)
|
||||||
|
} else {
|
||||||
|
// 6.1.2.2. Type 1
|
||||||
|
// 6.1.2.3. Type 2
|
||||||
|
// For a type-1 or type-2 chunk, the difference between the previous
|
||||||
|
// chunk's timestamp and the current chunk's timestamp is sent here.
|
||||||
|
chunk.header.Timestamp += uint64(chunk.header.timestampDelta)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if format <= formatType1 {
|
if format <= formatType1 {
|
||||||
payloadLength := uint32(p[0])<<16 | uint32(p[1])<<8 | uint32(p[2])
|
payloadLength := uint32(p[0])<<16 | uint32(p[1])<<8 | uint32(p[2])
|
||||||
|
|
@ -572,58 +585,27 @@ func (v *protocol) readMessageHeader(ctx context.Context, chunk *chunkStream, fo
|
||||||
p = p[4:]
|
p = p[4:]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Update the timestamp even fmt=3 for first chunk packet
|
||||||
|
if isFirstChunkOfMsg && !chunk.extendedTimestamp {
|
||||||
|
chunk.header.Timestamp += uint64(chunk.header.timestampDelta)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read extended-timestamp, present when the (delta) timestamp in the message header is
|
// Read extended-timestamp
|
||||||
// 0xffffff. Type-3 chunks inherit hasExtendedTimestamp from the preceding chunk.
|
if chunk.extendedTimestamp {
|
||||||
if chunk.hasExtendedTimestamp {
|
var timestamp uint32
|
||||||
// Peek instead of read, so the 4 bytes can be left in place when a sender omits the
|
if err = binary.Read(v.r, binary.BigEndian, ×tamp); err != nil {
|
||||||
// extended timestamp on a Type-3 chunk (see the detection below).
|
|
||||||
var b []byte
|
|
||||||
if b, err = v.r.Peek(4); err != nil {
|
|
||||||
return errors.Wrapf(err, "read ext-ts, pkt-ts=%v", chunk.header.Timestamp)
|
return errors.Wrapf(err, "read ext-ts, pkt-ts=%v", chunk.header.Timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We always use 31bits timestamp, for some server may use 32bits extended timestamp.
|
// We always use 31bits timestamp, for some server may use 32bits extended timestamp.
|
||||||
// @see https://github.com/ossrs/srs/issues/111
|
// @see https://github.com/ossrs/srs/issues/111
|
||||||
timestamp := binary.BigEndian.Uint32(b) & 0x7fffffff
|
timestamp &= 0x7fffffff
|
||||||
|
|
||||||
// For the RTMP v1 2009 version (6.1.3. Extended Timestamp), Type 3 chunks MUST NOT
|
// TODO: FIXME: Support detect the extended timestamp.
|
||||||
// have this field. For the RTMP v1 2012 version (5.3.1.3. Extended Timestamp), it is
|
|
||||||
// present in Type 3 chunks when the most recent Type 0/1/2 chunk indicated one.
|
|
||||||
//
|
|
||||||
// FMLE/FMS/Flash Player follow the 2012 version and always send the extended
|
|
||||||
// timestamp in Type 3 chunks; librtmp/ffmpeg may not. So detect it: if this is not
|
|
||||||
// the first chunk of the message and the peeked value differs from the previously
|
|
||||||
// stored extended timestamp, the sender omitted it and these 4 bytes are payload, so
|
|
||||||
// leave them in the reader. Otherwise consume and store them.
|
|
||||||
// @see http://blog.csdn.net/win_lin/article/details/13363699
|
// @see http://blog.csdn.net/win_lin/article/details/13363699
|
||||||
// @see https://github.com/veovera/enhanced-rtmp/issues/42
|
|
||||||
if !isFirstChunkOfMsg && chunk.extendedTimestamp > 0 && chunk.extendedTimestamp != timestamp {
|
|
||||||
// No extended timestamp on this Type-3 chunk; the 4 bytes belong to the payload.
|
|
||||||
} else {
|
|
||||||
if _, err = v.r.Discard(4); err != nil {
|
|
||||||
return errors.Wrapf(err, "discard ext-ts, pkt-ts=%v", chunk.header.Timestamp)
|
|
||||||
}
|
|
||||||
chunk.extendedTimestamp = timestamp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute the message timestamp. The source is the extended timestamp when present,
|
|
||||||
// otherwise the 3-byte (delta) timestamp from the message header.
|
|
||||||
//
|
|
||||||
// fmt=0: the value is the absolute timestamp of the message.
|
|
||||||
// fmt=1/2 (and a fmt=3 first chunk continuing them): the value is a delta and is
|
|
||||||
// accumulated onto the previous timestamp. This is required when the delta is >= 0xffffff
|
|
||||||
// and is therefore carried in the extended timestamp.
|
|
||||||
timestamp := chunk.header.timestampDelta
|
|
||||||
if chunk.hasExtendedTimestamp {
|
|
||||||
timestamp = chunk.extendedTimestamp
|
|
||||||
}
|
|
||||||
if format == formatType0 {
|
|
||||||
chunk.header.Timestamp = uint64(timestamp)
|
chunk.header.Timestamp = uint64(timestamp)
|
||||||
} else if isFirstChunkOfMsg {
|
|
||||||
chunk.header.Timestamp += uint64(timestamp)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The extended-timestamp must be unsigned-int,
|
// The extended-timestamp must be unsigned-int,
|
||||||
|
|
@ -714,11 +696,6 @@ func (v *protocol) readBasicHeader(ctx context.Context) (format formatType, cid
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Here cid is 0 or 1: a marker selecting the 2B or 3B form, not the real cid. Keep it,
|
|
||||||
// because cid is overwritten below and the marker decides whether a third byte (the
|
|
||||||
// high-order part of the cid) follows. Do not test the overwritten cid for this.
|
|
||||||
marker := cid
|
|
||||||
|
|
||||||
// 64-319, 2B chunk header
|
// 64-319, 2B chunk header
|
||||||
if err = binary.Read(v.r, binary.BigEndian, &t); err != nil {
|
if err = binary.Read(v.r, binary.BigEndian, &t); err != nil {
|
||||||
return format, cid, errors.Wrapf(err, "read basic header for cid=%v", cid)
|
return format, cid, errors.Wrapf(err, "read basic header for cid=%v", cid)
|
||||||
|
|
@ -726,7 +703,7 @@ func (v *protocol) readBasicHeader(ctx context.Context) (format formatType, cid
|
||||||
cid = chunkID(64 + uint32(t))
|
cid = chunkID(64 + uint32(t))
|
||||||
|
|
||||||
// 64-65599, 3B chunk header
|
// 64-65599, 3B chunk header
|
||||||
if marker == 1 {
|
if cid == 1 {
|
||||||
if err = binary.Read(v.r, binary.BigEndian, &t); err != nil {
|
if err = binary.Read(v.r, binary.BigEndian, &t); err != nil {
|
||||||
return format, cid, errors.Wrapf(err, "read basic header for cid=%v", cid)
|
return format, cid, errors.Wrapf(err, "read basic header for cid=%v", cid)
|
||||||
}
|
}
|
||||||
|
|
@ -1306,12 +1283,6 @@ func (v *variantCallPacket) UnmarshalBinary(data []byte) (err error) {
|
||||||
}
|
}
|
||||||
p = p[v.TransactionID.Size():]
|
p = p[v.TransactionID.Size():]
|
||||||
|
|
||||||
// Reset the optional command object before deciding whether it is present.
|
|
||||||
// A New*Packet constructor may have pre-set it to a default (e.g. Null), but
|
|
||||||
// when the wire data is exhausted here the object is absent. Leaving the stale
|
|
||||||
// default would make Size() count bytes that were never parsed, overflowing the
|
|
||||||
// caller's p = p[Size():] advance on truncated, untrusted input.
|
|
||||||
v.CommandObject = nil
|
|
||||||
if len(p) > 0 {
|
if len(p) > 0 {
|
||||||
if v.CommandObject, err = Amf0Discovery(p); err != nil {
|
if v.CommandObject, err = Amf0Discovery(p); err != nil {
|
||||||
return errors.WithMessage(err, "discovery command object")
|
return errors.WithMessage(err, "discovery command object")
|
||||||
|
|
@ -1382,32 +1353,14 @@ func (v *CallPacket) Size() int {
|
||||||
return size
|
return size
|
||||||
}
|
}
|
||||||
|
|
||||||
// advanceBytes returns p[n:] after verifying n lies within p. Packet
|
|
||||||
// UnmarshalBinary advances its cursor by each embedded field's decoded Size();
|
|
||||||
// on untrusted wire input a malformed length can make Size() exceed the bytes
|
|
||||||
// actually present, so this guard turns a slice-out-of-range panic into a clean
|
|
||||||
// error. See the RTMP test plan, P8 (adversarial resource-safety).
|
|
||||||
func advanceBytes(p []byte, n int) ([]byte, error) {
|
|
||||||
if n < 0 || n > len(p) {
|
|
||||||
return nil, errors.Errorf("advance %v exceeds remaining %v bytes", n, len(p))
|
|
||||||
}
|
|
||||||
return p[n:], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *CallPacket) UnmarshalBinary(data []byte) (err error) {
|
func (v *CallPacket) UnmarshalBinary(data []byte) (err error) {
|
||||||
p := data
|
p := data
|
||||||
|
|
||||||
if err = v.variantCallPacket.UnmarshalBinary(p); err != nil {
|
if err = v.variantCallPacket.UnmarshalBinary(p); err != nil {
|
||||||
return errors.WithMessage(err, "unmarshal call")
|
return errors.WithMessage(err, "unmarshal call")
|
||||||
}
|
}
|
||||||
if p, err = advanceBytes(p, v.variantCallPacket.Size()); err != nil {
|
p = p[v.variantCallPacket.Size():]
|
||||||
return errors.WithMessage(err, "advance call")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset the optional args before deciding whether they are present, for the
|
|
||||||
// same reason as variantCallPacket.CommandObject: a stale constructor default
|
|
||||||
// would be counted by Size() and overflow a later advance.
|
|
||||||
v.Args = nil
|
|
||||||
if len(p) > 0 {
|
if len(p) > 0 {
|
||||||
if v.Args, err = Amf0Discovery(p); err != nil {
|
if v.Args, err = Amf0Discovery(p); err != nil {
|
||||||
return errors.WithMessage(err, "discovery args")
|
return errors.WithMessage(err, "discovery args")
|
||||||
|
|
@ -1483,9 +1436,7 @@ func (v *CreateStreamResPacket) UnmarshalBinary(data []byte) (err error) {
|
||||||
if err = v.variantCallPacket.UnmarshalBinary(p); err != nil {
|
if err = v.variantCallPacket.UnmarshalBinary(p); err != nil {
|
||||||
return errors.WithMessage(err, "unmarshal call")
|
return errors.WithMessage(err, "unmarshal call")
|
||||||
}
|
}
|
||||||
if p, err = advanceBytes(p, v.variantCallPacket.Size()); err != nil {
|
p = p[v.variantCallPacket.Size():]
|
||||||
return errors.WithMessage(err, "advance call")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = v.StreamID.UnmarshalBinary(p); err != nil {
|
if err = v.StreamID.UnmarshalBinary(p); err != nil {
|
||||||
return errors.WithMessage(err, "unmarshal sid")
|
return errors.WithMessage(err, "unmarshal sid")
|
||||||
|
|
@ -1535,9 +1486,7 @@ func (v *PublishPacket) UnmarshalBinary(data []byte) (err error) {
|
||||||
if err = v.variantCallPacket.UnmarshalBinary(p); err != nil {
|
if err = v.variantCallPacket.UnmarshalBinary(p); err != nil {
|
||||||
return errors.WithMessage(err, "unmarshal call")
|
return errors.WithMessage(err, "unmarshal call")
|
||||||
}
|
}
|
||||||
if p, err = advanceBytes(p, v.variantCallPacket.Size()); err != nil {
|
p = p[v.variantCallPacket.Size():]
|
||||||
return errors.WithMessage(err, "advance call")
|
|
||||||
}
|
|
||||||
|
|
||||||
v.StreamName = newAmf0String("")
|
v.StreamName = newAmf0String("")
|
||||||
if err = v.StreamName.UnmarshalBinary(p); err != nil {
|
if err = v.StreamName.UnmarshalBinary(p); err != nil {
|
||||||
|
|
@ -1597,9 +1546,7 @@ func (v *PlayPacket) UnmarshalBinary(data []byte) (err error) {
|
||||||
if err = v.variantCallPacket.UnmarshalBinary(p); err != nil {
|
if err = v.variantCallPacket.UnmarshalBinary(p); err != nil {
|
||||||
return errors.WithMessage(err, "unmarshal call")
|
return errors.WithMessage(err, "unmarshal call")
|
||||||
}
|
}
|
||||||
if p, err = advanceBytes(p, v.variantCallPacket.Size()); err != nil {
|
p = p[v.variantCallPacket.Size():]
|
||||||
return errors.WithMessage(err, "advance call")
|
|
||||||
}
|
|
||||||
|
|
||||||
v.StreamName = newAmf0String("")
|
v.StreamName = newAmf0String("")
|
||||||
if err = v.StreamName.UnmarshalBinary(p); err != nil {
|
if err = v.StreamName.UnmarshalBinary(p); err != nil {
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -6,7 +6,7 @@ package version
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
func VersionMajor() int {
|
func VersionMajor() int {
|
||||||
return 8
|
return 7
|
||||||
}
|
}
|
||||||
|
|
||||||
// VersionMinor specifies the typical version of SRS we adapt to.
|
// VersionMinor specifies the typical version of SRS we adapt to.
|
||||||
|
|
@ -15,7 +15,7 @@ func VersionMinor() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func VersionRevision() int {
|
func VersionRevision() int {
|
||||||
return 3
|
return 150
|
||||||
}
|
}
|
||||||
|
|
||||||
func Version() string {
|
func Version() string {
|
||||||
|
|
|
||||||
|
|
@ -9,14 +9,14 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestVersionComponents(t *testing.T) {
|
func TestVersionComponents(t *testing.T) {
|
||||||
if got := VersionMajor(); got != 8 {
|
if got := VersionMajor(); got != 7 {
|
||||||
t.Fatalf("VersionMajor = %d, want 8", got)
|
t.Fatalf("VersionMajor = %d, want 7", got)
|
||||||
}
|
}
|
||||||
if got := VersionMinor(); got != 0 {
|
if got := VersionMinor(); got != 0 {
|
||||||
t.Fatalf("VersionMinor = %d, want 0", got)
|
t.Fatalf("VersionMinor = %d, want 0", got)
|
||||||
}
|
}
|
||||||
if got := VersionRevision(); got < 0 {
|
if got := VersionRevision(); got <= 0 {
|
||||||
t.Fatalf("VersionRevision = %d, want >= 0", got)
|
t.Fatalf("VersionRevision = %d, want > 0", got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ The C++ media server (`trunk/src/`) serves as both origin server and edge server
|
||||||
|
|
||||||
`core/` — Foundational definitions:
|
`core/` — Foundational definitions:
|
||||||
- `core` — Core includes, macros, config generated by configure
|
- `core` — Core includes, macros, config generated by configure
|
||||||
- `core_version` through `core_version8` — Version definitions per major release
|
- `core_version` through `core_version7` — Version definitions per major release
|
||||||
- `core_autofree` — SrsUniquePtr smart pointer (RAII)
|
- `core_autofree` — SrsUniquePtr smart pointer (RAII)
|
||||||
- `core_deprecated` — Deprecated SrsAutoFree, kept for compat
|
- `core_deprecated` — Deprecated SrsAutoFree, kept for compat
|
||||||
- `core_performance` — Performance tuning constants (merge-read, etc.)
|
- `core_performance` — Performance tuning constants (merge-read, etc.)
|
||||||
|
|
@ -227,7 +227,7 @@ The next-generation server (`cmd/` + `internal/`) is written in Go and maintaine
|
||||||
|
|
||||||
`internal/env` — Environment-based configuration. All settings via env vars (or `.env` file parsed by an in-tree custom parser — no third-party dep; supports comments, `export` prefix, quoted values, escape sequences, and inline comments). Exposes a `ProxyEnvironment` interface (with a counterfeiter-generated fake in `envfakes/` for downstream tests) with methods for each config value. Default ports: RTMP=11935, HTTP API=11985, HTTP Stream=18080, WebRTC=18000, SRT=20080, System API=12025. Timeouts: grace=20s, force=30s. Supports Redis config and default backend config for debugging.
|
`internal/env` — Environment-based configuration. All settings via env vars (or `.env` file parsed by an in-tree custom parser — no third-party dep; supports comments, `export` prefix, quoted values, escape sequences, and inline comments). Exposes a `ProxyEnvironment` interface (with a counterfeiter-generated fake in `envfakes/` for downstream tests) with methods for each config value. Default ports: RTMP=11935, HTTP API=11985, HTTP Stream=18080, WebRTC=18000, SRT=20080, System API=12025. Timeouts: grace=20s, force=30s. Supports Redis config and default backend config for debugging.
|
||||||
|
|
||||||
`internal/version` — Version constants. Signature `SRSX`, version tracks the SRS project version (currently 8.0.x). Used in HTTP API responses and startup logging.
|
`internal/version` — Version constants. Signature `SRSX`, version tracks the SRS project version (currently 7.0.x). Used in HTTP API responses and startup logging.
|
||||||
|
|
||||||
`internal/errors` — Error handling with stack traces, thin wrapper over stdlib `errors`. Provides `New`, `Errorf`, `Wrap`, `Wrapf`, `WithMessage`, `WithStack`, `Cause`, and re-exports `Is`/`As`/`Unwrap`/`Join`. Every error captures a stack trace at creation; `%+v` prints the full trace. `Cause()` walks the error chain to find the root error.
|
`internal/errors` — Error handling with stack traces, thin wrapper over stdlib `errors`. Provides `New`, `Errorf`, `Wrap`, `Wrapf`, `WithMessage`, `WithStack`, `Cause`, and re-exports `Is`/`As`/`Unwrap`/`Join`. Every error captures a stack trace at creation; `%+v` prints the full trace. `Cause()` walks the error chain to find the root error.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -77,13 +77,13 @@ Do NOT attempt unsupported tasks.
|
||||||
1. Ask the user for the PR number if they haven't given it.
|
1. Ask the user for the PR number if they haven't given it.
|
||||||
2. Bump revision by one in **both** version files, keeping them in sync:
|
2. Bump revision by one in **both** version files, keeping them in sync:
|
||||||
- `internal/version/version.go` — `VersionRevision()`
|
- `internal/version/version.go` — `VersionRevision()`
|
||||||
- `trunk/src/core/srs_core_version8.hpp` — `VERSION_REVISION`
|
- `trunk/src/core/srs_core_version7.hpp` — `VERSION_REVISION`
|
||||||
3. Add a new top entry to `trunk/doc/CHANGELOG.md` under `## SRS 8.0 Changelog`, matching the existing format:
|
3. Add a new top entry to `trunk/doc/CHANGELOG.md` under `## SRS 7.0 Changelog`, matching the existing format:
|
||||||
```
|
```
|
||||||
* v8.0, YYYY-MM-DD, Merge [#PR](URL): <Prefix>: <one-line summary>. v8.0.<rev> (#PR)
|
* v7.0, YYYY-MM-DD, Merge [#PR](URL): <Prefix>: <one-line summary>. v7.0.<rev> (#PR)
|
||||||
```
|
```
|
||||||
Propose the summary to the user; don't invent one unilaterally.
|
Propose the summary to the user; don't invent one unilaterally.
|
||||||
4. Stop. Let the user review. When they `git add` the version files and changelog, commit with a short message like `Proxy: Bump to v8.0.<rev> for #<PR>.`.
|
4. Stop. Let the user review. When they `git add` the version files and changelog, commit with a short message like `Proxy: Bump to v7.0.<rev> for #<PR>.`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -143,7 +143,7 @@ Only after the user confirms the routing do you proceed to Step 2.
|
||||||
```
|
```
|
||||||
bash scripts/proxy-utest.sh --coverage
|
bash scripts/proxy-utest.sh --coverage
|
||||||
```
|
```
|
||||||
4. Run **all** of the proxy E2E tests below — every one, not just the first. Run them one at a time (they bind fixed ports, so they cannot run in parallel), and do not stop early: a later test can fail even when the earlier ones pass.
|
4. Run the proxy E2E tests:
|
||||||
- Single-origin RTMP proxy test (starts proxy + one SRS origin, publishes RTMP, verifies playback):
|
- Single-origin RTMP proxy test (starts proxy + one SRS origin, publishes RTMP, verifies playback):
|
||||||
```
|
```
|
||||||
bash scripts/proxy-e2e-test.sh
|
bash scripts/proxy-e2e-test.sh
|
||||||
|
|
|
||||||
2
trunk/configure
vendored
2
trunk/configure
vendored
|
|
@ -237,7 +237,7 @@ fi
|
||||||
MODULE_ID="CORE"
|
MODULE_ID="CORE"
|
||||||
MODULE_DEPENDS=()
|
MODULE_DEPENDS=()
|
||||||
ModuleLibIncs=(${SRS_OBJS})
|
ModuleLibIncs=(${SRS_OBJS})
|
||||||
MODULE_FILES=("srs_core" "srs_core_version" "srs_core_version8" "srs_core_autofree"
|
MODULE_FILES=("srs_core" "srs_core_version" "srs_core_version7" "srs_core_autofree"
|
||||||
"srs_core_time" "srs_core_platform" "srs_core_deprecated" "srs_core_performance")
|
"srs_core_time" "srs_core_platform" "srs_core_deprecated" "srs_core_performance")
|
||||||
CORE_INCS="src/core"; MODULE_DIR=${CORE_INCS} . $SRS_WORKDIR/auto/modules.sh
|
CORE_INCS="src/core"; MODULE_DIR=${CORE_INCS} . $SRS_WORKDIR/auto/modules.sh
|
||||||
CORE_OBJS="${MODULE_OBJS[@]}"
|
CORE_OBJS="${MODULE_OBJS[@]}"
|
||||||
|
|
|
||||||
|
|
@ -4,17 +4,11 @@
|
||||||
|
|
||||||
The changelog for SRS.
|
The changelog for SRS.
|
||||||
|
|
||||||
<a name="v8-changes"></a>
|
|
||||||
|
|
||||||
## SRS 8.0 Changelog
|
|
||||||
* v8.0, 2026-05-28, Merge [#4680](https://github.com/ossrs/srs/pull/4680): RTMP: Fix chunk timestamp/basic-header decoding and harden packet unmarshal. v8.0.3 (#4680)
|
|
||||||
* v8.0, 2026-05-19, Merge [#4678](https://github.com/ossrs/srs/pull/4678): Edge: Fix HTTP-FLV 404 and RTMP late-join missing sequence headers. v8.0.2 (#4678)
|
|
||||||
* v8.0, 2026-05-17, Merge [#4676](https://github.com/ossrs/srs/pull/4676): Proxy: Fix RTC/SRT reader goroutine leak; unwrap legacy WHEP JSON envelope; add WHEP pprof guide. v8.0.1 (#4676)
|
|
||||||
* v8.0, 2026-05-17, Init SRS 8.0, code Free. v8.0.0
|
|
||||||
|
|
||||||
<a name="v7-changes"></a>
|
<a name="v7-changes"></a>
|
||||||
|
|
||||||
## SRS 7.0 Changelog
|
## SRS 7.0 Changelog
|
||||||
|
* v7.0, 2026-05-19, Merge [#4678](https://github.com/ossrs/srs/pull/4678): Edge: Fix HTTP-FLV 404 and RTMP late-join missing sequence headers. v7.0.150 (#4678)
|
||||||
|
* v7.0, 2026-05-17, Merge [#4676](https://github.com/ossrs/srs/pull/4676): Proxy: Fix RTC/SRT reader goroutine leak; unwrap legacy WHEP JSON envelope; add WHEP pprof guide. v7.0.149 (#4676)
|
||||||
* v7.0, 2026-05-17, Merge [#4675](https://github.com/ossrs/srs/pull/4675): Proxy: Refactor for testability; add SRT/WHIP E2E and unit tests. v7.0.148 (#4675)
|
* v7.0, 2026-05-17, Merge [#4675](https://github.com/ossrs/srs/pull/4675): Proxy: Refactor for testability; add SRT/WHIP E2E and unit tests. v7.0.148 (#4675)
|
||||||
* v7.0, 2026-05-02, Merge [#4672](https://github.com/ossrs/srs/pull/4672): Proxy: Refactor server APIs and expand RTMP test coverage. v7.0.147 (#4672)
|
* v7.0, 2026-05-02, Merge [#4672](https://github.com/ossrs/srs/pull/4672): Proxy: Refactor server APIs and expand RTMP test coverage. v7.0.147 (#4672)
|
||||||
* v7.0, 2026-04-28, Merge [#4670](https://github.com/ossrs/srs/pull/4670): Proxy: Refine logger and environment APIs. v7.0.146 (#4670)
|
* v7.0, 2026-04-28, Merge [#4670](https://github.com/ossrs/srs/pull/4670): Proxy: Refine logger and environment APIs. v7.0.146 (#4670)
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,6 @@
|
||||||
#ifndef SRS_CORE_VERSION_HPP
|
#ifndef SRS_CORE_VERSION_HPP
|
||||||
#define SRS_CORE_VERSION_HPP
|
#define SRS_CORE_VERSION_HPP
|
||||||
|
|
||||||
#include <srs_core_version8.hpp>
|
#include <srs_core_version7.hpp>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,6 @@
|
||||||
|
|
||||||
#define VERSION_MAJOR 7
|
#define VERSION_MAJOR 7
|
||||||
#define VERSION_MINOR 0
|
#define VERSION_MINOR 0
|
||||||
#define VERSION_REVISION 148
|
#define VERSION_REVISION 150
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2013-2026 The SRS Authors
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <srs_core_version8.hpp>
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2013-2026 The SRS Authors
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef SRS_CORE_VERSION8_HPP
|
|
||||||
#define SRS_CORE_VERSION8_HPP
|
|
||||||
|
|
||||||
#define VERSION_MAJOR 8
|
|
||||||
#define VERSION_MINOR 0
|
|
||||||
#define VERSION_REVISION 3
|
|
||||||
|
|
||||||
#endif
|
|
||||||
Loading…
Reference in New Issue
Block a user