Add primitive subtitle view. Remove unused Film member from Decoder hierarchy.
authorCarl Hetherington <cth@carlh.net>
Fri, 7 Mar 2014 20:13:22 +0000 (20:13 +0000)
committerCarl Hetherington <cth@carlh.net>
Fri, 7 Mar 2014 20:13:22 +0000 (20:13 +0000)
28 files changed:
ChangeLog
src/lib/audio_decoder.cc
src/lib/audio_decoder.h
src/lib/decoder.cc
src/lib/decoder.h
src/lib/ffmpeg_content.cc
src/lib/ffmpeg_decoder.cc
src/lib/ffmpeg_decoder.h
src/lib/image_decoder.cc
src/lib/image_decoder.h
src/lib/player.cc
src/lib/sndfile_content.cc
src/lib/sndfile_decoder.cc
src/lib/sndfile_decoder.h
src/lib/subrip_decoder.cc
src/lib/subrip_decoder.h
src/lib/subtitle_decoder.cc
src/lib/subtitle_decoder.h
src/lib/video_decoder.cc
src/lib/video_decoder.h
src/wx/subtitle_panel.cc
src/wx/subtitle_panel.h
src/wx/subtitle_view.cc [new file with mode: 0644]
src/wx/subtitle_view.h [new file with mode: 0644]
src/wx/wscript
test/ffmpeg_pts_offset.cc
test/seek_zero_test.cc
test/subrip_test.cc

index 420486e1fc22a121ef673ac84a437e0f42f1a36a..d7cd6adf85a86e81b2b1dde654f3846b5fd22ff0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2014-03-07  Carl Hetherington  <cth@carlh.net>
+
+       * Add subtitle view.
+
 2014-03-06  Carl Hetherington  <cth@carlh.net>
 
        * Version 1.65.0 released.
index b0d0cc22f87802de3f34162b44e1deb7deee1546..32453cc13c974d58218cf5dae9eb4eb6da5047d2 100644 (file)
@@ -23,7 +23,6 @@
 #include "log.h"
 #include "resampler.h"
 #include "util.h"
-#include "film.h"
 
 #include "i18n.h"
 
@@ -34,9 +33,8 @@ using std::cout;
 using boost::optional;
 using boost::shared_ptr;
 
-AudioDecoder::AudioDecoder (shared_ptr<const Film> film, shared_ptr<const AudioContent> content)
-       : Decoder (film)
-       , _audio_content (content)
+AudioDecoder::AudioDecoder (shared_ptr<const AudioContent> content)
+       : _audio_content (content)
 {
        if (content->output_audio_frame_rate() != content->content_audio_frame_rate() && content->audio_channels ()) {
                _resampler.reset (new Resampler (content->content_audio_frame_rate(), content->output_audio_frame_rate(), content->audio_channels ()));
@@ -58,8 +56,6 @@ AudioDecoder::audio (shared_ptr<const AudioBuffers> data, ContentTime time)
        }
 
        if (!_audio_position) {
-               shared_ptr<const Film> film = _film.lock ();
-               assert (film);
                _audio_position = time;
        }
 
index 5b68a51a17534d8f07f719927927bf022699f35b..35d9f3560b7d55565ddc3eb8cf9b17e1bebe4ac7 100644 (file)
@@ -38,7 +38,7 @@ class Resampler;
 class AudioDecoder : public virtual Decoder
 {
 public:
-       AudioDecoder (boost::shared_ptr<const Film>, boost::shared_ptr<const AudioContent>);
+       AudioDecoder (boost::shared_ptr<const AudioContent>);
        
        boost::shared_ptr<const AudioContent> audio_content () const {
                return _audio_content;
index 53a0c31e140d6ceab0a3d2f222fe419bda88237b..0901f73b020027cc733ab325c2085f494db65d45 100644 (file)
@@ -21,7 +21,6 @@
  *  @brief Parent class for decoders of content.
  */
 
-#include "film.h"
 #include "decoder.h"
 #include "decoded.h"
 
 using std::cout;
 using boost::shared_ptr;
 
-/** @param f Film.
- *  @param o Decode options.
+/** @param o Decode options.
  */
-Decoder::Decoder (shared_ptr<const Film> f)
-       : _film (f)
-       , _done (false)
+Decoder::Decoder ()
+       : _done (false)
 {
 
 }
index aeb39d0b2a05483cc2afe5f736e0534d44658d5d..0f14dbba7255c5cc356d0f22ff0ed1eb54dbdaf1 100644 (file)
@@ -30,7 +30,6 @@
 #include "types.h"
 #include "dcpomatic_time.h"
 
-class Film;
 class Decoded;
 
 /** @class Decoder.
@@ -39,7 +38,7 @@ class Decoded;
 class Decoder : public boost::noncopyable
 {
 public:
-       Decoder (boost::shared_ptr<const Film>);
+       Decoder ();
        virtual ~Decoder () {}
 
        /** Seek so that the next peek() will yield the next thing
@@ -67,9 +66,6 @@ protected:
        virtual bool pass () = 0;
        virtual void flush () {};
        
-       /** The Film that we are decoding in */
-       boost::weak_ptr<const Film> _film;
-
        std::list<boost::shared_ptr<Decoded> > _pending;
        bool _done;
 };
index e9be3cc46bfa1c69284f805e2d39c0129de7f0ad..2b535a2ab75182eb2cb698489987ab8d46e6aec7 100644 (file)
@@ -158,13 +158,13 @@ FFmpegContent::examine (shared_ptr<Job> job)
 
        Content::examine (job);
 
-       shared_ptr<const Film> film = _film.lock ();
-       assert (film);
-
        shared_ptr<FFmpegExaminer> examiner (new FFmpegExaminer (shared_from_this ()));
        take_from_video_examiner (examiner);
 
        ContentTime video_length = examiner->video_length ();
+
+       shared_ptr<const Film> film = _film.lock ();
+       assert (film);
        film->log()->log (String::compose ("Video length obtained from header as %1 frames", video_length.frames (video_frame_rate ())));
 
        {
index 8b28a5c13da4ae0e2320c1b323a8429714e5f4a7..dc2a5590b450f2226ef55ef0ffab005022aa899c 100644 (file)
@@ -33,7 +33,6 @@ extern "C" {
 #include <libavcodec/avcodec.h>
 #include <libavformat/avformat.h>
 }
-#include "film.h"
 #include "filter.h"
 #include "exceptions.h"
 #include "image.h"
@@ -58,16 +57,16 @@ using boost::optional;
 using boost::dynamic_pointer_cast;
 using dcp::Size;
 
-FFmpegDecoder::FFmpegDecoder (shared_ptr<const Film> f, shared_ptr<const FFmpegContent> c, bool video, bool audio)
-       : Decoder (f)
-       , VideoDecoder (f, c)
-       , AudioDecoder (f, c)
-       , SubtitleDecoder (f)
+FFmpegDecoder::FFmpegDecoder (shared_ptr<const FFmpegContent> c, shared_ptr<Log> log, bool video, bool audio, bool subtitles)
+       : VideoDecoder (c)
+       , AudioDecoder (c)
        , FFmpeg (c)
+       , _log (log)
        , _subtitle_codec_context (0)
        , _subtitle_codec (0)
        , _decode_video (video)
        , _decode_audio (audio)
+       , _decode_subtitles (subtitles)
        , _pts_offset (0)
 {
        setup_subtitle ();
@@ -144,25 +143,20 @@ FFmpegDecoder::pass ()
                        /* Maybe we should fail here, but for now we'll just finish off instead */
                        char buf[256];
                        av_strerror (r, buf, sizeof(buf));
-                       shared_ptr<const Film> film = _film.lock ();
-                       assert (film);
-                       film->log()->log (String::compose (N_("error on av_read_frame (%1) (%2)"), buf, r));
+                       _log->log (String::compose (N_("error on av_read_frame (%1) (%2)"), buf, r));
                }
 
                flush ();
                return true;
        }
 
-       shared_ptr<const Film> film = _film.lock ();
-       assert (film);
-
        int const si = _packet.stream_index;
        
        if (si == _video_stream && _decode_video) {
                decode_video_packet ();
        } else if (_ffmpeg_content->audio_stream() && _ffmpeg_content->audio_stream()->uses_index (_format_context, si) && _decode_audio) {
                decode_audio_packet ();
-       } else if (_ffmpeg_content->subtitle_stream() && _ffmpeg_content->subtitle_stream()->uses_index (_format_context, si) && film->with_subtitles ()) {
+       } else if (_ffmpeg_content->subtitle_stream() && _ffmpeg_content->subtitle_stream()->uses_index (_format_context, si) && _decode_subtitles) {
                decode_subtitle_packet ();
        }
 
@@ -427,9 +421,7 @@ FFmpegDecoder::decode_audio_packet ()
                int const decode_result = avcodec_decode_audio4 (audio_codec_context(), _frame, &frame_finished, &copy_packet);
 
                if (decode_result < 0) {
-                       shared_ptr<const Film> film = _film.lock ();
-                       assert (film);
-                       film->log()->log (String::compose ("avcodec_decode_audio4 failed (%1)", decode_result));
+                       _log->log (String::compose ("avcodec_decode_audio4 failed (%1)", decode_result));
                        return;
                }
 
@@ -469,13 +461,9 @@ FFmpegDecoder::decode_video_packet ()
        }
 
        if (i == _filter_graphs.end ()) {
-               shared_ptr<const Film> film = _film.lock ();
-               assert (film);
-
                graph.reset (new FilterGraph (_ffmpeg_content, dcp::Size (_frame->width, _frame->height), (AVPixelFormat) _frame->format));
                _filter_graphs.push_back (graph);
-
-               film->log()->log (String::compose (N_("New graph for %1x%2, pixel format %3"), _frame->width, _frame->height, _frame->format));
+               _log->log (String::compose (N_("New graph for %1x%2, pixel format %3"), _frame->width, _frame->height, _frame->format));
        } else {
                graph = *i;
        }
@@ -494,9 +482,7 @@ FFmpegDecoder::decode_video_packet ()
                if (i->second != AV_NOPTS_VALUE) {
                        video (image, false, ContentTime::from_seconds (i->second * av_q2d (_format_context->streams[_video_stream]->time_base)) + _pts_offset);
                } else {
-                       shared_ptr<const Film> film = _film.lock ();
-                       assert (film);
-                       film->log()->log ("Dropping frame without PTS");
+                       _log->log ("Dropping frame without PTS");
                }
        }
 
index 8eadb116fd0df60202112c53aae59376e28f2b8f..fbf802bb01004cf9c7d3f27f12e65a0f962af888 100644 (file)
@@ -38,7 +38,7 @@ extern "C" {
 #include "subtitle_decoder.h"
 #include "ffmpeg.h"
 
-class Film;
+class Log;
 class FilterGraph;
 class ffmpeg_pts_offset_test;
 
@@ -48,7 +48,7 @@ class ffmpeg_pts_offset_test;
 class FFmpegDecoder : public VideoDecoder, public AudioDecoder, public SubtitleDecoder, public FFmpeg
 {
 public:
-       FFmpegDecoder (boost::shared_ptr<const Film>, boost::shared_ptr<const FFmpegContent>, bool video, bool audio);
+       FFmpegDecoder (boost::shared_ptr<const FFmpegContent>, boost::shared_ptr<Log>, bool video, bool audio, bool subtitles);
        ~FFmpegDecoder ();
 
        void seek (ContentTime time, bool);
@@ -76,6 +76,7 @@ private:
        int minimal_run (boost::function<bool (boost::optional<ContentTime>, boost::optional<ContentTime>, int)>);
        void seek_and_flush (ContentTime);
 
+       boost::shared_ptr<Log> _log;
        AVCodecContext* _subtitle_codec_context; ///< may be 0 if there is no subtitle
        AVCodec* _subtitle_codec;                ///< may be 0 if there is no subtitle
        
@@ -84,6 +85,7 @@ private:
 
        bool _decode_video;
        bool _decode_audio;
+       bool _decode_subtitles;
 
        ContentTime _pts_offset;
 };
index c9b17add8a11036b7f5458cb063acff3de2e9b78..58ba732bb57b09abdc113f6ae3646e2ebde0ea61 100644 (file)
@@ -32,9 +32,8 @@ using std::cout;
 using boost::shared_ptr;
 using dcp::Size;
 
-ImageDecoder::ImageDecoder (shared_ptr<const Film> f, shared_ptr<const ImageContent> c)
-       : Decoder (f)
-       , VideoDecoder (f, c)
+ImageDecoder::ImageDecoder (shared_ptr<const ImageContent> c)
+       : VideoDecoder (c)
        , _image_content (c)
 {
 
index f4d81dfb507a5ef545c0f573542904472d023956..13ffea13deb1a734ac4be925fa779c1abe53712e 100644 (file)
@@ -28,7 +28,7 @@ class ImageContent;
 class ImageDecoder : public VideoDecoder
 {
 public:
-       ImageDecoder (boost::shared_ptr<const Film>, boost::shared_ptr<const ImageContent>);
+       ImageDecoder (boost::shared_ptr<const ImageContent>);
 
        boost::shared_ptr<const ImageContent> content () {
                return _image_content;
index e6e1f375373dd79cfdbe2790f40d126d4d1ef845..e89e84aa6488179a1caf20f600a0d7b8e640f061 100644 (file)
@@ -486,7 +486,7 @@ Player::setup_pieces ()
                /* FFmpeg */
                shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> (*i);
                if (fc) {
-                       decoder.reset (new FFmpegDecoder (_film, fc, _video, _audio));
+                       decoder.reset (new FFmpegDecoder (fc, _film->log(), _video, _audio, _film->with_subtitles ()));
                        frc = FrameRateChange (fc->video_frame_rate(), _film->video_frame_rate());
                }
 
@@ -502,7 +502,7 @@ Player::setup_pieces ()
                        }
 
                        if (!decoder) {
-                               decoder.reset (new ImageDecoder (_film, ic));
+                               decoder.reset (new ImageDecoder (ic));
                        }
 
                        frc = FrameRateChange (ic->video_frame_rate(), _film->video_frame_rate());
@@ -511,14 +511,14 @@ Player::setup_pieces ()
                /* SndfileContent */
                shared_ptr<const SndfileContent> sc = dynamic_pointer_cast<const SndfileContent> (*i);
                if (sc) {
-                       decoder.reset (new SndfileDecoder (_film, sc));
+                       decoder.reset (new SndfileDecoder (sc));
                        frc = best_overlap_frc;
                }
 
                /* SubRipContent */
                shared_ptr<const SubRipContent> rc = dynamic_pointer_cast<const SubRipContent> (*i);
                if (rc) {
-                       decoder.reset (new SubRipDecoder (_film, rc));
+                       decoder.reset (new SubRipDecoder (rc));
                        frc = best_overlap_frc;
                }
 
index 1aa7bde618283095d13a69ec2d8193cd293f44e0..71b549d51a056b89e6bde4dac439053d8575d4a5 100644 (file)
@@ -102,10 +102,7 @@ SndfileContent::examine (shared_ptr<Job> job)
        job->set_progress_unknown ();
        Content::examine (job);
 
-       shared_ptr<const Film> film = _film.lock ();
-       assert (film);
-
-       SndfileDecoder dec (film, shared_from_this());
+       SndfileDecoder dec (shared_from_this());
 
        {
                boost::mutex::scoped_lock lm (_mutex);
index 3a71fab528508ece0dfdf713356308b2e8af8cfa..67bb25e0dc71e56fe5678c8bef2b25bd0f17c655 100644 (file)
@@ -25,7 +25,6 @@
 #include <sndfile.h>
 #include "sndfile_content.h"
 #include "sndfile_decoder.h"
-#include "film.h"
 #include "exceptions.h"
 #include "audio_buffers.h"
 
@@ -37,9 +36,8 @@ using std::min;
 using std::cout;
 using boost::shared_ptr;
 
-SndfileDecoder::SndfileDecoder (shared_ptr<const Film> f, shared_ptr<const SndfileContent> c)
-       : Decoder (f)
-       , AudioDecoder (f, c)
+SndfileDecoder::SndfileDecoder (shared_ptr<const SndfileContent> c)
+       : AudioDecoder (c)
        , _sndfile_content (c)
        , _deinterleave_buffer (0)
 {
index aaa4c0da89e19ee106c44c978965a74d3044f7a8..1de123917ad53a324dc65643e5a7756e4b77f8c4 100644 (file)
@@ -26,7 +26,7 @@ class SndfileContent;
 class SndfileDecoder : public AudioDecoder
 {
 public:
-       SndfileDecoder (boost::shared_ptr<const Film>, boost::shared_ptr<const SndfileContent>);
+       SndfileDecoder (boost::shared_ptr<const SndfileContent>);
        ~SndfileDecoder ();
 
        void seek (ContentTime, bool);
index 6ebb883230849676f07b56527d2b18c26433bf0a..47b6ea04410cdc3d477ded4257a331a347789048 100644 (file)
 using std::list;
 using boost::shared_ptr;
 
-SubRipDecoder::SubRipDecoder (shared_ptr<const Film> film, shared_ptr<const SubRipContent> content)
-       : Decoder (film)
-       , SubtitleDecoder (film)
-       , SubRip (content)
+SubRipDecoder::SubRipDecoder (shared_ptr<const SubRipContent> content)
+       : SubRip (content)
        , _next (0)
 {
 
index 26d5d501006c021ee7892667246b626e817a43f3..6025c90e2943e357f16b78a7dcfebbc295f33db5 100644 (file)
@@ -28,8 +28,9 @@ class SubRipContent;
 class SubRipDecoder : public SubtitleDecoder, public SubRip
 {
 public:
-       SubRipDecoder (boost::shared_ptr<const Film>, boost::shared_ptr<const SubRipContent>);
-       
+       SubRipDecoder (boost::shared_ptr<const SubRipContent>);
+
+protected:     
        bool pass ();
 
 private:
index cf5550e42eaa31177b54b8256f77e7ec5fee5bc5..a9674fe923ca3186ab178adbb30c927637f29d36 100644 (file)
@@ -24,8 +24,7 @@ using std::list;
 using boost::shared_ptr;
 using boost::optional;
 
-SubtitleDecoder::SubtitleDecoder (shared_ptr<const Film> f)
-       : Decoder (f)
+SubtitleDecoder::SubtitleDecoder ()
 {
 
 }
index e2bd9c9d6ee6575ed5a56849eccc83ca6a09bd2d..78ee6801ecd89eb85c755af7f488103570203e8b 100644 (file)
@@ -34,7 +34,7 @@ class Image;
 class SubtitleDecoder : public virtual Decoder
 {
 public:
-       SubtitleDecoder (boost::shared_ptr<const Film>);
+       SubtitleDecoder ();
 
 protected:
        void image_subtitle (boost::shared_ptr<Image>, dcpomatic::Rect<double>, ContentTime, ContentTime);
index e4d5516a17ab020008cd02d7f665727d4f5db46e..15f91b8923b99ea0a8eff66f3bfc69eb005b4158 100644 (file)
@@ -26,9 +26,8 @@ using std::cout;
 using boost::shared_ptr;
 using boost::optional;
 
-VideoDecoder::VideoDecoder (shared_ptr<const Film> f, shared_ptr<const VideoContent> c)
-       : Decoder (f)
-       , _video_content (c)
+VideoDecoder::VideoDecoder (shared_ptr<const VideoContent> c)
+       : _video_content (c)
 {
 
 }
index d8c362354ee02b2f9614b265c6159ee1b200bf7d..c3228e88dac3fb2fcb633c32b752f8e7a8676f61 100644 (file)
@@ -33,7 +33,7 @@ class Image;
 class VideoDecoder : public virtual Decoder
 {
 public:
-       VideoDecoder (boost::shared_ptr<const Film>, boost::shared_ptr<const VideoContent>);
+       VideoDecoder (boost::shared_ptr<const VideoContent>);
 
        boost::shared_ptr<const VideoContent> video_content () const {
                return _video_content;
index 63a18b0ce874ce5daea97ded5204ef92287ac4ba..b4b5a7b4239e332ba55886cbcdcc3cd329d249df 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
 #include <boost/lexical_cast.hpp>
 #include <wx/spinctrl.h>
 #include "lib/ffmpeg_content.h"
+#include "lib/subrip_content.h"
 #include "subtitle_panel.h"
 #include "film_editor.h"
 #include "wx_util.h"
+#include "subtitle_view.h"
 
 using std::vector;
 using std::string;
@@ -32,6 +34,7 @@ using boost::dynamic_pointer_cast;
 
 SubtitlePanel::SubtitlePanel (FilmEditor* e)
        : FilmEditorPanel (e, _("Subtitles"))
+       , _view (0)
 {
        wxFlexGridSizer* grid = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
        _sizer->Add (grid, 0, wxALL, 8);
@@ -70,6 +73,9 @@ SubtitlePanel::SubtitlePanel (FilmEditor* e)
        add_label_to_sizer (grid, this, _("Subtitle Stream"), true);
        _stream = new wxChoice (this, wxID_ANY);
        grid->Add (_stream, 1, wxEXPAND);
+
+       _view_button = new wxButton (this, wxID_ANY, _("View..."));
+       grid->Add (_view_button);
        
        _x_offset->SetRange (-100, 100);
        _y_offset->SetRange (-100, 100);
@@ -81,6 +87,7 @@ SubtitlePanel::SubtitlePanel (FilmEditor* e)
        _y_offset->Bind       (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&SubtitlePanel::y_offset_changed, this));
        _scale->Bind          (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&SubtitlePanel::scale_changed, this));
        _stream->Bind         (wxEVT_COMMAND_CHOICE_SELECTED,  boost::bind (&SubtitlePanel::stream_changed, this));
+       _view_button->Bind    (wxEVT_COMMAND_BUTTON_CLICKED,   boost::bind (&SubtitlePanel::view_clicked, this));
 }
 
 void
@@ -164,6 +171,9 @@ SubtitlePanel::setup_sensitivity ()
        _y_offset->Enable (j);
        _scale->Enable (j);
        _stream->Enable (j);
+
+       SubtitleContentList c = _editor->selected_subtitle_content ();
+       _view_button->Enable (c.size() == 1);
 }
 
 void
@@ -223,3 +233,21 @@ SubtitlePanel::content_selection_changed ()
        film_content_changed (SubtitleContentProperty::SUBTITLE_Y_OFFSET);
        film_content_changed (SubtitleContentProperty::SUBTITLE_SCALE);
 }
+
+void
+SubtitlePanel::view_clicked ()
+{
+       if (_view) {
+               _view->Destroy ();
+               _view = 0;
+       }
+
+       SubtitleContentList c = _editor->selected_subtitle_content ();
+       assert (c.size() == 1);
+       shared_ptr<SubRipContent> sr = dynamic_pointer_cast<SubRipContent> (c.front ());
+       if (sr) {
+               _view = new SubtitleView (this, sr);
+       }
+
+       _view->Show ();
+}
index 20d7c40c2eb1d3eb1add4350a1b1482b3cbfc2a1..1ee775025ae80710638f869c2488fb9366a1b182 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -21,6 +21,7 @@
 
 class wxCheckBox;
 class wxSpinCtrl;
+class SubtitleView;
 
 class SubtitlePanel : public FilmEditorPanel
 {
@@ -37,6 +38,7 @@ private:
        void y_offset_changed ();
        void scale_changed ();
        void stream_changed ();
+       void view_clicked ();
 
        void setup_sensitivity ();
        
@@ -45,4 +47,6 @@ private:
        wxSpinCtrl* _y_offset;
        wxSpinCtrl* _scale;
        wxChoice* _stream;
+       wxButton* _view_button;
+       SubtitleView* _view;
 };
diff --git a/src/wx/subtitle_view.cc b/src/wx/subtitle_view.cc
new file mode 100644 (file)
index 0000000..f6fbd9a
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+    Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "lib/subrip_decoder.h"
+#include "lib/decoded.h"
+#include "subtitle_view.h"
+
+using std::list;
+using boost::shared_ptr;
+using boost::dynamic_pointer_cast;
+
+SubtitleView::SubtitleView (wxWindow* parent, shared_ptr<SubRipContent> content)
+       : wxDialog (parent, wxID_ANY, _("Subtitles"))
+{
+       _list = new wxListCtrl (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL);
+
+       {
+               wxListItem ip;
+               ip.SetId (0);
+               ip.SetText (_("Start"));
+               ip.SetWidth (100);
+               _list->InsertColumn (0, ip);
+       }
+
+       {
+               wxListItem ip;
+               ip.SetId (1);
+               ip.SetText (_("End"));
+               ip.SetWidth (100);
+               _list->InsertColumn (1, ip);
+       }               
+
+       {
+               wxListItem ip;
+               ip.SetId (2);
+               ip.SetText (_("Subtitle"));
+               ip.SetWidth (640);
+               _list->InsertColumn (2, ip);
+       }
+
+       wxBoxSizer* sizer = new wxBoxSizer (wxVERTICAL);
+       sizer->Add (_list, 1, wxEXPAND);
+
+       wxSizer* buttons = CreateSeparatedButtonSizer (wxOK | wxCANCEL);
+       if (buttons) {
+               sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder());
+       }
+
+       shared_ptr<SubRipDecoder> decoder (new SubRipDecoder (content));
+       int n = 0;
+       while (1) {
+               shared_ptr<Decoded> dec = decoder->peek ();
+               if (!dec) {
+                       break;
+               }
+
+               shared_ptr<DecodedTextSubtitle> sub = dynamic_pointer_cast<DecodedTextSubtitle> (dec);
+               assert (sub);
+
+               for (list<dcp::SubtitleString>::const_iterator i = sub->subs.begin(); i != sub->subs.end(); ++i) {
+                       wxListItem list_item;
+                       list_item.SetId (n);
+                       _list->InsertItem (list_item);
+                       _list->SetItem (n, 2, i->text ());
+                       ++n;
+               }
+
+               decoder->consume ();
+       }
+
+       SetSizerAndFit (sizer);
+}
+
diff --git a/src/wx/subtitle_view.h b/src/wx/subtitle_view.h
new file mode 100644 (file)
index 0000000..94a25b7
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+    Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <boost/shared_ptr.hpp>
+#include <wx/wx.h>
+#include <wx/listctrl.h>
+
+class SubRipContent;
+
+class SubtitleView : public wxDialog
+{
+public:
+       SubtitleView (wxWindow *, boost::shared_ptr<SubRipContent>);
+
+private:       
+       wxListCtrl* _list;
+};
index 1ffaa6097fd276cc3e086c8e3171dc5249a2a041..45a5bc96d5c436c455bc42bbc33fbc8dea5ad605 100644 (file)
@@ -35,6 +35,7 @@ sources = """
           server_dialog.cc
           servers_list_dialog.cc
           subtitle_panel.cc
+          subtitle_view.cc
           timecode.cc
           timeline.cc
           timeline_dialog.cc
index 4a9a57b402295e52d6668fec3b2e1ef92ed06109..bada6a40be8b98c261d46b6922e50151aa72c935 100644 (file)
@@ -36,7 +36,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_pts_offset_test)
                /* Sound == video so no offset required */
                content->_first_video = ContentTime ();
                content->_audio_stream->first_audio = ContentTime ();
-               FFmpegDecoder decoder (film, content, true, true);
+               FFmpegDecoder decoder (content, film->log(), true, true, true);
                BOOST_CHECK_EQUAL (decoder._pts_offset, ContentTime ());
        }
 
@@ -44,7 +44,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_pts_offset_test)
                /* Common offset should be removed */
                content->_first_video = ContentTime::from_seconds (600);
                content->_audio_stream->first_audio = ContentTime::from_seconds (600);
-               FFmpegDecoder decoder (film, content, true, true);
+               FFmpegDecoder decoder (content, film->log(), true, true, true);
                BOOST_CHECK_EQUAL (decoder._pts_offset, ContentTime::from_seconds (-600));
        }
 
@@ -52,7 +52,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_pts_offset_test)
                /* Video is on a frame boundary */
                content->_first_video = ContentTime::from_frames (1, 24);
                content->_audio_stream->first_audio = ContentTime ();
-               FFmpegDecoder decoder (film, content, true, true);
+               FFmpegDecoder decoder (content, film->log(),true, true, true);
                BOOST_CHECK_EQUAL (decoder._pts_offset, ContentTime ());
        }
 
@@ -61,7 +61,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_pts_offset_test)
                double const frame = 1.0 / 24.0;
                content->_first_video = ContentTime::from_seconds (frame + 0.0215);
                content->_audio_stream->first_audio = ContentTime ();
-               FFmpegDecoder decoder (film, content, true, true);
+               FFmpegDecoder decoder (content, film->log(), true, true, true);
                BOOST_CHECK_CLOSE (decoder._pts_offset.seconds(), (frame - 0.0215), 0.00001);
        }
 
@@ -70,7 +70,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_pts_offset_test)
                double const frame = 1.0 / 24.0;
                content->_first_video = ContentTime::from_seconds (frame + 0.0215 + 4.1);
                content->_audio_stream->first_audio = ContentTime::from_seconds (4.1);
-               FFmpegDecoder decoder (film, content, true, true);
+               FFmpegDecoder decoder (content, film->log(), true, true, true);
                BOOST_CHECK_EQUAL (decoder._pts_offset.seconds(), (frame - 0.0215) - 4.1);
        }
 }
index 22004bcb8c876a2ea37f09b8af688f476f2fbafe..07f9e3694b15af5d09044975f3f7ab2e765d96b6 100644 (file)
@@ -45,7 +45,7 @@ BOOST_AUTO_TEST_CASE (seek_zero_test)
        film->examine_and_add_content (content);
        wait_for_jobs ();
 
-       FFmpegDecoder decoder (film, content, true, false);
+       FFmpegDecoder decoder (content, film->log(), true, false, false);
        shared_ptr<DecodedVideo> a = dynamic_pointer_cast<DecodedVideo> (decoder.peek ());
        decoder.seek (ContentTime(), true);
        shared_ptr<DecodedVideo> b = dynamic_pointer_cast<DecodedVideo> (decoder.peek ());
index 315c0cf1e569deb02d1fd5640e18ca3fc8c2b29a..85bb7c4e853f37e5a0d8178680a17e60638ee678 100644 (file)
@@ -185,7 +185,7 @@ BOOST_AUTO_TEST_CASE (subrip_render_test)
 
        shared_ptr<Film> film = new_test_film ("subrip_render_test");
 
-       shared_ptr<SubRipDecoder> decoder (new SubRipDecoder (film, content));
+       shared_ptr<SubRipDecoder> decoder (new SubRipDecoder (content));
        shared_ptr<DecodedTextSubtitle> dts = dynamic_pointer_cast<DecodedTextSubtitle> (decoder->peek ());
 
        shared_ptr<Image> image;