cudaconverter: Add support for configuration update
Allow updating various configuration values via property Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8170>
This commit is contained in:
parent
1fa51046d1
commit
d761196bb7
@ -23,6 +23,7 @@
|
||||
|
||||
#include "gstcudaconverter.h"
|
||||
#include <string.h>
|
||||
#include <mutex>
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (gst_cuda_converter_debug);
|
||||
#define GST_CAT_DEFAULT gst_cuda_converter_debug
|
||||
@ -32,13 +33,13 @@ GST_DEBUG_CATEGORY_STATIC (gst_cuda_converter_debug);
|
||||
#define DIV_UP(size,block) (((size) + ((block) - 1)) / (block))
|
||||
|
||||
/* from GstD3D11 */
|
||||
typedef struct _GstCudaColorMatrix
|
||||
struct GstCudaColorMatrix
|
||||
{
|
||||
gdouble matrix[3][3];
|
||||
gdouble offset[3];
|
||||
gdouble min[3];
|
||||
gdouble max[3];
|
||||
} GstCudaColorMatrix;
|
||||
};
|
||||
|
||||
static gchar *
|
||||
gst_cuda_dump_color_matrix (GstCudaColorMatrix * matrix)
|
||||
@ -598,7 +599,7 @@ gst_cuda_rgb_to_yuv_matrix_unorm (const GstVideoInfo * in_rgb_info,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
struct ColorMatrix
|
||||
{
|
||||
float coeffX[3];
|
||||
float coeffY[3];
|
||||
@ -606,9 +607,9 @@ typedef struct
|
||||
float offset[3];
|
||||
float min[3];
|
||||
float max[3];
|
||||
} ColorMatrix;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
struct ConstBuffer
|
||||
{
|
||||
ColorMatrix toRGBCoeff;
|
||||
ColorMatrix toYuvCoeff;
|
||||
@ -620,13 +621,13 @@ typedef struct
|
||||
int bottom;
|
||||
int view_width;
|
||||
int view_height;
|
||||
float offset_x;
|
||||
float offset_y;
|
||||
float border_x;
|
||||
float border_y;
|
||||
float border_z;
|
||||
float border_w;
|
||||
} ConstBuffer;
|
||||
int fill_border;
|
||||
int video_direction;
|
||||
};
|
||||
|
||||
#define COLOR_SPACE_IDENTITY "color_space_identity"
|
||||
#define COLOR_SPACE_CONVERT "color_space_convert"
|
||||
@ -685,14 +686,6 @@ typedef struct
|
||||
#define WRITE_GBR_16 "write_gbr_16"
|
||||
#define WRITE_GBRA "write_gbra"
|
||||
#define WRITE_VUYA "write_vuya"
|
||||
#define ROTATE_IDENTITY "rotate_identity"
|
||||
#define ROTATE_90R "rotate_90r"
|
||||
#define ROTATE_180 "rotate_180"
|
||||
#define ROTATE_90L "rotate_90l"
|
||||
#define ROTATE_HORIZ "rotate_horiz"
|
||||
#define ROTATE_VERT "rotate_vert"
|
||||
#define ROTATE_UL_LR "rotate_ul_lr"
|
||||
#define ROTATE_UR_LL "rotate_ur_ll"
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
const static gchar KERNEL_COMMON[] =
|
||||
@ -1307,52 +1300,74 @@ WRITE_VUYA "(unsigned char * dst0, unsigned char * dst1, unsigned char * dst2,\n
|
||||
"}\n"
|
||||
"\n"
|
||||
"__device__ inline float2\n"
|
||||
ROTATE_IDENTITY "(float x, float y)\n"
|
||||
"rotate_identity (float x, float y)\n"
|
||||
"{\n"
|
||||
" return make_float2(x, y);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"__device__ inline float2\n"
|
||||
ROTATE_90R "(float x, float y)\n"
|
||||
"rotate_90r (float x, float y)\n"
|
||||
"{\n"
|
||||
" return make_float2(y, 1.0 - x);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"__device__ inline float2\n"
|
||||
ROTATE_180 "(float x, float y)\n"
|
||||
"rotate_180 (float x, float y)\n"
|
||||
"{\n"
|
||||
" return make_float2(1.0 - x, 1.0 - y);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"__device__ inline float2\n"
|
||||
ROTATE_90L "(float x, float y)\n"
|
||||
"rotate_90l (float x, float y)\n"
|
||||
"{\n"
|
||||
" return make_float2(1.0 - y, x);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"__device__ inline float2\n"
|
||||
ROTATE_HORIZ "(float x, float y)\n"
|
||||
"rotate_horiz (float x, float y)\n"
|
||||
"{\n"
|
||||
" return make_float2(1.0 - x, y);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"__device__ inline float2\n"
|
||||
ROTATE_VERT "(float x, float y)\n"
|
||||
"rotate_vert (float x, float y)\n"
|
||||
"{\n"
|
||||
" return make_float2(x, 1.0 - y);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"__device__ inline float2\n"
|
||||
ROTATE_UL_LR "(float x, float y)\n"
|
||||
"rotate_ul_lr (float x, float y)\n"
|
||||
"{\n"
|
||||
" return make_float2(y, x);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"__device__ inline float2\n"
|
||||
ROTATE_UR_LL "(float x, float y)\n"
|
||||
"rotate_ur_ll (float x, float y)\n"
|
||||
"{\n"
|
||||
" return make_float2(1.0 - y, 1.0 - x);\n"
|
||||
"}\n"
|
||||
"__device__ inline float2\n"
|
||||
"do_rotate (float x, float y, int direction)"
|
||||
"{\n"
|
||||
" switch (direction) {\n"
|
||||
" case 1:\n"
|
||||
" return rotate_90r (x, y);\n"
|
||||
" case 2:\n"
|
||||
" return rotate_180 (x, y);\n"
|
||||
" case 3:\n"
|
||||
" return rotate_90l (x, y);\n"
|
||||
" case 4:\n"
|
||||
" return rotate_horiz (x, y);\n"
|
||||
" case 5:\n"
|
||||
" return rotate_vert (x, y);\n"
|
||||
" case 6:\n"
|
||||
" return rotate_ul_lr (x, y);\n"
|
||||
" case 7:\n"
|
||||
" return rotate_ur_ll (x, y);\n"
|
||||
" default:\n"
|
||||
" return rotate_identity (x, y);\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"\n";
|
||||
|
||||
#define GST_CUDA_KERNEL_UNPACK_FUNC "gst_cuda_kernel_unpack_func"
|
||||
@ -1455,12 +1470,12 @@ static const gchar TEMPLATE_KERNEL[] =
|
||||
" int bottom;\n"
|
||||
" int view_width;\n"
|
||||
" int view_height;\n"
|
||||
" float offset_x;\n"
|
||||
" float offset_y;\n"
|
||||
" float border_x;\n"
|
||||
" float border_y;\n"
|
||||
" float border_z;\n"
|
||||
" float border_w;\n"
|
||||
" int fill_border;\n"
|
||||
" int video_direction;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"extern \"C\" {\n"
|
||||
@ -1468,32 +1483,28 @@ static const gchar TEMPLATE_KERNEL[] =
|
||||
GST_CUDA_KERNEL_MAIN_FUNC "(cudaTextureObject_t tex0, cudaTextureObject_t tex1,\n"
|
||||
" cudaTextureObject_t tex2, cudaTextureObject_t tex3, unsigned char * dst0,\n"
|
||||
" unsigned char * dst1, unsigned char * dst2, unsigned char * dst3,\n"
|
||||
" int stride0, int stride1, ConstBuffer * const_buf)\n"
|
||||
" int stride0, int stride1, ConstBuffer * const_buf, int off_x, int off_y)\n"
|
||||
"{\n"
|
||||
" int x_pos = blockIdx.x * blockDim.x + threadIdx.x;\n"
|
||||
" int y_pos = blockIdx.y * blockDim.y + threadIdx.y;\n"
|
||||
" int x_pos = blockIdx.x * blockDim.x + threadIdx.x + off_x;\n"
|
||||
" int y_pos = blockIdx.y * blockDim.y + threadIdx.y + off_y;\n"
|
||||
" float4 sample;\n"
|
||||
" if (x_pos >= const_buf->width || y_pos >= const_buf->height)\n"
|
||||
" if (x_pos >= const_buf->width || y_pos >= const_buf->height ||\n"
|
||||
" const_buf->view_width <= 0 || const_buf->view_height <= 0)\n"
|
||||
" return;\n"
|
||||
" if (x_pos < const_buf->left || x_pos >= const_buf->right ||\n"
|
||||
" y_pos < const_buf->top || y_pos >= const_buf->bottom) {\n"
|
||||
" if (!const_buf->fill_border)\n"
|
||||
" return;\n"
|
||||
" sample = make_float4 (const_buf->border_x, const_buf->border_y,\n"
|
||||
" const_buf->border_z, const_buf->border_w);\n"
|
||||
" } else {\n"
|
||||
" float x, y;"
|
||||
" if (const_buf->view_width > 0) {\n"
|
||||
" x = const_buf->offset_x +\n"
|
||||
" __int2float_rz (x_pos - const_buf->left) / const_buf->view_width;\n"
|
||||
" } else {\n"
|
||||
" x = const_buf->offset_x;\n"
|
||||
" }\n"
|
||||
" if (const_buf->view_height > 0) {\n"
|
||||
" y = const_buf->offset_y +\n"
|
||||
" __int2float_rz (y_pos - const_buf->top) / const_buf->view_height;\n"
|
||||
" } else {\n"
|
||||
" y = const_buf->offset_y;\n"
|
||||
" }\n"
|
||||
" float2 rotated = %s (x, y);\n"
|
||||
" float x = (__int2float_rz (x_pos - const_buf->left) + 0.5) / const_buf->view_width;\n"
|
||||
" if (x < 0.0 || x > 1.0)\n"
|
||||
" return;\n"
|
||||
" float y = (__int2float_rz (y_pos - const_buf->top) + 0.5) / const_buf->view_height;\n"
|
||||
" if (y < 0.0 || y > 1.0)\n"
|
||||
" return;\n"
|
||||
" float2 rotated = do_rotate (x, y, const_buf->video_direction);\n"
|
||||
" float4 s = %s (tex0, tex1, tex2, tex3, rotated.x, rotated.y);\n"
|
||||
" float3 xyz = make_float3 (s.x, s.y, s.z);\n"
|
||||
" float3 rgb = %s (xyz, &const_buf->toRGBCoeff);\n"
|
||||
@ -1513,7 +1524,7 @@ typedef struct _TextureFormat
|
||||
const gchar *sample_func;
|
||||
} TextureFormat;
|
||||
|
||||
#define CU_AD_FORMAT_NONE 0
|
||||
#define CU_AD_FORMAT_NONE ((CUarray_format)0)
|
||||
#define MAKE_FORMAT_YUV_PLANAR(f,cf,sample_func) \
|
||||
{ GST_VIDEO_FORMAT_ ##f, { CU_AD_FORMAT_ ##cf, CU_AD_FORMAT_ ##cf, \
|
||||
CU_AD_FORMAT_ ##cf, CU_AD_FORMAT_NONE }, {1, 1, 1, 0}, sample_func }
|
||||
@ -1564,60 +1575,111 @@ static const TextureFormat format_map[] = {
|
||||
MAKE_FORMAT_RGB (VUYA, UNSIGNED_INT8, SAMPLE_VUYA),
|
||||
};
|
||||
|
||||
typedef struct _TextureBuffer
|
||||
struct TextureBuffer
|
||||
{
|
||||
CUdeviceptr ptr;
|
||||
gsize stride;
|
||||
CUtexObject texture;
|
||||
} TextureBuffer;
|
||||
CUdeviceptr ptr = 0;
|
||||
gsize stride = 0;
|
||||
CUtexObject texture = 0;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
enum
|
||||
{
|
||||
gint x;
|
||||
gint y;
|
||||
gint width;
|
||||
gint height;
|
||||
} ConverterRect;
|
||||
PROP_0,
|
||||
PROP_DEST_X,
|
||||
PROP_DEST_Y,
|
||||
PROP_DEST_WIDTH,
|
||||
PROP_DEST_HEIGHT,
|
||||
PROP_FILL_BORDER,
|
||||
PROP_VIDEO_DIRECTION,
|
||||
};
|
||||
|
||||
struct _GstCudaConverterPrivate
|
||||
{
|
||||
_GstCudaConverterPrivate ()
|
||||
{
|
||||
config = gst_structure_new_empty ("converter-config");
|
||||
}
|
||||
|
||||
~_GstCudaConverterPrivate ()
|
||||
{
|
||||
if (config)
|
||||
gst_structure_free (config);
|
||||
}
|
||||
|
||||
std::mutex lock;
|
||||
|
||||
GstVideoInfo in_info;
|
||||
GstVideoInfo out_info;
|
||||
|
||||
GstVideoOrientationMethod method;
|
||||
|
||||
GstStructure *config;
|
||||
GstStructure *config = nullptr;
|
||||
|
||||
GstVideoInfo texture_info;
|
||||
const TextureFormat *texture_fmt;
|
||||
gint texture_align;
|
||||
ConverterRect dest_rect;
|
||||
|
||||
TextureBuffer fallback_buffer[GST_VIDEO_MAX_COMPONENTS];
|
||||
CUfilter_mode filter_mode[GST_VIDEO_MAX_COMPONENTS];
|
||||
TextureBuffer unpack_buffer;
|
||||
ConstBuffer *const_buf_staging;
|
||||
CUdeviceptr const_buf;
|
||||
ConstBuffer *const_buf_staging = nullptr;
|
||||
CUdeviceptr const_buf = 0;
|
||||
|
||||
CUmodule module;
|
||||
CUfunction main_func;
|
||||
CUfunction unpack_func;
|
||||
CUmodule module = nullptr;
|
||||
CUfunction main_func = nullptr;
|
||||
CUfunction unpack_func = nullptr;
|
||||
|
||||
gboolean update_const_buf = FALSE;
|
||||
|
||||
/* properties */
|
||||
gint dest_x = 0;
|
||||
gint dest_y = 0;
|
||||
gint dest_width = 0;
|
||||
gint dest_height = 0;
|
||||
GstVideoOrientationMethod video_direction = GST_VIDEO_ORIENTATION_IDENTITY;
|
||||
gboolean fill_border = FALSE;
|
||||
CUfilter_mode filter_mode = CU_TR_FILTER_MODE_LINEAR;
|
||||
};
|
||||
|
||||
static void gst_cuda_converter_dispose (GObject * object);
|
||||
static void gst_cuda_converter_finalize (GObject * object);
|
||||
static void gst_cuda_converter_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_cuda_converter_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
#define gst_cuda_converter_parent_class parent_class
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GstCudaConverter, gst_cuda_converter,
|
||||
GST_TYPE_OBJECT);
|
||||
G_DEFINE_TYPE (GstCudaConverter, gst_cuda_converter, GST_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
gst_cuda_converter_class_init (GstCudaConverterClass * klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
auto object_class = G_OBJECT_CLASS (klass);
|
||||
auto param_flags = (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
object_class->dispose = gst_cuda_converter_dispose;
|
||||
object_class->finalize = gst_cuda_converter_finalize;
|
||||
object_class->set_property = gst_cuda_converter_set_property;
|
||||
object_class->get_property = gst_cuda_converter_get_property;
|
||||
|
||||
g_object_class_install_property (object_class, PROP_DEST_X,
|
||||
g_param_spec_int ("dest-x", "Dest-X",
|
||||
"x poisition in the destination frame", G_MININT, G_MAXINT, 0,
|
||||
param_flags));
|
||||
g_object_class_install_property (object_class, PROP_DEST_Y,
|
||||
g_param_spec_int ("dest-y", "Dest-Y",
|
||||
"y poisition in the destination frame", G_MININT, G_MAXINT, 0,
|
||||
param_flags));
|
||||
g_object_class_install_property (object_class, PROP_DEST_WIDTH,
|
||||
g_param_spec_int ("dest-width", "Dest-Width",
|
||||
"Width in the destination frame", 0, G_MAXINT, 0, param_flags));
|
||||
g_object_class_install_property (object_class, PROP_DEST_HEIGHT,
|
||||
g_param_spec_int ("dest-height", "Dest-Height",
|
||||
"Height in the destination frame", 0, G_MAXINT, 0, param_flags));
|
||||
g_object_class_install_property (object_class, PROP_FILL_BORDER,
|
||||
g_param_spec_boolean ("fill-border", "Fill border",
|
||||
"Fill border", FALSE, param_flags));
|
||||
g_object_class_install_property (object_class, PROP_VIDEO_DIRECTION,
|
||||
g_param_spec_enum ("video-direction", "Video Direction",
|
||||
"Video direction", GST_TYPE_VIDEO_ORIENTATION_METHOD,
|
||||
GST_VIDEO_ORIENTATION_IDENTITY, param_flags));
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (gst_cuda_converter_debug,
|
||||
"cudaconverter", 0, "cudaconverter");
|
||||
@ -1626,26 +1688,22 @@ gst_cuda_converter_class_init (GstCudaConverterClass * klass)
|
||||
static void
|
||||
gst_cuda_converter_init (GstCudaConverter * self)
|
||||
{
|
||||
GstCudaConverterPrivate *priv;
|
||||
|
||||
self->priv = priv = gst_cuda_converter_get_instance_private (self);
|
||||
priv->config = gst_structure_new_empty ("GstCudaConverter");
|
||||
self->priv = new GstCudaConverterPrivate ();
|
||||
}
|
||||
|
||||
static void
|
||||
gst_cuda_converter_dispose (GObject * object)
|
||||
{
|
||||
GstCudaConverter *self = GST_CUDA_CONVERTER (object);
|
||||
GstCudaConverterPrivate *priv = self->priv;
|
||||
guint i;
|
||||
auto self = GST_CUDA_CONVERTER (object);
|
||||
auto priv = self->priv;
|
||||
|
||||
if (self->context && gst_cuda_context_push (self->context)) {
|
||||
if (priv->module) {
|
||||
CuModuleUnload (priv->module);
|
||||
priv->module = NULL;
|
||||
priv->module = nullptr;
|
||||
}
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (priv->fallback_buffer); i++) {
|
||||
for (guint i = 0; i < G_N_ELEMENTS (priv->fallback_buffer); i++) {
|
||||
if (priv->fallback_buffer[i].ptr) {
|
||||
if (priv->fallback_buffer[i].texture) {
|
||||
CuTexObjectDestroy (priv->fallback_buffer[i].texture);
|
||||
@ -1669,7 +1727,7 @@ gst_cuda_converter_dispose (GObject * object)
|
||||
|
||||
if (priv->const_buf_staging) {
|
||||
CuMemFreeHost (priv->const_buf_staging);
|
||||
priv->const_buf_staging = NULL;
|
||||
priv->const_buf_staging = nullptr;
|
||||
}
|
||||
|
||||
if (priv->const_buf) {
|
||||
@ -1677,7 +1735,7 @@ gst_cuda_converter_dispose (GObject * object)
|
||||
priv->const_buf = 0;
|
||||
}
|
||||
|
||||
gst_cuda_context_pop (NULL);
|
||||
gst_cuda_context_pop (nullptr);
|
||||
}
|
||||
|
||||
gst_clear_object (&self->context);
|
||||
@ -1688,14 +1746,126 @@ gst_cuda_converter_dispose (GObject * object)
|
||||
static void
|
||||
gst_cuda_converter_finalize (GObject * object)
|
||||
{
|
||||
GstCudaConverter *self = GST_CUDA_CONVERTER (object);
|
||||
GstCudaConverterPrivate *priv = self->priv;
|
||||
auto self = GST_CUDA_CONVERTER (object);
|
||||
|
||||
gst_structure_free (priv->config);
|
||||
delete self->priv;
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_cuda_converter_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
auto self = GST_CUDA_CONVERTER (object);
|
||||
auto priv = self->priv;
|
||||
|
||||
std::lock_guard < std::mutex > lk (priv->lock);
|
||||
switch (prop_id) {
|
||||
case PROP_DEST_X:
|
||||
{
|
||||
auto dest_x = g_value_get_int (value);
|
||||
if (priv->dest_x != dest_x) {
|
||||
priv->update_const_buf = TRUE;
|
||||
priv->dest_x = dest_x;
|
||||
priv->const_buf_staging->left = dest_x;
|
||||
priv->const_buf_staging->right = priv->dest_x + priv->dest_width;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PROP_DEST_Y:
|
||||
{
|
||||
auto dest_y = g_value_get_int (value);
|
||||
if (priv->dest_y != dest_y) {
|
||||
priv->update_const_buf = TRUE;
|
||||
priv->dest_y = dest_y;
|
||||
priv->const_buf_staging->top = dest_y;
|
||||
priv->const_buf_staging->bottom = priv->dest_y + priv->dest_height;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PROP_DEST_WIDTH:
|
||||
{
|
||||
auto dest_width = g_value_get_int (value);
|
||||
if (priv->dest_width != dest_width) {
|
||||
priv->update_const_buf = TRUE;
|
||||
priv->dest_width = dest_width;
|
||||
priv->const_buf_staging->right = priv->dest_x + dest_width;
|
||||
priv->const_buf_staging->view_width = dest_width;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PROP_DEST_HEIGHT:
|
||||
{
|
||||
auto dest_height = g_value_get_int (value);
|
||||
if (priv->dest_height != dest_height) {
|
||||
priv->update_const_buf = TRUE;
|
||||
priv->dest_height = dest_height;
|
||||
priv->const_buf_staging->bottom = priv->dest_y + dest_height;
|
||||
priv->const_buf_staging->view_height = dest_height;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PROP_FILL_BORDER:
|
||||
{
|
||||
auto fill_border = g_value_get_boolean (value);
|
||||
if (priv->fill_border != fill_border) {
|
||||
priv->update_const_buf = TRUE;
|
||||
priv->fill_border = fill_border;
|
||||
priv->const_buf_staging->fill_border = fill_border;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PROP_VIDEO_DIRECTION:
|
||||
{
|
||||
auto video_direction =
|
||||
(GstVideoOrientationMethod) g_value_get_enum (value);
|
||||
if (priv->video_direction != video_direction) {
|
||||
priv->update_const_buf = TRUE;
|
||||
priv->video_direction = video_direction;
|
||||
priv->const_buf_staging->video_direction = video_direction;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_cuda_converter_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
auto self = GST_CUDA_CONVERTER (object);
|
||||
auto priv = self->priv;
|
||||
|
||||
std::lock_guard < std::mutex > lk (priv->lock);
|
||||
switch (prop_id) {
|
||||
case PROP_DEST_X:
|
||||
g_value_set_int (value, priv->dest_x);
|
||||
break;
|
||||
case PROP_DEST_Y:
|
||||
g_value_set_int (value, priv->dest_y);
|
||||
break;
|
||||
case PROP_DEST_WIDTH:
|
||||
g_value_set_int (value, priv->dest_width);
|
||||
break;
|
||||
case PROP_DEST_HEIGHT:
|
||||
g_value_set_int (value, priv->dest_height);
|
||||
break;
|
||||
case PROP_FILL_BORDER:
|
||||
g_value_set_boolean (value, priv->fill_border);
|
||||
break;
|
||||
case PROP_VIDEO_DIRECTION:
|
||||
g_value_set_enum (value, priv->video_direction);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
get_color_range_name (GstVideoColorRange range)
|
||||
{
|
||||
@ -1722,16 +1892,15 @@ gst_cuda_converter_setup (GstCudaConverter * self)
|
||||
GstCudaColorMatrix to_yuv_matrix;
|
||||
GstCudaColorMatrix border_color_matrix;
|
||||
gdouble border_color[4];
|
||||
gint i, j;
|
||||
const gchar *unpack_function = NULL;
|
||||
const gchar *write_func = NULL;
|
||||
guint i, j;
|
||||
const gchar *unpack_function = nullptr;
|
||||
const gchar *write_func = nullptr;
|
||||
const gchar *to_rgb_func = COLOR_SPACE_IDENTITY;
|
||||
const gchar *to_yuv_func = COLOR_SPACE_IDENTITY;
|
||||
const gchar *rotate_func = ROTATE_IDENTITY;
|
||||
const GstVideoColorimetry *in_color;
|
||||
const GstVideoColorimetry *out_color;
|
||||
gchar *str;
|
||||
gchar *program = NULL;
|
||||
gchar *program = nullptr;
|
||||
CUresult ret;
|
||||
|
||||
in_info = &priv->in_info;
|
||||
@ -2014,51 +2183,21 @@ gst_cuda_converter_setup (GstCudaConverter * self)
|
||||
|
||||
priv->const_buf_staging->width = out_info->width;
|
||||
priv->const_buf_staging->height = out_info->height;
|
||||
priv->const_buf_staging->left = priv->dest_rect.x;
|
||||
priv->const_buf_staging->top = priv->dest_rect.y;
|
||||
priv->const_buf_staging->right = priv->dest_rect.x + priv->dest_rect.width;
|
||||
priv->const_buf_staging->bottom = priv->dest_rect.y + priv->dest_rect.height;
|
||||
priv->const_buf_staging->view_width = priv->dest_rect.width;
|
||||
priv->const_buf_staging->view_height = priv->dest_rect.height;
|
||||
priv->const_buf_staging->offset_x = priv->dest_rect.width != 0 ?
|
||||
0.5 / priv->dest_rect.width : 0;
|
||||
priv->const_buf_staging->offset_y = priv->dest_rect.height != 0 ?
|
||||
0.5 / priv->dest_rect.height : 0;
|
||||
priv->const_buf_staging->left = 0;
|
||||
priv->const_buf_staging->top = 0;
|
||||
priv->const_buf_staging->right = out_info->width;
|
||||
priv->const_buf_staging->bottom = out_info->height;
|
||||
priv->const_buf_staging->view_width = out_info->width;
|
||||
priv->const_buf_staging->view_height = out_info->height;
|
||||
priv->const_buf_staging->border_x = border_color[0];
|
||||
priv->const_buf_staging->border_y = border_color[1];
|
||||
priv->const_buf_staging->border_z = border_color[2];
|
||||
priv->const_buf_staging->border_w = border_color[3];
|
||||
|
||||
switch (priv->method) {
|
||||
case GST_VIDEO_ORIENTATION_90R:
|
||||
rotate_func = ROTATE_90R;
|
||||
break;
|
||||
case GST_VIDEO_ORIENTATION_180:
|
||||
rotate_func = ROTATE_180;
|
||||
break;
|
||||
case GST_VIDEO_ORIENTATION_90L:
|
||||
rotate_func = ROTATE_90L;
|
||||
break;
|
||||
case GST_VIDEO_ORIENTATION_HORIZ:
|
||||
rotate_func = ROTATE_HORIZ;
|
||||
break;
|
||||
case GST_VIDEO_ORIENTATION_VERT:
|
||||
rotate_func = ROTATE_VERT;
|
||||
break;
|
||||
case GST_VIDEO_ORIENTATION_UL_LR:
|
||||
rotate_func = ROTATE_UL_LR;
|
||||
break;
|
||||
case GST_VIDEO_ORIENTATION_UR_LL:
|
||||
rotate_func = ROTATE_UR_LL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
priv->const_buf_staging->fill_border = 0;
|
||||
priv->const_buf_staging->video_direction = 0;
|
||||
|
||||
str = g_strdup_printf (TEMPLATE_KERNEL, KERNEL_COMMON,
|
||||
unpack_function ? unpack_function : "",
|
||||
/* adjust coord before sampling */
|
||||
rotate_func,
|
||||
/* sampler function name */
|
||||
priv->texture_fmt->sample_func,
|
||||
/* TO RGB conversion function name */
|
||||
@ -2070,7 +2209,7 @@ gst_cuda_converter_setup (GstCudaConverter * self)
|
||||
|
||||
GST_LOG_OBJECT (self, "kernel code:\n%s\n", str);
|
||||
gint cuda_device;
|
||||
g_object_get (self->context, "cuda-device-id", &cuda_device, NULL);
|
||||
g_object_get (self->context, "cuda-device-id", &cuda_device, nullptr);
|
||||
program = gst_cuda_nvrtc_compile_cubin (str, cuda_device);
|
||||
if (!program) {
|
||||
GST_WARNING_OBJECT (self, "Couldn't compile to cubin, trying ptx");
|
||||
@ -2083,18 +2222,6 @@ gst_cuda_converter_setup (GstCudaConverter * self)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (priv->dest_rect.x != 0 || priv->dest_rect.y != 0 ||
|
||||
priv->dest_rect.width != out_info->width ||
|
||||
priv->dest_rect.height != out_info->height ||
|
||||
in_info->width != out_info->width
|
||||
|| in_info->height != out_info->height) {
|
||||
for (i = 0; i < G_N_ELEMENTS (priv->filter_mode); i++)
|
||||
priv->filter_mode[i] = CU_TR_FILTER_MODE_LINEAR;
|
||||
} else {
|
||||
for (i = 0; i < G_N_ELEMENTS (priv->filter_mode); i++)
|
||||
priv->filter_mode[i] = CU_TR_FILTER_MODE_POINT;
|
||||
}
|
||||
|
||||
if (!gst_cuda_context_push (self->context)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't push context");
|
||||
g_free (program);
|
||||
@ -2128,13 +2255,13 @@ gst_cuda_converter_setup (GstCudaConverter * self)
|
||||
resource_desc.res.pitch2D.pitchInBytes = priv->unpack_buffer.stride;
|
||||
resource_desc.res.pitch2D.devPtr = priv->unpack_buffer.ptr;
|
||||
|
||||
texture_desc.filterMode = priv->filter_mode[0];
|
||||
texture_desc.filterMode = priv->filter_mode;
|
||||
texture_desc.flags = 0x2;
|
||||
texture_desc.addressMode[0] = 1;
|
||||
texture_desc.addressMode[1] = 1;
|
||||
texture_desc.addressMode[2] = 1;
|
||||
texture_desc.addressMode[0] = (CUaddress_mode) 1;
|
||||
texture_desc.addressMode[1] = (CUaddress_mode) 1;
|
||||
texture_desc.addressMode[2] = (CUaddress_mode) 1;
|
||||
|
||||
ret = CuTexObjectCreate (&texture, &resource_desc, &texture_desc, NULL);
|
||||
ret = CuTexObjectCreate (&texture, &resource_desc, &texture_desc, nullptr);
|
||||
if (!gst_cuda_result (ret)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't create unpack texture");
|
||||
goto error;
|
||||
@ -2147,7 +2274,7 @@ gst_cuda_converter_setup (GstCudaConverter * self)
|
||||
g_clear_pointer (&program, g_free);
|
||||
if (!gst_cuda_result (ret)) {
|
||||
GST_ERROR_OBJECT (self, "Could not load module");
|
||||
priv->module = NULL;
|
||||
priv->module = nullptr;
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -2174,12 +2301,12 @@ gst_cuda_converter_setup (GstCudaConverter * self)
|
||||
goto error;
|
||||
}
|
||||
|
||||
gst_cuda_context_pop (NULL);
|
||||
gst_cuda_context_pop (nullptr);
|
||||
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
gst_cuda_context_pop (NULL);
|
||||
gst_cuda_context_pop (nullptr);
|
||||
g_free (program);
|
||||
|
||||
return FALSE;
|
||||
@ -2203,15 +2330,6 @@ gst_cuda_converter_set_config (GstCudaConverter * self, GstStructure * config)
|
||||
gst_structure_free (config);
|
||||
}
|
||||
|
||||
static gint
|
||||
get_opt_int (GstCudaConverter * self, const gchar * opt, gint def)
|
||||
{
|
||||
gint res;
|
||||
if (!gst_structure_get_int (self->priv->config, opt, &res))
|
||||
res = def;
|
||||
return res;
|
||||
}
|
||||
|
||||
GstCudaConverter *
|
||||
gst_cuda_converter_new (const GstVideoInfo * in_info,
|
||||
const GstVideoInfo * out_info, GstCudaContext * context,
|
||||
@ -2219,41 +2337,29 @@ gst_cuda_converter_new (const GstVideoInfo * in_info,
|
||||
{
|
||||
GstCudaConverter *self;
|
||||
GstCudaConverterPrivate *priv;
|
||||
gint method;
|
||||
CUresult cuda_ret;
|
||||
|
||||
g_return_val_if_fail (in_info != NULL, NULL);
|
||||
g_return_val_if_fail (out_info != NULL, NULL);
|
||||
g_return_val_if_fail (GST_IS_CUDA_CONTEXT (context), NULL);
|
||||
g_return_val_if_fail (in_info != nullptr, nullptr);
|
||||
g_return_val_if_fail (out_info != nullptr, nullptr);
|
||||
g_return_val_if_fail (GST_IS_CUDA_CONTEXT (context), nullptr);
|
||||
|
||||
self = g_object_new (GST_TYPE_CUDA_CONVERTER, NULL);
|
||||
self = (GstCudaConverter *) g_object_new (GST_TYPE_CUDA_CONVERTER, nullptr);
|
||||
|
||||
if (!GST_IS_CUDA_CONTEXT (context)) {
|
||||
GST_WARNING_OBJECT (self, "Not a valid cuda context object");
|
||||
goto error;
|
||||
}
|
||||
|
||||
self->context = gst_object_ref (context);
|
||||
self->context = (GstCudaContext *) gst_object_ref (context);
|
||||
priv = self->priv;
|
||||
priv->in_info = *in_info;
|
||||
priv->out_info = *out_info;
|
||||
priv->dest_width = out_info->width;
|
||||
priv->dest_height = out_info->height;
|
||||
|
||||
if (config)
|
||||
gst_cuda_converter_set_config (self, config);
|
||||
|
||||
priv->dest_rect.x = get_opt_int (self, GST_CUDA_CONVERTER_OPT_DEST_X, 0);
|
||||
priv->dest_rect.y = get_opt_int (self, GST_CUDA_CONVERTER_OPT_DEST_Y, 0);
|
||||
priv->dest_rect.width = get_opt_int (self,
|
||||
GST_CUDA_CONVERTER_OPT_DEST_WIDTH, out_info->width);
|
||||
priv->dest_rect.height = get_opt_int (self,
|
||||
GST_CUDA_CONVERTER_OPT_DEST_HEIGHT, out_info->height);
|
||||
if (gst_structure_get_enum (priv->config,
|
||||
GST_CUDA_CONVERTER_OPT_ORIENTATION_METHOD,
|
||||
GST_TYPE_VIDEO_ORIENTATION_METHOD, &method)) {
|
||||
priv->method = method;
|
||||
GST_DEBUG_OBJECT (self, "Selected orientation method %d", method);
|
||||
}
|
||||
|
||||
if (!gst_cuda_context_push (context)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't push context");
|
||||
goto error;
|
||||
@ -2263,12 +2369,12 @@ gst_cuda_converter_new (const GstVideoInfo * in_info,
|
||||
sizeof (ConstBuffer));
|
||||
if (!gst_cuda_result (cuda_ret)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't allocate staging const buf");
|
||||
gst_cuda_context_pop (NULL);
|
||||
gst_cuda_context_pop (nullptr);
|
||||
goto error;
|
||||
}
|
||||
|
||||
cuda_ret = CuMemAlloc (&priv->const_buf, sizeof (ConstBuffer));
|
||||
gst_cuda_context_pop (NULL);
|
||||
gst_cuda_context_pop (nullptr);
|
||||
if (!gst_cuda_result (cuda_ret)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't allocate const buf");
|
||||
goto error;
|
||||
@ -2284,10 +2390,9 @@ gst_cuda_converter_new (const GstVideoInfo * in_info,
|
||||
|
||||
error:
|
||||
gst_object_unref (self);
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
static CUtexObject
|
||||
gst_cuda_converter_create_texture_unchecked (GstCudaConverter * self,
|
||||
CUdeviceptr src, gint width, gint height, CUarray_format format,
|
||||
@ -2315,11 +2420,12 @@ gst_cuda_converter_create_texture_unchecked (GstCudaConverter * self,
|
||||
/* CU_TRSF_NORMALIZED_COORDINATES */
|
||||
texture_desc.flags = 0x2;
|
||||
/* CU_TR_ADDRESS_MODE_CLAMP */
|
||||
texture_desc.addressMode[0] = 1;
|
||||
texture_desc.addressMode[1] = 1;
|
||||
texture_desc.addressMode[2] = 1;
|
||||
texture_desc.addressMode[0] = (CUaddress_mode) 1;
|
||||
texture_desc.addressMode[1] = (CUaddress_mode) 1;
|
||||
texture_desc.addressMode[2] = (CUaddress_mode) 1;
|
||||
|
||||
cuda_ret = CuTexObjectCreate (&texture, &resource_desc, &texture_desc, NULL);
|
||||
cuda_ret =
|
||||
CuTexObjectCreate (&texture, &resource_desc, &texture_desc, nullptr);
|
||||
|
||||
if (!gst_cuda_result (cuda_ret)) {
|
||||
GST_ERROR_OBJECT (self, "Could not create texture");
|
||||
@ -2415,7 +2521,7 @@ gst_cuda_converter_unpack_rgb (GstCudaConverter * self,
|
||||
|
||||
ret = CuLaunchKernel (priv->unpack_func, DIV_UP (width, CUDA_BLOCK_X),
|
||||
DIV_UP (height, CUDA_BLOCK_Y), 1, CUDA_BLOCK_X, CUDA_BLOCK_Y, 1, 0,
|
||||
stream, args, NULL);
|
||||
stream, args, nullptr);
|
||||
|
||||
if (!gst_cuda_result (ret)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't unpack source RGB");
|
||||
@ -2433,27 +2539,44 @@ gst_cuda_converter_convert_frame (GstCudaConverter * converter,
|
||||
GstCudaConverterPrivate *priv;
|
||||
const TextureFormat *format;
|
||||
CUtexObject texture[GST_VIDEO_MAX_COMPONENTS] = { 0, };
|
||||
guint8 *dst[GST_VIDEO_MAX_COMPONENTS] = { NULL, };
|
||||
guint8 *dst[GST_VIDEO_MAX_COMPONENTS] = { nullptr, };
|
||||
gint stride[2] = { 0, };
|
||||
gint i;
|
||||
guint i;
|
||||
gboolean ret = FALSE;
|
||||
CUresult cuda_ret;
|
||||
gint width, height;
|
||||
gboolean need_sync = FALSE;
|
||||
GstCudaMemory *cmem;
|
||||
gint off_x = 0;
|
||||
gint off_y = 0;
|
||||
|
||||
g_return_val_if_fail (GST_IS_CUDA_CONVERTER (converter), FALSE);
|
||||
g_return_val_if_fail (src_frame != NULL, FALSE);
|
||||
g_return_val_if_fail (dst_frame != NULL, FALSE);
|
||||
g_return_val_if_fail (src_frame != nullptr, FALSE);
|
||||
g_return_val_if_fail (dst_frame != nullptr, FALSE);
|
||||
|
||||
priv = converter->priv;
|
||||
format = priv->texture_fmt;
|
||||
|
||||
g_assert (format);
|
||||
|
||||
std::lock_guard < std::mutex > lk (priv->lock);
|
||||
if (!priv->fill_border && (priv->dest_width <= 0 || priv->dest_height <= 0))
|
||||
return TRUE;
|
||||
|
||||
if (priv->update_const_buf) {
|
||||
priv->update_const_buf = FALSE;
|
||||
cuda_ret = CuMemcpyHtoDAsync (priv->const_buf, priv->const_buf_staging,
|
||||
sizeof (ConstBuffer), stream);
|
||||
|
||||
if (!gst_cuda_result (cuda_ret)) {
|
||||
GST_ERROR_OBJECT (converter, "Couldn't upload const buffer");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
gpointer args[] = { &texture[0], &texture[1], &texture[2], &texture[3],
|
||||
&dst[0], &dst[1], &dst[2], &dst[3], &stride[0], &stride[1],
|
||||
&priv->const_buf
|
||||
&priv->const_buf, &off_x, &off_y
|
||||
};
|
||||
|
||||
cmem = (GstCudaMemory *) gst_buffer_peek_memory (src_frame->buffer, 0);
|
||||
@ -2476,14 +2599,14 @@ gst_cuda_converter_convert_frame (GstCudaConverter * converter,
|
||||
} else {
|
||||
for (i = 0; i < GST_VIDEO_FRAME_N_PLANES (src_frame); i++) {
|
||||
if (!gst_cuda_memory_get_texture (cmem,
|
||||
i, priv->filter_mode[i], &texture[i])) {
|
||||
i, priv->filter_mode, &texture[i])) {
|
||||
CUdeviceptr src;
|
||||
src = (CUdeviceptr) GST_VIDEO_FRAME_PLANE_DATA (src_frame, i);
|
||||
texture[i] = gst_cuda_converter_create_texture (converter,
|
||||
src, GST_VIDEO_FRAME_COMP_WIDTH (src_frame, i),
|
||||
GST_VIDEO_FRAME_COMP_HEIGHT (src_frame, i),
|
||||
GST_VIDEO_FRAME_PLANE_STRIDE (src_frame, i),
|
||||
priv->filter_mode[i], format->array_format[i], format->channels[i],
|
||||
priv->filter_mode, format->array_format[i], format->channels[i],
|
||||
i, stream);
|
||||
need_sync = TRUE;
|
||||
}
|
||||
@ -2498,8 +2621,20 @@ gst_cuda_converter_convert_frame (GstCudaConverter * converter,
|
||||
width = GST_VIDEO_FRAME_WIDTH (dst_frame);
|
||||
height = GST_VIDEO_FRAME_HEIGHT (dst_frame);
|
||||
|
||||
if (!priv->fill_border) {
|
||||
if (priv->dest_width < width) {
|
||||
off_x = priv->dest_x;
|
||||
width = priv->dest_width;
|
||||
}
|
||||
|
||||
if (priv->dest_height < height) {
|
||||
off_y = priv->dest_y;
|
||||
height = priv->dest_height;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < GST_VIDEO_FRAME_N_PLANES (dst_frame); i++)
|
||||
dst[i] = GST_VIDEO_FRAME_PLANE_DATA (dst_frame, i);
|
||||
dst[i] = (guint8 *) GST_VIDEO_FRAME_PLANE_DATA (dst_frame, i);
|
||||
|
||||
stride[0] = stride[1] = GST_VIDEO_FRAME_PLANE_STRIDE (dst_frame, 0);
|
||||
if (GST_VIDEO_FRAME_N_PLANES (dst_frame) > 1)
|
||||
@ -2507,7 +2642,7 @@ gst_cuda_converter_convert_frame (GstCudaConverter * converter,
|
||||
|
||||
cuda_ret = CuLaunchKernel (priv->main_func, DIV_UP (width, CUDA_BLOCK_X),
|
||||
DIV_UP (height, CUDA_BLOCK_Y), 1, CUDA_BLOCK_X, CUDA_BLOCK_Y, 1, 0,
|
||||
stream, args, NULL);
|
||||
stream, args, nullptr);
|
||||
|
||||
if (!gst_cuda_result (cuda_ret)) {
|
||||
GST_ERROR_OBJECT (converter, "Couldn't convert frame");
|
||||
@ -2523,6 +2658,6 @@ gst_cuda_converter_convert_frame (GstCudaConverter * converter,
|
||||
ret = TRUE;
|
||||
|
||||
out:
|
||||
gst_cuda_context_pop (NULL);
|
||||
gst_cuda_context_pop (nullptr);
|
||||
return ret;
|
||||
}
|
@ -36,41 +36,6 @@ typedef struct _GstCudaConverter GstCudaConverter;
|
||||
typedef struct _GstCudaConverterClass GstCudaConverterClass;
|
||||
typedef struct _GstCudaConverterPrivate GstCudaConverterPrivate;
|
||||
|
||||
/**
|
||||
* GST_CUDA_CONVERTER_OPT_DEST_X:
|
||||
*
|
||||
* #G_TYPE_INT, x position in the destination frame, default 0
|
||||
*/
|
||||
#define GST_CUDA_CONVERTER_OPT_DEST_X "GstCudaConverter.dest-x"
|
||||
|
||||
/**
|
||||
* GST_CUDA_CONVERTER_OPT_DEST_Y:
|
||||
*
|
||||
* #G_TYPE_INT, y position in the destination frame, default 0
|
||||
*/
|
||||
#define GST_CUDA_CONVERTER_OPT_DEST_Y "GstCudaConverter.dest-y"
|
||||
|
||||
/**
|
||||
* GST_CUDA_CONVERTER_OPT_DEST_WIDTH:
|
||||
*
|
||||
* #G_TYPE_INT, width in the destination frame, default destination width
|
||||
*/
|
||||
#define GST_CUDA_CONVERTER_OPT_DEST_WIDTH "GstCudaConverter.dest-width"
|
||||
|
||||
/**
|
||||
* GST_CUDA_CONVERTER_OPT_DEST_HEIGHT:
|
||||
*
|
||||
* #G_TYPE_INT, height in the destination frame, default destination height
|
||||
*/
|
||||
#define GST_CUDA_CONVERTER_OPT_DEST_HEIGHT "GstCudaConverter.dest-height"
|
||||
|
||||
/**
|
||||
* GST_CUDA_CONVERTER_OPT_ORIENTATION_METHOD:
|
||||
*
|
||||
* #GstVideoOrientationMethod, default #GST_VIDEO_ORIENTATION_IDENTITY
|
||||
*/
|
||||
#define GST_CUDA_CONVERTER_OPT_ORIENTATION_METHOD "GstCudaConverter.orientation-method"
|
||||
|
||||
struct _GstCudaConverter
|
||||
{
|
||||
GstObject parent;
|
||||
|
@ -1415,27 +1415,20 @@ gst_cuda_base_convert_set_info (GstCudaBaseTransform * btrans,
|
||||
!needs_color_convert (in_info, out_info)) {
|
||||
gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (self), TRUE);
|
||||
} else {
|
||||
GstStructure *config;
|
||||
|
||||
gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (self), FALSE);
|
||||
|
||||
config = gst_structure_new_empty ("GstCudaConverter");
|
||||
gst_structure_set (config,
|
||||
GST_CUDA_CONVERTER_OPT_DEST_X, G_TYPE_INT, self->borders_w / 2,
|
||||
GST_CUDA_CONVERTER_OPT_DEST_Y, G_TYPE_INT, self->borders_h / 2,
|
||||
GST_CUDA_CONVERTER_OPT_DEST_WIDTH,
|
||||
G_TYPE_INT, out_info->width - self->borders_w,
|
||||
GST_CUDA_CONVERTER_OPT_DEST_HEIGHT,
|
||||
G_TYPE_INT, out_info->height - self->borders_h,
|
||||
GST_CUDA_CONVERTER_OPT_ORIENTATION_METHOD,
|
||||
GST_TYPE_VIDEO_ORIENTATION_METHOD, active_method, NULL);
|
||||
|
||||
self->converter = gst_cuda_converter_new (in_info,
|
||||
out_info, btrans->context, config);
|
||||
out_info, btrans->context, NULL);
|
||||
if (!self->converter) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't create converter");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_object_set (self->converter, "dest-x", self->borders_w / 2,
|
||||
"dest-y", self->borders_h / 2,
|
||||
"dest-width", out_info->width - self->borders_w,
|
||||
"dest-height", out_info->height - self->borders_h,
|
||||
"fill-border", TRUE, "video-direction", active_method, NULL);
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (self, "%s from=%dx%d (par=%d/%d dar=%d/%d), size %"
|
||||
|
@ -1,6 +1,6 @@
|
||||
nvcodec_sources = [
|
||||
'gstcudabasetransform.c',
|
||||
'gstcudaconverter.c',
|
||||
'gstcudaconverter.cpp',
|
||||
'gstcudaconvertscale.c',
|
||||
'gstcudaipc.cpp',
|
||||
'gstcudaipcclient.cpp',
|
||||
|
Loading…
x
Reference in New Issue
Block a user