+
+void H264Encoder::encode_frame(H264Encoder::PendingFrame frame, int64_t pts, int64_t dts)
+{
+ // Wait for the GPU to be done with the frame.
+ glClientWaitSync(frame.fence.get(), 0, 0);
+
+ // Release back any input frames we needed to render this frame.
+ frame.input_frames.clear();
+
+ // Unmap the image.
+ GLSurface *surf = &gl_surfaces[current_frame_display % SURFACE_NUM];
+ eglDestroyImageKHR(eglGetCurrentDisplay(), surf->y_egl_image);
+ eglDestroyImageKHR(eglGetCurrentDisplay(), surf->cbcr_egl_image);
+ VAStatus va_status = vaReleaseBufferHandle(va_dpy, surf->surface_image.buf);
+ CHECK_VASTATUS(va_status, "vaReleaseBufferHandle");
+ va_status = vaDestroyImage(va_dpy, surf->surface_image.image_id);
+ CHECK_VASTATUS(va_status, "vaDestroyImage");
+
+ VASurfaceID surface = surf->src_surface;
+
+ // Schedule the frame for encoding.
+ va_status = vaBeginPicture(va_dpy, context_id, surface);
+ CHECK_VASTATUS(va_status, "vaBeginPicture");
+
+ if (current_frame_type == FRAME_IDR) {
+ render_sequence();
+ render_picture();
+ if (h264_packedheader) {
+ render_packedsequence();
+ render_packedpicture();
+ }
+ } else {
+ //render_sequence();
+ render_picture();
+ }
+ render_slice();
+
+ va_status = vaEndPicture(va_dpy, context_id);
+ CHECK_VASTATUS(va_status, "vaEndPicture");
+
+ // so now the data is done encoding (well, async job kicked off)...
+ // we send that to the storage thread
+ storage_task tmp;
+ tmp.display_order = current_frame_display;
+ tmp.frame_type = current_frame_type;
+ tmp.pts = pts;
+ tmp.dts = dts;
+ storage_task_enqueue(move(tmp));
+
+ update_ReferenceFrames();
+}