- /* 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 ();
+ Frame frame;
+ Eyes eyes = EYES_BOTH;
+ if (!_position) {
+ /* This is the first data we have received since initialisation or seek. Set
+ the position based on the frame that was given. After this first time
+ we just cound frames, since (as with audio) it seems that ContentTimes
+ are unreliable from FFmpegDecoder. They are much better than audio times
+ but still we get the occasional one which is duplicated. In this case
+ ffmpeg seems to carry on regardless, processing the video frame as normal.
+ If we drop the frame with the duplicated timestamp we obviously lose sync.
+ */
+ _position = ContentTime::from_frames (decoder_frame, afr);
+ if (vft == VIDEO_FRAME_TYPE_3D_ALTERNATE) {
+ frame = decoder_frame / 2;
+ _last_emitted_eyes = EYES_RIGHT;
+ } else {
+ frame = decoder_frame;
+ }
+ } else {
+ if (vft == VIDEO_FRAME_TYPE_3D || vft == VIDEO_FRAME_TYPE_3D_ALTERNATE) {
+ DCPOMATIC_ASSERT (_last_emitted_eyes);
+ if (_last_emitted_eyes.get() == EYES_RIGHT) {
+ frame = _position->frames_round(afr) + 1;
+ eyes = EYES_LEFT;
+ } else {
+ frame = _position->frames_round(afr);
+ eyes = EYES_RIGHT;
+ }
+ } else {
+ frame = _position->frames_round(afr) + 1;
+ }