fix(goLive): encode H264 baseline to match SDP profile-level-id (black tile)
SDP offer advertises profile-level-id=42e01f (constrained baseline) but
x264 encoded the default High profile — Discord's receiver configures its
decoder from the negotiated profile, so the High-profile bitstream failed
to decode → black GoLive tile despite valid access units + correct RTP
timestamps (fixed in 42a503c).
- Add -profile:v baseline to H264 encoder options (matches @dank074's
proven config; SPS now 6742c01e → profile_idc=66 baseline, aligns with
the 42e01f fmtp).
- Default x264 tune film → zerolatency (no lookahead — correct for live
GoLive; @dank074 uses it).
- Update goLive-port test to assert baseline + zerolatency.
This commit is contained in:
@@ -26,13 +26,24 @@ export function software(
|
|||||||
} = {},
|
} = {},
|
||||||
): () => EncoderSet {
|
): () => EncoderSet {
|
||||||
const { x264, x265 } = opts;
|
const { x264, x265 } = opts;
|
||||||
const { preset: x264Preset = "superfast", tune: x264Tune = "film" } =
|
const { preset: x264Preset = "superfast", tune: x264Tune = "zerolatency" } =
|
||||||
x264 ?? {};
|
x264 ?? {};
|
||||||
const { preset: x265Preset = "superfast", tune: x265Tune } = x265 ?? {};
|
const { preset: x265Preset = "superfast", tune: x265Tune } = x265 ?? {};
|
||||||
return () => ({
|
return () => ({
|
||||||
H264: {
|
H264: {
|
||||||
name: "libx264",
|
name: "libx264",
|
||||||
options: ["-forced-idr 1", `-tune ${x264Tune}`, `-preset ${x264Preset}`],
|
// -profile:v baseline is REQUIRED: the SDP advertises
|
||||||
|
// profile-level-id=42e01f (constrained baseline) and Discord's
|
||||||
|
// receiver decodes with that profile. x264's default is High — a
|
||||||
|
// High-profile bitstream against a baseline SDP negotiation fails to
|
||||||
|
// decode → black GoLive tile (production bug, fixed 2026-08-12).
|
||||||
|
// zerolatency matches @dank074 (no lookahead — correct for live).
|
||||||
|
options: [
|
||||||
|
"-forced-idr 1",
|
||||||
|
"-profile:v baseline",
|
||||||
|
`-tune ${x264Tune}`,
|
||||||
|
`-preset ${x264Preset}`,
|
||||||
|
],
|
||||||
},
|
},
|
||||||
H265: {
|
H265: {
|
||||||
name: "libx265",
|
name: "libx265",
|
||||||
|
|||||||
@@ -22,11 +22,14 @@ describe("goLive port: codec + encoders", () => {
|
|||||||
expect(normalizeVideoCodec("av1")).toBe("AV1");
|
expect(normalizeVideoCodec("av1")).toBe("AV1");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("software encoder exposes x264 libx264 superfast film", () => {
|
it("software encoder exposes x264 libx264 baseline zerolatency", () => {
|
||||||
const enc = Encoders.software()();
|
const enc = Encoders.software()();
|
||||||
expect(enc.H264.name).toBe("libx264");
|
expect(enc.H264.name).toBe("libx264");
|
||||||
expect(enc.H264.options).toContain("-preset superfast");
|
expect(enc.H264.options).toContain("-preset superfast");
|
||||||
expect(enc.H264.options).toContain("-tune film");
|
expect(enc.H264.options).toContain("-tune zerolatency");
|
||||||
|
// Baseline profile is REQUIRED to match the SDP's profile-level-id=42e01f
|
||||||
|
// (constrained baseline) — High-profile bitstreams fail to decode → black
|
||||||
|
expect(enc.H264.options).toContain("-profile:v baseline");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("CodecPayloadType has opus + H264 entries", () => {
|
it("CodecPayloadType has opus + H264 entries", () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user