+
+ BMDTimeValue stream_frame_time, played_at_time;
+ BMDTimeValue hardwareTime, timeInFrame, ticksPerFrame;
+ double playback_speed;
+ output->GetFrameCompletionReferenceTimestamp(frame, TIMEBASE, &played_at_time);
+ output->GetScheduledStreamTime(TIMEBASE, &stream_frame_time, &playback_speed);
+ output->GetHardwareReferenceClock(TIMEBASE, &hardwareTime, &timeInFrame, &ticksPerFrame);
+
+ steady_clock::time_point now = steady_clock::now();
+ int frame_delay = (stream_frame_time - frame->pts) / frame_duration - 1;
+ map<int, string> status = {
+ { bmdOutputFrameCompleted, "played" },
+ { bmdOutputFrameDisplayedLate, "DELAYED" },
+ { bmdOutputFrameDropped, "DROPPED" },
+ { bmdOutputFrameFlushed, "FLUSHED" }
+ };
+
+ if ((result == bmdOutputFrameCompleted || result == bmdOutputFrameDisplayedLate) && false) {
+ fprintf(stderr, "now=%ld / %.2f: frame with pts=%ld (%ld ago, %d delay) / %.2f was %s at time %ld (%ld ago)\n",
+ stream_frame_time, PTSToTime(stream_frame_time),
+ frame->pts, stream_frame_time - frame->pts, frame_delay, PTSToTime(frame->pts),
+ status[result].c_str(),
+ played_at_time, hardwareTime - played_at_time);
+ } else if (result == bmdOutputFrameDisplayedLate) {
+ fprintf(stderr, "now=%ld / %.2f: frame with pts=%ld (%ld ago, %d delay) / %.2f was %s to %.2f\n",
+ stream_frame_time, PTSToTime(stream_frame_time),
+ frame->pts, stream_frame_time - frame->pts, frame_delay, PTSToTime(frame->pts),
+ status[result].c_str(), PTSToTime(frame->pts) + frame_delay);
+ } else {
+ fprintf(stderr, "now=%ld / %.2f: frame with pts=%ld (%ld ago, %d delay) / %.2f was %s\n",
+ stream_frame_time, PTSToTime(stream_frame_time),
+ frame->pts, stream_frame_time - frame->pts, frame_delay, PTSToTime(frame->pts),
+ status[result].c_str());
+ }
+ if (frame_delay < 0) {
+ fprintf(stderr, "ERROR: Frame went backwards in time (scheduled to start at pts=%ld, ended at or before pts=%ld), something is strange.\n",
+ frame->pts, stream_frame_time);
+ frame_delay = 0;
+ }
+