{"record":{"id":"6eb0a457de8d3bde","repo":"SubtitleEdit/subtitleedit","slug":"no-vobsub-subpictures-found-in-mp4-track","errorCode":null,"errorMessage":"No VobSub subpictures found in MP4 track.","messagePattern":"No VobSub subpictures found in MP4 track\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/seconv/Core/BitmapSubtitleLoader.cs","lineNumber":348,"sourceCode":"        var count = Math.Min(paragraphs.Count, subPictures.Count);\n\n        var items = new List<BitmapSubtitleItem>(count);\n        for (var i = 0; i < count; i++)\n        {\n            var bmp = subPictures[i].GetBitmap(\n                palette, SKColors.Transparent, SKColors.Black, SKColors.White, SKColors.Black, false);\n            if (bmp is null)\n            {\n                continue;\n            }\n            // ImageDisplayArea is filled in by GetBitmap above.\n            var displayArea = subPictures[i].ImageDisplayArea;\n            items.Add(new BitmapSubtitleItem(paragraphs[i].StartTime, paragraphs[i].EndTime, bmp,\n                Position: new SKPointI(displayArea.Left, displayArea.Top)));\n        }\n        if (items.Count == 0)\n        {\n            throw new InvalidOperationException(\"No VobSub subpictures found in MP4 track.\");\n        }\n        return items;\n    }\n\n    /// <summary>\n    /// Transport stream DVB-sub → one bitmap list per packet ID. Caller is responsible\n    /// for routing each PID to its own output file (multiple subtitle streams =\n    /// multiple languages, same as the OCR path in <see cref=\"ImageOcrLoader\"/>).\n    /// </summary>\n    public static List<(IReadOnlyList<BitmapSubtitleItem> Items, int PacketId)> LoadTransportStreamDvbSub(string filePath)\n    {\n        var parser = new TransportStreamParser();\n        parser.Parse(filePath, null);\n\n        var results = new List<(IReadOnlyList<BitmapSubtitleItem>, int)>();\n        if (parser.SubtitlePacketIds.Count == 0)\n        {\n            return results;","sourceCodeStart":330,"sourceCodeEnd":366,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/seconv/Core/BitmapSubtitleLoader.cs#L330-L366","documentation":"Thrown by BitmapSubtitleLoader.LoadMp4VobSub when, after iterating the parallel paragraphs/subPictures arrays of an MP4 'subp' track, no bitmap decoded successfully. Either the track has zero paragraphs/subpictures, or every subPictures[i].GetBitmap(...) returned null because the palette or RLE payload is unusable. It is a terminal guard for an MP4 VobSub track that cannot yield any image events.","triggerScenarios":"Calling LoadMp4VobSub(track) where track.Mdia.Minf.Stbl.GetParagraphs() and .SubPictures are both non-empty but every GetBitmap(palette, ...) at line 335 returns null (missing VobSubPalette in the sample entry, or corrupt RLE); or where count == Math.Min(paragraphs, subPictures) is 0 so the loop never runs.","commonSituations":"An MP4 produced by MP4Box (or a similar muxer) whose VobSub track lost its CLUT; a truncated MP4 where the subpicture samples are incomplete; a file with an 'subp' handler type that is actually empty.","solutions":["Check the track with an MP4 inspector (mp4box -info / ffprobe) to confirm it carries VobSub samples and a palette.","If the palette is absent, re-mux from the original .sub+.idx with a tool that writes the sample-entry CLUT.","Skip the track at the caller level by catching InvalidOperationException and continuing with remaining MP4 tracks."],"exampleFix":"// before\nvar items = BitmapSubtitleLoader.LoadMp4VobSub(trak);\n\n// after\nList<BitmapSubtitleItem> items;\ntry { items = BitmapSubtitleLoader.LoadMp4VobSub(trak).ToList(); }\ncatch (InvalidOperationException) { continue; }  // skip empty VobSub track","handlingStrategy":"validation","validationCode":"// Guard before calling LoadMp4VobSub.\nvar paragraphs = track.Mdia.Minf.Stbl.GetParagraphs();\nvar subPictures = track.Mdia.Minf.Stbl.SubPictures;\nif (paragraphs.Count == 0 || subPictures.Count == 0) continue;","typeGuard":null,"tryCatchPattern":"try { items = BitmapSubtitleLoader.LoadMp4VobSub(trak).ToList(); }\ncatch (InvalidOperationException) { continue; }  // empty VobSub track, skip","preventionTips":["Pre-check GetParagraphs() and SubPictures are non-empty before calling LoadMp4VobSub.","Wrap the call in try/catch(InvalidOperationException) and skip the track so other MP4 tracks still convert.","Prefer MP4 sources muxed with a complete sample-entry CLUT."],"tags":["vobsub","mp4","bitmap","subtitle"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}