fill in the texture_setimage function, fill in a few other functions, and change certain names to be a little more consistent
This commit is contained in:
@@ -282,12 +282,6 @@ void effect_setint(effect_t effect, eparam_t param, int val)
|
||||
effect_setval_inline(effect, param, &val, sizeof(int));
|
||||
}
|
||||
|
||||
void effect_setmatrix3(effect_t effect, eparam_t param,
|
||||
const struct matrix3 *val)
|
||||
{
|
||||
effect_setval_inline(effect, param, val, sizeof(struct matrix3));
|
||||
}
|
||||
|
||||
void effect_setmatrix4(effect_t effect, eparam_t param,
|
||||
const struct matrix4 *val)
|
||||
{
|
||||
|
@@ -138,7 +138,7 @@ struct gs_exports {
|
||||
uint32_t (*texture_getheight)(texture_t tex);
|
||||
enum gs_color_format (*texture_getcolorformat)(texture_t tex);
|
||||
bool (*texture_map)(texture_t tex, void **ptr,
|
||||
uint32_t *byte_width);
|
||||
uint32_t *row_bytes);
|
||||
void (*texture_unmap)(texture_t tex);
|
||||
|
||||
void (*cubetexture_destroy)(texture_t cubetex);
|
||||
@@ -157,7 +157,7 @@ struct gs_exports {
|
||||
enum gs_color_format (*stagesurface_getcolorformat)(
|
||||
stagesurf_t stagesurf);
|
||||
bool (*stagesurface_map)(stagesurf_t stagesurf, const void **data,
|
||||
uint32_t *byte_width);
|
||||
uint32_t *row_bytes);
|
||||
void (*stagesurface_unmap)(stagesurf_t stagesurf);
|
||||
|
||||
void (*zstencil_destroy)(zstencil_t zstencil);
|
||||
|
@@ -722,13 +722,39 @@ void gs_viewport_pop(void)
|
||||
da_pop_back(thread_graphics->viewport_stack);
|
||||
}
|
||||
|
||||
void texture_setimage(texture_t tex, const void *data, uint32_t byte_width)
|
||||
void texture_setimage(texture_t tex, const void *data, uint32_t row_bytes,
|
||||
bool flip)
|
||||
{
|
||||
/* TODO */
|
||||
void *ptr;
|
||||
uint32_t row_bytes_out;
|
||||
uint32_t row_copy;
|
||||
int32_t height = (int32_t)texture_getheight(tex);
|
||||
int32_t y;
|
||||
|
||||
if (!texture_map(tex, &ptr, &row_bytes_out))
|
||||
return;
|
||||
|
||||
row_copy = (row_bytes < row_bytes_out) ? row_bytes : row_bytes_out;
|
||||
|
||||
if (flip) {
|
||||
for (y = height-1; y >= 0; y--)
|
||||
memcpy((uint8_t*)ptr + (uint32_t)y * row_bytes_out,
|
||||
(uint8_t*)data + (uint32_t)y * row_bytes,
|
||||
row_copy);
|
||||
|
||||
} else if (row_bytes == row_bytes_out) {
|
||||
memcpy(ptr, data, row_copy * height);
|
||||
|
||||
} else {
|
||||
for (y = 0; y < height; y++)
|
||||
memcpy((uint8_t*)ptr + (uint32_t)y * row_bytes_out,
|
||||
(uint8_t*)data + (uint32_t)y * row_bytes,
|
||||
row_copy);
|
||||
}
|
||||
}
|
||||
|
||||
void cubetexture_setimage(texture_t cubetex, uint32_t side, const void *data,
|
||||
uint32_t byte_width)
|
||||
uint32_t row_bytes, bool invert)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
@@ -1347,10 +1373,10 @@ enum gs_color_format texture_getcolorformat(texture_t tex)
|
||||
return graphics->exports.texture_getcolorformat(tex);
|
||||
}
|
||||
|
||||
bool texture_map(texture_t tex, void **ptr, uint32_t *byte_width)
|
||||
bool texture_map(texture_t tex, void **ptr, uint32_t *row_bytes)
|
||||
{
|
||||
graphics_t graphics = thread_graphics;
|
||||
return graphics->exports.texture_map(tex, ptr, byte_width);
|
||||
return graphics->exports.texture_map(tex, ptr, row_bytes);
|
||||
}
|
||||
|
||||
void texture_unmap(texture_t tex)
|
||||
@@ -1432,10 +1458,10 @@ enum gs_color_format stagesurface_getcolorformat(stagesurf_t stagesurf)
|
||||
}
|
||||
|
||||
bool stagesurface_map(stagesurf_t stagesurf, const void **data,
|
||||
uint32_t *byte_width)
|
||||
uint32_t *row_bytes)
|
||||
{
|
||||
graphics_t graphics = thread_graphics;
|
||||
return graphics->exports.stagesurface_map(stagesurf, data, byte_width);
|
||||
return graphics->exports.stagesurface_map(stagesurf, data, row_bytes);
|
||||
}
|
||||
|
||||
void stagesurface_unmap(stagesurf_t stagesurf)
|
||||
|
@@ -366,8 +366,6 @@ EXPORT eparam_t effect_getworldmatrix(effect_t effect);
|
||||
EXPORT void effect_setbool(effect_t effect, eparam_t param, bool val);
|
||||
EXPORT void effect_setfloat(effect_t effect, eparam_t param, float val);
|
||||
EXPORT void effect_setint(effect_t effect, eparam_t param, int val);
|
||||
EXPORT void effect_setmatrix3(effect_t effect, eparam_t param,
|
||||
const struct matrix3 *val);
|
||||
EXPORT void effect_setmatrix4(effect_t effect, eparam_t param,
|
||||
const struct matrix4 *val);
|
||||
EXPORT void effect_setvec2(effect_t effect, eparam_t param,
|
||||
@@ -377,7 +375,7 @@ EXPORT void effect_setvec3(effect_t effect, eparam_t param,
|
||||
EXPORT void effect_setvec4(effect_t effect, eparam_t param,
|
||||
const struct vec4 *val);
|
||||
EXPORT void effect_settexture(effect_t effect, eparam_t param, texture_t val);
|
||||
EXPORT void effect_setval(effect_t shader, eparam_t param, const void *val,
|
||||
EXPORT void effect_setval(effect_t effect, eparam_t param, const void *val,
|
||||
size_t size);
|
||||
EXPORT void effect_setdefault(effect_t effect, eparam_t param);
|
||||
|
||||
@@ -498,9 +496,9 @@ EXPORT void gs_viewport_push(void);
|
||||
EXPORT void gs_viewport_pop(void);
|
||||
|
||||
EXPORT void texture_setimage(texture_t tex, const void *data,
|
||||
uint32_t byte_width);
|
||||
uint32_t row_bytes, bool invert);
|
||||
EXPORT void cubetexture_setimage(texture_t cubetex, uint32_t side,
|
||||
const void *data, uint32_t byte_width);
|
||||
const void *data, uint32_t row_bytes, bool invert);
|
||||
|
||||
EXPORT void gs_perspective(float fovy, float aspect, float znear, float zfar);
|
||||
|
||||
@@ -623,7 +621,7 @@ EXPORT void texture_destroy(texture_t tex);
|
||||
EXPORT uint32_t texture_getwidth(texture_t tex);
|
||||
EXPORT uint32_t texture_getheight(texture_t tex);
|
||||
EXPORT enum gs_color_format texture_getcolorformat(texture_t tex);
|
||||
EXPORT bool texture_map(texture_t tex, void **ptr, uint32_t *byte_width);
|
||||
EXPORT bool texture_map(texture_t tex, void **ptr, uint32_t *row_bytes);
|
||||
EXPORT void texture_unmap(texture_t tex);
|
||||
|
||||
EXPORT void cubetexture_destroy(texture_t cubetex);
|
||||
@@ -641,7 +639,7 @@ EXPORT uint32_t stagesurface_getwidth(stagesurf_t stagesurf);
|
||||
EXPORT uint32_t stagesurface_getheight(stagesurf_t stagesurf);
|
||||
EXPORT enum gs_color_format stagesurface_getcolorformat(stagesurf_t stagesurf);
|
||||
EXPORT bool stagesurface_map(stagesurf_t stagesurf, const void **data,
|
||||
uint32_t *byte_width);
|
||||
uint32_t *row_bytes);
|
||||
EXPORT void stagesurface_unmap(stagesurf_t stagesurf);
|
||||
|
||||
EXPORT void zstencil_destroy(zstencil_t zstencil);
|
||||
|
@@ -34,6 +34,7 @@ SRCFILES=util/bmem.c \
|
||||
media-io/video-io.c \
|
||||
media-io/audio-io.c \
|
||||
media-io/media-io.c \
|
||||
media-io/format-conversion.c \
|
||||
obs-module.c \
|
||||
obs-output.c \
|
||||
obs-source.c \
|
||||
|
@@ -34,18 +34,27 @@ typedef struct video_output *video_t;
|
||||
|
||||
enum video_type {
|
||||
VIDEO_FORMAT_UNKNOWN,
|
||||
VIDEO_FORMAT_YUV444,
|
||||
VIDEO_FORMAT_YUV422,
|
||||
VIDEO_FORMAT_YUV420,
|
||||
|
||||
/* planar 420 format */
|
||||
VIDEO_FORMAT_I420, /* planar 4:2:0 */
|
||||
VIDEO_FORMAT_NV12, /* two-plane lum and packed chroma */
|
||||
|
||||
/* packed 422 formats */
|
||||
VIDEO_FORMAT_YVYU,
|
||||
VIDEO_FORMAT_YUY2, /* YUYV */
|
||||
VIDEO_FORMAT_UYVY,
|
||||
|
||||
/* packed uncompressed formats */
|
||||
VIDEO_FORMAT_UYVX, /* packed UYV */
|
||||
VIDEO_FORMAT_RGBA,
|
||||
VIDEO_FORMAT_BGRA,
|
||||
VIDEO_FORMAT_BGRX,
|
||||
};
|
||||
|
||||
struct video_frame {
|
||||
const void *data;
|
||||
uint32_t row_size;
|
||||
uint64_t timestamp;
|
||||
const void *data;
|
||||
uint32_t row_size; /* for RGB/BGR formats and UYVX */
|
||||
uint64_t timestamp;
|
||||
};
|
||||
|
||||
struct video_info {
|
||||
|
@@ -55,6 +55,7 @@ struct obs_data {
|
||||
/* graphics */
|
||||
graphics_t graphics;
|
||||
stagesurf_t copy_surfaces[NUM_TEXTURES];
|
||||
effect_t default_effect;
|
||||
bool textures_copied[NUM_TEXTURES];
|
||||
bool copy_mapped;
|
||||
int cur_texture;
|
||||
|
@@ -179,12 +179,14 @@ void obs_source_destroy(obs_source_t source)
|
||||
texture_destroy(source->output_texture);
|
||||
gs_leavecontext();
|
||||
|
||||
da_free(source->filters);
|
||||
if (source->data)
|
||||
source->callbacks.destroy(source->data);
|
||||
|
||||
audio_line_destroy(source->audio_line);
|
||||
|
||||
da_free(source->video_frames);
|
||||
da_free(source->audio_buffer);
|
||||
da_free(source->filters);
|
||||
pthread_mutex_destroy(&source->filter_mutex);
|
||||
pthread_mutex_destroy(&source->audio_mutex);
|
||||
pthread_mutex_destroy(&source->video_mutex);
|
||||
@@ -278,6 +280,51 @@ static void obs_source_flush_audio_buffer(obs_source_t source)
|
||||
pthread_mutex_unlock(&source->audio_mutex);
|
||||
}
|
||||
|
||||
static bool set_texture_size(obs_source_t source, struct source_frame *frame)
|
||||
{
|
||||
if (source->output_texture) {
|
||||
uint32_t width = texture_getwidth(source->output_texture);
|
||||
uint32_t height = texture_getheight(source->output_texture);
|
||||
|
||||
if (width == frame->width && height == frame->height)
|
||||
return true;
|
||||
}
|
||||
|
||||
texture_destroy(source->output_texture);
|
||||
source->output_texture = gs_create_texture(frame->width, frame->height,
|
||||
GS_RGBA, 1, NULL, GS_DYNAMIC);
|
||||
|
||||
return source->output_texture != NULL;
|
||||
}
|
||||
|
||||
static void obs_source_draw_texture(texture_t tex, struct source_frame *frame)
|
||||
{
|
||||
effect_t effect = obs->default_effect;
|
||||
const char *type = frame->yuv ? "DrawYUVToRGB" : "DrawRGB";
|
||||
technique_t tech;
|
||||
eparam_t param;
|
||||
|
||||
texture_setimage(tex, frame->data, frame->row_bytes, frame->flip);
|
||||
|
||||
tech = effect_gettechnique(effect, type);
|
||||
technique_begin(tech);
|
||||
technique_beginpass(tech, 0);
|
||||
|
||||
if (frame->yuv) {
|
||||
param = effect_getparambyname(effect, "yuv_matrix");
|
||||
effect_setval(effect, param, frame->yuv_matrix,
|
||||
sizeof(float) * 16);
|
||||
}
|
||||
|
||||
param = effect_getparambyname(effect, "diffuse");
|
||||
effect_settexture(effect, param, tex);
|
||||
|
||||
gs_draw_sprite(tex);
|
||||
|
||||
technique_endpass(tech);
|
||||
technique_end(tech);
|
||||
}
|
||||
|
||||
static void obs_source_render_async_video(obs_source_t source)
|
||||
{
|
||||
struct source_frame *frame = obs_source_getframe(source);
|
||||
@@ -288,9 +335,8 @@ static void obs_source_render_async_video(obs_source_t source)
|
||||
if (!source->timing_set && source->audio_buffer.num)
|
||||
obs_source_flush_audio_buffer(source);
|
||||
|
||||
if (!source->output_texture) {
|
||||
/* TODO */
|
||||
}
|
||||
if (set_texture_size(source, frame))
|
||||
obs_source_draw_texture(source->output_texture, frame);
|
||||
|
||||
obs_source_releaseframe(source, frame);
|
||||
}
|
||||
@@ -469,7 +515,7 @@ static inline struct filter_frame *filter_async_video(obs_source_t source,
|
||||
static struct filter_frame *process_video(obs_source_t source,
|
||||
const struct source_video *frame)
|
||||
{
|
||||
/* TODO: convert to YUV444 or RGB */
|
||||
/* TODO: convert to UYV444 or RGB */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
12
libobs/obs.c
12
libobs/obs.c
@@ -25,6 +25,7 @@ static bool obs_init_graphics(const char *graphics_module,
|
||||
struct gs_init_data *graphics_data, struct video_info *vi)
|
||||
{
|
||||
int errorcode;
|
||||
bool success = true;
|
||||
size_t i;
|
||||
|
||||
errorcode = gs_create(&obs->graphics, graphics_module, graphics_data);
|
||||
@@ -41,11 +42,18 @@ static bool obs_init_graphics(const char *graphics_module,
|
||||
obs->copy_surfaces[i] = gs_create_stagesurface(vi->width,
|
||||
vi->height, graphics_data->format);
|
||||
if (!obs->copy_surfaces[i])
|
||||
return false;
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (success) {
|
||||
obs->default_effect = gs_create_effect_from_file(
|
||||
"build/data/default.effect", NULL);
|
||||
if (!obs->default_effect)
|
||||
success = false;
|
||||
}
|
||||
|
||||
gs_leavecontext();
|
||||
return true;
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool obs_init_media(struct video_info *vi, struct audio_info *ai)
|
||||
|
@@ -70,8 +70,10 @@ struct source_video {
|
||||
|
||||
enum video_type type;
|
||||
float yuv_matrix[16];
|
||||
bool flip;
|
||||
};
|
||||
|
||||
/* differs from source_video in that it's YUV444 or RGB only */
|
||||
struct source_frame {
|
||||
void *data;
|
||||
uint32_t width;
|
||||
@@ -81,6 +83,7 @@ struct source_frame {
|
||||
|
||||
bool yuv;
|
||||
float yuv_matrix[16];
|
||||
bool flip;
|
||||
};
|
||||
|
||||
static inline void source_frame_destroy(struct source_frame *frame)
|
||||
|
Reference in New Issue
Block a user