Skip to content

Commit

Permalink
broadcaster: Fix media compatibility check (#3164)
Browse files Browse the repository at this point in the history
Not all fields will be identical segment-to-segment,
particularly DurationSecs. This caused unnecessary
transcoder re-initialization.
  • Loading branch information
j0sh authored Sep 9, 2024
1 parent 48a92a1 commit a99a631
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 1 deletion.
14 changes: 13 additions & 1 deletion server/mediaserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -989,7 +989,7 @@ func (s *LivepeerServer) HandlePush(w http.ResponseWriter, r *http.Request) {
cxn.mu.Lock()
if cxn.mediaFormat == (ffmpeg.MediaFormatInfo{}) {
cxn.mediaFormat = mediaFormat
} else if cxn.mediaFormat != mediaFormat {
} else if !mediaCompatible(cxn.mediaFormat, mediaFormat) {
cxn.mediaFormat = mediaFormat
segPar.ForceSessionReinit = true
}
Expand Down Expand Up @@ -1649,3 +1649,15 @@ func getRemoteAddr(r *http.Request) string {
}
return strings.Split(addr, ":")[0]
}

func mediaCompatible(a, b ffmpeg.MediaFormatInfo) bool {
return a.Acodec == b.Acodec &&
a.Vcodec == b.Vcodec &&
a.PixFormat == b.PixFormat &&
a.Width == b.Width &&
a.Height == b.Height

// NB: there is also a Format field but that does
// not need to match since transcoder will reopen
// a new demuxer each time
}
95 changes: 95 additions & 0 deletions server/mediaserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1494,6 +1494,101 @@ func TestJsonProfileToVideoProfiles(t *testing.T) {
assert.Equal("unable to parse the H264 encoder profile: unknown VideoProfile profile name", err.Error())
}

func TestMediaCompatible(t *testing.T) {
empty := ffmpeg.MediaFormatInfo{}
normal := ffmpeg.MediaFormatInfo{
Acodec: "aac",
Vcodec: "h264",
PixFormat: ffmpeg.PixelFormat{RawValue: ffmpeg.PixelFormatNV12},
Format: "mpegts",
Width: 100,
Height: 200,
AudioBitrate: 300,
DurSecs: 5,
}
tests := []struct {
name string
a ffmpeg.MediaFormatInfo
b ffmpeg.MediaFormatInfo
match bool
}{{
name: "empty",
a: empty,
match: true,
}, {
name: "normal",
match: true,
a: normal,
b: ffmpeg.MediaFormatInfo{
Format: "mp4",
DurSecs: 10,
AudioBitrate: 400,
Acodec: normal.Acodec,
Vcodec: normal.Vcodec,
PixFormat: normal.PixFormat,
Width: normal.Width,
Height: normal.Height,
},
}, {
name: "w",
a: normal,
b: ffmpeg.MediaFormatInfo{
Width: normal.Width + 1,
Acodec: normal.Acodec,
Vcodec: normal.Vcodec,
PixFormat: normal.PixFormat,
Height: normal.Height,
},
}, {
name: "h",
a: normal,
b: ffmpeg.MediaFormatInfo{
Height: normal.Height + 1,
Acodec: normal.Acodec,
Vcodec: normal.Vcodec,
PixFormat: normal.PixFormat,
Width: normal.Width,
},
}, {
name: "pixfmt",
a: normal,
b: ffmpeg.MediaFormatInfo{
Width: normal.Width,
Acodec: normal.Acodec,
Vcodec: normal.Vcodec,
PixFormat: ffmpeg.PixelFormat{RawValue: ffmpeg.PixelFormatYUV420P},
Height: normal.Height,
},
}, {
name: "video codec",
a: normal,
b: ffmpeg.MediaFormatInfo{
Vcodec: "flv",
Acodec: normal.Acodec,
Format: normal.Format,
PixFormat: normal.PixFormat,
Width: normal.Width,
Height: normal.Height,
},
}, {
name: "audio codec",
a: normal,
b: ffmpeg.MediaFormatInfo{
Acodec: "opus",
Vcodec: normal.Vcodec,
Format: normal.Format,
PixFormat: normal.PixFormat,
Width: normal.Width,
Height: normal.Height,
},
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.match, mediaCompatible(tt.a, tt.b))
})
}
}

func mustParseUrl(t *testing.T, str string) *url.URL {
url, err := url.Parse(str)
if err != nil {
Expand Down

0 comments on commit a99a631

Please sign in to comment.