bool vl_compositor_init(struct vl_compositor *c, struct pipe_context *pipe) { assert(c); memset(c, 0, sizeof(*c)); c->pipe = pipe; if (!init_pipe_state(c)) return false; if (!init_shaders(c)) { cleanup_pipe_state(c); return false; } if (!init_buffers(c)) { cleanup_shaders(c); cleanup_pipe_state(c); return false; } return true; }
bool vl_compositor_init(struct vl_compositor *c, struct pipe_context *pipe) { assert(c); memset(c, 0, sizeof(*c)); c->pipe = pipe; c->upload = u_upload_create(pipe, 128 * 1024, 4, PIPE_BIND_VERTEX_BUFFER); if (!c->upload) return false; if (!init_pipe_state(c)) { u_upload_destroy(c->upload); return false; } if (!init_shaders(c)) { u_upload_destroy(c->upload); cleanup_pipe_state(c); return false; } if (!init_buffers(c)) { u_upload_destroy(c->upload); cleanup_shaders(c); cleanup_pipe_state(c); return false; } return true; }
bool vl_mc_init(struct vl_mc *renderer, struct pipe_context *pipe, unsigned buffer_width, unsigned buffer_height, unsigned macroblock_size, float scale, vl_mc_ycbcr_vert_shader vs_callback, vl_mc_ycbcr_frag_shader fs_callback, void *callback_priv) { assert(renderer); assert(pipe); memset(renderer, 0, sizeof(struct vl_mc)); renderer->pipe = pipe; renderer->buffer_width = buffer_width; renderer->buffer_height = buffer_height; renderer->macroblock_size = macroblock_size; if (!init_pipe_state(renderer)) goto error_pipe_state; renderer->vs_ref = create_ref_vert_shader(renderer); if (!renderer->vs_ref) goto error_vs_ref; renderer->vs_ycbcr = create_ycbcr_vert_shader(renderer, vs_callback, callback_priv); if (!renderer->vs_ycbcr) goto error_vs_ycbcr; renderer->fs_ref = create_ref_frag_shader(renderer); if (!renderer->fs_ref) goto error_fs_ref; renderer->fs_ycbcr = create_ycbcr_frag_shader(renderer, scale, false, fs_callback, callback_priv); if (!renderer->fs_ycbcr) goto error_fs_ycbcr; renderer->fs_ycbcr_sub = create_ycbcr_frag_shader(renderer, scale, true, fs_callback, callback_priv); if (!renderer->fs_ycbcr_sub) goto error_fs_ycbcr_sub; return true; error_fs_ycbcr_sub: renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ycbcr); error_fs_ycbcr: renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ref); error_fs_ref: renderer->pipe->delete_vs_state(renderer->pipe, renderer->vs_ycbcr); error_vs_ycbcr: renderer->pipe->delete_vs_state(renderer->pipe, renderer->vs_ref); error_vs_ref: cleanup_pipe_state(renderer); error_pipe_state: return false; }
struct pipe_video_decoder * vl_create_mpeg12_decoder(struct pipe_context *context, enum pipe_video_profile profile, enum pipe_video_entrypoint entrypoint, enum pipe_video_chroma_format chroma_format, unsigned width, unsigned height, unsigned max_references, bool expect_chunked_decode) { const unsigned block_size_pixels = VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT; const struct format_config *format_config; struct vl_mpeg12_decoder *dec; assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12); dec = CALLOC_STRUCT(vl_mpeg12_decoder); if (!dec) return NULL; dec->base.context = context; dec->base.profile = profile; dec->base.entrypoint = entrypoint; dec->base.chroma_format = chroma_format; dec->base.width = width; dec->base.height = height; dec->base.max_references = max_references; dec->base.destroy = vl_mpeg12_destroy; dec->base.begin_frame = vl_mpeg12_begin_frame; dec->base.decode_macroblock = vl_mpeg12_decode_macroblock; dec->base.decode_bitstream = vl_mpeg12_decode_bitstream; dec->base.end_frame = vl_mpeg12_end_frame; dec->base.flush = vl_mpeg12_flush; dec->blocks_per_line = MAX2(util_next_power_of_two(dec->base.width) / block_size_pixels, 4); dec->num_blocks = (dec->base.width * dec->base.height) / block_size_pixels; dec->width_in_macroblocks = align(dec->base.width, VL_MACROBLOCK_WIDTH) / VL_MACROBLOCK_WIDTH; dec->expect_chunked_decode = expect_chunked_decode; /* TODO: Implement 422, 444 */ assert(dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420); if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) { dec->chroma_width = dec->base.width / 2; dec->chroma_height = dec->base.height / 2; dec->num_blocks = dec->num_blocks * 2; } else if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) { dec->chroma_width = dec->base.width; dec->chroma_height = dec->base.height / 2; dec->num_blocks = dec->num_blocks * 2 + dec->num_blocks; } else { dec->chroma_width = dec->base.width; dec->chroma_height = dec->base.height; dec->num_blocks = dec->num_blocks * 3; } dec->quads = vl_vb_upload_quads(dec->base.context); dec->pos = vl_vb_upload_pos( dec->base.context, dec->base.width / VL_MACROBLOCK_WIDTH, dec->base.height / VL_MACROBLOCK_HEIGHT ); dec->ves_ycbcr = vl_vb_get_ves_ycbcr(dec->base.context); dec->ves_mv = vl_vb_get_ves_mv(dec->base.context); switch (entrypoint) { case PIPE_VIDEO_ENTRYPOINT_BITSTREAM: format_config = find_format_config(dec, bitstream_format_config, num_bitstream_format_configs); break; case PIPE_VIDEO_ENTRYPOINT_IDCT: format_config = find_format_config(dec, idct_format_config, num_idct_format_configs); break; case PIPE_VIDEO_ENTRYPOINT_MC: format_config = find_format_config(dec, mc_format_config, num_mc_format_configs); break; default: assert(0); FREE(dec); return NULL; } if (!format_config) { FREE(dec); return NULL; } if (!init_zscan(dec, format_config)) goto error_zscan; if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { if (!init_idct(dec, format_config)) goto error_sources; } else { if (!init_mc_source_widthout_idct(dec, format_config)) goto error_sources; } if (!vl_mc_init(&dec->mc_y, dec->base.context, dec->base.width, dec->base.height, VL_MACROBLOCK_HEIGHT, format_config->mc_scale, mc_vert_shader_callback, mc_frag_shader_callback, dec)) goto error_mc_y; // TODO if (!vl_mc_init(&dec->mc_c, dec->base.context, dec->base.width, dec->base.height, VL_BLOCK_HEIGHT, format_config->mc_scale, mc_vert_shader_callback, mc_frag_shader_callback, dec)) goto error_mc_c; if (!init_pipe_state(dec)) goto error_pipe_state; return &dec->base; error_pipe_state: vl_mc_cleanup(&dec->mc_c); error_mc_c: vl_mc_cleanup(&dec->mc_y); error_mc_y: if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { vl_idct_cleanup(&dec->idct_y); vl_idct_cleanup(&dec->idct_c); dec->idct_source->destroy(dec->idct_source); } dec->mc_source->destroy(dec->mc_source); error_sources: vl_zscan_cleanup(&dec->zscan_y); vl_zscan_cleanup(&dec->zscan_c); error_zscan: FREE(dec); return NULL; }