From a43e291577fe1a401dfdca46f2c4072c6d7ece12 Mon Sep 17 00:00:00 2001 From: jp9000 Date: Fri, 25 Oct 2013 10:25:28 -0700 Subject: [PATCH] fill in the texture_setimage function, fill in a few other functions, and change certain names to be a little more consistent --- build/data/effects/default.effect | 10 ++--- libobs-d3d11/d3d11-exports.h | 4 +- libobs-d3d11/d3d11-subsystem.cpp | 8 ++-- libobs-opengl/gl-exports.h | 4 +- libobs-opengl/gl-stagesurf.c | 4 +- libobs-opengl/gl-texture2d.c | 6 +-- libobs/graphics/effect.c | 6 --- libobs/graphics/graphics-internal.h | 4 +- libobs/graphics/graphics.c | 40 +++++++++++++++---- libobs/graphics/graphics.h | 12 +++--- libobs/makefile | 1 + libobs/media-io/video-io.h | 21 +++++++--- libobs/obs-data.h | 1 + libobs/obs-source.c | 56 ++++++++++++++++++++++++--- libobs/obs.c | 12 +++++- libobs/obs.h | 3 ++ vs/2010/libobs/libobs.vcxproj | 2 + vs/2010/libobs/libobs.vcxproj.filters | 20 ++++++---- 18 files changed, 154 insertions(+), 60 deletions(-) diff --git a/build/data/effects/default.effect b/build/data/effects/default.effect index fd9adafe8..e36a89e90 100644 --- a/build/data/effects/default.effect +++ b/build/data/effects/default.effect @@ -21,12 +21,12 @@ VertInOut VSDefault(VertInOut vert_in) return vert_out; } -float4 DrawRGB(VertInOut vert_in) : TARGET +float4 PSDrawRGB(VertInOut vert_in) : TARGET { return tex.Sample(def_sampler, vert_in.uv); } -float4 DrawYUVToRGB(VertInOut vert_in) : TARGET +float4 PSDrawYUVToRGB(VertInOut vert_in) : TARGET { float4 yuv = tex.Sample(def_sampler, vert_in.uv); return saturate(mul(float4(yuv.xyz, 1.0), yuv_matrix)); @@ -37,15 +37,15 @@ technique DrawRGB pass { vertex_shader = VSDefault(vert_in); - pixel_shader = DrawRGB(vert_in); + pixel_shader = PSDrawRGB(vert_in); } } -technique ConvertYUV +technique DrawYUVToRGB { pass { vertex_shader = VSDefault(vert_in); - pixel_shader = DrawYUVToRGB(vert_in); + pixel_shader = PSDrawYUVToRGB(vert_in); } } diff --git a/libobs-d3d11/d3d11-exports.h b/libobs-d3d11/d3d11-exports.h index 73625a440..6b88cce32 100644 --- a/libobs-d3d11/d3d11-exports.h +++ b/libobs-d3d11/d3d11-exports.h @@ -133,7 +133,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); @@ -151,7 +151,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); diff --git a/libobs-d3d11/d3d11-subsystem.cpp b/libobs-d3d11/d3d11-subsystem.cpp index b18461721..ecf763c3f 100644 --- a/libobs-d3d11/d3d11-subsystem.cpp +++ b/libobs-d3d11/d3d11-subsystem.cpp @@ -1438,7 +1438,7 @@ enum gs_color_format texture_getcolorformat(texture_t tex) return static_cast(tex)->format; } -bool texture_map(texture_t tex, void **ptr, uint32_t *byte_width) +bool texture_map(texture_t tex, void **ptr, uint32_t *row_bytes) { HRESULT hr; @@ -1454,7 +1454,7 @@ bool texture_map(texture_t tex, void **ptr, uint32_t *byte_width) return false; *ptr = map.pData; - *byte_width = map.RowPitch; + *row_bytes = map.RowPitch; return true; } @@ -1543,7 +1543,7 @@ 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) { D3D11_MAPPED_SUBRESOURCE map; if (FAILED(stagesurf->device->context->Map(stagesurf->texture, 0, @@ -1551,7 +1551,7 @@ bool stagesurface_map(stagesurf_t stagesurf, const void **data, return false; *data = map.pData; - *byte_width = map.RowPitch; + *row_bytes = map.RowPitch; return true; } diff --git a/libobs-opengl/gl-exports.h b/libobs-opengl/gl-exports.h index 5c4dae82a..9fc6f48ae 100644 --- a/libobs-opengl/gl-exports.h +++ b/libobs-opengl/gl-exports.h @@ -127,7 +127,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); @@ -145,7 +145,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); diff --git a/libobs-opengl/gl-stagesurf.c b/libobs-opengl/gl-stagesurf.c index 80897ea9e..f14d836c7 100644 --- a/libobs-opengl/gl-stagesurf.c +++ b/libobs-opengl/gl-stagesurf.c @@ -179,7 +179,7 @@ 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) { if (!gl_bind_buffer(GL_PIXEL_PACK_BUFFER, stagesurf->pack_buffer)) goto fail; @@ -190,7 +190,7 @@ bool stagesurface_map(stagesurf_t stagesurf, const void **data, gl_bind_buffer(GL_PIXEL_PACK_BUFFER, 0); - *byte_width = stagesurf->bytes_per_pixel * stagesurf->width; + *row_bytes = stagesurf->bytes_per_pixel * stagesurf->width; return true; fail: diff --git a/libobs-opengl/gl-texture2d.c b/libobs-opengl/gl-texture2d.c index 4c7544b40..40085f3bc 100644 --- a/libobs-opengl/gl-texture2d.c +++ b/libobs-opengl/gl-texture2d.c @@ -162,7 +162,7 @@ enum gs_color_format texture_getcolorformat(texture_t tex) return tex->format; } -bool texture_map(texture_t tex, void **ptr, uint32_t *byte_width) +bool texture_map(texture_t tex, void **ptr, uint32_t *row_bytes) { struct gs_texture_2d *tex2d = (struct gs_texture_2d*)tex; @@ -183,8 +183,8 @@ bool texture_map(texture_t tex, void **ptr, uint32_t *byte_width) gl_bind_buffer(GL_PIXEL_UNPACK_BUFFER, 0); - *byte_width = tex2d->width * gs_get_format_bpp(tex->format) / 8; - *byte_width = (*byte_width + 3) & 0xFFFFFFFC; + *row_bytes = tex2d->width * gs_get_format_bpp(tex->format) / 8; + *row_bytes = (*row_bytes + 3) & 0xFFFFFFFC; return true; fail: diff --git a/libobs/graphics/effect.c b/libobs/graphics/effect.c index 49ec03404..fbf69b7f3 100644 --- a/libobs/graphics/effect.c +++ b/libobs/graphics/effect.c @@ -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) { diff --git a/libobs/graphics/graphics-internal.h b/libobs/graphics/graphics-internal.h index ea1df7707..b6760822d 100644 --- a/libobs/graphics/graphics-internal.h +++ b/libobs/graphics/graphics-internal.h @@ -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); diff --git a/libobs/graphics/graphics.c b/libobs/graphics/graphics.c index 20c6cb2d5..3bdccab8e 100644 --- a/libobs/graphics/graphics.c +++ b/libobs/graphics/graphics.c @@ -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) diff --git a/libobs/graphics/graphics.h b/libobs/graphics/graphics.h index 84f16f5f9..c74dadff2 100644 --- a/libobs/graphics/graphics.h +++ b/libobs/graphics/graphics.h @@ -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); diff --git a/libobs/makefile b/libobs/makefile index 211bef54a..6ac9dd272 100644 --- a/libobs/makefile +++ b/libobs/makefile @@ -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 \ diff --git a/libobs/media-io/video-io.h b/libobs/media-io/video-io.h index a0694cb5a..70c5bcacd 100644 --- a/libobs/media-io/video-io.h +++ b/libobs/media-io/video-io.h @@ -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 { diff --git a/libobs/obs-data.h b/libobs/obs-data.h index dd4497267..9b0660ba7 100644 --- a/libobs/obs-data.h +++ b/libobs/obs-data.h @@ -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; diff --git a/libobs/obs-source.c b/libobs/obs-source.c index 9fd70f15e..70072d9bf 100644 --- a/libobs/obs-source.c +++ b/libobs/obs-source.c @@ -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; } diff --git a/libobs/obs.c b/libobs/obs.c index 851f9e7f5..27b1007bd 100644 --- a/libobs/obs.c +++ b/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) diff --git a/libobs/obs.h b/libobs/obs.h index 0aedf9a58..e0e69fab2 100644 --- a/libobs/obs.h +++ b/libobs/obs.h @@ -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) diff --git a/vs/2010/libobs/libobs.vcxproj b/vs/2010/libobs/libobs.vcxproj index bcc9a4efe..ac8c2d18c 100644 --- a/vs/2010/libobs/libobs.vcxproj +++ b/vs/2010/libobs/libobs.vcxproj @@ -37,6 +37,7 @@ + @@ -80,6 +81,7 @@ + diff --git a/vs/2010/libobs/libobs.vcxproj.filters b/vs/2010/libobs/libobs.vcxproj.filters index d72aed36f..c94e2775e 100644 --- a/vs/2010/libobs/libobs.vcxproj.filters +++ b/vs/2010/libobs/libobs.vcxproj.filters @@ -25,10 +25,6 @@ {c90a618f-1096-41f5-9ce5-f2f78d978983} h;hpp;hxx;hm;inl;inc;xsd - - {21a99cbb-e167-4baf-82ae-47d23dc12c7d} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - {b7228a18-6051-4cab-b53b-ff299eb969c0} h;hpp;hxx;hm;inl;inc;xsd @@ -49,6 +45,10 @@ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + {21a99cbb-e167-4baf-82ae-47d23dc12c7d} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + @@ -177,6 +177,9 @@ graphics\Header Files + + media-io\Header Files + @@ -198,13 +201,13 @@ libobs\Source Files - media-io\Soruce Files + media-io\Source Files - media-io\Soruce Files + media-io\Source Files - media-io\Soruce Files + media-io\Source Files util\Source Files @@ -290,5 +293,8 @@ graphics\Source Files + + media-io\Source Files + \ No newline at end of file