summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-12-21 18:44:52 +0000
committerCarl Hetherington <cth@carlh.net>2013-12-21 18:44:52 +0000
commit7d67f4a38bf7de1b901facf5390a730d307de671 (patch)
tree57fcb21affed7b7f4f153da9ec000271a106190a /src/lib
parenta5b59faff75265d3256ad0dbd9f0c69e51e31ce4 (diff)
Add some more tests; improve seeking.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/ffmpeg_decoder.cc27
-rw-r--r--src/lib/ffmpeg_decoder.h4
-rw-r--r--src/lib/player.cc24
3 files changed, 25 insertions, 30 deletions
diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc
index 1cf9bd92d..80c3d9906 100644
--- a/src/lib/ffmpeg_decoder.cc
+++ b/src/lib/ffmpeg_decoder.cc
@@ -296,11 +296,11 @@ FFmpegDecoder::bytes_per_audio_sample () const
}
int
-FFmpegDecoder::minimal_run (boost::function<bool (ContentTime, ContentTime, int)> finished)
+FFmpegDecoder::minimal_run (boost::function<bool (optional<ContentTime>, optional<ContentTime>, int)> finished)
{
int frames_read = 0;
- ContentTime last_video = 0;
- ContentTime last_audio = 0;
+ optional<ContentTime> last_video;
+ optional<ContentTime> last_audio;
while (!finished (last_video, last_audio, frames_read)) {
int r = av_read_frame (_format_context, &_packet);
@@ -353,9 +353,9 @@ FFmpegDecoder::minimal_run (boost::function<bool (ContentTime, ContentTime, int)
}
bool
-FFmpegDecoder::seek_overrun_finished (ContentTime seek, ContentTime last_video, ContentTime last_audio) const
+FFmpegDecoder::seek_overrun_finished (ContentTime seek, optional<ContentTime> last_video, optional<ContentTime> last_audio) const
{
- return last_video >= seek || last_audio >= seek;
+ return (last_video && last_video.get() >= seek) || (last_audio && last_audio.get() >= seek);
}
bool
@@ -369,16 +369,11 @@ FFmpegDecoder::seek_and_flush (ContentTime t)
{
int64_t const initial_v = ((double (t) / TIME_HZ) - _video_pts_offset) /
av_q2d (_format_context->streams[_video_stream]->time_base);
+
+ int64_t const initial_a = ((double (t) / TIME_HZ) - _audio_pts_offset) /
+ av_q2d (_ffmpeg_content->audio_stream()->stream(_format_context)->time_base);
- av_seek_frame (_format_context, _video_stream, initial_v, AVSEEK_FLAG_BACKWARD);
-
- shared_ptr<FFmpegAudioStream> as = _ffmpeg_content->audio_stream ();
- if (as) {
- int64_t initial_a = ((double (t) / TIME_HZ) - _audio_pts_offset) /
- av_q2d (as->stream(_format_context)->time_base);
-
- av_seek_frame (_format_context, as->index (_format_context), initial_a, AVSEEK_FLAG_BACKWARD);
- }
+ av_seek_frame (_format_context, _video_stream, min (initial_v, initial_a), AVSEEK_FLAG_BACKWARD);
avcodec_flush_buffers (video_codec_context());
if (audio_codec_context ()) {
@@ -409,8 +404,8 @@ FFmpegDecoder::seek (ContentTime time, bool accurate)
seek_and_flush (initial_seek);
- if (time == 0 || !accurate) {
- /* We're already there, or we're as close as we need to be */
+ if (!accurate) {
+ /* That'll do */
return;
}
diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h
index e50b248cf..55b624bd6 100644
--- a/src/lib/ffmpeg_decoder.h
+++ b/src/lib/ffmpeg_decoder.h
@@ -71,9 +71,9 @@ private:
void maybe_add_subtitle ();
boost::shared_ptr<AudioBuffers> deinterleave_audio (uint8_t** data, int size);
- bool seek_overrun_finished (ContentTime, ContentTime, ContentTime) const;
+ bool seek_overrun_finished (ContentTime, boost::optional<ContentTime>, boost::optional<ContentTime>) const;
bool seek_final_finished (int, int) const;
- int minimal_run (boost::function<bool (ContentTime, ContentTime, int)>);
+ int minimal_run (boost::function<bool (boost::optional<ContentTime>, boost::optional<ContentTime>, int)>);
void seek_and_flush (int64_t);
AVCodecContext* _subtitle_codec_context; ///< may be 0 if there is no subtitle
diff --git a/src/lib/player.cc b/src/lib/player.cc
index daefd6db0..17b44cdb8 100644
--- a/src/lib/player.cc
+++ b/src/lib/player.cc
@@ -142,7 +142,8 @@ Player::pass ()
shared_ptr<DecodedSubtitle> ds = dynamic_pointer_cast<DecodedSubtitle> (earliest_decoded);
if (dv && _video) {
- if (!_just_did_inaccurate_seek && earliest_time > _video_position) {
+ DCPTime const frame = TIME_HZ / _film->video_frame_rate ();
+ if (!_just_did_inaccurate_seek && earliest_time > (_video_position + frame)) {
/* See if we're inside some video content */
list<shared_ptr<Piece> >::iterator i = _pieces.begin();
@@ -157,10 +158,19 @@ Player::pass ()
_last_incoming_video.video->dcp_time = _video_position;
emit_video (_last_incoming_video.weak_piece, _last_incoming_video.video);
}
+
} else {
- emit_video (earliest_piece, dv);
+ if (
+ dv->dcp_time >= _video_position &&
+ !earliest_piece->content->trimmed (dv->dcp_time - earliest_piece->content->position ())
+ ) {
+
+ emit_video (earliest_piece, dv);
+ }
+
earliest_piece->decoder->get ();
}
+
} else if (da && _audio) {
if (!_just_did_inaccurate_seek && earliest_time > _audio_position) {
emit_silence (earliest_time - _audio_position);
@@ -196,16 +206,6 @@ Player::emit_video (weak_ptr<Piece> weak_piece, shared_ptr<DecodedVideo> video)
assert (content);
FrameRateChange frc (content->video_frame_rate(), _film->video_frame_rate());
-#if 0
- XXX
- if (frc.skip && (frame % 2) == 1) {
- return;
- }
-#endif
-
- if (content->trimmed (video->dcp_time - content->position ())) {
- return;
- }
float const ratio = content->ratio() ? content->ratio()->ratio() : content->video_size_after_crop().ratio();
libdcp::Size image_size = fit_ratio_within (ratio, _video_container_size);