summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-07-09 22:56:47 +0100
committerCarl Hetherington <cth@carlh.net>2013-07-09 22:56:47 +0100
commitc37d4e41da190144806463387fdbe64e65196730 (patch)
treeab96f3928470913f202477b645cb80b8e37ddf41 /src
parentdf52b97f307605aad15ab5f01c8fdcf93afc9d15 (diff)
Hopefully fix seek back/forward.
Diffstat (limited to 'src')
-rw-r--r--src/lib/ffmpeg_decoder.cc35
-rw-r--r--src/lib/ffmpeg_decoder.h4
-rw-r--r--src/lib/imagemagick_decoder.cc10
-rw-r--r--src/lib/imagemagick_decoder.h3
-rw-r--r--src/lib/player.cc11
-rw-r--r--src/lib/player.h3
-rw-r--r--src/lib/video_decoder.h3
-rw-r--r--src/wx/film_viewer.cc9
8 files changed, 23 insertions, 55 deletions
diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc
index 3b7d727b8..bcd1e738a 100644
--- a/src/lib/ffmpeg_decoder.cc
+++ b/src/lib/ffmpeg_decoder.cc
@@ -281,26 +281,11 @@ FFmpegDecoder::bytes_per_audio_sample () const
}
void
-FFmpegDecoder::seek (VideoContent::Frame frame)
+FFmpegDecoder::seek (VideoContent::Frame frame, bool accurate)
{
- do_seek (frame, false, false);
-}
-
-void
-FFmpegDecoder::seek_back ()
-{
- if (_video_position == 0) {
- return;
- }
-
- do_seek (_video_position - 1, true, true);
-}
-
-void
-FFmpegDecoder::do_seek (VideoContent::Frame frame, bool backwards, bool accurate)
-{
- int64_t const vt = frame / (_ffmpeg_content->video_frame_rate() * av_q2d (_format_context->streams[_video_stream]->time_base));
- av_seek_frame (_format_context, _video_stream, vt, backwards ? AVSEEK_FLAG_BACKWARD : 0);
+ double const time_base = av_q2d (_format_context->streams[_video_stream]->time_base);
+ int64_t const vt = frame / (_ffmpeg_content->video_frame_rate() * time_base);
+ av_seek_frame (_format_context, _video_stream, vt, AVSEEK_FLAG_BACKWARD);
avcodec_flush_buffers (video_codec_context());
if (_subtitle_codec_context) {
@@ -323,9 +308,11 @@ FFmpegDecoder::do_seek (VideoContent::Frame frame, bool backwards, bool accurate
int const r = avcodec_decode_video2 (video_codec_context(), _frame, &finished, &_packet);
if (r >= 0 && finished) {
int64_t const bet = av_frame_get_best_effort_timestamp (_frame);
- if (bet > vt) {
- _video_position = (bet * av_q2d (_format_context->streams[_video_stream]->time_base) + _pts_offset)
- * _ffmpeg_content->video_frame_rate();
+ if (bet >= vt) {
+ _video_position = rint (
+ (bet * time_base + _pts_offset) * _ffmpeg_content->video_frame_rate()
+ );
+ av_free_packet (&_packet);
break;
}
}
@@ -427,10 +414,10 @@ FFmpegDecoder::decode_video_packet ()
/* We just did a seek, so disable any attempts to correct for where we
are / should be.
*/
- _video_position = pts * _ffmpeg_content->video_frame_rate ();
+ _video_position = rint (pts * _ffmpeg_content->video_frame_rate ());
_just_sought = false;
}
-
+
double const next = _video_position / _ffmpeg_content->video_frame_rate();
double const one_frame = 1 / _ffmpeg_content->video_frame_rate ();
double delta = pts - next;
diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h
index 2e64d8801..eebf75445 100644
--- a/src/lib/ffmpeg_decoder.h
+++ b/src/lib/ffmpeg_decoder.h
@@ -50,8 +50,7 @@ public:
~FFmpegDecoder ();
void pass ();
- void seek (VideoContent::Frame);
- void seek_back ();
+ void seek (VideoContent::Frame, bool);
bool done () const;
private:
@@ -67,7 +66,6 @@ private:
AVSampleFormat audio_sample_format () const;
int bytes_per_audio_sample () const;
- void do_seek (VideoContent::Frame, bool, bool);
bool decode_video_packet ();
void decode_audio_packet ();
diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc
index 04d3d9df7..6178443cf 100644
--- a/src/lib/imagemagick_decoder.cc
+++ b/src/lib/imagemagick_decoder.cc
@@ -75,19 +75,11 @@ ImageMagickDecoder::pass ()
}
void
-ImageMagickDecoder::seek (VideoContent::Frame frame)
+ImageMagickDecoder::seek (VideoContent::Frame frame, bool)
{
_video_position = frame;
}
-void
-ImageMagickDecoder::seek_back ()
-{
- if (_video_position > 0) {
- _video_position--;
- }
-}
-
bool
ImageMagickDecoder::done () const
{
diff --git a/src/lib/imagemagick_decoder.h b/src/lib/imagemagick_decoder.h
index 286f47337..3e551c3b7 100644
--- a/src/lib/imagemagick_decoder.h
+++ b/src/lib/imagemagick_decoder.h
@@ -34,8 +34,7 @@ public:
/* Decoder */
void pass ();
- void seek (VideoContent::Frame);
- void seek_back ();
+ void seek (VideoContent::Frame, bool);
bool done () const;
private:
diff --git a/src/lib/player.cc b/src/lib/player.cc
index 7488364bd..4de691c0b 100644
--- a/src/lib/player.cc
+++ b/src/lib/player.cc
@@ -337,7 +337,7 @@ Player::flush ()
/** @return true on error */
void
-Player::seek (Time t)
+Player::seek (Time t, bool accurate)
{
if (!_have_valid_pieces) {
setup_pieces ();
@@ -360,19 +360,12 @@ Player::seek (Time t)
FrameRateConversion frc (vc->video_frame_rate(), _film->dcp_video_frame_rate());
VideoContent::Frame f = s * _film->dcp_video_frame_rate() / (frc.factor() * TIME_HZ);
- dynamic_pointer_cast<VideoDecoder>((*i)->decoder)->seek (f);
+ dynamic_pointer_cast<VideoDecoder>((*i)->decoder)->seek (f, accurate);
}
/* XXX: don't seek audio because we don't need to... */
}
-
-void
-Player::seek_back ()
-{
-
-}
-
void
Player::setup_pieces ()
{
diff --git a/src/lib/player.h b/src/lib/player.h
index 3f8d59d29..15fa4dbd6 100644
--- a/src/lib/player.h
+++ b/src/lib/player.h
@@ -49,8 +49,7 @@ public:
void disable_audio ();
bool pass ();
- void seek (Time);
- void seek_back ();
+ void seek (Time, bool);
Time video_position () const {
return _video_position;
diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h
index d24219d95..0b3350472 100644
--- a/src/lib/video_decoder.h
+++ b/src/lib/video_decoder.h
@@ -30,8 +30,7 @@ class VideoDecoder : public virtual Decoder
public:
VideoDecoder (boost::shared_ptr<const Film>);
- virtual void seek (VideoContent::Frame) = 0;
- virtual void seek_back () = 0;
+ virtual void seek (VideoContent::Frame, bool) = 0;
/** Emitted when a video frame is ready.
* First parameter is the video image.
diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc
index 6469d0962..6d7181b5f 100644
--- a/src/wx/film_viewer.cc
+++ b/src/wx/film_viewer.cc
@@ -141,8 +141,7 @@ FilmViewer::fetch_current_frame_again ()
return;
}
- /* This will cause a Player::Changed to be emitted */
- _player->seek (_player->video_position() - _film->video_frames_to_time (1));
+ _player->seek (_player->video_position() - _film->video_frames_to_time (1), false);
fetch_next_frame ();
}
@@ -202,7 +201,7 @@ void
FilmViewer::slider_moved (wxScrollEvent &)
{
if (_film && _player) {
- _player->seek (_slider->GetValue() * _film->length() / 4096);
+ _player->seek (_slider->GetValue() * _film->length() / 4096, false);
fetch_next_frame ();
}
}
@@ -336,8 +335,10 @@ FilmViewer::back_clicked (wxCommandEvent &)
if (!_player) {
return;
}
+
+ Time const t = _film->video_frames_to_time (1);
- _player->seek_back ();
+ _player->seek (_player->video_position() - t * 2.5, true);
fetch_next_frame ();
}