Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support publishing VP9 tracks with RTMP #2247

Merged
merged 1 commit into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Live streams can be published to the server with:
|[WebRTC servers](#webrtc-servers)|WHEP|AV1, VP9, VP8, H264|Opus, G722, G711|
|[RTSP clients](#rtsp-clients)|UDP, TCP, RTSPS|AV1, VP9, VP8, H265, H264, MPEG-4 Video (H263, Xvid), MPEG-1/2 Video, M-JPEG and any RTP-compatible codec|Opus, MPEG-4 Audio (AAC), MPEG-1/2 Audio (MP3), G726, G722, G711, LPCM and any RTP-compatible codec|
|[RTSP cameras and servers](#rtsp-cameras-and-servers)|UDP, UDP-Multicast, TCP, RTSPS|AV1, VP9, VP8, H265, H264, MPEG-4 Video (H263, Xvid), MPEG-1/2 Video, M-JPEG and any RTP-compatible codec|Opus, MPEG-4 Audio (AAC), MPEG-1/2 Audio (MP3), G726, G722, G711, LPCM and any RTP-compatible codec|
|[RTMP clients](#rtmp-clients)|RTMP, RTMPS, Enhanced RTMP|AV1, H265, H264|MPEG-4 Audio (AAC), MPEG-1/2 Audio (MP3)|
|[RTMP clients](#rtmp-clients)|RTMP, RTMPS, Enhanced RTMP|AV1, VP9, H265, H264|MPEG-4 Audio (AAC), MPEG-1/2 Audio (MP3)|
|[RTMP cameras and servers](#rtmp-cameras-and-servers)|RTMP, RTMPS, Enhanced RTMP|H264|MPEG-4 Audio (AAC), MPEG-1/2 Audio (MP3)|
|[HLS cameras and servers](#hls-cameras-and-servers)|Low-Latency HLS, MP4-based HLS, legacy HLS|AV1, VP9, H265, H264|Opus, MPEG-4 Audio (AAC)|
|[UDP/MPEG-TS](#udpmpeg-ts)|Unicast, broadcast, multicast|H265, H264|Opus, MPEG-4 Audio (AAC), MPEG-1/2 Audio (MP3)|
Expand All @@ -46,7 +46,6 @@ And can be read from the server with:

* Publish live streams to the server
* Read live streams from the server
* Proxy streams from other servers or cameras, always or on-demand
* Streams are automatically converted from a protocol to another. For instance, it's possible to publish a stream with RTSP and read it with HLS
* Serve multiple streams at once in separate paths
* Authenticate users; use internal or external authentication
Expand Down Expand Up @@ -102,7 +101,7 @@ _rtsp-simple-server_ has been rebranded as _MediaMTX_. The reason is pretty obvi
* [RTSP](#rtsp)
* [RTMP](#rtmp)
* [HLS](#hls)
* [Features](#features)
* [Other features](#other-features)
* [Configuration](#configuration)
* [Authentication](#authentication)
* [Encrypt the configuration](#encrypt-the-configuration)
Expand Down Expand Up @@ -977,7 +976,7 @@ To decrease the latency, you can:
ffmpeg -i rtsp://original-stream -pix_fmt yuv420p -c:v libx264 -preset ultrafast -b:v 600k -max_muxing_queue_size 1024 -g 30 -f rtsp rtsp://localhost:$RTSP_PORT/compressed
```

## Features
## Other features

### Configuration

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.20

require (
code.cloudfoundry.org/bytefmt v0.0.0
github.com/abema/go-mp4 v0.12.0
github.com/abema/go-mp4 v0.13.0
github.com/alecthomas/kong v0.8.0
github.com/bluenviron/gohlslib v1.0.0
github.com/bluenviron/gortsplib/v3 v3.10.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
github.com/abema/go-mp4 v0.12.0 h1:XI9PPt1BpjB3wFl18oFiX6C99uesx7F/X13Z+ga8bYY=
github.com/abema/go-mp4 v0.12.0/go.mod h1:vPl9t5ZK7K0x68jh12/+ECWBCXoWuIDtNgPtU2f04ws=
github.com/abema/go-mp4 v0.13.0 h1:gjEZLt7g0ePpYA5sUDrI2r8X+WuI8o+USkgG5wMgmkI=
github.com/abema/go-mp4 v0.13.0/go.mod h1:vPl9t5ZK7K0x68jh12/+ECWBCXoWuIDtNgPtU2f04ws=
github.com/alecthomas/assert/v2 v2.1.0 h1:tbredtNcQnoSd3QBhQWI7QZ3XHOVkw1Moklp2ojoH/0=
github.com/alecthomas/kong v0.8.0 h1:ryDCzutfIqJPnNn0omnrgHLbAggDQM2VWHikE1xqK7s=
github.com/alecthomas/kong v0.8.0/go.mod h1:n1iCIO2xS46oE8ZfYCNDqdR0b0wZNrXAIAqro/2132U=
Expand Down
17 changes: 17 additions & 0 deletions internal/core/rtmp_conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,17 @@ func (c *rtmpConn) runPublish(conn *rtmp.Conn, u *url.URL) error {
})
})

case *formats.VP9:
r.OnDataVP9(func(pts time.Duration, frame []byte) {
stream.WriteUnit(videoMedia, videoFormat, &formatprocessor.UnitVP9{
BaseUnit: formatprocessor.BaseUnit{
NTP: time.Now(),
},
PTS: pts,
Frame: frame,
})
})

case *formats.H265:
r.OnDataH265(func(pts time.Duration, au [][]byte) {
stream.WriteUnit(videoMedia, videoFormat, &formatprocessor.UnitH265{
Expand All @@ -654,6 +665,9 @@ func (c *rtmpConn) runPublish(conn *rtmp.Conn, u *url.URL) error {
AU: au,
})
})

default:
return fmt.Errorf("unsupported video codec: %T", videoFormat)
}
}

Expand Down Expand Up @@ -686,6 +700,9 @@ func (c *rtmpConn) runPublish(conn *rtmp.Conn, u *url.URL) error {
Frames: [][]byte{frame},
})
})

default:
return fmt.Errorf("unsupported audio codec: %T", audioFormat)
}
}

Expand Down
14 changes: 8 additions & 6 deletions internal/core/rtmp_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,6 @@ func (s *rtmpSource) runReader(u *url.URL, nconn net.Conn) error {

videoFormat, audioFormat := mc.Tracks()

switch videoFormat.(type) {
case *formats.H265, *formats.AV1:
return fmt.Errorf("proxying H265 or AV1 tracks with RTMP is not supported")
}

var medias media.Medias
var stream *stream.Stream

Expand All @@ -128,7 +123,8 @@ func (s *rtmpSource) runReader(u *url.URL, nconn net.Conn) error {
}
medias = append(medias, videoMedia)

if _, ok := videoFormat.(*formats.H264); ok {
switch videoFormat.(type) {
case *formats.H264:
mc.OnDataH264(func(pts time.Duration, au [][]byte) {
stream.WriteUnit(videoMedia, videoFormat, &formatprocessor.UnitH264{
BaseUnit: formatprocessor.BaseUnit{
Expand All @@ -138,6 +134,9 @@ func (s *rtmpSource) runReader(u *url.URL, nconn net.Conn) error {
AU: au,
})
})

default:
return fmt.Errorf("unsupported video codec: %T", videoFormat)
}
}

Expand Down Expand Up @@ -170,6 +169,9 @@ func (s *rtmpSource) runReader(u *url.URL, nconn net.Conn) error {
Frames: [][]byte{frame},
})
})

default:
return fmt.Errorf("unsupported audio codec: %T", audioFormat)
}
}

Expand Down
21 changes: 20 additions & 1 deletion internal/rtmp/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ import (
// OnDataAV1Func is the prototype of the callback passed to OnDataAV1().
type OnDataAV1Func func(pts time.Duration, tu [][]byte)

// OnDataVP9Func is the prototype of the callback passed to OnDataVP9().
type OnDataVP9Func func(pts time.Duration, frame []byte)

// OnDataH26xFunc is the prototype of the callback passed to OnDataH26x().
type OnDataH26xFunc func(pts time.Duration, au [][]byte)

Expand Down Expand Up @@ -252,7 +255,13 @@ func tracksFromMetadata(conn *Conn, payload []interface{}) (formats.Format, form
videoTrack = &formats.AV1{}

default: // VP9
return nil, nil, fmt.Errorf("VP9 is not supported yet")
var vpcc mp4.VpcC
_, err := mp4.Unmarshal(bytes.NewReader(tmsg.Config), uint64(len(tmsg.Config)), &vpcc, mp4.Context{})
if err != nil {
return nil, nil, fmt.Errorf("invalid VP9 configuration: %v", err)
}

videoTrack = &formats.VP9{}
}
}

Expand Down Expand Up @@ -449,6 +458,16 @@ func (r *Reader) OnDataAV1(cb OnDataAV1Func) {
}
}

// OnDataVP9 sets a callback that is called when VP9 data is received.
func (r *Reader) OnDataVP9(cb OnDataVP9Func) {
r.onDataVideo = func(msg message.Message) error {
if msg, ok := msg.(*message.ExtendedCodedFrames); ok {
cb(msg.DTS, msg.Payload)
}
return nil
}
}

// OnDataH265 sets a callback that is called when H265 data is received.
func (r *Reader) OnDataH265(cb OnDataH26xFunc) {
r.onDataVideo = func(msg message.Message) error {
Expand Down