X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fvideo_decoder.cc;h=5dd078553659b21d3c09bcf8a030ea77e73ad783;hb=1f82930e73679d6aec5223caa255f564339a1a2a;hp=43b1049ccaf5f89920147f040cf5e96635f66675;hpb=39bc73fe192f932ed6695eb87b19de446e8b4f55;p=dcpomatic.git diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index 43b1049cc..5dd078553 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -35,6 +35,7 @@ VideoDecoder::VideoDecoder (shared_ptr c) #else : _video_content (c) #endif + , _same (false) { } @@ -61,8 +62,12 @@ VideoDecoder::decoded_video (VideoFrame frame) list VideoDecoder::get_video (VideoFrame frame, bool accurate) { - if (_decoded_video.empty() || (frame < _decoded_video.front().frame || frame > (_decoded_video.back().frame + 1))) { - /* Either we have no decoded data, or what we do have is a long way from what we want: seek */ + /* 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. + */ + + if (_decoded_video.empty() || frame < _decoded_video.front().frame || frame > (_decoded_video.back().frame + 1)) { seek (ContentTime::from_frames (frame, _video_content->video_frame_rate()), accurate); } @@ -70,7 +75,8 @@ VideoDecoder::get_video (VideoFrame frame, bool accurate) /* Now enough pass() calls should either: * (a) give us what we want, or - * (b) hit the end of the decoder. + * (b) give us something after what we want, indicating that we will never get what we want, or + * (c) hit the end of the decoder. */ if (accurate) { /* We are being accurate, so we want the right frame. @@ -105,8 +111,8 @@ VideoDecoder::get_video (VideoFrame frame, bool accurate) } } - /* Clean up decoded_video */ - while (!_decoded_video.empty() && _decoded_video.front().frame < (frame - 1)) { + /* Clean up _decoded_video; keep the frame we are returning, but nothing before that */ + while (!_decoded_video.empty() && _decoded_video.front().frame < dec.front().frame) { _decoded_video.pop_front (); } @@ -118,8 +124,10 @@ VideoDecoder::get_video (VideoFrame frame, bool accurate) void VideoDecoder::video (shared_ptr image, VideoFrame frame) { - /* We should not receive the same thing twice */ - assert (_decoded_video.empty() || frame != _decoded_video.back().frame); + /* We may receive the same frame index twice for 3D, and we need to know + when that happens. + */ + _same = (!_decoded_video.empty() && frame == _decoded_video.back().frame); /* Fill in gaps */ /* XXX: 3D */ @@ -143,7 +151,7 @@ VideoDecoder::video (shared_ptr image, VideoFrame frame) _decoded_video.push_back (ContentVideo (image, EYES_BOTH, PART_WHOLE, frame)); break; case VIDEO_FRAME_TYPE_3D_ALTERNATE: - _decoded_video.push_back (ContentVideo (image, (frame % 2) ? EYES_RIGHT : EYES_LEFT, PART_WHOLE, frame)); + _decoded_video.push_back (ContentVideo (image, _same ? EYES_RIGHT : EYES_LEFT, PART_WHOLE, frame)); break; case VIDEO_FRAME_TYPE_3D_LEFT_RIGHT: _decoded_video.push_back (ContentVideo (image, EYES_LEFT, PART_LEFT_HALF, frame));