{"record":{"id":"bc170c377f9f7017","repo":"AlexxIT/go2rtc","slug":"bitstream-unsupported-header","errorCode":null,"errorMessage":"bitstream: unsupported header: ","messagePattern":"bitstream: unsupported header: ","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/magic/bitstream/producer.go","lineNumber":41,"sourceCode":"\tbuf, err := rd.Peek(256)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tbuf = annexb.EncodeToAVCC(buf) // won't break original buffer\n\n\tvar codec *core.Codec\n\tvar format string\n\n\tswitch {\n\tcase h264.NALUType(buf) == h264.NALUTypeSPS:\n\t\tcodec = h264.AVCCToCodec(buf)\n\t\tformat = \"h264\"\n\tcase h265.NALUType(buf) == h265.NALUTypeVPS:\n\t\tcodec = h265.AVCCToCodec(buf)\n\t\tformat = \"hevc\"\n\tdefault:\n\t\treturn nil, errors.New(\"bitstream: unsupported header: \" + hex.EncodeToString(buf[:8]))\n\t}\n\n\tmedias := []*core.Media{\n\t\t{\n\t\t\tKind:      core.KindVideo,\n\t\t\tDirection: core.DirectionRecvonly,\n\t\t\tCodecs:    []*core.Codec{codec},\n\t\t},\n\t}\n\treturn &Producer{\n\t\tConnection: core.Connection{\n\t\t\tID:         core.NewID(),\n\t\t\tFormatName: format,\n\t\t\tMedias:     medias,\n\t\t\tTransport:  r,\n\t\t},\n\t\trd: rd,\n\t}, nil","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/magic/bitstream/producer.go#L23-L59","documentation":"bitstream.Open is given a raw Annex-B H.264/H.265 elementary stream. After the magic.Open sniffing dispatches on the annexb start code, bitstream peeks 256 bytes and requires the first NAL unit to be an H.264 SPS or an H.265 VPS so it can build codec parameters. If the first NAL is anything else (an IDR/non-IDR slice, AUD, SEI, etc.), it cannot determine the codec and throws this error with the first 8 bytes hex-encoded.","triggerScenarios":"Calling magic.Open (or bitstream.Open directly) on a stream whose Annex-B start code is followed by a NAL unit that is not SPS (H.264 type 7) or VPS (H.265 type 32) — e.g. the capture started mid-GOP on an IDR slice, the stream begins with AUD/SEI NALs, or non-Annex-B data was fed in and only coincidentally matched the start code.","commonSituations":"Dumping an RTP/RTSP track to file and feeding the dump back for consumption; ffmpeg piped output missing SPS because the encoder emits it only periodically; reading a truncated file whose SPS was cut off; piping H.265 streams whose first NAL is VPS in a different order than expected.","solutions":["Ensure the bitstream begins with the parameter sets: prepend the SPS/PPS (H.264) or VPS/SPS/PPS (H.265) NAL units in Annex-B format before the first slice.","Re-encode or remux the source with parameter sets inline, e.g. `ffmpeg -i in -c copy -bsf:v h264_mp4toannexb out.h264`, which inserts SPS/PPS at each keyframe.","Check that the producer that created the stream was started before the camera/encoder began, so the first bytes captured are the parameter sets rather than a mid-stream slice.","Verify the input is actually H.264/H.265 Annex-B; if it is MP4-format (AVCC, length-prefixed) or another container, use the matching package instead of the bitstream one."],"exampleFix":"// before: feeding a dump that starts with an IDR slice\nf, _ := os.Open(\"gop-dump.h264\")\np, err := magic.Open(f) // error: bitstream: unsupported header: 410102...\n\n// after: prepend SPS/PPS captured at stream start\nf, _ := os.Open(\"gop-dump.h264\")\nr := io.MultiReader(bytes.NewReader(spsppsAnnexB), f)\np, err := magic.Open(r)","handlingStrategy":"validation","validationCode":"func isAnnexBParameterStream(data []byte) bool {\n\t// after start code (00 00 00 01), first NAL must be SPS(7) or VPS(32)\n\tif !bytes.HasPrefix(data, []byte{0, 0, 0, 1}) {\n\t\treturn false\n\t}\n\tn := data[4] & 0x7E // nal type = (b>>1)&0x3F\n\tnalType := (data[4] >> 1) & 0x3F\n\treturn nalType == 7 || nalType == 32\n}\n// call before magic.Open: if !ok, prepend/prepend SPS/PPS or transcode first","typeGuard":null,"tryCatchPattern":"p, err := magic.Open(rd)\nif err != nil && strings.Contains(err.Error(), \"bitstream: unsupported header\") {\n\t// re-open after prepending parameter sets or transcoding\n\tp, err = magic.Open(io.MultiReader(bytes.NewReader(spsPpsAnnexB), original))\n}","preventionTips":["Always capture the stream from its start so SPS/PPS (H.264) or VPS/SPS/PPS (H.265) are the first NAL units","Use ffmpeg with h264_mp4toannexb/hevc_mp4toannexb bitstream filters to guarantee inline parameter sets","Validate the first bytes (start code + NAL type) before handing a reader to magic.Open"],"tags":["h264","h265","bitstream","unsupported-codec","streaming"],"backgroundTag":"unsupported-enum-value","analyzedSha":"c245815e75e2a5fd60b4290f12bfc04e55a984d3","analyzedAt":"2026-09-07T11:47:02.965Z","contentChangedAt":"2026-09-07T11:47:02.965Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}