summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--hacks/check_packets.py35
-rw-r--r--src/lib/decoder.h1
-rw-r--r--src/lib/video_decoder.cc11
-rw-r--r--src/lib/video_decoder.h5
5 files changed, 52 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 427c36294..c2d05c5eb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2016-01-24 Carl Hetherington <cth@carlh.net>
+
+ * Fix encodes getting stuck in some cases (#783).
+
2016-01-23 Carl Hetherington <cth@carlh.net>
* Fix estimate of required disk space to take referencing
diff --git a/hacks/check_packets.py b/hacks/check_packets.py
new file mode 100644
index 000000000..916813a1f
--- /dev/null
+++ b/hacks/check_packets.py
@@ -0,0 +1,35 @@
+#!/usr/bin/python
+
+import subprocess
+import shlex
+import sys
+
+last_video_pts = None
+
+def handle(frame):
+ global last_video_pts
+ if frame['media_type'] == 'video':
+ if last_video_pts is not None and frame['pkt_pts_time'] <= last_video_pts:
+ print 'Out of order video frame %f is ahead of %f' % (frame['pkt_pts_time'], last_video_pts)
+ else:
+ print 'OK frame %f' % frame['pkt_pts_time']
+ last_video_pts = frame['pkt_pts_time']
+
+p = subprocess.Popen(shlex.split('ffprobe -show_frames %s' % sys.argv[1]), stdin=None, stdout=subprocess.PIPE)
+frame = dict()
+while True:
+ l = p.stdout.readline()
+ if l == '':
+ break
+
+ l = l.strip()
+
+ if l == '[/FRAME]':
+ handle(frame)
+ frame = dict()
+ elif l != '[FRAME]' and l != '[SIDE_DATA]' and l != '[/SIDE_DATA]':
+ s = l.split('=')
+ if s[0] == 'pkt_pts_time':
+ frame[s[0]] = float(s[1])
+ else:
+ frame[s[0]] = s[1]
diff --git a/src/lib/decoder.h b/src/lib/decoder.h
index 9867b79b0..10bb45310 100644
--- a/src/lib/decoder.h
+++ b/src/lib/decoder.h
@@ -57,6 +57,7 @@ protected:
PASS_REASON_SUBTITLE
};
+ /** @return true if this decoder has already returned all its data and will give no more */
virtual bool pass (PassReason, bool accurate) = 0;
};
diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc
index 5d08615a6..38b9e8ced 100644
--- a/src/lib/video_decoder.cc
+++ b/src/lib/video_decoder.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -70,6 +70,10 @@ VideoDecoder::decoded_video (Frame frame)
list<ContentVideo>
VideoDecoder::get_video (Frame frame, bool accurate)
{
+ if (_no_data_frame && frame >= _no_data_frame.get()) {
+ return list<ContentVideo> ();
+ }
+
/* At this stage, if we have get_video()ed before, _decoded_video will contain the last frame that this
method returned (and possibly a few more). If the requested frame is not in _decoded_video and it is not the next
one after the end of _decoded_video we need to seek.
@@ -100,6 +104,7 @@ VideoDecoder::get_video (Frame frame, bool accurate)
if (pass (PASS_REASON_VIDEO, accurate)) {
/* The decoder has nothing more for us */
+ _no_data_frame = frame;
break;
}
@@ -121,9 +126,9 @@ VideoDecoder::get_video (Frame frame, bool accurate)
}
}
- /* Clean up _decoded_video; keep the frame we are returning (which may have two images
+ /* Clean up _decoded_video; keep the frame we are returning, if any (which may have two images
for 3D), but nothing before that */
- while (!_decoded_video.empty() && _decoded_video.front().frame < dec.front().frame) {
+ while (!_decoded_video.empty() && !dec.empty() && _decoded_video.front().frame < dec.front().frame) {
_decoded_video.pop_front ();
}
diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h
index 42cfc4906..af24b93bc 100644
--- a/src/lib/video_decoder.h
+++ b/src/lib/video_decoder.h
@@ -70,9 +70,12 @@ protected:
boost::shared_ptr<Image> _black_image;
boost::optional<ContentTime> _last_seek_time;
bool _last_seek_accurate;
-
/** true if this decoder should ignore all video; i.e. never produce any */
bool _ignore_video;
+ /** if set, this is a frame for which we got no data because the Decoder said
+ * it has no more to give.
+ */
+ boost::optional<Frame> _no_data_frame;
};
#endif