+ // Pass the frame on to x264 (or uncompressed to HTTP) as needed.
+ // Note that this implicitly waits for the frame to be done rendering.
+ pass_frame(frame, display_frame_num, frame.pts, frame.duration);
+ reorder_buffer[display_frame_num] = move(frame);
+
+ // Now encode as many QuickSync frames as we can using the frames we have available.
+ // (It could be zero, or it could be multiple.) FIXME: make a function.
+ for ( ;; ) {
+ int pts_lag;
+ int frame_type, quicksync_display_frame_num;
+ encoding2display_order(quicksync_encoding_frame_num, intra_period, intra_idr_period, ip_period,
+ &quicksync_display_frame_num, &frame_type, &pts_lag);
+ if (!reorder_buffer.count(quicksync_display_frame_num)) {
+ break;
+ }
+ frame = move(reorder_buffer[quicksync_display_frame_num]);
+ reorder_buffer.erase(quicksync_display_frame_num);
+
+ if (frame_type == FRAME_IDR) {
+ // Release any reference frames from the previous GOP.
+ for (const ReferenceFrame &frame : reference_frames) {
+ release_gl_surface(frame.display_number);
+ }
+ reference_frames.clear();
+ current_ref_frame_num = 0;
+ gop_start_display_frame_num = quicksync_display_frame_num;
+ }
+
+ // Determine the dts of this frame.
+ int64_t dts;
+ if (pts_lag == -1) {
+ assert(last_dts != -1);
+ dts = last_dts + (TIMEBASE / MAX_FPS);
+ } else {
+ dts = frame.pts - pts_lag;
+ }
+ last_dts = dts;