}
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
}
}
- _position = _next;
+ _video_position = _audio_position = _subtitle_position = _next;
_next += ContentTime::from_frames (1, vfr);
if ((*_reel)->main_picture ()) {
}
subtitle->give_text (p, s);
- _position = p.from;
+ _subtitle_position = p.from;
return false;
}
*/
#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);
+}
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;
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
* 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
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) {
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");
}
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;
}
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);
}
}
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;
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));
}
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()) {
}
}
- _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;
}
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 ());
}
boost::shared_ptr<const ImageContent> _image_content;
boost::shared_ptr<ImageProxy> _image;
- Frame _video_position;
+ Frame _frame_video_position;
};
/* 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:
ContentTimePeriod const p = content_time_period (_subtitles[_next]);
subtitle->give_text (p, _subtitles[_next]);
- _position = p.from;
+ _subtitle_position = p.from;
++_next;
return false;
*/
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
);
}
- _position = _next;
+ _video_position = _next;
_next += ContentTime::from_frames (1, vfr);
return false;
}