summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2016-11-19 00:31:37 +0000
committerCarl Hetherington <cth@carlh.net>2016-11-19 00:51:05 +0000
commit24e890682b3f2aa211277ad8b6b3591f2026d4be (patch)
treeb3b8b23c295e1efc1846c0a37088773da97606f8 /src
parent5d6e2ffca8e4b0d587eff8723716003a6d81be47 (diff)
Cope with offsets between video/audio/subtitle data in a muxed file.
Diffstat (limited to 'src')
-rw-r--r--src/lib/audio_decoder_stream.cc2
-rw-r--r--src/lib/dcp_decoder.cc2
-rw-r--r--src/lib/dcp_subtitle_decoder.cc2
-rw-r--r--src/lib/decoder.cc30
-rw-r--r--src/lib/decoder.h9
-rw-r--r--src/lib/ffmpeg_decoder.cc18
-rw-r--r--src/lib/ffmpeg_decoder.h2
-rw-r--r--src/lib/image_decoder.cc14
-rw-r--r--src/lib/image_decoder.h2
-rw-r--r--src/lib/subtitle_decoder.cc2
-rw-r--r--src/lib/text_subtitle_decoder.cc2
-rw-r--r--src/lib/video_decoder.cc2
-rw-r--r--src/lib/video_mxf_decoder.cc2
13 files changed, 58 insertions, 31 deletions
diff --git a/src/lib/audio_decoder_stream.cc b/src/lib/audio_decoder_stream.cc
index c14dc654e..7e8e304ef 100644
--- a/src/lib/audio_decoder_stream.cc
+++ b/src/lib/audio_decoder_stream.cc
@@ -86,7 +86,7 @@ AudioDecoderStream::get (Frame frame, Frame length, bool accurate)
}
if (missing) {
- _decoder->maybe_seek (ContentTime::from_frames (*missing, _content->resampled_frame_rate()), accurate);
+ _decoder->maybe_seek_audio (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/dcp_decoder.cc b/src/lib/dcp_decoder.cc
index 38c2a7ccf..4f17bdb3b 100644
--- a/src/lib/dcp_decoder.cc
+++ b/src/lib/dcp_decoder.cc
@@ -163,7 +163,7 @@ DCPDecoder::pass (PassReason reason, bool)
}
}
- _position = _next;
+ _video_position = _audio_position = _subtitle_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 d4e1a7fa2..c67133012 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);
- _position = p.from;
+ _subtitle_position = p.from;
return false;
}
diff --git a/src/lib/decoder.cc b/src/lib/decoder.cc
index cba674d04..50356da78 100644
--- a/src/lib/decoder.cc
+++ b/src/lib/decoder.cc
@@ -19,20 +19,42 @@
*/
#include "decoder.h"
+#include <iostream>
+
+using std::cout;
+using boost::optional;
void
-Decoder::maybe_seek (ContentTime time, bool accurate)
+Decoder::maybe_seek (optional<ContentTime>& position, ContentTime time, bool accurate)
{
- if (!_position) {
+ if (!position) {
/* A seek has just happened */
return;
}
- if (time >= *_position && time < (*_position + ContentTime::from_seconds(1))) {
+ if (time >= *position && time < (*position + ContentTime::from_seconds(1))) {
/* No need to seek: caller should just pass() */
return;
}
- _position.reset ();
+ 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 84661ee8c..d2302d7a2 100644
--- a/src/lib/decoder.h
+++ b/src/lib/decoder.h
@@ -52,7 +52,9 @@ public:
PASS_REASON_SUBTITLE
};
- void maybe_seek (ContentTime time, bool accurate);
+ 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;
@@ -63,7 +65,9 @@ public:
virtual void reset () {}
protected:
- boost::optional<ContentTime> _position;
+ boost::optional<ContentTime> _video_position;
+ boost::optional<ContentTime> _audio_position;
+ boost::optional<ContentTime> _subtitle_position;
private:
/** Seek so that the next pass() will yield the next thing
@@ -75,6 +79,7 @@ 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/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc
index 253272e96..8f196542a 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 (ct);
+ update_position (_audio_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 (ContentTime::from_seconds (pts));
+ update_position (_video_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 (period.from);
+ update_position (_subtitle_position, period.from);
if (sub_period.to) {
/* We already know the subtitle period `to' time */
period.to = sub_period.to.get() + _pts_offset;
@@ -646,14 +646,14 @@ FFmpegDecoder::decode_ass_subtitle (string ass, ContentTimePeriod period)
}
void
-FFmpegDecoder::update_position (ContentTime p)
+FFmpegDecoder::update_position (optional<ContentTime>& current, ContentTime p)
{
- /* _position should err on the side of being too big, as then there is less
- chance that we will erroneously decide not to seek when _position > request.
+ /* 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 (!_position) {
- _position = p;
+ if (!current) {
+ current = p;
} else {
- _position = max (*_position, p);
+ current = max (*current, p);
}
}
diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h
index dfe1f2694..d6f50cd43 100644
--- a/src/lib/ffmpeg_decoder.h
+++ b/src/lib/ffmpeg_decoder.h
@@ -52,7 +52,7 @@ private:
bool pass (PassReason, bool accurate);
void seek (ContentTime time, bool);
void flush ();
- void update_position (ContentTime p);
+ 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 41a4949ba..7270c9782 100644
--- a/src/lib/image_decoder.cc
+++ b/src/lib/image_decoder.cc
@@ -39,7 +39,7 @@ using dcp::Size;
ImageDecoder::ImageDecoder (shared_ptr<const ImageContent> c, shared_ptr<Log> log)
: _image_content (c)
- , _video_position (0)
+ , _frame_video_position (0)
{
video.reset (new VideoDecoder (this, c, log));
}
@@ -47,13 +47,13 @@ ImageDecoder::ImageDecoder (shared_ptr<const ImageContent> c, shared_ptr<Log> lo
bool
ImageDecoder::pass (PassReason, bool)
{
- if (_video_position >= _image_content->video->length()) {
+ if (_frame_video_position >= _image_content->video->length()) {
return true;
}
if (!_image_content->still() || !_image) {
/* Either we need an image or we are using moving images, so load one */
- boost::filesystem::path path = _image_content->path (_image_content->still() ? 0 : _video_position);
+ boost::filesystem::path path = _image_content->path (_image_content->still() ? 0 : _frame_video_position);
if (valid_j2k_file (path)) {
AVPixelFormat pf;
if (_image_content->video->colour_conversion()) {
@@ -72,9 +72,9 @@ ImageDecoder::pass (PassReason, bool)
}
}
- _position = ContentTime::from_frames (_video_position, _image_content->active_video_frame_rate ());
- video->give (_image, _video_position);
- ++_video_position;
+ _video_position = ContentTime::from_frames (_frame_video_position, _image_content->active_video_frame_rate ());
+ video->give (_image, _frame_video_position);
+ ++_frame_video_position;
return false;
}
@@ -82,5 +82,5 @@ void
ImageDecoder::seek (ContentTime time, bool accurate)
{
video->seek (time, accurate);
- _video_position = time.frames_round (_image_content->active_video_frame_rate ());
+ _frame_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 9b8cf73bb..d023636bf 100644
--- a/src/lib/image_decoder.h
+++ b/src/lib/image_decoder.h
@@ -39,5 +39,5 @@ private:
boost::shared_ptr<const ImageContent> _image_content;
boost::shared_ptr<ImageProxy> _image;
- Frame _video_position;
+ Frame _frame_video_position;
};
diff --git a/src/lib/subtitle_decoder.cc b/src/lib/subtitle_decoder.cc
index 4be5c96b3..020a0383c 100644
--- a/src/lib/subtitle_decoder.cc
+++ b/src/lib/subtitle_decoder.cc
@@ -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 (*missing, true);
+ _parent->maybe_seek_subtitle (*missing, true);
}
/* Now enough pass() calls will either:
diff --git a/src/lib/text_subtitle_decoder.cc b/src/lib/text_subtitle_decoder.cc
index e29bf5809..5f5545108 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]);
- _position = p.from;
+ _subtitle_position = p.from;
++_next;
return false;
diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc
index f240640d0..e3755e44f 100644
--- a/src/lib/video_decoder.cc
+++ b/src/lib/video_decoder.cc
@@ -99,7 +99,7 @@ VideoDecoder::get (Frame frame, bool accurate)
*/
seek_frame *= 2;
}
- _parent->maybe_seek (ContentTime::from_frames (seek_frame, _content->active_video_frame_rate()), accurate);
+ _parent->maybe_seek_video (ContentTime::from_frames (seek_frame, _content->active_video_frame_rate()), accurate);
}
/* Work out the number of frames that we should return; we
diff --git a/src/lib/video_mxf_decoder.cc b/src/lib/video_mxf_decoder.cc
index 84aec869a..321728f58 100644
--- a/src/lib/video_mxf_decoder.cc
+++ b/src/lib/video_mxf_decoder.cc
@@ -89,7 +89,7 @@ VideoMXFDecoder::pass (PassReason, bool)
);
}
- _position = _next;
+ _video_position = _next;
_next += ContentTime::from_frames (1, vfr);
return false;
}