summaryrefslogtreecommitdiff
path: root/src/lib/video_decoder.cc
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2016-06-22 01:15:45 +0100
committerCarl Hetherington <cth@carlh.net>2016-06-22 01:15:45 +0100
commitc5fe4e83db7a6fa7263e0d67804fd5a5569bf00a (patch)
tree5fb69429e2524c7dbae3e97f462c2f9d8fc10d07 /src/lib/video_decoder.cc
parenta8a0dfd1b21de6c0facf965ab119833ff6f790bf (diff)
Optimization for the referenced video case.
With referenced video from a DCP decoder, no video will ever be fetched from the decoder. Hence the code to discard given video will be activated after _decoded builds up to the magic size. Before this commit the code would attempt to fill with black up to given frame N (with N very large) from the last frame in _decoded when _decoded had been trimmed. This would result in exponential growth in execution time for the VideoDecoder::give() path.
Diffstat (limited to 'src/lib/video_decoder.cc')
-rw-r--r--src/lib/video_decoder.cc48
1 files changed, 27 insertions, 21 deletions
diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc
index edc746010..f856d93aa 100644
--- a/src/lib/video_decoder.cc
+++ b/src/lib/video_decoder.cc
@@ -294,39 +294,45 @@ VideoDecoder::give (shared_ptr<const ImageProxy> image, Frame frame)
/* If we've pre-rolled on a seek we may now receive out-of-order frames
(frames before the last seek time) which we can just ignore.
*/
-
if (from && (*from) > to_push.front().frame) {
return;
}
- if (from) {
- switch (_content->video->frame_type ()) {
- case VIDEO_FRAME_TYPE_2D:
- fill_one_eye (from->index(), to_push.front().frame.index(), EYES_BOTH);
- break;
- case VIDEO_FRAME_TYPE_3D:
- case VIDEO_FRAME_TYPE_3D_LEFT_RIGHT:
- case VIDEO_FRAME_TYPE_3D_TOP_BOTTOM:
- case VIDEO_FRAME_TYPE_3D_ALTERNATE:
- fill_both_eyes (from.get(), to_push.front().frame);
- break;
- case VIDEO_FRAME_TYPE_3D_LEFT:
- fill_one_eye (from->index(), to_push.front().frame.index(), EYES_LEFT);
- break;
- case VIDEO_FRAME_TYPE_3D_RIGHT:
- fill_one_eye (from->index(), to_push.front().frame.index(), EYES_RIGHT);
- break;
+ int const max_decoded_size = 96;
+
+ /* If _decoded is already `full' there is no point in adding anything more to it,
+ as the new stuff will just be removed again.
+ */
+ if (_decoded.size() < max_decoded_size) {
+ if (from) {
+ switch (_content->video->frame_type ()) {
+ case VIDEO_FRAME_TYPE_2D:
+ fill_one_eye (from->index(), to_push.front().frame.index(), EYES_BOTH);
+ break;
+ case VIDEO_FRAME_TYPE_3D:
+ case VIDEO_FRAME_TYPE_3D_LEFT_RIGHT:
+ case VIDEO_FRAME_TYPE_3D_TOP_BOTTOM:
+ case VIDEO_FRAME_TYPE_3D_ALTERNATE:
+ fill_both_eyes (from.get(), to_push.front().frame);
+ break;
+ case VIDEO_FRAME_TYPE_3D_LEFT:
+ fill_one_eye (from->index(), to_push.front().frame.index(), EYES_LEFT);
+ break;
+ case VIDEO_FRAME_TYPE_3D_RIGHT:
+ fill_one_eye (from->index(), to_push.front().frame.index(), EYES_RIGHT);
+ break;
+ }
}
- }
- copy (to_push.begin(), to_push.end(), back_inserter (_decoded));
+ copy (to_push.begin(), to_push.end(), back_inserter (_decoded));
+ }
/* We can't let this build up too much or we will run out of memory. There is a
`best' value for the allowed size of _decoded which balances memory use
with decoding efficiency (lack of seeks). Throwing away video frames here
is not a problem for correctness, so do it.
*/
- while (_decoded.size() > 96) {
+ while (_decoded.size() > max_decoded_size) {
_decoded.pop_back ();
}
}