Handle multiple bitmap subtitles at the same time correctly (#2239).
authorCarl Hetherington <cth@carlh.net>
Thu, 28 Apr 2022 12:00:07 +0000 (14:00 +0200)
committerCarl Hetherington <cth@carlh.net>
Thu, 28 Apr 2022 12:00:07 +0000 (14:00 +0200)
Previously if there were two images at the same time we would start
them both, then the stop time would be set in the second one but
not the first.  This meant that the first one would hang around
forever.

src/lib/content_text.h
src/lib/ffmpeg_decoder.cc
src/lib/ffmpeg_decoder.h

index fb86bc78637b599b7ff820b583583c0b324c7e2f..438a76a6e17870fe2b7f52e4a52d51515c71125a 100644 (file)
@@ -45,9 +45,14 @@ private:
        dcpomatic::ContentTime _from;
 };
 
+
 class ContentBitmapText : public ContentText
 {
 public:
+       ContentBitmapText (dcpomatic::ContentTime from)
+               : ContentText(from)
+       {}
+
        ContentBitmapText (dcpomatic::ContentTime f, std::shared_ptr<const Image> im, dcpomatic::Rect<double> r)
                : ContentText (f)
                , subs{ {im, r} }
@@ -57,6 +62,7 @@ public:
        std::vector<BitmapText> subs;
 };
 
+
 /** A text caption.  We store the time period separately (as well as in the dcp::SubtitleStrings)
  *  as the dcp::SubtitleString timings are sometimes quite heavily quantised and this causes problems
  *  when we want to compare the quantised periods to the unquantised ones.
index f76c7699e3901d5dbcbdb1d48517438f06dd4ba8..bc7d28d7dc0ccf958b139d45c1c057d1f0c0b3a4 100644 (file)
@@ -644,6 +644,7 @@ FFmpegDecoder::decode_and_process_subtitle_packet (AVPacket* packet)
                _have_current_subtitle = true;
        }
 
+       ContentBitmapText bitmap_text(from);
        for (unsigned int i = 0; i < sub.num_rects; ++i) {
                auto const rect = sub.rects[i];
 
@@ -651,7 +652,7 @@ FFmpegDecoder::decode_and_process_subtitle_packet (AVPacket* packet)
                case SUBTITLE_NONE:
                        break;
                case SUBTITLE_BITMAP:
-                       process_bitmap_subtitle (rect, from);
+                       bitmap_text.subs.push_back(process_bitmap_subtitle(rect));
                        break;
                case SUBTITLE_TEXT:
                        cout << "XXX: SUBTITLE_TEXT " << rect->text << "\n";
@@ -662,6 +663,10 @@ FFmpegDecoder::decode_and_process_subtitle_packet (AVPacket* packet)
                }
        }
 
+       if (!bitmap_text.subs.empty()) {
+               only_text()->emit_bitmap_start(bitmap_text);
+       }
+
        if (_current_subtitle_to) {
                only_text()->emit_stop (*_current_subtitle_to);
        }
@@ -670,8 +675,8 @@ FFmpegDecoder::decode_and_process_subtitle_packet (AVPacket* packet)
 }
 
 
-void
-FFmpegDecoder::process_bitmap_subtitle (AVSubtitleRect const * rect, ContentTime from)
+BitmapText
+FFmpegDecoder::process_bitmap_subtitle (AVSubtitleRect const * rect)
 {
        /* Note BGRA is expressed little-endian, so the first byte in the word is B, second
           G, third R, fourth A.
@@ -754,7 +759,7 @@ FFmpegDecoder::process_bitmap_subtitle (AVSubtitleRect const * rect, ContentTime
                static_cast<double>(rect->h) / target_height
                );
 
-       only_text()->emit_bitmap_start ({ from, image, scaled_rect });
+       return { image, scaled_rect };
 }
 
 
index 663a3c6870cbf2006c70946518e141285f506e29..ce2476fb03b5bf6e1903ffe0de43c6cc33394b8e 100644 (file)
@@ -24,6 +24,7 @@
  */
 
 
+#include "bitmap_text.h"
 #include "decoder.h"
 #include "ffmpeg.h"
 #include "util.h"
@@ -72,7 +73,7 @@ private:
        void decode_and_process_audio_packet (AVPacket* packet);
        void decode_and_process_subtitle_packet (AVPacket* packet);
 
-       void process_bitmap_subtitle (AVSubtitleRect const * rect, dcpomatic::ContentTime from);
+       BitmapText process_bitmap_subtitle (AVSubtitleRect const * rect);
        void process_ass_subtitle (std::string ass, dcpomatic::ContentTime from);
 
        void maybe_add_subtitle ();