diff options
| author | Carl Hetherington <cth@carlh.net> | 2016-05-10 14:29:14 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2016-05-18 11:50:29 +0100 |
| commit | 504c63b3d62038bc486ca8a09e77fbb403907edd (patch) | |
| tree | d9118c185110dd9eb103ed033700d4b3f486785d /src | |
| parent | 9423e02c37daba7f9e406929a1cfc1bb10fb4b62 (diff) | |
Basics of splitting up Decoder tree like Content.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/audio_decoder.cc | 4 | ||||
| -rw-r--r-- | src/lib/audio_decoder.h | 5 | ||||
| -rw-r--r-- | src/lib/audio_decoder_stream.cc | 4 | ||||
| -rw-r--r-- | src/lib/audio_decoder_stream.h | 5 | ||||
| -rw-r--r-- | src/lib/dcp_decoder.cc | 36 | ||||
| -rw-r--r-- | src/lib/dcp_decoder.h | 7 | ||||
| -rw-r--r-- | src/lib/dcp_subtitle_decoder.cc | 17 | ||||
| -rw-r--r-- | src/lib/dcp_subtitle_decoder.h | 2 | ||||
| -rw-r--r-- | src/lib/decoder.h | 20 | ||||
| -rw-r--r-- | src/lib/ffmpeg_decoder.cc | 42 | ||||
| -rw-r--r-- | src/lib/ffmpeg_decoder.h | 9 | ||||
| -rw-r--r-- | src/lib/image_decoder.cc | 19 | ||||
| -rw-r--r-- | src/lib/image_decoder.h | 8 | ||||
| -rw-r--r-- | src/lib/player.cc | 11 | ||||
| -rw-r--r-- | src/lib/sndfile_decoder.cc | 7 | ||||
| -rw-r--r-- | src/lib/sndfile_decoder.h | 2 | ||||
| -rw-r--r-- | src/lib/subtitle_decoder.cc | 23 | ||||
| -rw-r--r-- | src/lib/subtitle_decoder.h | 30 | ||||
| -rw-r--r-- | src/lib/text_subtitle_decoder.cc | 22 | ||||
| -rw-r--r-- | src/lib/text_subtitle_decoder.h | 2 | ||||
| -rw-r--r-- | src/lib/video_decoder.cc | 12 | ||||
| -rw-r--r-- | src/lib/video_decoder.h | 12 | ||||
| -rw-r--r-- | src/wx/subtitle_panel.cc | 2 | ||||
| -rw-r--r-- | src/wx/subtitle_view.cc | 4 | ||||
| -rw-r--r-- | src/wx/subtitle_view.h | 6 |
25 files changed, 192 insertions, 119 deletions
diff --git a/src/lib/audio_decoder.cc b/src/lib/audio_decoder.cc index 705fdbef1..7ceb9680b 100644 --- a/src/lib/audio_decoder.cc +++ b/src/lib/audio_decoder.cc @@ -30,13 +30,13 @@ using std::cout; using std::map; using boost::shared_ptr; -AudioDecoder::AudioDecoder (shared_ptr<const AudioContent> content, bool fast, shared_ptr<Log> log) +AudioDecoder::AudioDecoder (Decoder* parent, shared_ptr<const AudioContent> content, bool fast, shared_ptr<Log> log) : _audio_content (content) , _ignore_audio (false) , _fast (fast) { BOOST_FOREACH (AudioStreamPtr i, content->streams ()) { - _streams[i] = shared_ptr<AudioDecoderStream> (new AudioDecoderStream (_audio_content, i, this, log)); + _streams[i] = shared_ptr<AudioDecoderStream> (new AudioDecoderStream (_audio_content, i, parent, log)); } } diff --git a/src/lib/audio_decoder.h b/src/lib/audio_decoder.h index 31d0785c6..a56847daf 100644 --- a/src/lib/audio_decoder.h +++ b/src/lib/audio_decoder.h @@ -37,10 +37,10 @@ class Log; /** @class AudioDecoder. * @brief Parent class for audio decoders. */ -class AudioDecoder : public virtual Decoder, public boost::enable_shared_from_this<AudioDecoder> +class AudioDecoder : public boost::enable_shared_from_this<AudioDecoder> { public: - AudioDecoder (boost::shared_ptr<const AudioContent>, bool fast, boost::shared_ptr<Log> log); + AudioDecoder (Decoder* parent, boost::shared_ptr<const AudioContent>, bool fast, boost::shared_ptr<Log> log); /** Try to fetch some audio from a specific place in this content. * @param frame Frame to start from (after resampling, if applicable) @@ -56,7 +56,6 @@ public: return _fast; } -protected: void audio (AudioStreamPtr stream, boost::shared_ptr<const AudioBuffers>, ContentTime); void flush (); void seek (ContentTime t, bool accurate); diff --git a/src/lib/audio_decoder_stream.cc b/src/lib/audio_decoder_stream.cc index cd2e3a388..bbe26b6ef 100644 --- a/src/lib/audio_decoder_stream.cc +++ b/src/lib/audio_decoder_stream.cc @@ -39,14 +39,14 @@ using std::max; using boost::optional; using boost::shared_ptr; -AudioDecoderStream::AudioDecoderStream (shared_ptr<const AudioContent> content, AudioStreamPtr stream, AudioDecoder* decoder, shared_ptr<Log> log) +AudioDecoderStream::AudioDecoderStream (shared_ptr<const AudioContent> content, AudioStreamPtr stream, Decoder* decoder, shared_ptr<Log> log) : _content (content) , _stream (stream) , _decoder (decoder) , _log (log) { if (content->resampled_frame_rate() != _stream->frame_rate() && _stream->channels() > 0) { - _resampler.reset (new Resampler (_stream->frame_rate(), content->resampled_frame_rate(), _stream->channels (), decoder->fast ())); + _resampler.reset (new Resampler (_stream->frame_rate(), content->resampled_frame_rate(), _stream->channels (), decoder->audio->fast ())); } reset_decoded (); diff --git a/src/lib/audio_decoder_stream.h b/src/lib/audio_decoder_stream.h index 90269a0f4..265bbe004 100644 --- a/src/lib/audio_decoder_stream.h +++ b/src/lib/audio_decoder_stream.h @@ -29,11 +29,12 @@ class AudioContent; class AudioDecoder; class Resampler; class Log; +class Decoder; class AudioDecoderStream { public: - AudioDecoderStream (boost::shared_ptr<const AudioContent>, AudioStreamPtr, AudioDecoder* decoder, boost::shared_ptr<Log> log); + AudioDecoderStream (boost::shared_ptr<const AudioContent>, AudioStreamPtr, Decoder* decoder, boost::shared_ptr<Log> log); ContentAudio get (Frame time, Frame length, bool accurate); void audio (boost::shared_ptr<const AudioBuffers>, ContentTime); @@ -47,7 +48,7 @@ private: boost::shared_ptr<const AudioContent> _content; AudioStreamPtr _stream; - AudioDecoder* _decoder; + Decoder* _decoder; boost::shared_ptr<Log> _log; boost::shared_ptr<Resampler> _resampler; boost::optional<Frame> _position; diff --git a/src/lib/dcp_decoder.cc b/src/lib/dcp_decoder.cc index 8008fe515..2a7691666 100644 --- a/src/lib/dcp_decoder.cc +++ b/src/lib/dcp_decoder.cc @@ -20,7 +20,10 @@ #include "dcp_decoder.h" #include "dcp_content.h" #include "audio_content.h" +#include "video_decoder.h" +#include "audio_decoder.h" #include "j2k_image_proxy.h" +#include "subtitle_decoder.h" #include "image.h" #include "config.h" #include <dcp/dcp.h> @@ -44,11 +47,20 @@ using boost::shared_ptr; using boost::dynamic_pointer_cast; DCPDecoder::DCPDecoder (shared_ptr<const DCPContent> c, shared_ptr<Log> log, bool fast) - : VideoDecoder (c, log) - , AudioDecoder (c->audio, fast, log) - , SubtitleDecoder (c->subtitle) - , _dcp_content (c) + : _dcp_content (c) { + video.reset (new VideoDecoder (this, c, log)); + audio.reset (new AudioDecoder (this, c->audio, fast, log)); + + subtitle.reset ( + new SubtitleDecoder ( + this, + c->subtitle, + bind (&DCPDecoder::image_subtitles_during, this, _1, _2), + bind (&DCPDecoder::text_subtitles_during, this, _1, _2) + ) + ); + dcp::DCP dcp (c->directory ()); dcp.read (false, 0, true); if (c->kdm ()) { @@ -85,14 +97,14 @@ DCPDecoder::pass (PassReason reason, bool) shared_ptr<dcp::StereoPictureAsset> stereo = dynamic_pointer_cast<dcp::StereoPictureAsset> (asset); int64_t const entry_point = (*_reel)->main_picture()->entry_point (); if (mono) { - video (shared_ptr<ImageProxy> (new J2KImageProxy (mono->get_frame (entry_point + frame), asset->size())), offset + frame); + video->video (shared_ptr<ImageProxy> (new J2KImageProxy (mono->get_frame (entry_point + frame), asset->size())), offset + frame); } else { - video ( + video->video ( shared_ptr<ImageProxy> (new J2KImageProxy (stereo->get_frame (entry_point + frame), asset->size(), dcp::EYE_LEFT)), offset + frame ); - video ( + video->video ( shared_ptr<ImageProxy> (new J2KImageProxy (stereo->get_frame (entry_point + frame), asset->size(), dcp::EYE_RIGHT)), offset + frame ); @@ -114,7 +126,7 @@ DCPDecoder::pass (PassReason reason, bool) } } - audio (_dcp_content->audio->stream(), data, ContentTime::from_frames (offset, vfr) + _next); + audio->audio (_dcp_content->audio->stream(), data, ContentTime::from_frames (offset, vfr) + _next); } if ((*_reel)->main_subtitle ()) { @@ -127,7 +139,7 @@ DCPDecoder::pass (PassReason reason, bool) if (!subs.empty ()) { /* XXX: assuming that all `subs' are at the same time; maybe this is ok */ - text_subtitle ( + subtitle->text_subtitle ( ContentTimePeriod ( ContentTime::from_frames (offset - entry_point, vfr) + ContentTime::from_seconds (subs.front().in().as_seconds ()), ContentTime::from_frames (offset - entry_point, vfr) + ContentTime::from_seconds (subs.front().out().as_seconds ()) @@ -152,9 +164,9 @@ DCPDecoder::pass (PassReason reason, bool) void DCPDecoder::seek (ContentTime t, bool accurate) { - VideoDecoder::seek (t, accurate); - AudioDecoder::seek (t, accurate); - SubtitleDecoder::seek (t, accurate); + video->seek (t, accurate); + audio->seek (t, accurate); + subtitle->seek (t, accurate); _reel = _reels.begin (); while (_reel != _reels.end() && t >= ContentTime::from_frames ((*_reel)->main_picture()->duration(), _dcp_content->active_video_frame_rate ())) { diff --git a/src/lib/dcp_decoder.h b/src/lib/dcp_decoder.h index ce9a3ef9a..6e58c4904 100644 --- a/src/lib/dcp_decoder.h +++ b/src/lib/dcp_decoder.h @@ -21,18 +21,17 @@ * @brief A decoder of existing DCPs. */ -#include "video_decoder.h" -#include "audio_decoder.h" -#include "subtitle_decoder.h" +#include "decoder.h" namespace dcp { class Reel; } class DCPContent; +class Log; struct dcp_subtitle_within_dcp_test; -class DCPDecoder : public VideoDecoder, public AudioDecoder, public SubtitleDecoder +class DCPDecoder : public Decoder { public: DCPDecoder (boost::shared_ptr<const DCPContent>, boost::shared_ptr<Log> log, bool fast); diff --git a/src/lib/dcp_subtitle_decoder.cc b/src/lib/dcp_subtitle_decoder.cc index 964ee6f20..23f5dd529 100644 --- a/src/lib/dcp_subtitle_decoder.cc +++ b/src/lib/dcp_subtitle_decoder.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Carl Hetherington <cth@carlh.net> + Copyright (C) 2014-2016 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 @@ -25,10 +25,19 @@ using std::list; using std::cout; using boost::shared_ptr; +using boost::bind; DCPSubtitleDecoder::DCPSubtitleDecoder (shared_ptr<const DCPSubtitleContent> content) - : SubtitleDecoder (content->subtitle) { + subtitle.reset ( + new SubtitleDecoder ( + this, + content->subtitle, + bind (&DCPSubtitleDecoder::image_subtitles_during, this, _1, _2), + bind (&DCPSubtitleDecoder::text_subtitles_during, this, _1, _2) + ) + ); + shared_ptr<dcp::SubtitleAsset> c (load (content->path (0))); _subtitles = c->subtitles (); _next = _subtitles.begin (); @@ -37,7 +46,7 @@ DCPSubtitleDecoder::DCPSubtitleDecoder (shared_ptr<const DCPSubtitleContent> con void DCPSubtitleDecoder::seek (ContentTime time, bool accurate) { - SubtitleDecoder::seek (time, accurate); + subtitle->seek (time, accurate); _next = _subtitles.begin (); list<dcp::SubtitleString>::const_iterator i = _subtitles.begin (); @@ -68,7 +77,7 @@ DCPSubtitleDecoder::pass (PassReason, bool) ++_next; } - text_subtitle (p, s); + subtitle->text_subtitle (p, s); return false; } diff --git a/src/lib/dcp_subtitle_decoder.h b/src/lib/dcp_subtitle_decoder.h index 1f5377622..fcefc0201 100644 --- a/src/lib/dcp_subtitle_decoder.h +++ b/src/lib/dcp_subtitle_decoder.h @@ -22,7 +22,7 @@ class DCPSubtitleContent; -class DCPSubtitleDecoder : public SubtitleDecoder, public DCPSubtitle +class DCPSubtitleDecoder : public DCPSubtitle, public Decoder { public: DCPSubtitleDecoder (boost::shared_ptr<const DCPSubtitleContent>); diff --git a/src/lib/decoder.h b/src/lib/decoder.h index 10bb45310..979c6cf58 100644 --- a/src/lib/decoder.h +++ b/src/lib/decoder.h @@ -29,6 +29,9 @@ #include <boost/utility.hpp> class Decoded; +class VideoDecoder; +class AudioDecoder; +class SubtitleDecoder; /** @class Decoder. * @brief Parent class for decoders of content. @@ -38,8 +41,15 @@ class Decoder : public boost::noncopyable public: virtual ~Decoder () {} -protected: - friend class AudioDecoderStream; + boost::shared_ptr<VideoDecoder> video; + boost::shared_ptr<AudioDecoder> audio; + boost::shared_ptr<SubtitleDecoder> subtitle; + + enum PassReason { + PASS_REASON_VIDEO, + PASS_REASON_AUDIO, + PASS_REASON_SUBTITLE + }; /** Seek so that the next pass() will yield the next thing * (video/sound frame, subtitle etc.) at or after the requested @@ -51,12 +61,6 @@ protected: */ virtual void seek (ContentTime time, bool accurate) = 0; - enum PassReason { - PASS_REASON_VIDEO, - PASS_REASON_AUDIO, - PASS_REASON_SUBTITLE - }; - /** @return true if this decoder has already returned all its data and will give no more */ virtual bool pass (PassReason, bool accurate) = 0; }; diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index d84bb2a52..2f123e484 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -27,14 +27,17 @@ #include "util.h" #include "log.h" #include "ffmpeg_decoder.h" +#include "subtitle_decoder.h" #include "ffmpeg_audio_stream.h" #include "ffmpeg_subtitle_stream.h" #include "video_filter_graph.h" #include "audio_buffers.h" #include "ffmpeg_content.h" #include "raw_image_proxy.h" +#include "video_decoder.h" #include "film.h" #include "md5_digester.h" +#include "audio_decoder.h" #include "compose.hpp" #include <dcp/subtitle_string.h> #include <sub/ssa_reader.h> @@ -72,17 +75,30 @@ using boost::split; using dcp::Size; FFmpegDecoder::FFmpegDecoder (shared_ptr<const FFmpegContent> c, shared_ptr<Log> log, bool fast) - : VideoDecoder (c, log) - , AudioDecoder (c->audio, fast, log) - , SubtitleDecoder (c->subtitle) - , FFmpeg (c) + : FFmpeg (c) , _log (log) { if (c->video) { + video.reset (new VideoDecoder (this, c, log)); _pts_offset = pts_offset (c->ffmpeg_audio_streams(), c->first_video(), c->active_video_frame_rate()); } else { _pts_offset = ContentTime (); } + + if (c->audio) { + audio.reset (new AudioDecoder (this, c->audio, fast, log)); + } + + if (c->subtitle) { + subtitle.reset ( + new SubtitleDecoder ( + this, + c->subtitle, + bind (&FFmpegDecoder::image_subtitles_during, this, _1, _2), + bind (&FFmpegDecoder::text_subtitles_during, this, _1, _2) + ) + ); + } } void @@ -98,7 +114,7 @@ FFmpegDecoder::flush () while (decode_video_packet ()) {} decode_audio_packet (); - AudioDecoder::flush (); + audio->flush (); } bool @@ -125,7 +141,7 @@ FFmpegDecoder::pass (PassReason reason, bool accurate) int const si = _packet.stream_index; shared_ptr<const FFmpegContent> fc = _ffmpeg_content; - if (_video_stream && si == _video_stream.get() && !_ignore_video && (accurate || reason != PASS_REASON_SUBTITLE)) { + if (_video_stream && si == _video_stream.get() && !video->ignore_video() && (accurate || reason != PASS_REASON_SUBTITLE)) { decode_video_packet (); } else if (fc->subtitle_stream() && fc->subtitle_stream()->uses_index (_format_context, si)) { decode_subtitle_packet (); @@ -284,9 +300,9 @@ FFmpegDecoder::bytes_per_audio_sample (shared_ptr<FFmpegAudioStream> stream) con void FFmpegDecoder::seek (ContentTime time, bool accurate) { - VideoDecoder::seek (time, accurate); - AudioDecoder::seek (time, accurate); - SubtitleDecoder::seek (time, accurate); + video->seek (time, accurate); + audio->seek (time, accurate); + subtitle->seek (time, accurate); /* If we are doing an `accurate' seek, we need to use pre-roll, as we don't really know what the seek will give us. @@ -379,7 +395,7 @@ FFmpegDecoder::decode_audio_packet () } if (data->frames() > 0) { - audio (*stream, data, ct); + audio->audio (*stream, data, ct); } } @@ -424,7 +440,7 @@ FFmpegDecoder::decode_video_packet () if (i->second != AV_NOPTS_VALUE) { double const pts = i->second * av_q2d (_format_context->streams[_video_stream.get()]->time_base) + _pts_offset.seconds (); - video ( + video->video ( shared_ptr<ImageProxy> (new RawImageProxy (image)), llrint (pts * _ffmpeg_content->active_video_frame_rate ()) ); @@ -568,7 +584,7 @@ FFmpegDecoder::decode_bitmap_subtitle (AVSubtitleRect const * rect, ContentTimeP static_cast<double> (rect->h) / vs.height ); - image_subtitle (period, image, scaled_rect); + subtitle->image_subtitle (period, image, scaled_rect); } void @@ -635,5 +651,5 @@ FFmpegDecoder::decode_ass_subtitle (string ass, ContentTimePeriod period) } } - text_subtitle (period, ss); + subtitle->text_subtitle (period, ss); } diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index 990d643a7..40ccb9793 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net> + Copyright (C) 2012-2016 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 @@ -22,9 +22,7 @@ */ #include "util.h" -#include "video_decoder.h" -#include "audio_decoder.h" -#include "subtitle_decoder.h" +#include "decoder.h" #include "ffmpeg.h" extern "C" { #include <libavcodec/avcodec.h> @@ -36,12 +34,13 @@ extern "C" { class Log; class VideoFilterGraph; class FFmpegAudioStream; +class AudioBuffers; struct ffmpeg_pts_offset_test; /** @class FFmpegDecoder * @brief A decoder using FFmpeg to decode content. */ -class FFmpegDecoder : public VideoDecoder, public AudioDecoder, public SubtitleDecoder, public FFmpeg +class FFmpegDecoder : public FFmpeg, public Decoder { public: FFmpegDecoder (boost::shared_ptr<const FFmpegContent>, boost::shared_ptr<Log>, bool fast); diff --git a/src/lib/image_decoder.cc b/src/lib/image_decoder.cc index 6c46b9c08..71157dd5d 100644 --- a/src/lib/image_decoder.cc +++ b/src/lib/image_decoder.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net> + Copyright (C) 2012-2016 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 @@ -17,16 +17,18 @@ */ -#include <iostream> -#include <boost/filesystem.hpp> -#include <Magick++.h> #include "image_content.h" #include "image_decoder.h" +#include "video_decoder.h" #include "image.h" #include "magick_image_proxy.h" #include "j2k_image_proxy.h" #include "film.h" #include "exceptions.h" +#include "video_content.h" +#include <Magick++.h> +#include <boost/filesystem.hpp> +#include <iostream> #include "i18n.h" @@ -35,11 +37,10 @@ using boost::shared_ptr; using dcp::Size; ImageDecoder::ImageDecoder (shared_ptr<const ImageContent> c, shared_ptr<Log> log) - : VideoDecoder (c, log) - , _image_content (c) + : _image_content (c) , _video_position (0) { - + video.reset (new VideoDecoder (this, c, log)); } bool @@ -62,7 +63,7 @@ ImageDecoder::pass (PassReason, bool) } } - video (_image, _video_position); + video->video (_image, _video_position); ++_video_position; return false; } @@ -70,6 +71,6 @@ ImageDecoder::pass (PassReason, bool) void ImageDecoder::seek (ContentTime time, bool accurate) { - VideoDecoder::seek (time, accurate); + video->seek (time, accurate); _video_position = time.frames_round (_image_content->active_video_frame_rate ()); } diff --git a/src/lib/image_decoder.h b/src/lib/image_decoder.h index 9d81cdac1..862baffee 100644 --- a/src/lib/image_decoder.h +++ b/src/lib/image_decoder.h @@ -17,11 +17,13 @@ */ -#include "video_decoder.h" +#include "decoder.h" class ImageContent; +class Log; +class ImageProxy; -class ImageDecoder : public VideoDecoder +class ImageDecoder : public Decoder { public: ImageDecoder (boost::shared_ptr<const ImageContent> c, boost::shared_ptr<Log> log); @@ -31,7 +33,7 @@ public: } private: - bool pass (PassReason, bool); + bool pass (Decoder::PassReason, bool); void seek (ContentTime, bool); boost::shared_ptr<const ImageContent> _image_content; diff --git a/src/lib/player.cc b/src/lib/player.cc index 2abb6a30c..ba386e39a 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -20,6 +20,7 @@ #include "player.h" #include "film.h" #include "ffmpeg_decoder.h" +#include "video_decoder.h" #include "audio_buffers.h" #include "audio_content.h" #include "ffmpeg_content.h" @@ -206,14 +207,12 @@ Player::setup_pieces () frc = FrameRateChange (dsc->active_video_frame_rate(), _film->video_frame_rate()); } - shared_ptr<VideoDecoder> vd = dynamic_pointer_cast<VideoDecoder> (decoder); - if (vd && _ignore_video) { - vd->set_ignore_video (); + if (decoder->video && _ignore_video) { + decoder->video->set_ignore_video (); } - shared_ptr<AudioDecoder> ad = dynamic_pointer_cast<AudioDecoder> (decoder); - if (ad && _ignore_audio) { - ad->set_ignore_audio (); + if (decoder->audio && _ignore_audio) { + decoder->audio->set_ignore_audio (); } _pieces.push_back (shared_ptr<Piece> (new Piece (i, decoder, frc.get ()))); diff --git a/src/lib/sndfile_decoder.cc b/src/lib/sndfile_decoder.cc index b05750ac8..7762ab1e4 100644 --- a/src/lib/sndfile_decoder.cc +++ b/src/lib/sndfile_decoder.cc @@ -35,12 +35,11 @@ using boost::shared_ptr; SndfileDecoder::SndfileDecoder (shared_ptr<const SndfileContent> c, bool fast, shared_ptr<Log> log) : Sndfile (c) - , AudioDecoder (c->audio, fast, log) , _done (0) , _remaining (_info.frames) , _deinterleave_buffer (0) { - + audio.reset (new AudioDecoder (this, c->audio, fast, log)); } SndfileDecoder::~SndfileDecoder () @@ -87,7 +86,7 @@ SndfileDecoder::pass (PassReason, bool) } data->set_frames (this_time); - audio (_sndfile_content->audio->stream (), data, ContentTime::from_frames (_done, _info.samplerate)); + audio->audio (_sndfile_content->audio->stream (), data, ContentTime::from_frames (_done, _info.samplerate)); _done += this_time; _remaining -= this_time; @@ -97,7 +96,7 @@ SndfileDecoder::pass (PassReason, bool) void SndfileDecoder::seek (ContentTime t, bool accurate) { - AudioDecoder::seek (t, accurate); + audio->seek (t, accurate); _done = t.frames_round (_info.samplerate); _remaining = _info.frames - _done; diff --git a/src/lib/sndfile_decoder.h b/src/lib/sndfile_decoder.h index 6f3a6cc48..d3f9342b3 100644 --- a/src/lib/sndfile_decoder.h +++ b/src/lib/sndfile_decoder.h @@ -22,7 +22,7 @@ class SndfileContent; -class SndfileDecoder : public Sndfile, public AudioDecoder +class SndfileDecoder : public Sndfile, public Decoder { public: SndfileDecoder (boost::shared_ptr<const SndfileContent> c, bool fast, boost::shared_ptr<Log> log); diff --git a/src/lib/subtitle_decoder.cc b/src/lib/subtitle_decoder.cc index 454243b52..e9692b99f 100644 --- a/src/lib/subtitle_decoder.cc +++ b/src/lib/subtitle_decoder.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2015 Carl Hetherington <cth@carlh.net> + Copyright (C) 2013-2016 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 @@ -27,9 +27,18 @@ using std::list; using std::cout; using boost::shared_ptr; using boost::optional; - -SubtitleDecoder::SubtitleDecoder (shared_ptr<const SubtitleContent> c) - : _subtitle_content (c) +using boost::function; + +SubtitleDecoder::SubtitleDecoder ( + Decoder* parent, + shared_ptr<const SubtitleContent> c, + function<list<ContentTimePeriod> (ContentTimePeriod, bool)> image_subtitles_during, + function<list<ContentTimePeriod> (ContentTimePeriod, bool)> text_subtitles_during + ) + : _parent (parent) + , _subtitle_content (c) + , _image_subtitles_during (image_subtitles_during) + , _text_subtitles_during (text_subtitles_during) { } @@ -72,7 +81,7 @@ SubtitleDecoder::get (list<T> const & subs, list<ContentTimePeriod> const & sp, * (a) give us what we want, or * (b) hit the end of the decoder. */ - while (!pass(PASS_REASON_SUBTITLE, accurate) && (subs.empty() || (subs.back().period().to < sp.back().to))) {} + while (!_parent->pass(Decoder::PASS_REASON_SUBTITLE, accurate) && (subs.empty() || (subs.back().period().to < sp.back().to))) {} /* Now look for what we wanted in the data we have collected */ /* XXX: inefficient */ @@ -107,13 +116,13 @@ SubtitleDecoder::get (list<T> const & subs, list<ContentTimePeriod> const & sp, list<ContentTextSubtitle> SubtitleDecoder::get_text_subtitles (ContentTimePeriod period, bool starting, bool accurate) { - return get<ContentTextSubtitle> (_decoded_text_subtitles, text_subtitles_during (period, starting), period, starting, accurate); + return get<ContentTextSubtitle> (_decoded_text_subtitles, _text_subtitles_during (period, starting), period, starting, accurate); } list<ContentImageSubtitle> SubtitleDecoder::get_image_subtitles (ContentTimePeriod period, bool starting, bool accurate) { - return get<ContentImageSubtitle> (_decoded_image_subtitles, image_subtitles_during (period, starting), period, starting, accurate); + return get<ContentImageSubtitle> (_decoded_image_subtitles, _image_subtitles_during (period, starting), period, starting, accurate); } void diff --git a/src/lib/subtitle_decoder.h b/src/lib/subtitle_decoder.h index ef62d8b88..317755107 100644 --- a/src/lib/subtitle_decoder.h +++ b/src/lib/subtitle_decoder.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Carl Hetherington <cth@carlh.net> + Copyright (C) 2013-2016 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 @@ -28,33 +28,43 @@ class Image; -class SubtitleDecoder : public virtual Decoder +class SubtitleDecoder { public: - SubtitleDecoder (boost::shared_ptr<const SubtitleContent>); + /** Second parameter to the _during functions is true if we + * want only subtitles that start during the period, + * otherwise we want subtitles that overlap the period. + */ + SubtitleDecoder ( + Decoder* parent, + boost::shared_ptr<const SubtitleContent>, + boost::function<std::list<ContentTimePeriod> (ContentTimePeriod, bool)> image_subtitles_during, + boost::function<std::list<ContentTimePeriod> (ContentTimePeriod, bool)> text_subtitles_during + ); std::list<ContentImageSubtitle> get_image_subtitles (ContentTimePeriod period, bool starting, bool accurate); std::list<ContentTextSubtitle> get_text_subtitles (ContentTimePeriod period, bool starting, bool accurate); -protected: void seek (ContentTime, bool); void image_subtitle (ContentTimePeriod period, boost::shared_ptr<Image>, dcpomatic::Rect<double>); void text_subtitle (ContentTimePeriod period, std::list<dcp::SubtitleString>); + boost::shared_ptr<const SubtitleContent> content () const { + return _subtitle_content; + } + +private: + Decoder* _parent; std::list<ContentImageSubtitle> _decoded_image_subtitles; std::list<ContentTextSubtitle> _decoded_text_subtitles; boost::shared_ptr<const SubtitleContent> _subtitle_content; -private: template <class T> std::list<T> get (std::list<T> const & subs, std::list<ContentTimePeriod> const & sp, ContentTimePeriod period, bool starting, bool accurate); - /** @param starting true if we want only subtitles that start during the period, otherwise - * we want subtitles that overlap the period. - */ - virtual std::list<ContentTimePeriod> image_subtitles_during (ContentTimePeriod period, bool starting) const = 0; - virtual std::list<ContentTimePeriod> text_subtitles_during (ContentTimePeriod period, bool starting) const = 0; + boost::function<std::list<ContentTimePeriod> (ContentTimePeriod, bool)> _image_subtitles_during; + boost::function<std::list<ContentTimePeriod> (ContentTimePeriod, bool)> _text_subtitles_during; }; #endif diff --git a/src/lib/text_subtitle_decoder.cc b/src/lib/text_subtitle_decoder.cc index 94604cd71..f76bb7f75 100644 --- a/src/lib/text_subtitle_decoder.cc +++ b/src/lib/text_subtitle_decoder.cc @@ -34,17 +34,23 @@ using boost::optional; using boost::dynamic_pointer_cast; TextSubtitleDecoder::TextSubtitleDecoder (shared_ptr<const TextSubtitleContent> content) - : SubtitleDecoder (content->subtitle) - , TextSubtitle (content) + : TextSubtitle (content) , _next (0) { - + subtitle.reset ( + new SubtitleDecoder ( + this, + content->subtitle, + bind (&TextSubtitleDecoder::image_subtitles_during, this, _1, _2), + bind (&TextSubtitleDecoder::text_subtitles_during, this, _1, _2) + ) + ); } void TextSubtitleDecoder::seek (ContentTime time, bool accurate) { - SubtitleDecoder::seek (time, accurate); + subtitle->seek (time, accurate); _next = 0; while (_next < _subtitles.size() && ContentTime::from_seconds (_subtitles[_next].from.all_as_seconds ()) < time) { @@ -79,7 +85,7 @@ TextSubtitleDecoder::pass (PassReason, bool) j.italic, j.bold, /* force the colour to whatever is configured */ - _subtitle_content->colour(), + subtitle->content()->colour(), j.font_size.points (72 * 11), 1.0, dcp::Time (_subtitles[_next].from.all_as_seconds(), 1000), @@ -93,8 +99,8 @@ TextSubtitleDecoder::pass (PassReason, bool) dcp::VALIGN_TOP, dcp::DIRECTION_LTR, j.text, - _subtitle_content->outline() ? dcp::BORDER : dcp::NONE, - _subtitle_content->outline_colour(), + subtitle->content()->outline() ? dcp::BORDER : dcp::NONE, + subtitle->content()->outline_colour(), dcp::Time (0, 1000), dcp::Time (0, 1000) ) @@ -102,7 +108,7 @@ TextSubtitleDecoder::pass (PassReason, bool) } } - text_subtitle (content_time_period (_subtitles[_next]), out); + subtitle->text_subtitle (content_time_period (_subtitles[_next]), out); ++_next; return false; diff --git a/src/lib/text_subtitle_decoder.h b/src/lib/text_subtitle_decoder.h index 67d2caca8..9e37ecc3b 100644 --- a/src/lib/text_subtitle_decoder.h +++ b/src/lib/text_subtitle_decoder.h @@ -25,7 +25,7 @@ class TextSubtitleContent; -class TextSubtitleDecoder : public SubtitleDecoder, public TextSubtitle +class TextSubtitleDecoder : public Decoder, public TextSubtitle { public: TextSubtitleDecoder (boost::shared_ptr<const TextSubtitleContent>); diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index 8862eaa6e..fce5b367a 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -34,12 +34,14 @@ using std::back_inserter; using boost::shared_ptr; using boost::optional; -VideoDecoder::VideoDecoder (shared_ptr<const Content> c, shared_ptr<Log> log) +VideoDecoder::VideoDecoder (Decoder* parent, shared_ptr<const Content> c, shared_ptr<Log> log) #ifdef DCPOMATIC_DEBUG : test_gaps (0) - , _video_content (c) + , _parent (parent), + _video_content (c) #else - : _video_content (c) + : _parent (parent) + , _video_content (c) #endif , _log (log) , _last_seek_accurate (true) @@ -105,7 +107,7 @@ VideoDecoder::get_video (Frame frame, bool accurate) break; } - if (pass (PASS_REASON_VIDEO, accurate)) { + if (_parent->pass (Decoder::PASS_REASON_VIDEO, accurate)) { /* The decoder has nothing more for us */ no_data = true; break; @@ -128,7 +130,7 @@ VideoDecoder::get_video (Frame frame, bool accurate) } else { /* Any frame will do: use the first one that comes out of pass() */ - while (_decoded_video.empty() && !pass (PASS_REASON_VIDEO, accurate)) {} + while (_decoded_video.empty() && !_parent->pass (Decoder::PASS_REASON_VIDEO, accurate)) {} if (!_decoded_video.empty ()) { dec.push_back (_decoded_video.front ()); } diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h index 669a5ef1e..c14a877f2 100644 --- a/src/lib/video_decoder.h +++ b/src/lib/video_decoder.h @@ -39,20 +39,22 @@ class Log; /** @class VideoDecoder * @brief Parent for classes which decode video. */ -class VideoDecoder : public virtual Decoder +class VideoDecoder { public: - VideoDecoder (boost::shared_ptr<const Content> c, boost::shared_ptr<Log> log); + VideoDecoder (Decoder* parent, boost::shared_ptr<const Content> c, boost::shared_ptr<Log> log); std::list<ContentVideo> get_video (Frame frame, bool accurate); void set_ignore_video (); + bool ignore_video () const { + return _ignore_video; + } #ifdef DCPOMATIC_DEBUG int test_gaps; #endif -protected: friend struct video_decoder_fill_test1; friend struct video_decoder_fill_test2; friend struct ffmpeg_pts_offset_test; @@ -60,10 +62,14 @@ protected: void seek (ContentTime time, bool accurate); void video (boost::shared_ptr<const ImageProxy>, Frame frame); + +private: + std::list<ContentVideo> decoded_video (Frame frame); void fill_one_eye (Frame from, Frame to, Eyes); void fill_both_eyes (Frame from, Frame to, Eyes); + Decoder* _parent; boost::shared_ptr<const Content> _video_content; boost::shared_ptr<Log> _log; std::list<ContentVideo> _decoded_video; diff --git a/src/wx/subtitle_panel.cc b/src/wx/subtitle_panel.cc index 3a0063c95..1d6325dfd 100644 --- a/src/wx/subtitle_panel.cc +++ b/src/wx/subtitle_panel.cc @@ -377,7 +377,7 @@ SubtitlePanel::subtitle_view_clicked () ContentList c = _parent->selected_subtitle (); DCPOMATIC_ASSERT (c.size() == 1); - shared_ptr<SubtitleDecoder> decoder; + shared_ptr<Decoder> decoder; shared_ptr<TextSubtitleContent> sr = dynamic_pointer_cast<TextSubtitleContent> (c.front ()); if (sr) { diff --git a/src/wx/subtitle_view.cc b/src/wx/subtitle_view.cc index 916f1eedc..a33a401df 100644 --- a/src/wx/subtitle_view.cc +++ b/src/wx/subtitle_view.cc @@ -28,7 +28,7 @@ using std::list; using boost::shared_ptr; using boost::dynamic_pointer_cast; -SubtitleView::SubtitleView (wxWindow* parent, shared_ptr<Film> film, shared_ptr<SubtitleDecoder> decoder, DCPTime position) +SubtitleView::SubtitleView (wxWindow* parent, shared_ptr<Film> film, shared_ptr<Decoder> decoder, DCPTime position) : wxDialog (parent, wxID_ANY, _("Subtitles"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) { _list = new wxListCtrl (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL); @@ -65,7 +65,7 @@ SubtitleView::SubtitleView (wxWindow* parent, shared_ptr<Film> film, shared_ptr< sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder()); } - list<ContentTextSubtitle> subs = decoder->get_text_subtitles (ContentTimePeriod (ContentTime(), ContentTime::max ()), true, true); + list<ContentTextSubtitle> subs = decoder->subtitle->get_text_subtitles (ContentTimePeriod (ContentTime(), ContentTime::max ()), true, true); FrameRateChange const frc = film->active_frame_rate_change (position); int n = 0; for (list<ContentTextSubtitle>::const_iterator i = subs.begin(); i != subs.end(); ++i) { diff --git a/src/wx/subtitle_view.h b/src/wx/subtitle_view.h index f5a61890b..d95f26668 100644 --- a/src/wx/subtitle_view.h +++ b/src/wx/subtitle_view.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Carl Hetherington <cth@carlh.net> + Copyright (C) 2014-2016 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,12 +21,12 @@ #include <wx/wx.h> #include <wx/listctrl.h> -class SubtitleDecoder; +class Decoder; class SubtitleView : public wxDialog { public: - SubtitleView (wxWindow *, boost::shared_ptr<Film>, boost::shared_ptr<SubtitleDecoder>, DCPTime position); + SubtitleView (wxWindow *, boost::shared_ptr<Film>, boost::shared_ptr<Decoder>, DCPTime position); private: wxListCtrl* _list; |
