Revert "Write one TTI block per subtitle line for binary STL."
authorCarl Hetherington <cth@carlh.net>
Thu, 26 Mar 2020 20:45:46 +0000 (21:45 +0100)
committerCarl Hetherington <cth@carlh.net>
Thu, 26 Mar 2020 20:45:46 +0000 (21:45 +0100)
It's wrong as where multiple TTI blocks are used only the first
block of the subtitle carries relevant information for time in/out,
position, justification and comment.

This reverts commit c18e3a2e54f992245feeac384a41792b82f698aa.

src/stl_binary_writer.cc

index 993198588c81931cafd4e5bc9d203ad8b959d5c2..baed8d80cc0714b81e14870c99509d18a0c2f384 100644 (file)
@@ -170,9 +170,10 @@ sub::write_stl_binary (
        ofstream output (file_name.string().c_str ());
        STLBinaryTables tables;
 
-       /* Find the longest subtitle in characters and count the number of lines we have */
+       /* Find the longest subtitle in characters */
+
        int longest = 0;
-       int lines = 0;
+
        BOOST_FOREACH (Subtitle const& i, subtitles) {
                BOOST_FOREACH (Line const& j, i.lines) {
                        int t = 0;
@@ -180,7 +181,6 @@ sub::write_stl_binary (
                                t += k.text.size ();
                        }
                        longest = std::max (longest, t);
-                       ++lines;
                }
        }
 
@@ -205,7 +205,7 @@ sub::write_stl_binary (
        put_string (buffer + 230, revision_date);
        put_int_as_string (buffer + 236, revision_number, 2);
        /* TTI blocks */
-       put_int_as_string (buffer + 238, lines, 5);
+       put_int_as_string (buffer + 238, subtitles.size(), 5);
        /* Total number of subtitles */
        put_int_as_string (buffer + 243, subtitles.size(), 5);
        /* Total number of subtitle groups */
@@ -233,53 +233,76 @@ sub::write_stl_binary (
 
        BOOST_FOREACH (Subtitle const& i, subtitles) {
 
-               size_t line = 0;
+               /* Find the top vertical position of this subtitle */
+               optional<int> top;
                BOOST_FOREACH (Line const& j, i.lines) {
-
-                       memset (buffer, 0, 128);
-
-                       /* XXX: these should increment, surely! */
-                       /* Subtitle group number */
-                       put_int_as_int (buffer + 0, 1, 1);
-                       /* Subtitle number */
-                       put_int_as_int (buffer + 1, 0, 2);
-                       /* Extension block number.  These are indexed from zero except the last one is 255 */
-                       put_int_as_int (buffer + 3, line == (i.lines.size() - 1) ? 255 : line, 1);
-                       /* Cumulative status */
-                       put_int_as_int (buffer + 4, tables.cumulative_status_enum_to_file (CUMULATIVE_STATUS_NOT_CUMULATIVE), 1);
-                       /* Time code in */
-                       put_int_as_int (buffer + 5, i.from.hours(), 1);
-                       put_int_as_int (buffer + 6, i.from.minutes(), 1);
-                       put_int_as_int (buffer + 7, i.from.seconds(), 1);
-                       put_int_as_int (buffer + 8, i.from.frames_at(sub::Rational(frames_per_second * 1000, 1000)), 1);
-                       /* Time code out */
-                       put_int_as_int (buffer + 9, i.to.hours(), 1);
-                       put_int_as_int (buffer + 10, i.to.minutes(), 1);
-                       put_int_as_int (buffer + 11, i.to.seconds(), 1);
-                       put_int_as_int (buffer + 12, i.to.frames_at(sub::Rational(frames_per_second * 1000, 1000)), 1);
-                       /* Vertical position */
-                       put_int_as_int (buffer + 13, vertical_position(j), 1);
-
-                       /* Justification code */
-                       switch (j.horizontal_position.reference) {
-                       case LEFT_OF_SCREEN:
-                               put_int_as_int (buffer + 14, tables.justification_enum_to_file (JUSTIFICATION_LEFT), 1);
-                               break;
-                       case HORIZONTAL_CENTRE_OF_SCREEN:
-                               put_int_as_int (buffer + 14, tables.justification_enum_to_file (JUSTIFICATION_CENTRE), 1);
-                               break;
-                       case RIGHT_OF_SCREEN:
-                               put_int_as_int (buffer + 14, tables.justification_enum_to_file (JUSTIFICATION_RIGHT), 1);
-                               break;
+                       int const vp = vertical_position (j);
+                       if (!top || vp < top.get ()) {
+                               top = vp;
                        }
+               }
+
+               memset (buffer, 0, 128);
+
+               /* XXX: these should increment, surely! */
+               /* Subtitle group number */
+               put_int_as_int (buffer + 0, 1, 1);
+               /* Subtitle number */
+               put_int_as_int (buffer + 1, 0, 2);
+               /* Extension block number.  Use 0xff here to indicate that it is the last TTI
+                  block in this subtitle "set", as we only ever use one.
+               */
+               put_int_as_int (buffer + 3, 255, 1);
+               /* Cumulative status */
+               put_int_as_int (buffer + 4, tables.cumulative_status_enum_to_file (CUMULATIVE_STATUS_NOT_CUMULATIVE), 1);
+               /* Time code in */
+               put_int_as_int (buffer + 5, i.from.hours(), 1);
+               put_int_as_int (buffer + 6, i.from.minutes(), 1);
+               put_int_as_int (buffer + 7, i.from.seconds(), 1);
+               put_int_as_int (buffer + 8, i.from.frames_at(sub::Rational(frames_per_second * 1000, 1000)), 1);
+               /* Time code out */
+               put_int_as_int (buffer + 9, i.to.hours(), 1);
+               put_int_as_int (buffer + 10, i.to.minutes(), 1);
+               put_int_as_int (buffer + 11, i.to.seconds(), 1);
+               put_int_as_int (buffer + 12, i.to.frames_at(sub::Rational(frames_per_second * 1000, 1000)), 1);
+               /* Vertical position */
+               put_int_as_int (buffer + 13, top.get(), 1);
+
+               /* Justification code */
+               /* XXX: this assumes the first line has the right value */
+               switch (i.lines.front().horizontal_position.reference) {
+               case LEFT_OF_SCREEN:
+                       put_int_as_int (buffer + 14, tables.justification_enum_to_file (JUSTIFICATION_LEFT), 1);
+                       break;
+               case HORIZONTAL_CENTRE_OF_SCREEN:
+                       put_int_as_int (buffer + 14, tables.justification_enum_to_file (JUSTIFICATION_CENTRE), 1);
+                       break;
+               case RIGHT_OF_SCREEN:
+                       put_int_as_int (buffer + 14, tables.justification_enum_to_file (JUSTIFICATION_RIGHT), 1);
+                       break;
+               }
+
+               /* Comment flag */
+               put_int_as_int (buffer + 15, tables.comment_enum_to_file (COMMENT_NO), 1);
+
+               /* Text */
+               string text;
+               bool italic = false;
+               bool underline = false;
+               optional<int> last_vp;
+
+               BOOST_FOREACH (Line const& j, i.lines) {
 
-                       /* Comment flag */
-                       put_int_as_int (buffer + 15, tables.comment_enum_to_file (COMMENT_NO), 1);
+                       /* CR/LF down to this line */
+                       int const vp = vertical_position (j);
 
-                       /* Text */
-                       string text;
-                       bool italic = false;
-                       bool underline = false;
+                       if (last_vp) {
+                               for (int k = last_vp.get(); k < vp; ++k) {
+                                       text += "\x8A";
+                               }
+                       }
+
+                       last_vp = vp;
 
                        BOOST_FOREACH (Block const& k, j.blocks) {
                                if (k.underline && !underline) {
@@ -299,29 +322,28 @@ sub::write_stl_binary (
 
                                text += utf16_to_iso6937 (utf_to_utf<wchar_t> (k.text));
                        }
+               }
 
-                       /* Turn italic/underline off before the end of this subtitle */
-
-                       if (underline) {
-                               text += "\x83";
-                       }
+               /* Turn italic/underline off before the end of this subtitle */
 
-                       if (italic) {
-                               text += "\x81";
-                       }
+               if (underline) {
+                       text += "\x83";
+               }
 
-                       if (text.length() > 111) {
-                               text = text.substr (111);
-                       }
+               if (italic) {
+                       text += "\x81";
+               }
 
-                       while (text.length() < 112) {
-                               text += "\x8F";
-                       }
+               if (text.length() > 111) {
+                       text = text.substr (111);
+               }
 
-                       put_string (buffer + 16, text);
-                       output.write (buffer, 128);
-                       ++line;
+               while (text.length() < 112) {
+                       text += "\x8F";
                }
+
+               put_string (buffer + 16, text);
+               output.write (buffer, 128);
        }
 
        delete[] buffer;