}
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;
- bool flushing = false;
+ optional<ContentTime> last_video;
+ optional<ContentTime> last_audio;
while (!finished (last_video, last_audio, frames_read)) {
int r = av_read_frame (_format_context, &_packet);
}
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
void
FFmpegDecoder::seek_and_flush (ContentTime t)
{
- int64_t const initial_v = ((double (t) / TIME_HZ) - _video_pts_offset) /
+ int64_t s = ((double (t) / TIME_HZ) - _video_pts_offset) /
av_q2d (_format_context->streams[_video_stream]->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);
+
+ if (_ffmpeg_content->audio_stream ()) {
+ s = min (
+ s, int64_t (
+ ((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, s, AVSEEK_FLAG_BACKWARD);
+
avcodec_flush_buffers (video_codec_context());
if (audio_codec_context ()) {
avcodec_flush_buffers (audio_codec_context ());
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;
}
double const packet_time = static_cast<double> (sub.pts) / AV_TIME_BASE;
/* hence start time for this sub */
- DCPTime const from = (packet_time + (double (sub.start_display_time) / 1e3)) * TIME_HZ;
- DCPTime const to = (packet_time + (double (sub.end_display_time) / 1e3)) * TIME_HZ;
+ ContentTime const from = (packet_time + (double (sub.start_display_time) / 1e3)) * TIME_HZ;
+ ContentTime const to = (packet_time + (double (sub.end_display_time) / 1e3)) * TIME_HZ;
AVSubtitleRect const * rect = sub.rects[0];