+
+void H264EncoderImpl::encode_frame(H264EncoderImpl::PendingFrame frame, int encoding_frame_num, int display_frame_num, int gop_start_display_frame_num,
+ int frame_type, 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[display_frame_num % 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 (frame_type == FRAME_IDR) {
+ render_sequence();
+ render_picture(frame_type, display_frame_num, gop_start_display_frame_num);
+ if (h264_packedheader) {
+ render_packedsequence();
+ render_packedpicture();
+ }
+ } else {
+ //render_sequence();
+ render_picture(frame_type, display_frame_num, gop_start_display_frame_num);
+ }
+ render_slice(encoding_frame_num, display_frame_num, gop_start_display_frame_num, frame_type);
+
+ 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 = display_frame_num;
+ tmp.frame_type = frame_type;
+ tmp.pts = pts;
+ tmp.dts = dts;
+ storage_task_enqueue(move(tmp));
+
+ update_ReferenceFrames(frame_type);
+}
+
+// Proxy object.
+H264Encoder::H264Encoder(QSurface *surface, int width, int height, HTTPD *httpd)
+ : impl(new H264EncoderImpl(surface, width, height, httpd)) {}
+
+// Must be defined here because unique_ptr<> destructor needs to know the impl.
+H264Encoder::~H264Encoder() {}
+
+void H264Encoder::add_audio(int64_t pts, std::vector<float> audio)
+{
+ impl->add_audio(pts, audio);
+}
+
+bool H264Encoder::begin_frame(GLuint *y_tex, GLuint *cbcr_tex)
+{
+ return impl->begin_frame(y_tex, cbcr_tex);
+}
+
+void H264Encoder::end_frame(RefCountedGLsync fence, int64_t pts, const std::vector<RefCountedFrame> &input_frames)
+{
+ impl->end_frame(fence, pts, input_frames);
+}
+
+// Real class.