summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--capture.c10
-rw-r--r--encode.c12
-rw-r--r--gpu.c180
-rw-r--r--gpu.h24
-rw-r--r--main.c12
5 files changed, 123 insertions, 115 deletions
diff --git a/capture.c b/capture.c
index cca4ce3..72a641d 100644
--- a/capture.c
+++ b/capture.c
@@ -135,7 +135,8 @@ const struct GpuFrame* CaptureContextGetFrame(
return NULL;
if (capture_context->gpu_frame) {
- GpuFrameDestroy(capture_context->gpu_frame);
+ GpuContextDestroyFrame(capture_context->gpu_context,
+ capture_context->gpu_frame);
capture_context->gpu_frame = NULL;
}
@@ -155,7 +156,7 @@ const struct GpuFrame* CaptureContextGetFrame(
planes[nplanes].modifier = drm_mode_fb_cmd2.modifier[nplanes];
}
- capture_context->gpu_frame = GpuFrameCreate(
+ capture_context->gpu_frame = GpuContextCreateFrame(
capture_context->gpu_context, drm_mode_fb_cmd2.width,
drm_mode_fb_cmd2.height, drm_mode_fb_cmd2.pixel_format, nplanes, planes);
@@ -165,7 +166,10 @@ release_planes:
}
void CaptureContextDestroy(struct CaptureContext* capture_context) {
- if (capture_context->gpu_frame) GpuFrameDestroy(capture_context->gpu_frame);
+ if (capture_context->gpu_frame) {
+ GpuContextDestroyFrame(capture_context->gpu_context,
+ capture_context->gpu_frame);
+ }
drmClose(capture_context->drm_fd);
free(capture_context);
}
diff --git a/encode.c b/encode.c
index 09c03ad..5dc9cdd 100644
--- a/encode.c
+++ b/encode.c
@@ -166,8 +166,8 @@ static struct GpuFrame* PrimeToGpuFrame(
};
}
struct GpuFrame* gpu_frame =
- GpuFrameCreate(gpu_context, prime->width, prime->height, prime->fourcc,
- prime->layers[0].num_planes, planes);
+ GpuContextCreateFrame(gpu_context, prime->width, prime->height,
+ prime->fourcc, prime->layers[0].num_planes, planes);
for (size_t i = prime->num_objects; i; i--) close(prime->objects[i - 1].fd);
return gpu_frame;
}
@@ -248,7 +248,8 @@ static bool DrainPacket(const struct AVPacket* packet, int fd) {
bool EncodeContextEncodeFrame(struct EncodeContext* encode_context, int fd) {
bool result = false;
if (encode_context->gpu_frame) {
- GpuFrameDestroy(encode_context->gpu_frame);
+ GpuContextDestroyFrame(encode_context->gpu_context,
+ encode_context->gpu_frame);
encode_context->gpu_frame = NULL;
}
AVPacket* packet = av_packet_alloc();
@@ -293,7 +294,10 @@ rollback_hw_frame:
}
void EncodeContextDestroy(struct EncodeContext* encode_context) {
- if (encode_context->gpu_frame) GpuFrameDestroy(encode_context->gpu_frame);
+ if (encode_context->gpu_frame) {
+ GpuContextDestroyFrame(encode_context->gpu_context,
+ encode_context->gpu_frame);
+ }
if (encode_context->hw_frame) av_frame_free(&encode_context->hw_frame);
avcodec_free_context(&encode_context->codec_context);
av_buffer_unref(&encode_context->hwdevice_context);
diff --git a/gpu.c b/gpu.c
index 6aa07b0..9f09323 100644
--- a/gpu.c
+++ b/gpu.c
@@ -20,6 +20,7 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
#include <GLES3/gl32.h>
#include <drm_fourcc.h>
#include <errno.h>
@@ -28,9 +29,6 @@
#include <string.h>
#include <unistd.h>
-// mburakov: Must be included after GLES2/gl2.h
-#include <GLES2/gl2ext.h>
-
#ifndef USE_EGL_MESA_PLATFORM_SURFACELESS
#include <fcntl.h>
#include <gbm.h>
@@ -77,9 +75,8 @@ struct GpuContext {
GLuint vertices;
};
-struct GpuFrame {
- struct GpuContext* gpu_context;
- uint32_t width, height;
+struct GpuFrameImpl {
+ struct GpuFrame size;
int dmabuf_fds[4];
EGLImage images[2];
GLuint textures[2];
@@ -449,33 +446,6 @@ rollback_gpu_context:
return NULL;
}
-bool GpuContextSync(struct GpuContext* gpu_context) {
- EGLSync sync = eglCreateSync(gpu_context->display, EGL_SYNC_FENCE, NULL);
- if (sync == EGL_NO_SYNC) {
- LOG("Failed to create egl fence sync (%s)", EglErrorString(eglGetError()));
- return false;
- }
- eglClientWaitSync(gpu_context->display, sync, 0, EGL_FOREVER);
- eglDestroySync(gpu_context->display, sync);
- return true;
-}
-
-void GpuContextDestroy(struct GpuContext* gpu_context) {
- glDeleteBuffers(1, &gpu_context->vertices);
- glDeleteFramebuffers(1, &gpu_context->framebuffer);
- glDeleteProgram(gpu_context->program_chroma);
- glDeleteProgram(gpu_context->program_luma);
- eglMakeCurrent(gpu_context->display, EGL_NO_SURFACE, EGL_NO_SURFACE,
- EGL_NO_CONTEXT);
- eglDestroyContext(gpu_context->display, gpu_context->context);
- eglTerminate(gpu_context->display);
-#ifndef USE_EGL_MESA_PLATFORM_SURFACELESS
- gbm_device_destroy(gpu_context->device);
- close(gpu_context->render_node);
-#endif // USE_EGL_MESA_PLATFORM_SURFACELESS
- free(gpu_context);
-}
-
static void DumpEglImageParams(const EGLAttrib* attribs) {
for (; *attribs != EGL_NONE; attribs += 2) {
switch (attribs[0]) {
@@ -665,26 +635,25 @@ static GLuint CreateTexture(struct GpuContext* gpu_context, EGLImage image) {
return texture;
}
-struct GpuFrame* GpuFrameCreate(struct GpuContext* gpu_context, uint32_t width,
- uint32_t height, uint32_t fourcc,
- size_t nplanes,
- const struct GpuFramePlane* planes) {
- struct GpuFrame* gpu_frame = malloc(sizeof(struct GpuFrame));
- if (!gpu_frame) {
+struct GpuFrame* GpuContextCreateFrame(struct GpuContext* gpu_context,
+ uint32_t width, uint32_t height,
+ uint32_t fourcc, size_t nplanes,
+ const struct GpuFramePlane* planes) {
+ struct GpuFrameImpl* gpu_frame_impl = malloc(sizeof(struct GpuFrameImpl));
+ if (!gpu_frame_impl) {
LOG("Failed to allocate gpu frame (%s)", strerror(errno));
return NULL;
}
- *gpu_frame = (struct GpuFrame){
- .gpu_context = gpu_context,
- .width = width,
- .height = height,
+ *gpu_frame_impl = (struct GpuFrameImpl){
+ .size.width = width,
+ .size.height = height,
.dmabuf_fds = {-1, -1, -1, -1},
.images = {EGL_NO_IMAGE, EGL_NO_IMAGE},
};
for (size_t i = 0; i < nplanes; i++) {
- gpu_frame->dmabuf_fds[i] = dup(planes[i].dmabuf_fd);
- if (gpu_frame->dmabuf_fds[i] == -1) {
+ gpu_frame_impl->dmabuf_fds[i] = dup(planes[i].dmabuf_fd);
+ if (gpu_frame_impl->dmabuf_fds[i] == -1) {
LOG("Failed to dup dmabuf fd (%s)", strerror(errno));
goto rollback_dmabuf_fds;
}
@@ -693,7 +662,7 @@ struct GpuFrame* GpuFrameCreate(struct GpuContext* gpu_context, uint32_t width,
struct GpuFramePlane dummy_planes[4];
for (size_t i = 0; i < nplanes; i++) {
dummy_planes[i] = (struct GpuFramePlane){
- .dmabuf_fd = gpu_frame->dmabuf_fds[i],
+ .dmabuf_fd = gpu_frame_impl->dmabuf_fds[i],
.offset = planes[i].offset,
.pitch = planes[i].pitch,
.modifier = planes[i].modifier,
@@ -701,61 +670,58 @@ struct GpuFrame* GpuFrameCreate(struct GpuContext* gpu_context, uint32_t width,
}
if (fourcc == DRM_FORMAT_NV12) {
- gpu_frame->images[0] = CreateEglImage(gpu_context, width, height,
- DRM_FORMAT_R8, 1, &dummy_planes[0]);
- if (gpu_frame->images[0] == EGL_NO_IMAGE) {
+ gpu_frame_impl->images[0] = CreateEglImage(
+ gpu_context, width, height, DRM_FORMAT_R8, 1, &dummy_planes[0]);
+ if (gpu_frame_impl->images[0] == EGL_NO_IMAGE) {
LOG("Failed to create luma plane image");
goto rollback_dmabuf_fds;
}
- gpu_frame->images[1] = CreateEglImage(gpu_context, width / 2, height / 2,
- DRM_FORMAT_GR88, 1, &dummy_planes[1]);
- if (gpu_frame->images[1] == EGL_NO_IMAGE) {
+ gpu_frame_impl->images[1] =
+ CreateEglImage(gpu_context, width / 2, height / 2, DRM_FORMAT_GR88, 1,
+ &dummy_planes[1]);
+ if (gpu_frame_impl->images[1] == EGL_NO_IMAGE) {
LOG("Failed to create chroma plane image");
goto rollback_images;
}
} else {
- gpu_frame->images[0] = CreateEglImage(gpu_context, width, height, fourcc,
- nplanes, dummy_planes);
- if (gpu_frame->images[0] == EGL_NO_IMAGE) {
+ gpu_frame_impl->images[0] = CreateEglImage(gpu_context, width, height,
+ fourcc, nplanes, dummy_planes);
+ if (gpu_frame_impl->images[0] == EGL_NO_IMAGE) {
LOG("Failed to create multiplanar image");
goto rollback_dmabuf_fds;
}
}
- for (size_t i = 0; i < LENGTH(gpu_frame->images); i++) {
- if (gpu_frame->images[i] == EGL_NO_IMAGE) break;
- gpu_frame->textures[i] = CreateTexture(gpu_context, gpu_frame->images[i]);
- if (!gpu_frame->textures[i]) {
+ for (size_t i = 0; i < LENGTH(gpu_frame_impl->images); i++) {
+ if (gpu_frame_impl->images[i] == EGL_NO_IMAGE) break;
+ gpu_frame_impl->textures[i] =
+ CreateTexture(gpu_context, gpu_frame_impl->images[i]);
+ if (!gpu_frame_impl->textures[i]) {
LOG("Failed to create texture");
goto rollback_textures;
}
}
- return gpu_frame;
+ return (struct GpuFrame*)gpu_frame_impl;
rollback_textures:
- for (size_t i = LENGTH(gpu_frame->textures); i; i--) {
- if (gpu_frame->textures[i - 1])
- glDeleteTextures(1, &gpu_frame->textures[i - 1]);
+ for (size_t i = LENGTH(gpu_frame_impl->textures); i; i--) {
+ if (gpu_frame_impl->textures[i - 1])
+ glDeleteTextures(1, &gpu_frame_impl->textures[i - 1]);
}
rollback_images:
- for (size_t i = LENGTH(gpu_frame->images); i; i--) {
- if (gpu_frame->images[i - 1] != EGL_NO_IMAGE)
- eglDestroyImage(gpu_frame->gpu_context->device, gpu_frame->images[i - 1]);
+ for (size_t i = LENGTH(gpu_frame_impl->images); i; i--) {
+ if (gpu_frame_impl->images[i - 1] != EGL_NO_IMAGE)
+ eglDestroyImage(gpu_context->device, gpu_frame_impl->images[i - 1]);
}
rollback_dmabuf_fds:
- for (size_t i = LENGTH(gpu_frame->dmabuf_fds); i; i--) {
- if (gpu_frame->dmabuf_fds[i - 1] != -1) close(gpu_frame->dmabuf_fds[i - 1]);
+ for (size_t i = LENGTH(gpu_frame_impl->dmabuf_fds); i; i--) {
+ if (gpu_frame_impl->dmabuf_fds[i - 1] != -1)
+ close(gpu_frame_impl->dmabuf_fds[i - 1]);
}
- free(gpu_frame);
+ free(gpu_frame_impl);
return NULL;
}
-void GpuFrameGetSize(const struct GpuFrame* gpu_frame, uint32_t* width,
- uint32_t* height) {
- *width = gpu_frame->width;
- *height = gpu_frame->height;
-}
-
static bool GpuFrameConvertImpl(GLuint from, GLuint to) {
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
to, 0);
@@ -775,10 +741,15 @@ static bool GpuFrameConvertImpl(GLuint from, GLuint to) {
return true;
}
-bool GpuFrameConvert(const struct GpuFrame* from, const struct GpuFrame* to) {
- glUseProgram(from->gpu_context->program_luma);
+bool GpuContextConvertFrame(struct GpuContext* gpu_context,
+ const struct GpuFrame* from,
+ const struct GpuFrame* to) {
+ const struct GpuFrameImpl* from_impl = (const void*)from;
+ const struct GpuFrameImpl* to_impl = (const void*)to;
+
+ glUseProgram(gpu_context->program_luma);
glViewport(0, 0, (GLsizei)to->width, (GLsizei)to->height);
- if (!GpuFrameConvertImpl(from->textures[0], to->textures[0])) {
+ if (!GpuFrameConvertImpl(from_impl->textures[0], to_impl->textures[0])) {
LOG("Failed to convert luma plane");
return false;
}
@@ -790,27 +761,54 @@ bool GpuFrameConvert(const struct GpuFrame* from, const struct GpuFrame* to) {
_(1.f / (GLfloat)from->width, 1.f / (GLfloat)from->height),
};
- glUseProgram(from->gpu_context->program_chroma);
- glUniform2fv(from->gpu_context->sample_offsets, 4, sample_offsets);
+ glUseProgram(gpu_context->program_chroma);
+ glUniform2fv(gpu_context->sample_offsets, 4, sample_offsets);
glViewport(0, 0, (GLsizei)to->width / 2, (GLsizei)to->height / 2);
- if (!GpuFrameConvertImpl(from->textures[0], to->textures[1])) {
+ if (!GpuFrameConvertImpl(from_impl->textures[0], to_impl->textures[1])) {
LOG("Failed to convert chroma plane");
return false;
}
+
+ EGLSync sync = eglCreateSync(gpu_context->display, EGL_SYNC_FENCE, NULL);
+ if (sync == EGL_NO_SYNC) {
+ LOG("Failed to create egl fence sync (%s)", EglErrorString(eglGetError()));
+ return false;
+ }
+ eglClientWaitSync(gpu_context->display, sync, 0, EGL_FOREVER);
+ eglDestroySync(gpu_context->display, sync);
return true;
}
-void GpuFrameDestroy(struct GpuFrame* gpu_frame) {
- for (size_t i = LENGTH(gpu_frame->textures); i; i--) {
- if (gpu_frame->textures[i - 1])
- glDeleteTextures(1, &gpu_frame->textures[i - 1]);
+void GpuContextDestroyFrame(struct GpuContext* gpu_context,
+ struct GpuFrame* gpu_frame) {
+ struct GpuFrameImpl* gpu_frame_impl = (void*)gpu_frame;
+ for (size_t i = LENGTH(gpu_frame_impl->textures); i; i--) {
+ if (gpu_frame_impl->textures[i - 1])
+ glDeleteTextures(1, &gpu_frame_impl->textures[i - 1]);
}
- for (size_t i = LENGTH(gpu_frame->images); i; i--) {
- if (gpu_frame->images[i - 1] != EGL_NO_IMAGE)
- eglDestroyImage(gpu_frame->gpu_context->device, gpu_frame->images[i - 1]);
+ for (size_t i = LENGTH(gpu_frame_impl->images); i; i--) {
+ if (gpu_frame_impl->images[i - 1] != EGL_NO_IMAGE)
+ eglDestroyImage(gpu_context->device, gpu_frame_impl->images[i - 1]);
}
- for (size_t i = LENGTH(gpu_frame->dmabuf_fds); i; i--) {
- if (gpu_frame->dmabuf_fds[i - 1] != -1) close(gpu_frame->dmabuf_fds[i - 1]);
+ for (size_t i = LENGTH(gpu_frame_impl->dmabuf_fds); i; i--) {
+ if (gpu_frame_impl->dmabuf_fds[i - 1] != -1)
+ close(gpu_frame_impl->dmabuf_fds[i - 1]);
}
- free(gpu_frame);
+ free(gpu_frame_impl);
+}
+
+void GpuContextDestroy(struct GpuContext* gpu_context) {
+ glDeleteBuffers(1, &gpu_context->vertices);
+ glDeleteFramebuffers(1, &gpu_context->framebuffer);
+ glDeleteProgram(gpu_context->program_chroma);
+ glDeleteProgram(gpu_context->program_luma);
+ eglMakeCurrent(gpu_context->display, EGL_NO_SURFACE, EGL_NO_SURFACE,
+ EGL_NO_CONTEXT);
+ eglDestroyContext(gpu_context->display, gpu_context->context);
+ eglTerminate(gpu_context->display);
+#ifndef USE_EGL_MESA_PLATFORM_SURFACELESS
+ gbm_device_destroy(gpu_context->device);
+ close(gpu_context->render_node);
+#endif // USE_EGL_MESA_PLATFORM_SURFACELESS
+ free(gpu_context);
}
diff --git a/gpu.h b/gpu.h
index 0f0d71d..f8fa886 100644
--- a/gpu.h
+++ b/gpu.h
@@ -24,6 +24,11 @@
#include "colorspace.h"
+struct GpuFrame {
+ uint32_t width;
+ uint32_t height;
+};
+
struct GpuFramePlane {
int dmabuf_fd;
uint32_t pitch;
@@ -33,16 +38,15 @@ struct GpuFramePlane {
struct GpuContext* GpuContextCreate(enum YuvColorspace colorspace,
enum YuvRange range);
-bool GpuContextSync(struct GpuContext* gpu_context);
+struct GpuFrame* GpuContextCreateFrame(struct GpuContext* gpu_context,
+ uint32_t width, uint32_t height,
+ uint32_t fourcc, size_t nplanes,
+ const struct GpuFramePlane* planes);
+bool GpuContextConvertFrame(struct GpuContext* gpu_context,
+ const struct GpuFrame* from,
+ const struct GpuFrame* to);
+void GpuContextDestroyFrame(struct GpuContext* gpu_context,
+ struct GpuFrame* gpu_frame);
void GpuContextDestroy(struct GpuContext* gpu_context);
-struct GpuFrame* GpuFrameCreate(struct GpuContext* gpu_context, uint32_t width,
- uint32_t height, uint32_t fourcc,
- size_t nplanes,
- const struct GpuFramePlane* planes);
-void GpuFrameGetSize(const struct GpuFrame* gpu_frame, uint32_t* width,
- uint32_t* height);
-bool GpuFrameConvert(const struct GpuFrame* from, const struct GpuFrame* to);
-void GpuFrameDestroy(struct GpuFrame* gpu_frame);
-
#endif // STREAMER_GPU_H_
diff --git a/main.c b/main.c
index 1b27a0d..aa5a493 100644
--- a/main.c
+++ b/main.c
@@ -143,10 +143,9 @@ static void OnTimerExpire(void* user) {
}
if (!contexts->encode_context) {
- uint32_t width, height;
- GpuFrameGetSize(captured_frame, &width, &height);
- contexts->encode_context = EncodeContextCreate(contexts->gpu_context, width,
- height, colorspace, range);
+ contexts->encode_context =
+ EncodeContextCreate(contexts->gpu_context, captured_frame->width,
+ captured_frame->height, colorspace, range);
if (!contexts->encode_context) {
LOG("Failed to create encode context");
goto drop_client;
@@ -159,12 +158,11 @@ static void OnTimerExpire(void* user) {
LOG("Failed to get encoded frame");
goto drop_client;
}
- if (!GpuFrameConvert(captured_frame, encoded_frame)) {
+ if (!GpuContextConvertFrame(contexts->gpu_context, captured_frame,
+ encoded_frame)) {
LOG("Failed to convert frame");
goto drop_client;
}
-
- GpuContextSync(contexts->gpu_context);
if (!EncodeContextEncodeFrame(contexts->encode_context,
contexts->client_fd)) {
LOG("Failed to encode frame");