summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2016-11-19 20:40:36 +0000
committerCarl Hetherington <cth@carlh.net>2016-11-19 20:40:36 +0000
commitf113b2aaca7a65f7b37e12a7d9f3f99e2d834e81 (patch)
tree6ea2ed1d480304a4aaf512e380cd013bbf42e86c /src/lib
parentfab7fa5a9ef1d069c7ca32e3669d0e37e896250c (diff)
Move position variables into the video/audio/subtitle decoder classes.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/audio_decoder.cc13
-rw-r--r--src/lib/audio_decoder.h5
-rw-r--r--src/lib/audio_decoder_stream.cc7
-rw-r--r--src/lib/audio_decoder_stream.h3
-rw-r--r--src/lib/dcp_decoder.cc4
-rw-r--r--src/lib/dcp_subtitle_decoder.cc2
-rw-r--r--src/lib/decoder.cc18
-rw-r--r--src/lib/decoder.h10
-rw-r--r--src/lib/decoder_part.cc35
-rw-r--r--src/lib/decoder_part.h60
-rw-r--r--src/lib/ffmpeg_decoder.cc19
-rw-r--r--src/lib/ffmpeg_decoder.h1
-rw-r--r--src/lib/image_decoder.cc2
-rw-r--r--src/lib/subtitle_decoder.cc4
-rw-r--r--src/lib/subtitle_decoder.h4
-rw-r--r--src/lib/text_subtitle_decoder.cc2
-rw-r--r--src/lib/video_decoder.cc21
-rw-r--r--src/lib/video_decoder.h11
-rw-r--r--src/lib/video_mxf_decoder.cc2
-rw-r--r--src/lib/wscript1
20 files changed, 130 insertions, 94 deletions
diff --git a/src/lib/audio_decoder.cc b/src/lib/audio_decoder.cc
index bc3796058..9801a68da 100644
--- a/src/lib/audio_decoder.cc
+++ b/src/lib/audio_decoder.cc
@@ -32,10 +32,10 @@ using std::map;
using boost::shared_ptr;
AudioDecoder::AudioDecoder (Decoder* parent, shared_ptr<const AudioContent> content, shared_ptr<Log> log)
- : _ignore (false)
+ : DecoderPart (parent)
{
BOOST_FOREACH (AudioStreamPtr i, content->streams ()) {
- _streams[i] = shared_ptr<AudioDecoderStream> (new AudioDecoderStream (content, i, parent, log));
+ _streams[i] = shared_ptr<AudioDecoderStream> (new AudioDecoderStream (content, i, parent, this, log));
}
}
@@ -48,7 +48,7 @@ AudioDecoder::get (AudioStreamPtr stream, Frame frame, Frame length, bool accura
void
AudioDecoder::give (AudioStreamPtr stream, shared_ptr<const AudioBuffers> data, ContentTime time)
{
- if (_ignore) {
+ if (ignore ()) {
return;
}
@@ -94,13 +94,6 @@ AudioDecoder::seek (ContentTime t, bool accurate)
}
}
-/** Set this decoder never to produce any data */
-void
-AudioDecoder::set_ignore ()
-{
- _ignore = true;
-}
-
void
AudioDecoder::set_fast ()
{
diff --git a/src/lib/audio_decoder.h b/src/lib/audio_decoder.h
index 2415bd6ac..4b7594f35 100644
--- a/src/lib/audio_decoder.h
+++ b/src/lib/audio_decoder.h
@@ -28,6 +28,7 @@
#include "decoder.h"
#include "content_audio.h"
#include "audio_stream.h"
+#include "decoder_part.h"
#include <boost/enable_shared_from_this.hpp>
class AudioBuffers;
@@ -38,7 +39,7 @@ class Log;
/** @class AudioDecoder.
* @brief Parent class for audio decoders.
*/
-class AudioDecoder : public boost::enable_shared_from_this<AudioDecoder>
+class AudioDecoder : public boost::enable_shared_from_this<AudioDecoder>, public DecoderPart
{
public:
AudioDecoder (Decoder* parent, boost::shared_ptr<const AudioContent>, boost::shared_ptr<Log> log);
@@ -51,7 +52,6 @@ public:
*/
ContentAudio get (AudioStreamPtr stream, Frame time, Frame length, bool accurate);
- void set_ignore ();
void set_fast ();
void give (AudioStreamPtr stream, boost::shared_ptr<const AudioBuffers>, ContentTime);
@@ -61,7 +61,6 @@ public:
private:
/** An AudioDecoderStream object to manage each stream in _audio_content */
std::map<AudioStreamPtr, boost::shared_ptr<AudioDecoderStream> > _streams;
- bool _ignore;
};
#endif
diff --git a/src/lib/audio_decoder_stream.cc b/src/lib/audio_decoder_stream.cc
index 7e8e304ef..4f1a2f4ff 100644
--- a/src/lib/audio_decoder_stream.cc
+++ b/src/lib/audio_decoder_stream.cc
@@ -40,10 +40,13 @@ using std::max;
using boost::optional;
using boost::shared_ptr;
-AudioDecoderStream::AudioDecoderStream (shared_ptr<const AudioContent> content, AudioStreamPtr stream, Decoder* decoder, shared_ptr<Log> log)
+AudioDecoderStream::AudioDecoderStream (
+ shared_ptr<const AudioContent> content, AudioStreamPtr stream, Decoder* decoder, AudioDecoder* audio_decoder, shared_ptr<Log> log
+ )
: _content (content)
, _stream (stream)
, _decoder (decoder)
+ , _audio_decoder (audio_decoder)
, _log (log)
/* We effectively start having done a seek to zero; this allows silence-padding of the first
data that comes out of our decoder.
@@ -86,7 +89,7 @@ AudioDecoderStream::get (Frame frame, Frame length, bool accurate)
}
if (missing) {
- _decoder->maybe_seek_audio (ContentTime::from_frames (*missing, _content->resampled_frame_rate()), accurate);
+ _audio_decoder->maybe_seek (ContentTime::from_frames (*missing, _content->resampled_frame_rate()), accurate);
}
/* Offset of the data that we want from the start of _decoded.audio
diff --git a/src/lib/audio_decoder_stream.h b/src/lib/audio_decoder_stream.h
index a99464b89..78747bfc5 100644
--- a/src/lib/audio_decoder_stream.h
+++ b/src/lib/audio_decoder_stream.h
@@ -35,7 +35,7 @@ class Decoder;
class AudioDecoderStream
{
public:
- AudioDecoderStream (boost::shared_ptr<const AudioContent>, AudioStreamPtr, Decoder* decoder, boost::shared_ptr<Log> log);
+ AudioDecoderStream (boost::shared_ptr<const AudioContent>, AudioStreamPtr, Decoder* decoder, AudioDecoder* audio_decoder, boost::shared_ptr<Log> log);
ContentAudio get (Frame time, Frame length, bool accurate);
void audio (boost::shared_ptr<const AudioBuffers>, ContentTime);
@@ -51,6 +51,7 @@ private:
boost::shared_ptr<const AudioContent> _content;
AudioStreamPtr _stream;
Decoder* _decoder;
+ AudioDecoder* _audio_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 4f17bdb3b..1d7c66a5b 100644
--- a/src/lib/dcp_decoder.cc
+++ b/src/lib/dcp_decoder.cc
@@ -163,7 +163,9 @@ DCPDecoder::pass (PassReason reason, bool)
}
}
- _video_position = _audio_position = _subtitle_position = _next;
+ video->set_position (_next);
+ audio->set_position (_next);
+ subtitle->set_position (_next);
_next += ContentTime::from_frames (1, vfr);
if ((*_reel)->main_picture ()) {
diff --git a/src/lib/dcp_subtitle_decoder.cc b/src/lib/dcp_subtitle_decoder.cc
index c67133012..fe383226e 100644
--- a/src/lib/dcp_subtitle_decoder.cc
+++ b/src/lib/dcp_subtitle_decoder.cc
@@ -79,7 +79,7 @@ DCPSubtitleDecoder::pass (PassReason, bool)
}
subtitle->give_text (p, s);
- _subtitle_position = p.from;
+ subtitle->set_position (p.from);
return false;
}
diff --git a/src/lib/decoder.cc b/src/lib/decoder.cc
index 50356da78..988b8fe9b 100644
--- a/src/lib/decoder.cc
+++ b/src/lib/decoder.cc
@@ -40,21 +40,3 @@ Decoder::maybe_seek (optional<ContentTime>& position, ContentTime time, bool acc
position.reset ();
seek (time, accurate);
}
-
-void
-Decoder::maybe_seek_video (ContentTime time, bool accurate)
-{
- maybe_seek (_video_position, time, accurate);
-}
-
-void
-Decoder::maybe_seek_audio (ContentTime time, bool accurate)
-{
- maybe_seek (_audio_position, time, accurate);
-}
-
-void
-Decoder::maybe_seek_subtitle (ContentTime time, bool accurate)
-{
- maybe_seek (_subtitle_position, time, accurate);
-}
diff --git a/src/lib/decoder.h b/src/lib/decoder.h
index d2302d7a2..bd4bf01c2 100644
--- a/src/lib/decoder.h
+++ b/src/lib/decoder.h
@@ -52,10 +52,6 @@ public:
PASS_REASON_SUBTITLE
};
- void maybe_seek_video (ContentTime time, bool accurate);
- void maybe_seek_audio (ContentTime time, bool accurate);
- void maybe_seek_subtitle (ContentTime time, bool accurate);
-
/** @return true if this decoder has already returned all its data and will give no more */
virtual bool pass (PassReason, bool accurate) = 0;
@@ -64,10 +60,7 @@ public:
*/
virtual void reset () {}
-protected:
- boost::optional<ContentTime> _video_position;
- boost::optional<ContentTime> _audio_position;
- boost::optional<ContentTime> _subtitle_position;
+ void maybe_seek (boost::optional<ContentTime>& position, ContentTime time, bool accurate);
private:
/** Seek so that the next pass() will yield the next thing
@@ -79,7 +72,6 @@ private:
* it may seek to just the right spot.
*/
virtual void seek (ContentTime time, bool accurate) = 0;
- void maybe_seek (boost::optional<ContentTime>& position, ContentTime time, bool accurate);
};
#endif
diff --git a/src/lib/decoder_part.cc b/src/lib/decoder_part.cc
new file mode 100644
index 000000000..9ae9633e1
--- /dev/null
+++ b/src/lib/decoder_part.cc
@@ -0,0 +1,35 @@
+/*
+ Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "decoder_part.h"
+#include "decoder.h"
+
+DecoderPart::DecoderPart (Decoder* parent)
+ : _parent (parent)
+ , _ignore (false)
+{
+
+}
+
+void
+DecoderPart::maybe_seek (ContentTime time, bool accurate)
+{
+ _parent->maybe_seek (_position, time, accurate);
+}
diff --git a/src/lib/decoder_part.h b/src/lib/decoder_part.h
new file mode 100644
index 000000000..4b309a668
--- /dev/null
+++ b/src/lib/decoder_part.h
@@ -0,0 +1,60 @@
+/*
+ Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef DCPOMATIC_DECODER_PART_H
+#define DCPOMATIC_DECODER_PART_H
+
+#include "dcpomatic_time.h"
+#include <boost/optional.hpp>
+
+class Decoder;
+
+class DecoderPart
+{
+public:
+ DecoderPart (Decoder* parent);
+
+ void set_ignore () {
+ _ignore = true;
+ }
+
+ bool ignore () const {
+ return _ignore;
+ }
+
+ void set_position (ContentTime position) {
+ _position = position;
+ }
+
+ boost::optional<ContentTime> position () const {
+ return _position;
+ }
+
+ void maybe_seek (ContentTime time, bool accurate);
+
+protected:
+ Decoder* _parent;
+
+private:
+ bool _ignore;
+ boost::optional<ContentTime> _position;
+};
+
+#endif
diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc
index 8f196542a..ddc563b98 100644
--- a/src/lib/ffmpeg_decoder.cc
+++ b/src/lib/ffmpeg_decoder.cc
@@ -425,7 +425,7 @@ FFmpegDecoder::decode_audio_packet ()
LOG_WARNING ("Crazy timestamp %s", to_string (ct));
}
- update_position (_audio_position, ct);
+ audio->set_position (ct);
/* Give this data provided there is some, and its time is sane */
if (ct >= ContentTime() && data->frames() > 0) {
@@ -478,7 +478,7 @@ FFmpegDecoder::decode_video_packet ()
shared_ptr<ImageProxy> (new RawImageProxy (image)),
llrint (pts * _ffmpeg_content->active_video_frame_rate ())
);
- update_position (_video_position, ContentTime::from_seconds (pts));
+ video->set_position (ContentTime::from_seconds (pts));
} else {
LOG_WARNING_NC ("Dropping frame without PTS");
}
@@ -509,7 +509,7 @@ FFmpegDecoder::decode_subtitle_packet ()
FFmpegSubtitlePeriod sub_period = subtitle_period (sub);
ContentTimePeriod period;
period.from = sub_period.from + _pts_offset;
- update_position (_subtitle_position, period.from);
+ subtitle->set_position (period.from);
if (sub_period.to) {
/* We already know the subtitle period `to' time */
period.to = sub_period.to.get() + _pts_offset;
@@ -644,16 +644,3 @@ FFmpegDecoder::decode_ass_subtitle (string ass, ContentTimePeriod period)
subtitle->give_text (period, i);
}
}
-
-void
-FFmpegDecoder::update_position (optional<ContentTime>& current, ContentTime p)
-{
- /* current should err on the side of being too big, as then there is less
- chance that we will erroneously decide not to seek when current > request.
- */
- if (!current) {
- current = p;
- } else {
- current = max (*current, p);
- }
-}
diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h
index d6f50cd43..76755c1fc 100644
--- a/src/lib/ffmpeg_decoder.h
+++ b/src/lib/ffmpeg_decoder.h
@@ -52,7 +52,6 @@ private:
bool pass (PassReason, bool accurate);
void seek (ContentTime time, bool);
void flush ();
- void update_position (boost::optional<ContentTime>& current, ContentTime p);
AVSampleFormat audio_sample_format (boost::shared_ptr<FFmpegAudioStream> stream) const;
int bytes_per_audio_sample (boost::shared_ptr<FFmpegAudioStream> stream) const;
diff --git a/src/lib/image_decoder.cc b/src/lib/image_decoder.cc
index 7270c9782..28fc9c0a5 100644
--- a/src/lib/image_decoder.cc
+++ b/src/lib/image_decoder.cc
@@ -72,7 +72,7 @@ ImageDecoder::pass (PassReason, bool)
}
}
- _video_position = ContentTime::from_frames (_frame_video_position, _image_content->active_video_frame_rate ());
+ video->set_position (ContentTime::from_frames (_frame_video_position, _image_content->active_video_frame_rate ()));
video->give (_image, _frame_video_position);
++_frame_video_position;
return false;
diff --git a/src/lib/subtitle_decoder.cc b/src/lib/subtitle_decoder.cc
index 020a0383c..9c6ac969d 100644
--- a/src/lib/subtitle_decoder.cc
+++ b/src/lib/subtitle_decoder.cc
@@ -41,7 +41,7 @@ SubtitleDecoder::SubtitleDecoder (
function<list<ContentTimePeriod> (ContentTimePeriod, bool)> image_during,
function<list<ContentTimePeriod> (ContentTimePeriod, bool)> text_during
)
- : _parent (parent)
+ : DecoderPart (parent)
, _content (c)
, _image_during (image_during)
, _text_during (text_during)
@@ -104,7 +104,7 @@ SubtitleDecoder::get (list<T> const & subs, list<ContentTimePeriod> const & sp,
/* Suggest to our parent decoder that it might want to seek if we haven't got what we're being asked for */
if (missing) {
- _parent->maybe_seek_subtitle (*missing, true);
+ maybe_seek (*missing, true);
}
/* Now enough pass() calls will either:
diff --git a/src/lib/subtitle_decoder.h b/src/lib/subtitle_decoder.h
index eba36315e..df4946c07 100644
--- a/src/lib/subtitle_decoder.h
+++ b/src/lib/subtitle_decoder.h
@@ -25,6 +25,7 @@
#include "rect.h"
#include "types.h"
#include "content_subtitle.h"
+#include "decoder_part.h"
#include <dcp/subtitle_string.h>
namespace sub {
@@ -33,7 +34,7 @@ namespace sub {
class Image;
-class SubtitleDecoder
+class SubtitleDecoder : public DecoderPart
{
public:
/** Second parameter to the _during functions is true if we
@@ -63,7 +64,6 @@ public:
private:
- Decoder* _parent;
std::list<ContentImageSubtitle> _decoded_image;
std::list<ContentTextSubtitle> _decoded_text;
boost::shared_ptr<const SubtitleContent> _content;
diff --git a/src/lib/text_subtitle_decoder.cc b/src/lib/text_subtitle_decoder.cc
index 5f5545108..1576f50a1 100644
--- a/src/lib/text_subtitle_decoder.cc
+++ b/src/lib/text_subtitle_decoder.cc
@@ -68,7 +68,7 @@ TextSubtitleDecoder::pass (PassReason, bool)
ContentTimePeriod const p = content_time_period (_subtitles[_next]);
subtitle->give_text (p, _subtitles[_next]);
- _subtitle_position = p.from;
+ subtitle->set_position (p.from);
++_next;
return false;
diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc
index e3755e44f..bb9004e10 100644
--- a/src/lib/video_decoder.cc
+++ b/src/lib/video_decoder.cc
@@ -37,17 +37,13 @@ using boost::shared_ptr;
using boost::optional;
VideoDecoder::VideoDecoder (Decoder* parent, shared_ptr<const Content> c, shared_ptr<Log> log)
+ : DecoderPart (parent)
#ifdef DCPOMATIC_DEBUG
- : test_gaps (0)
- , _parent (parent),
- _content (c)
-#else
- : _parent (parent)
- , _content (c)
+ , test_gaps (0)
#endif
+ , _content (c)
, _log (log)
, _last_seek_accurate (true)
- , _ignore (false)
{
_black_image.reset (new Image (AV_PIX_FMT_RGB24, _content->video->size(), true));
_black_image->make_black ();
@@ -99,7 +95,7 @@ VideoDecoder::get (Frame frame, bool accurate)
*/
seek_frame *= 2;
}
- _parent->maybe_seek_video (ContentTime::from_frames (seek_frame, _content->active_video_frame_rate()), accurate);
+ maybe_seek (ContentTime::from_frames (seek_frame, _content->active_video_frame_rate()), accurate);
}
/* Work out the number of frames that we should return; we
@@ -274,7 +270,7 @@ VideoDecoder::fill_both_eyes (VideoFrame from, VideoFrame to)
void
VideoDecoder::give (shared_ptr<const ImageProxy> image, Frame frame)
{
- if (_ignore) {
+ if (ignore ()) {
return;
}
@@ -394,10 +390,3 @@ VideoDecoder::seek (ContentTime s, bool accurate)
_last_seek_time = s;
_last_seek_accurate = accurate;
}
-
-/** Set this decoder never to produce any data */
-void
-VideoDecoder::set_ignore ()
-{
- _ignore = true;
-}
diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h
index 692702444..2442d3173 100644
--- a/src/lib/video_decoder.h
+++ b/src/lib/video_decoder.h
@@ -29,6 +29,7 @@
#include "video_content.h"
#include "util.h"
#include "content_video.h"
+#include "decoder_part.h"
#include <boost/signals2.hpp>
#include <boost/shared_ptr.hpp>
@@ -40,18 +41,13 @@ class Log;
/** @class VideoDecoder
* @brief Parent for classes which decode video.
*/
-class VideoDecoder
+class VideoDecoder : public DecoderPart
{
public:
VideoDecoder (Decoder* parent, boost::shared_ptr<const Content> c, boost::shared_ptr<Log> log);
std::list<ContentVideo> get (Frame frame, bool accurate);
- void set_ignore ();
- bool ignore () const {
- return _ignore;
- }
-
#ifdef DCPOMATIC_DEBUG
int test_gaps;
#endif
@@ -70,15 +66,12 @@ private:
void fill_one_eye (Frame from, Frame to, Eyes);
void fill_both_eyes (VideoFrame from, VideoFrame to);
- Decoder* _parent;
boost::shared_ptr<const Content> _content;
boost::shared_ptr<Log> _log;
std::list<ContentVideo> _decoded;
boost::shared_ptr<Image> _black_image;
boost::optional<ContentTime> _last_seek_time;
bool _last_seek_accurate;
- /** true if this decoder should ignore all video; i.e. never produce any */
- bool _ignore;
/** if set, this is a frame for which we got no data because the Decoder said
* it has no more to give.
*/
diff --git a/src/lib/video_mxf_decoder.cc b/src/lib/video_mxf_decoder.cc
index 321728f58..90a58a16e 100644
--- a/src/lib/video_mxf_decoder.cc
+++ b/src/lib/video_mxf_decoder.cc
@@ -89,7 +89,7 @@ VideoMXFDecoder::pass (PassReason, bool)
);
}
- _video_position = _next;
+ video->set_position (_next);
_next += ContentTime::from_frames (1, vfr);
return false;
}
diff --git a/src/lib/wscript b/src/lib/wscript
index 4d63b9be3..14e14676e 100644
--- a/src/lib/wscript
+++ b/src/lib/wscript
@@ -58,6 +58,7 @@ sources = """
dcpomatic_time.cc
decoder.cc
decoder_factory.cc
+ decoder_part.cc
digester.cc
dolby_cp750.cc
emailer.cc