aboutsummaryrefslogtreecommitdiff
path: root/src/encoder
diff options
context:
space:
mode:
Diffstat (limited to 'src/encoder')
-rw-r--r--src/encoder/video/nvenc.c36
-rw-r--r--src/encoder/video/software.c18
-rw-r--r--src/encoder/video/vaapi.c31
-rw-r--r--src/encoder/video/vulkan.c30
4 files changed, 43 insertions, 72 deletions
diff --git a/src/encoder/video/nvenc.c b/src/encoder/video/nvenc.c
index 718560d..5f578c2 100644
--- a/src/encoder/video/nvenc.c
+++ b/src/encoder/video/nvenc.c
@@ -1,6 +1,7 @@
#include "../../../include/encoder/video/nvenc.h"
#include "../../../include/egl.h"
#include "../../../include/cuda.h"
+#include "../../../include/window/window.h"
#include <libavcodec/avcodec.h>
#include <libavutil/hwcontext_cuda.h>
@@ -64,21 +65,6 @@ static bool gsr_video_encoder_nvenc_setup_context(gsr_video_encoder_nvenc *self,
return true;
}
-static unsigned int gl_create_texture(gsr_egl *egl, int width, int height, int internal_format, unsigned int format) {
- unsigned int texture_id = 0;
- egl->glGenTextures(1, &texture_id);
- egl->glBindTexture(GL_TEXTURE_2D, texture_id);
- egl->glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, format, GL_UNSIGNED_BYTE, NULL);
-
- egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
- egl->glBindTexture(GL_TEXTURE_2D, 0);
- return texture_id;
-}
-
static bool cuda_register_opengl_texture(gsr_cuda *cuda, CUgraphicsResource *cuda_graphics_resource, CUarray *mapped_array, unsigned int texture_id) {
CUresult res;
res = cuda->cuGraphicsGLRegisterImage(cuda_graphics_resource, texture_id, GL_TEXTURE_2D, CU_GRAPHICS_REGISTER_FLAGS_NONE);
@@ -109,7 +95,7 @@ static bool gsr_video_encoder_nvenc_setup_textures(gsr_video_encoder_nvenc *self
const int div[2] = {1, 2}; // divide UV texture size by 2 because chroma is half size
for(int i = 0; i < 2; ++i) {
- self->target_textures[i] = gl_create_texture(self->params.egl, video_codec_context->width / div[i], video_codec_context->height / div[i], self->params.color_depth == GSR_COLOR_DEPTH_8_BITS ? internal_formats_nv12[i] : internal_formats_p010[i], formats[i]);
+ self->target_textures[i] = gl_create_texture(self->params.egl, video_codec_context->width / div[i], video_codec_context->height / div[i], self->params.color_depth == GSR_COLOR_DEPTH_8_BITS ? internal_formats_nv12[i] : internal_formats_p010[i], formats[i], GL_NEAREST);
if(self->target_textures[i] == 0) {
fprintf(stderr, "gsr error: gsr_video_encoder_nvenc_setup_textures: failed to create opengl texture\n");
return false;
@@ -128,13 +114,27 @@ static void gsr_video_encoder_nvenc_stop(gsr_video_encoder_nvenc *self, AVCodecC
static bool gsr_video_encoder_nvenc_start(gsr_video_encoder *encoder, AVCodecContext *video_codec_context, AVFrame *frame) {
gsr_video_encoder_nvenc *self = encoder->priv;
- const bool overclock = gsr_egl_get_display_server(self->params.egl) == GSR_DISPLAY_SERVER_X11 ? self->params.overclock : false;
- if(!gsr_cuda_load(&self->cuda, self->params.egl->x11.dpy, overclock)) {
+ const bool is_x11 = gsr_window_get_display_server(self->params.egl->window) == GSR_DISPLAY_SERVER_X11;
+ const bool overclock = is_x11 ? self->params.overclock : false;
+ Display *display = is_x11 ? gsr_window_get_display(self->params.egl->window) : NULL;
+ if(!gsr_cuda_load(&self->cuda, display, overclock)) {
fprintf(stderr, "gsr error: gsr_video_encoder_nvenc_start: failed to load cuda\n");
gsr_video_encoder_nvenc_stop(self, video_codec_context);
return false;
}
+ video_codec_context->width = FFALIGN(video_codec_context->width, 2);
+ video_codec_context->height = FFALIGN(video_codec_context->height, 2);
+
+ if(video_codec_context->width < 128)
+ video_codec_context->width = 128;
+
+ if(video_codec_context->height < 128)
+ video_codec_context->height = 128;
+
+ frame->width = video_codec_context->width;
+ frame->height = video_codec_context->height;
+
if(!gsr_video_encoder_nvenc_setup_context(self, video_codec_context)) {
gsr_video_encoder_nvenc_stop(self, video_codec_context);
return false;
diff --git a/src/encoder/video/software.c b/src/encoder/video/software.c
index be227f2..3649ff1 100644
--- a/src/encoder/video/software.c
+++ b/src/encoder/video/software.c
@@ -1,5 +1,6 @@
#include "../../../include/encoder/video/software.h"
#include "../../../include/egl.h"
+#include "../../../include/utils.h"
#include <libavcodec/avcodec.h>
#include <libavutil/frame.h>
@@ -14,21 +15,6 @@ typedef struct {
unsigned int target_textures[2];
} gsr_video_encoder_software;
-static unsigned int gl_create_texture(gsr_egl *egl, int width, int height, int internal_format, unsigned int format) {
- unsigned int texture_id = 0;
- egl->glGenTextures(1, &texture_id);
- egl->glBindTexture(GL_TEXTURE_2D, texture_id);
- egl->glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, format, GL_UNSIGNED_BYTE, NULL);
-
- egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
- egl->glBindTexture(GL_TEXTURE_2D, 0);
- return texture_id;
-}
-
static bool gsr_video_encoder_software_setup_textures(gsr_video_encoder_software *self, AVCodecContext *video_codec_context, AVFrame *frame) {
int res = av_frame_get_buffer(frame, LINESIZE_ALIGNMENT);
if(res < 0) {
@@ -48,7 +34,7 @@ static bool gsr_video_encoder_software_setup_textures(gsr_video_encoder_software
const int div[2] = {1, 2}; // divide UV texture size by 2 because chroma is half size
for(int i = 0; i < 2; ++i) {
- self->target_textures[i] = gl_create_texture(self->params.egl, video_codec_context->width / div[i], video_codec_context->height / div[i], self->params.color_depth == GSR_COLOR_DEPTH_8_BITS ? internal_formats_nv12[i] : internal_formats_p010[i], formats[i]);
+ self->target_textures[i] = gl_create_texture(self->params.egl, video_codec_context->width / div[i], video_codec_context->height / div[i], self->params.color_depth == GSR_COLOR_DEPTH_8_BITS ? internal_formats_nv12[i] : internal_formats_p010[i], formats[i], GL_NEAREST);
if(self->target_textures[i] == 0) {
fprintf(stderr, "gsr error: gsr_capture_kms_setup_cuda_textures: failed to create opengl texture\n");
return false;
diff --git a/src/encoder/video/vaapi.c b/src/encoder/video/vaapi.c
index d558785..8bb2f08 100644
--- a/src/encoder/video/vaapi.c
+++ b/src/encoder/video/vaapi.c
@@ -167,32 +167,21 @@ static bool gsr_video_encoder_vaapi_start(gsr_video_encoder *encoder, AVCodecCon
} else {
video_codec_context->height = FFALIGN(video_codec_context->height, 16);
}
+ } else {
+ video_codec_context->width = FFALIGN(video_codec_context->width, 2);
+ video_codec_context->height = FFALIGN(video_codec_context->height, 2);
}
- const int crop_top = (video_codec_context->height - frame->height) / 2;
- const int crop_left = (video_codec_context->width - frame->width) / 2;
- if(crop_top != 0 || crop_left != 0) {
+ if(FFALIGN(video_codec_context->width, 2) != FFALIGN(frame->width, 2) || FFALIGN(video_codec_context->height, 2) != FFALIGN(frame->height, 2)) {
fprintf(stderr, "gsr warning: gsr_video_encoder_vaapi_start: black bars have been added to the video because of a bug in AMD drivers/hardware. Record with h264 codec instead (-k h264) to get around this issue\n");
-#if 0
- #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 10, 100)
- const int crop_bottom = crop_top;
- const int crop_right = crop_left;
- fprintf(stderr, "gsr info: cropping metadata has been added to the file to try and workaround this issue. Video players that support this will remove the black bars when the video is playing\n");
- const int frame_cropping_data_size = 4 * sizeof(uint32_t);
- uint8_t *frame_cropping = av_malloc(frame_cropping_data_size);
- if(frame_cropping) {
- AV_WL32(frame_cropping + 0, crop_top);
- AV_WL32(frame_cropping + 4, crop_bottom);
- AV_WL32(frame_cropping + 8, crop_left);
- AV_WL32(frame_cropping + 12, crop_right);
- const bool sidedata_added = av_packet_side_data_add(&video_stream->codecpar->coded_side_data, &video_stream->codecpar->nb_coded_side_data, AV_PKT_DATA_FRAME_CROPPING, frame_cropping, frame_cropping_data_size, 0) != NULL;
- if(!sidedata_added)
- av_free(frame_cropping);
- }
- #endif
-#endif
}
+ if(video_codec_context->width < 128)
+ video_codec_context->width = 128;
+
+ if(video_codec_context->height < 128)
+ video_codec_context->height = 128;
+
frame->width = video_codec_context->width;
frame->height = video_codec_context->height;
diff --git a/src/encoder/video/vulkan.c b/src/encoder/video/vulkan.c
index 0b6c380..062967b 100644
--- a/src/encoder/video/vulkan.c
+++ b/src/encoder/video/vulkan.c
@@ -71,22 +71,6 @@ static bool gsr_video_encoder_vulkan_setup_context(gsr_video_encoder_vulkan *sel
return true;
}
-static unsigned int gl_create_texture(gsr_egl *egl, int width, int height, int internal_format, unsigned int format) {
- unsigned int texture_id = 0;
- egl->glGenTextures(1, &texture_id);
- egl->glBindTexture(GL_TEXTURE_2D, texture_id);
- //egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_TILING_EXT, GL_OPTIMAL_TILING_EXT);
- egl->glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, format, GL_UNSIGNED_BYTE, NULL);
-
- egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
- egl->glBindTexture(GL_TEXTURE_2D, 0);
- return texture_id;
-}
-
static AVVulkanDeviceContext* video_codec_context_get_vulkan_data(AVCodecContext *video_codec_context) {
AVBufferRef *hw_frames_ctx = video_codec_context->hw_frames_ctx;
if(!hw_frames_ctx)
@@ -116,7 +100,7 @@ static bool gsr_video_encoder_vulkan_setup_textures(gsr_video_encoder_vulkan *se
const int div[2] = {1, 2}; // divide UV texture size by 2 because chroma is half size
for(int i = 0; i < 2; ++i) {
- self->target_textures[i] = gl_create_texture(self->params.egl, video_codec_context->width / div[i], video_codec_context->height / div[i], self->params.color_depth == GSR_COLOR_DEPTH_8_BITS ? internal_formats_nv12[i] : internal_formats_p010[i], formats[i]);
+ self->target_textures[i] = gl_create_texture(self->params.egl, video_codec_context->width / div[i], video_codec_context->height / div[i], self->params.color_depth == GSR_COLOR_DEPTH_8_BITS ? internal_formats_nv12[i] : internal_formats_p010[i], formats[i], GL_NEAREST);
if(self->target_textures[i] == 0) {
fprintf(stderr, "gsr error: gsr_video_encoder_cuda_setup_textures: failed to create opengl texture\n");
return false;
@@ -165,6 +149,18 @@ static void gsr_video_encoder_vulkan_stop(gsr_video_encoder_vulkan *self, AVCode
static bool gsr_video_encoder_vulkan_start(gsr_video_encoder *encoder, AVCodecContext *video_codec_context, AVFrame *frame) {
gsr_video_encoder_vulkan *self = encoder->priv;
+ video_codec_context->width = FFALIGN(video_codec_context->width, 2);
+ video_codec_context->height = FFALIGN(video_codec_context->height, 2);
+
+ if(video_codec_context->width < 128)
+ video_codec_context->width = 128;
+
+ if(video_codec_context->height < 128)
+ video_codec_context->height = 128;
+
+ frame->width = video_codec_context->width;
+ frame->height = video_codec_context->height;
+
if(!gsr_video_encoder_vulkan_setup_context(self, video_codec_context)) {
gsr_video_encoder_vulkan_stop(self, video_codec_context);
return false;