static bool init_mc_source_widthout_idct(struct vl_mpeg12_decoder *dec, const struct format_config* format_config) { enum pipe_format formats[3]; struct pipe_video_buffer templat; formats[0] = formats[1] = formats[2] = format_config->mc_source_format; memset(&templat, 0, sizeof(templat)); templat.width = dec->base.width; templat.height = dec->base.height; templat.chroma_format = dec->base.chroma_format; dec->mc_source = vl_video_buffer_create_ex ( dec->base.context, &templat, formats, 1, PIPE_USAGE_STATIC ); return dec->mc_source != NULL; }
struct pipe_video_buffer * vl_video_buffer_create(struct pipe_context *pipe, const struct pipe_video_buffer *tmpl) { const enum pipe_format *resource_formats; struct pipe_video_buffer templat, *result; bool pot_buffers; assert(pipe); assert(tmpl->width > 0 && tmpl->height > 0); pot_buffers = !pipe->screen->get_video_param ( pipe->screen, PIPE_VIDEO_PROFILE_UNKNOWN, PIPE_VIDEO_CAP_NPOT_TEXTURES ); resource_formats = vl_video_buffer_formats(pipe->screen, tmpl->buffer_format); if (!resource_formats) return NULL; templat = *tmpl; templat.width = pot_buffers ? util_next_power_of_two(tmpl->width) : align(tmpl->width, VL_MACROBLOCK_WIDTH); templat.height = pot_buffers ? util_next_power_of_two(tmpl->height) : align(tmpl->height, VL_MACROBLOCK_HEIGHT); if (tmpl->interlaced) templat.height /= 2; result = vl_video_buffer_create_ex ( pipe, &templat, resource_formats, 1, tmpl->interlaced ? 2 : 1, PIPE_USAGE_STATIC ); if (result && tmpl->interlaced) result->height *= 2; return result; }
struct pipe_video_buffer * vl_video_buffer_create(struct pipe_context *pipe, enum pipe_format buffer_format, enum pipe_video_chroma_format chroma_format, unsigned width, unsigned height) { const enum pipe_format *resource_formats; struct pipe_video_buffer *result; unsigned buffer_width, buffer_height; bool pot_buffers; assert(pipe); assert(width > 0 && height > 0); pot_buffers = !pipe->screen->get_video_param ( pipe->screen, PIPE_VIDEO_PROFILE_UNKNOWN, PIPE_VIDEO_CAP_NPOT_TEXTURES ); resource_formats = vl_video_buffer_formats(pipe->screen, buffer_format); if (!resource_formats) return NULL; buffer_width = pot_buffers ? util_next_power_of_two(width) : align(width, MACROBLOCK_WIDTH); buffer_height = pot_buffers ? util_next_power_of_two(height) : align(height, MACROBLOCK_HEIGHT); result = vl_video_buffer_create_ex ( pipe, buffer_width, buffer_height, 1, chroma_format, resource_formats, PIPE_USAGE_STATIC ); if (result) result->buffer_format = buffer_format; return result; }
static bool init_idct(struct vl_mpeg12_decoder *dec, const struct format_config* format_config) { unsigned nr_of_idct_render_targets, max_inst; enum pipe_format formats[3]; struct pipe_video_buffer templat; struct pipe_sampler_view *matrix = NULL; nr_of_idct_render_targets = dec->base.context->screen->get_param ( dec->base.context->screen, PIPE_CAP_MAX_RENDER_TARGETS ); max_inst = dec->base.context->screen->get_shader_param ( dec->base.context->screen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_INSTRUCTIONS ); // Just assume we need 32 inst per render target, not 100% true, but should work in most cases if (nr_of_idct_render_targets >= 4 && max_inst >= 32*4) // more than 4 render targets usually doesn't makes any seens nr_of_idct_render_targets = 4; else nr_of_idct_render_targets = 1; formats[0] = formats[1] = formats[2] = format_config->idct_source_format; memset(&templat, 0, sizeof(templat)); templat.width = dec->base.width / 4; templat.height = dec->base.height; templat.chroma_format = dec->base.chroma_format; dec->idct_source = vl_video_buffer_create_ex ( dec->base.context, &templat, formats, 1, PIPE_USAGE_STATIC ); if (!dec->idct_source) goto error_idct_source; formats[0] = formats[1] = formats[2] = format_config->mc_source_format; memset(&templat, 0, sizeof(templat)); templat.width = dec->base.width / nr_of_idct_render_targets; templat.height = dec->base.height / 4; templat.chroma_format = dec->base.chroma_format; dec->mc_source = vl_video_buffer_create_ex ( dec->base.context, &templat, formats, nr_of_idct_render_targets, PIPE_USAGE_STATIC ); if (!dec->mc_source) goto error_mc_source; if (!(matrix = vl_idct_upload_matrix(dec->base.context, format_config->idct_scale))) goto error_matrix; if (!vl_idct_init(&dec->idct_y, dec->base.context, dec->base.width, dec->base.height, nr_of_idct_render_targets, matrix, matrix)) goto error_y; if(!vl_idct_init(&dec->idct_c, dec->base.context, dec->chroma_width, dec->chroma_height, nr_of_idct_render_targets, matrix, matrix)) goto error_c; pipe_sampler_view_reference(&matrix, NULL); return true; error_c: vl_idct_cleanup(&dec->idct_y); error_y: pipe_sampler_view_reference(&matrix, NULL); error_matrix: dec->mc_source->destroy(dec->mc_source); error_mc_source: dec->idct_source->destroy(dec->idct_source); error_idct_source: return false; }