void schro_frame_print (SchroFrame *frame, const char* name) { printf ("schro_frame_print: %s\n", name); switch (SCHRO_FRAME_FORMAT_DEPTH (frame->format)) { case SCHRO_FRAME_FORMAT_DEPTH_U8: printf (" depth: U8\n"); break; case SCHRO_FRAME_FORMAT_DEPTH_S16: printf (" depth: S16\n"); break; case SCHRO_FRAME_FORMAT_DEPTH_S32: printf (" depth: S32\n"); break; default: printf (" depth: unknown\n"); break; } printf (" packed: %s\n", SCHRO_FRAME_IS_PACKED (frame->format) ? "yes": "no"); printf (" width: %i\n", frame->width); printf (" height: %i\n", frame->height); printf (" opengl: %s\n", SCHRO_FRAME_IS_OPENGL (frame) ? "yes": "no"); }
void schro_opengl_frame_setup (SchroOpenGL *opengl, SchroFrame *frame) { int i; int components; int width, height; SchroFrameFormat format; SchroOpenGLCanvasPool *canvas_pool; SchroOpenGLCanvas *canvas; SCHRO_ASSERT (frame != NULL); SCHRO_ASSERT (SCHRO_FRAME_IS_OPENGL (frame)); components = SCHRO_FRAME_IS_PACKED (frame->format) ? 1 : 3; schro_opengl_lock (opengl); canvas_pool = schro_opengl_get_canvas_pool (opengl); for (i = 0; i < components; ++i) { format = frame->components[i].format; width = frame->components[i].width; height = frame->components[i].height; SCHRO_ASSERT (frame->format == format); canvas = schro_opengl_canvas_pool_pull_or_new (canvas_pool, opengl, format, width, height); // FIXME: hack to store custom data per frame component *((SchroOpenGLCanvas **) frame->components[i].data) = canvas; } schro_opengl_unlock (opengl); }
void schro_opengl_frame_subtract (SchroFrame *dest, SchroFrame *src) { int i; SCHRO_ASSERT (dest != NULL); SCHRO_ASSERT (src != NULL); SCHRO_ASSERT (SCHRO_FRAME_IS_OPENGL (dest)); SCHRO_ASSERT (SCHRO_FRAME_IS_OPENGL (src)); for (i = 0; schro_opengl_frame_subtract_func_list[i].func; ++i) { if (schro_opengl_frame_subtract_func_list[i].dest == dest->format && schro_opengl_frame_subtract_func_list[i].src == src->format) { schro_opengl_frame_subtract_func_list[i].func (dest, src); return; } } SCHRO_ERROR ("subtraction unimplemented (%d -> %d)", src->format, dest->format); SCHRO_ASSERT (0); }
SchroFrame * schro_opengl_frame_clone_and_push (SchroOpenGL *opengl, SchroMemoryDomain *opengl_domain, SchroFrame *cpu_frame) { SchroFrame *opengl_frame; SCHRO_ASSERT (opengl_domain->flags & SCHRO_MEMORY_DOMAIN_OPENGL); SCHRO_ASSERT (!SCHRO_FRAME_IS_OPENGL (cpu_frame)); opengl_frame = schro_frame_clone (opengl_domain, cpu_frame); schro_opengl_frame_setup (opengl, opengl_frame); schro_opengl_frame_push (opengl_frame, cpu_frame); return opengl_frame; }
SchroFrame * schro_opengl_frame_clone (SchroFrame *opengl_frame) { SchroOpenGLCanvas *canvas; SCHRO_ASSERT (opengl_frame != NULL); SCHRO_ASSERT (SCHRO_FRAME_IS_OPENGL (opengl_frame)); // FIXME: hack to store custom data per frame component canvas = *((SchroOpenGLCanvas **) opengl_frame->components[0].data); SCHRO_ASSERT (canvas != NULL); return schro_opengl_frame_new (canvas->opengl, opengl_frame->domain, opengl_frame->format, opengl_frame->width, opengl_frame->height); }
void schro_opengl_frame_cleanup (SchroFrame *frame) { int i; int components; SchroOpenGL *opengl; SchroOpenGLCanvasPool *canvas_pool; SchroOpenGLCanvas *canvas; SCHRO_ASSERT (frame != NULL); SCHRO_ASSERT (SCHRO_FRAME_IS_OPENGL (frame)); components = SCHRO_FRAME_IS_PACKED (frame->format) ? 1 : 3; // FIXME: hack to store custom data per frame component canvas = *((SchroOpenGLCanvas **) frame->components[0].data); SCHRO_ASSERT (canvas != NULL); opengl = canvas->opengl; schro_opengl_lock (opengl); canvas_pool = schro_opengl_get_canvas_pool (opengl); for (i = 0; i < components; ++i) { // FIXME: hack to store custom data per frame component canvas = *((SchroOpenGLCanvas **) frame->components[i].data); SCHRO_ASSERT (canvas != NULL); SCHRO_ASSERT (canvas->opengl == opengl); schro_opengl_canvas_pool_push_or_free (canvas_pool, canvas); } schro_opengl_unlock (opengl); }
static void schro_opengl_frame_combine_with_shader (SchroFrame *dest, SchroFrame *src, int shader_index) { int i; int width, height; SchroOpenGLCanvas *dest_canvas = NULL; SchroOpenGLCanvas *src_canvas = NULL; SchroOpenGL *opengl = NULL; SchroOpenGLShader *shader_copy_u8; SchroOpenGLShader *shader_copy_s16; SchroOpenGLShader *shader_combine; SCHRO_ASSERT (dest != NULL); SCHRO_ASSERT (src != NULL); SCHRO_ASSERT (SCHRO_FRAME_IS_OPENGL (dest)); SCHRO_ASSERT (SCHRO_FRAME_IS_OPENGL (src)); // FIXME: hack to store custom data per frame component dest_canvas = *((SchroOpenGLCanvas **) dest->components[0].data); src_canvas = *((SchroOpenGLCanvas **) src->components[0].data); SCHRO_ASSERT (dest_canvas != NULL); SCHRO_ASSERT (src_canvas != NULL); SCHRO_ASSERT (dest_canvas->opengl == src_canvas->opengl); opengl = src_canvas->opengl; schro_opengl_lock (opengl); shader_copy_u8 = schro_opengl_shader_get (opengl, SCHRO_OPENGL_SHADER_COPY_U8); shader_copy_s16 = schro_opengl_shader_get (opengl, SCHRO_OPENGL_SHADER_COPY_S16); shader_combine = schro_opengl_shader_get (opengl, shader_index); SCHRO_ASSERT (shader_copy_u8); SCHRO_ASSERT (shader_copy_s16); SCHRO_ASSERT (shader_combine); for (i = 0; i < 3; ++i) { // FIXME: hack to store custom data per frame component dest_canvas = *((SchroOpenGLCanvas **) dest->components[i].data); src_canvas = *((SchroOpenGLCanvas **) src->components[i].data); SCHRO_ASSERT (dest_canvas != NULL); SCHRO_ASSERT (src_canvas != NULL); width = MIN (dest->components[i].width, src->components[i].width); height = MIN (dest->components[i].height, src->components[i].height); schro_opengl_setup_viewport (width, height); glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, dest_canvas->framebuffers[1]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, dest_canvas->texture.handles[0]); switch (SCHRO_FRAME_FORMAT_DEPTH (dest_canvas->format)) { case SCHRO_FRAME_FORMAT_DEPTH_U8: glUseProgramObjectARB (shader_copy_u8->program); glUniform1iARB (shader_copy_u8->textures[0], 0); break; case SCHRO_FRAME_FORMAT_DEPTH_S16: glUseProgramObjectARB (shader_copy_s16->program); glUniform1iARB (shader_copy_s16->textures[0], 0); break; default: SCHRO_ASSERT (0); break; } schro_opengl_render_quad (0, 0, width, height); SCHRO_OPENGL_CHECK_ERROR glFlush (); glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, dest_canvas->framebuffers[0]); glUseProgramObjectARB (shader_combine->program); //glActiveTextureARB (GL_TEXTURE0_ARB); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, dest_canvas->texture.handles[1]); glUniform1iARB (shader_combine->textures[0], 0); glActiveTextureARB (GL_TEXTURE1_ARB); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, src_canvas->texture.handles[0]); glUniform1iARB (shader_combine->textures[1], 1); glActiveTextureARB (GL_TEXTURE0_ARB); schro_opengl_render_quad (0, 0, width, height); glUseProgramObjectARB (0); SCHRO_OPENGL_CHECK_ERROR glFlush (); } #if SCHRO_OPENGL_UNBIND_TEXTURES glBindTexture (GL_TEXTURE_RECTANGLE_ARB, 0); glActiveTextureARB (GL_TEXTURE1_ARB); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, 0); glActiveTextureARB (GL_TEXTURE0_ARB); #endif glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); schro_opengl_unlock (opengl); }
void schro_opengl_upsampled_frame_upsample (SchroFrame *upsampled_frame) { int i; int width, height; SchroOpenGLCanvas *canvases[4]; SchroOpenGL *opengl; SchroOpenGLShader *shader = NULL; SCHRO_ASSERT (upsampled_frame->frames[0] != NULL); SCHRO_ASSERT (upsampled_frame->frames[1] == NULL); SCHRO_ASSERT (upsampled_frame->frames[2] == NULL); SCHRO_ASSERT (upsampled_frame->frames[3] == NULL); SCHRO_ASSERT (SCHRO_FRAME_IS_OPENGL (upsampled_frame->frames[0])); SCHRO_ASSERT (!SCHRO_FRAME_IS_PACKED (upsampled_frame->frames[0]->format)); // FIXME: hack to store custom data per frame component canvases[0] = *((SchroOpenGLCanvas **) upsampled_frame->frames[0]->components[0].data); SCHRO_ASSERT (canvases[0] != NULL); opengl = canvases[0]->opengl; schro_opengl_lock (opengl); upsampled_frame->frames[1] = schro_opengl_frame_clone (upsampled_frame->frames[0]); upsampled_frame->frames[2] = schro_opengl_frame_clone (upsampled_frame->frames[0]); upsampled_frame->frames[3] = schro_opengl_frame_clone (upsampled_frame->frames[0]); shader = schro_opengl_shader_get (opengl, SCHRO_OPENGL_SHADER_UPSAMPLE_U8); SCHRO_ASSERT (shader != NULL); glUseProgramObjectARB (shader->program); glUniform1iARB (shader->textures[0], 0); SCHRO_OPENGL_CHECK_ERROR for (i = 0; i < 3; ++i) { // FIXME: hack to store custom data per frame component canvases[0] = *((SchroOpenGLCanvas **) upsampled_frame->frames[0]->components[i].data); canvases[1] = *((SchroOpenGLCanvas **) upsampled_frame->frames[1]->components[i].data); canvases[2] = *((SchroOpenGLCanvas **) upsampled_frame->frames[2]->components[i].data); canvases[3] = *((SchroOpenGLCanvas **) upsampled_frame->frames[3]->components[i].data); SCHRO_ASSERT (canvases[0] != NULL); SCHRO_ASSERT (canvases[1] != NULL); SCHRO_ASSERT (canvases[2] != NULL); SCHRO_ASSERT (canvases[3] != NULL); SCHRO_ASSERT (canvases[0]->opengl == opengl); SCHRO_ASSERT (canvases[1]->opengl == opengl); SCHRO_ASSERT (canvases[2]->opengl == opengl); SCHRO_ASSERT (canvases[3]->opengl == opengl); width = upsampled_frame->frames[0]->components[i].width; height = upsampled_frame->frames[0]->components[i].height; SCHRO_ASSERT (width >= 2); SCHRO_ASSERT (height >= 2); SCHRO_ASSERT (width % 2 == 0); SCHRO_ASSERT (height % 2 == 0); schro_opengl_setup_viewport (width, height); /* horizontal filter 0 -> 1 */ glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, canvases[1]->framebuffers[0]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, canvases[0]->texture.handles[0]); SCHRO_OPENGL_CHECK_ERROR #define RENDER_QUAD_HORIZONTAL(_x, _quad_width) \ schro_opengl_upsampled_frame_render_quad (shader, _x, 0, _quad_width,\ height, width, height) RENDER_QUAD_HORIZONTAL (0, 1); if (width > 2) { RENDER_QUAD_HORIZONTAL (1, 1); if (width > 4) { RENDER_QUAD_HORIZONTAL (2, 1); if (width > 6) { RENDER_QUAD_HORIZONTAL (3, 1); if (width > 8) { RENDER_QUAD_HORIZONTAL (4, width - 8); } RENDER_QUAD_HORIZONTAL (width - 4, 1); } RENDER_QUAD_HORIZONTAL (width - 3, 1); } RENDER_QUAD_HORIZONTAL (width - 2, 1); } RENDER_QUAD_HORIZONTAL (width - 1, 1); #undef RENDER_QUAD_HORIZONTAL /* vertical filter 0 -> 2 */ glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, canvases[2]->framebuffers[0]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, canvases[0]->texture.handles[0]); SCHRO_OPENGL_CHECK_ERROR #define RENDER_QUAD_VERTICAL(_y, _quad_height) \ schro_opengl_upsampled_frame_render_quad (shader, 0, _y, width,\ _quad_height, width, height) RENDER_QUAD_VERTICAL (0, 1); if (height > 2) { RENDER_QUAD_VERTICAL (1, 1); if (height > 4) { RENDER_QUAD_VERTICAL (2, 1); if (height > 6) { RENDER_QUAD_VERTICAL (3, 1); if (height > 8) { RENDER_QUAD_VERTICAL (4, height - 8); } RENDER_QUAD_VERTICAL (height - 4, 1); } RENDER_QUAD_VERTICAL (height - 3, 1); } RENDER_QUAD_VERTICAL (height - 2, 1); } RENDER_QUAD_VERTICAL (height - 1, 1); #undef RENDER_QUAD_VERTICAL /* horizontal filter 2 -> 3 */ glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, canvases[3]->framebuffers[0]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, canvases[2]->texture.handles[0]); SCHRO_OPENGL_CHECK_ERROR #define RENDER_QUAD_HORIZONTAL(_x, _quad_width) \ schro_opengl_upsampled_frame_render_quad (shader, _x, 0, _quad_width,\ height, width, height) RENDER_QUAD_HORIZONTAL (0, 1); if (width > 2) { RENDER_QUAD_HORIZONTAL (1, 1); if (width > 4) { RENDER_QUAD_HORIZONTAL (2, 1); if (width > 6) { RENDER_QUAD_HORIZONTAL (3, 1); if (width > 8) { RENDER_QUAD_HORIZONTAL (4, width - 8); } RENDER_QUAD_HORIZONTAL (width - 4, 1); } RENDER_QUAD_HORIZONTAL (width - 3, 1); } RENDER_QUAD_HORIZONTAL (width - 2, 1); } RENDER_QUAD_HORIZONTAL (width - 1, 1); #undef RENDER_QUAD_HORIZONTAL } glUseProgramObjectARB (0); #if SCHRO_OPENGL_UNBIND_TEXTURES glBindTexture (GL_TEXTURE_RECTANGLE_ARB, 0); #endif glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); schro_opengl_unlock (opengl); }