5.27.0 - WebVTT placement and teletext grid rows
Follow-up to #233 from tresby's retest. Three findings, one of which contradicts a note that shipped with 5.26.0.
Added
- External WebVTT subtitle files load at all. The FFmpeg build carried the
webvttdecoder but never thewebvttdemuxer, soavformat_open_inputrejected every standalone.vttfile withAVERROR_INVALIDDATAand a sidecar WebVTT track failed before a single cue was decoded, on every path that opens one. Same shape as the raw-PGSsupgap fixed in FFmpegBuild 2.1.3, and it hid for the same reason: the codec was present, so the failure looked like it had to be elsewhere. Requires FFmpegBuild 2.3.0, which this release pins. - WebVTT cue settings reach the host after all:
line,positionandalignarrive asSubtitleCue.placement. 5.26.0 reported them as upstream-blocked, which was a conclusion about the wrong layer. libavcodec's WebVTT decoder really does drop them, and says so as a@todoinwebvttdec.c's file header, so nothing about the placement is in the ASS event line it synthesises. The demuxer keeps them:libavformat/webvttdec.cattaches the verbatim settings string to every packet asAV_PKT_DATA_WEBVTT_SETTINGS, andmatroskadec.cpropagates the same side data for WebVTT in Matroska. Both subtitle decoders now read it, and the packet store carries the string through a rebuild, since side data does not live in the payload and a stored packet would otherwise lose the placement a freshly demuxed one has. A percentagelinebecomes an anchor point plus the alignment row, anchored to the frame edge it is nearer (the spec's default line alignment would pin the box top atline:90%and hang a two-line cue off the frame); alinenumber keeps only the half of the frame it names, because line boxes need a rendered line height the engine does not have. An ASS\anor\posstill wins, since that came from the payload itself.sizeandverticalhave no equivalent in the placement model and are ignored, and apositionwithout alinekeeps only the alignment column, because an anchor point needs both axes.
Fixed
- Teletext captions keep their vertical placement on pages libzvbi does not flag as subtitle pages.
gen_sub_assderives the vertical anchor from the grid row itself and emits it as{\anN}, which the engine has read since 5.26.0, but that whole block sits behindis_subtitle_page. That flag comes from the row-0 page header (NEWSFLASH clear, SUBTITLE set, SUPPRESS_HEADER set), and when a broadcaster does not set all three, or the header has not been seen yet, the else path writes the whole page instead: one" \N"per grid row with the empty ones included, no\an, no per-row trim. The ordinal of the first non-blank row is then the only carrier of the position, and the edge trim was removing it before anything could read it. That ordinal now feeds libzvbi's own third-of-the-page formula rather than an invented scale, so a caption the broadcaster moved to the top of frame to clear a lower-third graphic stays there. Deliberately coarse: three bands is what the source encodes, and mapping each row to its own offset makes consecutive cues of different heights sit at different heights, which reads as a blink. It never overrides an\anthat arrived, including{\an2}, which is explicitly bottom and produces exactly the empty derived output that "no information" would. - A styled cue trims the same whitespace an unstyled one does. The plain path trimmed with
.whitespacesAndNewlines, the styled path tested for a literal space, tab or newline, so a Unicode space (U+00A0 among them) survived on a styled cue and not on an unstyled one carrying the same text. Teletext cannot produce one, since libzvbi maps U+00A0 to a space and writes it as\h, but SRT, WebVTT and ASS payloads can. - A blank teletext row that a colour change split into its own run folds like any other. The #107 interior blank-line fold worked per run plus one run boundary, which misses the shape the source produces most easily: the padding of an otherwise empty row carries the spacing attribute that changes colour, so the blank row lands in a whitespace-only run of its own and breaks the chain between the two text rows. The fold now runs on the flattened sequence and re-splits along the original run boundaries, so run structure cannot hide a blank row from it.
Reported by tresby (#233), whose teletext write-up identified the non-flagged-page case and whose push on WebVTT is what got the side-data path found.
No API changes. SubtitleCue.placement is populated on more sources than before; a host that ignores it is unaffected.