Fix assertion failure with .MTS files.
authorCarl Hetherington <cth@carlh.net>
Fri, 25 Sep 2015 21:10:35 +0000 (22:10 +0100)
committerCarl Hetherington <cth@carlh.net>
Fri, 25 Sep 2015 21:10:35 +0000 (22:10 +0100)
These files have subs which start but are never officially
finished; this means there are no `to' times to find in
find_subtitle_to.  Cope with this by stopping the previous sub when
a new one arrives if there hasn't been a proper "stop" in the
mean time.

ChangeLog
src/lib/ffmpeg_examiner.cc
src/lib/ffmpeg_examiner.h

index 2680c1793f68079efa20a6438beb83e59aa8b3ad..b81fc19a58a2e61cec01600ec58e07e00e5039e9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
 2015-09-25  Carl Hetherington  <cth@carlh.net>
 
+       * Fix assertion failure when loading .MTS files (#702).
+
        * Fix incorrect hint about 3D content in a 2D DCP.
 
        * Detect and convert from non-UTF-8
index 576782d0bd0d290b447a2e7b000d95d0559ea77d..6173e041529444ed9e2c6cf9e0c8ec305d554bf5 100644 (file)
@@ -134,6 +134,17 @@ FFmpegExaminer::FFmpegExaminer (shared_ptr<const FFmpegContent> c, shared_ptr<Jo
                        break;
                }
        }
+
+       for (LastSubtitleMap::const_iterator i = _last_subtitle_start.begin(); i != _last_subtitle_start.end(); ++i) {
+               if (i->second) {
+                       i->first->add_subtitle (
+                               ContentTimePeriod (
+                                       i->second.get (),
+                                       ContentTime::from_frames (video_length(), video_frame_rate().get_value_or (24))
+                                       )
+                               );
+               }
+       }
 }
 
 void
@@ -176,14 +187,23 @@ FFmpegExaminer::subtitle_packet (AVCodecContext* context, shared_ptr<FFmpegSubti
        AVSubtitle sub;
        if (avcodec_decode_subtitle2 (context, &sub, &frame_finished, &_packet) >= 0 && frame_finished) {
                FFmpegSubtitlePeriod const period = subtitle_period (sub);
-               if (sub.num_rects <= 0 && _last_subtitle_start) {
-                       stream->add_subtitle (ContentTimePeriod (_last_subtitle_start.get (), period.from));
-                       _last_subtitle_start = optional<ContentTime> ();
+               LastSubtitleMap::iterator last = _last_subtitle_start.find (stream);
+               if (last != _last_subtitle_start.end() && last->second) {
+                       /* We have seen the start of a subtitle but not yet the end.  Whatever this is
+                          finishes the previous subtitle, so add it */
+                       stream->add_subtitle (ContentTimePeriod (last->second.get (), period.from));
+                       if (sub.num_rects == 0) {
+                               /* This is a `proper' end-of-subtitle */
+                               _last_subtitle_start[stream] = optional<ContentTime> ();
+                       } else {
+                               /* This is just another subtitle, so we start again */
+                               _last_subtitle_start[stream] = period.from;
+                       }
                } else if (sub.num_rects == 1) {
                        if (period.to) {
                                stream->add_subtitle (ContentTimePeriod (period.from, period.to.get ()));
                        } else {
-                               _last_subtitle_start = period.from;
+                               _last_subtitle_start[stream] = period.from;
                        }
                }
                avsubtitle_free (&sub);
index 6fd3220d426377a03b9b609ec98a8f899a7483f5..27bff08b47426749eeee7201234a1aed4e955238 100644 (file)
@@ -85,5 +85,6 @@ private:
        Frame _video_length;
        bool _need_video_length;
 
-       boost::optional<ContentTime> _last_subtitle_start;
+       typedef std::map<boost::shared_ptr<FFmpegSubtitleStream>, boost::optional<ContentTime> > LastSubtitleMap;
+       LastSubtitleMap _last_subtitle_start;
 };