diff options
| author | Carl Hetherington <cth@carlh.net> | 2016-06-22 01:15:45 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2016-06-22 01:15:45 +0100 |
| commit | c5fe4e83db7a6fa7263e0d67804fd5a5569bf00a (patch) | |
| tree | 5fb69429e2524c7dbae3e97f462c2f9d8fc10d07 /src/lib/video_decoder.cc | |
| parent | a8a0dfd1b21de6c0facf965ab119833ff6f790bf (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.cc | 48 |
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 (); } } |
