vl_mpeg12_decoder.c revision 311eb749a1ab7ffd417bc456345d63eba75e3fec
1d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König/**************************************************************************
2d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König *
3d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * Copyright 2009 Younes Manton.
4d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * All Rights Reserved.
5d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König *
6d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * Permission is hereby granted, free of charge, to any person obtaining a
7d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * copy of this software and associated documentation files (the
8d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * "Software"), to deal in the Software without restriction, including
9d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * without limitation the rights to use, copy, modify, merge, publish,
10d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * distribute, sub license, and/or sell copies of the Software, and to
11d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * permit persons to whom the Software is furnished to do so, subject to
12d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * the following conditions:
13d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König *
14d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * The above copyright notice and this permission notice (including the
15d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * next paragraph) shall be included in all copies or substantial portions
16d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * of the Software.
17d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König *
18d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König *
26d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König **************************************************************************/
27d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
28fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König#include <math.h>
29fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König#include <assert.h>
30d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
31d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König#include <util/u_memory.h>
32d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König#include <util/u_rect.h>
33d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König#include <util/u_video.h>
34d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
35d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König#include "vl_mpeg12_decoder.h"
36d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König#include "vl_defines.h"
37d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
38ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian König#define SCALE_FACTOR_SNORM (32768.0f / 256.0f)
39ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian König#define SCALE_FACTOR_SSCALED (1.0f / 256.0f)
40fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König
41311eb749a1ab7ffd417bc456345d63eba75e3fecChristian Königstruct format_config {
42311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   enum pipe_format zscan_source_format;
43311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   enum pipe_format idct_source_format;
44311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   enum pipe_format mc_source_format;
45f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
46311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   float idct_scale;
47311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   float mc_scale;
48311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König};
49f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
50311eb749a1ab7ffd417bc456345d63eba75e3fecChristian Königstatic const struct format_config bitstream_format_config[] = {
51311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SSCALED },
52311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, 1.0f, SCALE_FACTOR_SSCALED },
53311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SNORM },
54311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, 1.0f, SCALE_FACTOR_SNORM }
55bad3085c7839de734f6b883088f91ae55db61a35Christian König};
56bad3085c7839de734f6b883088f91ae55db61a35Christian König
57311eb749a1ab7ffd417bc456345d63eba75e3fecChristian Königstatic const unsigned num_bitstream_format_configs =
58311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   sizeof(bitstream_format_config) / sizeof(struct format_config);
59bad3085c7839de734f6b883088f91ae55db61a35Christian König
60311eb749a1ab7ffd417bc456345d63eba75e3fecChristian Königstatic const struct format_config idct_format_config[] = {
61311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SSCALED },
62311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, 1.0f, SCALE_FACTOR_SSCALED },
63311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SNORM },
64311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, 1.0f, SCALE_FACTOR_SNORM }
65bad3085c7839de734f6b883088f91ae55db61a35Christian König};
66bad3085c7839de734f6b883088f91ae55db61a35Christian König
67311eb749a1ab7ffd417bc456345d63eba75e3fecChristian Königstatic const unsigned num_idct_format_configs =
68311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   sizeof(idct_format_config) / sizeof(struct format_config);
69bad3085c7839de734f6b883088f91ae55db61a35Christian König
70311eb749a1ab7ffd417bc456345d63eba75e3fecChristian Königstatic const struct format_config mc_format_config[] = {
71311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   //{ PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_NONE, PIPE_FORMAT_R16_SSCALED, 0.0f, SCALE_FACTOR_SSCALED },
72311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_NONE, PIPE_FORMAT_R16_SNORM, 0.0f, SCALE_FACTOR_SNORM }
73bad3085c7839de734f6b883088f91ae55db61a35Christian König};
74bad3085c7839de734f6b883088f91ae55db61a35Christian König
75311eb749a1ab7ffd417bc456345d63eba75e3fecChristian Königstatic const unsigned num_mc_format_configs =
76311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   sizeof(mc_format_config) / sizeof(struct format_config);
77bad3085c7839de734f6b883088f91ae55db61a35Christian König
78f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königstatic bool
79f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königinit_zscan_buffer(struct vl_mpeg12_buffer *buffer)
80f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König{
81f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   enum pipe_format formats[3];
82f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
83f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   struct pipe_sampler_view **source;
84f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   struct pipe_surface **destination;
85f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
86f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   struct vl_mpeg12_decoder *dec;
87f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
88f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   unsigned i;
89f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
90f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   assert(buffer);
91f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
92f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   dec = (struct vl_mpeg12_decoder*)buffer->base.decoder;
93f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
94f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   formats[0] = formats[1] = formats[2] = dec->zscan_source_format;
95f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   buffer->zscan_source = vl_video_buffer_init(dec->base.context, dec->pipe,
96f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König                                               dec->blocks_per_line * BLOCK_WIDTH * BLOCK_HEIGHT,
97f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König                                               dec->max_blocks / dec->blocks_per_line,
98f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König                                               1, PIPE_VIDEO_CHROMA_FORMAT_444,
99f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König                                               formats, PIPE_USAGE_STATIC);
100f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   if (!buffer->zscan_source)
101f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      goto error_source;
102f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
1033ea7e2713c836f23d59c4034385609e371a94c8dChristian König   source = buffer->zscan_source->get_sampler_view_planes(buffer->zscan_source);
104f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   if (!source)
105f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      goto error_sampler;
106f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
107f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
1080121aae967d3d1366cccc8946cf89ad22818365eChristian König      destination = dec->idct_source->get_surfaces(dec->idct_source);
109f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   else
1100121aae967d3d1366cccc8946cf89ad22818365eChristian König      destination = dec->mc_source->get_surfaces(dec->mc_source);
111f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
112f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   if (!destination)
113f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      goto error_surface;
114f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
115f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   for (i = 0; i < VL_MAX_PLANES; ++i)
116f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      if (!vl_zscan_init_buffer(i == 0 ? &dec->zscan_y : &dec->zscan_c,
117f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König                                &buffer->zscan[i], source[i], destination[i]))
118f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König         goto error_plane;
119f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
120f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   return true;
121f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
122f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königerror_plane:
123f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   for (; i > 0; --i)
124f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      vl_zscan_cleanup_buffer(&buffer->zscan[i - 1]);
125f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
126f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königerror_surface:
127f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königerror_sampler:
128f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   buffer->zscan_source->destroy(buffer->zscan_source);
129f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
130f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königerror_source:
131f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   return false;
132f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König}
133f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
134f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königstatic void
135f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königcleanup_zscan_buffer(struct vl_mpeg12_buffer *buffer)
136f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König{
137f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   unsigned i;
138f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
139f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   assert(buffer);
140f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
141f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   for (i = 0; i < VL_MAX_PLANES; ++i)
142f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      vl_zscan_cleanup_buffer(&buffer->zscan[i]);
143f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   buffer->zscan_source->destroy(buffer->zscan_source);
144f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König}
145f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
146f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königstatic bool
147f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königinit_idct_buffer(struct vl_mpeg12_buffer *buffer)
148f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König{
1497f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   struct pipe_sampler_view **idct_source_sv, **mc_source_sv;
150f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   struct pipe_surface **idct_surfaces;
151f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
152f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   struct vl_mpeg12_decoder *dec;
153f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
154f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   unsigned i;
155f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
156f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   assert(buffer);
157f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
158f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   dec = (struct vl_mpeg12_decoder*)buffer->base.decoder;
159f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
1600121aae967d3d1366cccc8946cf89ad22818365eChristian König   idct_source_sv = dec->idct_source->get_sampler_view_planes(dec->idct_source);
161f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   if (!idct_source_sv)
162f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      goto error_source_sv;
163f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
1640121aae967d3d1366cccc8946cf89ad22818365eChristian König   mc_source_sv = dec->mc_source->get_sampler_view_planes(dec->mc_source);
1657f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   if (!mc_source_sv)
1667f04fe5338d0846ec9a6003033da5357d2785c8bChristian König      goto error_mc_source_sv;
167f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
1680121aae967d3d1366cccc8946cf89ad22818365eChristian König   idct_surfaces = dec->mc_source->get_surfaces(dec->mc_source);
169f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   if (!idct_surfaces)
170f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      goto error_surfaces;
171f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
172f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   for (i = 0; i < 3; ++i)
173f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      if (!vl_idct_init_buffer(i == 0 ? &dec->idct_y : &dec->idct_c,
174f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König                               &buffer->idct[i], idct_source_sv[i],
1757f04fe5338d0846ec9a6003033da5357d2785c8bChristian König                               mc_source_sv[i], idct_surfaces[i]))
176f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König         goto error_plane;
177f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
178f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   return true;
179f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
180f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königerror_plane:
181f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   for (; i > 0; --i)
182f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      vl_idct_cleanup_buffer(i == 1 ? &dec->idct_c : &dec->idct_y, &buffer->idct[i - 1]);
183f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
184f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königerror_surfaces:
1857f04fe5338d0846ec9a6003033da5357d2785c8bChristian Königerror_mc_source_sv:
186f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königerror_source_sv:
187f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   return false;
188f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König}
189f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
1909d2e630cd02362bfa8f090640a55cf2dea9d64b3Christian Königstatic void
191ad4ed0e7f642a536618be183b293286fff1b206bChristian Königcleanup_idct_buffer(struct vl_mpeg12_buffer *buf)
192ad4ed0e7f642a536618be183b293286fff1b206bChristian König{
193ad4ed0e7f642a536618be183b293286fff1b206bChristian König   struct vl_mpeg12_decoder *dec;
194ad4ed0e7f642a536618be183b293286fff1b206bChristian König   assert(buf);
195ad4ed0e7f642a536618be183b293286fff1b206bChristian König
196ad4ed0e7f642a536618be183b293286fff1b206bChristian König   dec = (struct vl_mpeg12_decoder*)buf->base.decoder;
197ad4ed0e7f642a536618be183b293286fff1b206bChristian König   assert(dec);
198ad4ed0e7f642a536618be183b293286fff1b206bChristian König
199ad4ed0e7f642a536618be183b293286fff1b206bChristian König   vl_idct_cleanup_buffer(&dec->idct_y, &buf->idct[0]);
200ad4ed0e7f642a536618be183b293286fff1b206bChristian König   vl_idct_cleanup_buffer(&dec->idct_c, &buf->idct[1]);
201ad4ed0e7f642a536618be183b293286fff1b206bChristian König   vl_idct_cleanup_buffer(&dec->idct_c, &buf->idct[2]);
202ad4ed0e7f642a536618be183b293286fff1b206bChristian König}
203ad4ed0e7f642a536618be183b293286fff1b206bChristian König
20424d76d2966a5c666c9627034e6751621b17024c8Christian Königstatic bool
20524d76d2966a5c666c9627034e6751621b17024c8Christian Königinit_mc_buffer(struct vl_mpeg12_buffer *buf)
20624d76d2966a5c666c9627034e6751621b17024c8Christian König{
20724d76d2966a5c666c9627034e6751621b17024c8Christian König   struct vl_mpeg12_decoder *dec;
20824d76d2966a5c666c9627034e6751621b17024c8Christian König
20924d76d2966a5c666c9627034e6751621b17024c8Christian König   assert(buf);
21024d76d2966a5c666c9627034e6751621b17024c8Christian König
21124d76d2966a5c666c9627034e6751621b17024c8Christian König   dec = (struct vl_mpeg12_decoder*)buf->base.decoder;
21224d76d2966a5c666c9627034e6751621b17024c8Christian König   assert(dec);
21324d76d2966a5c666c9627034e6751621b17024c8Christian König
2143ea7e2713c836f23d59c4034385609e371a94c8dChristian König   if(!vl_mc_init_buffer(&dec->mc_y, &buf->mc[0]))
21524d76d2966a5c666c9627034e6751621b17024c8Christian König      goto error_mc_y;
21624d76d2966a5c666c9627034e6751621b17024c8Christian König
2173ea7e2713c836f23d59c4034385609e371a94c8dChristian König   if(!vl_mc_init_buffer(&dec->mc_c, &buf->mc[1]))
21824d76d2966a5c666c9627034e6751621b17024c8Christian König      goto error_mc_cb;
21924d76d2966a5c666c9627034e6751621b17024c8Christian König
2203ea7e2713c836f23d59c4034385609e371a94c8dChristian König   if(!vl_mc_init_buffer(&dec->mc_c, &buf->mc[2]))
22124d76d2966a5c666c9627034e6751621b17024c8Christian König      goto error_mc_cr;
22224d76d2966a5c666c9627034e6751621b17024c8Christian König
22324d76d2966a5c666c9627034e6751621b17024c8Christian König   return true;
22424d76d2966a5c666c9627034e6751621b17024c8Christian König
22524d76d2966a5c666c9627034e6751621b17024c8Christian Königerror_mc_cr:
22624d76d2966a5c666c9627034e6751621b17024c8Christian König   vl_mc_cleanup_buffer(&buf->mc[1]);
22724d76d2966a5c666c9627034e6751621b17024c8Christian König
22824d76d2966a5c666c9627034e6751621b17024c8Christian Königerror_mc_cb:
22924d76d2966a5c666c9627034e6751621b17024c8Christian König   vl_mc_cleanup_buffer(&buf->mc[0]);
23024d76d2966a5c666c9627034e6751621b17024c8Christian König
23124d76d2966a5c666c9627034e6751621b17024c8Christian Königerror_mc_y:
23224d76d2966a5c666c9627034e6751621b17024c8Christian König   return false;
23324d76d2966a5c666c9627034e6751621b17024c8Christian König}
23424d76d2966a5c666c9627034e6751621b17024c8Christian König
23524d76d2966a5c666c9627034e6751621b17024c8Christian Königstatic void
23624d76d2966a5c666c9627034e6751621b17024c8Christian Königcleanup_mc_buffer(struct vl_mpeg12_buffer *buf)
23724d76d2966a5c666c9627034e6751621b17024c8Christian König{
23824d76d2966a5c666c9627034e6751621b17024c8Christian König   unsigned i;
23924d76d2966a5c666c9627034e6751621b17024c8Christian König
24024d76d2966a5c666c9627034e6751621b17024c8Christian König   assert(buf);
24124d76d2966a5c666c9627034e6751621b17024c8Christian König
24224d76d2966a5c666c9627034e6751621b17024c8Christian König   for (i = 0; i < VL_MAX_PLANES; ++i)
24324d76d2966a5c666c9627034e6751621b17024c8Christian König      vl_mc_cleanup_buffer(&buf->mc[i]);
24424d76d2966a5c666c9627034e6751621b17024c8Christian König}
24524d76d2966a5c666c9627034e6751621b17024c8Christian König
246ad4ed0e7f642a536618be183b293286fff1b206bChristian Königstatic void
247d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königvl_mpeg12_buffer_destroy(struct pipe_video_decode_buffer *buffer)
248d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König{
249d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
250ad4ed0e7f642a536618be183b293286fff1b206bChristian König   struct vl_mpeg12_decoder *dec;
25110c49b28752f5f2d822dfb1e2e6a1ec213cc44daChristian König
252ad4ed0e7f642a536618be183b293286fff1b206bChristian König   assert(buf);
253ad4ed0e7f642a536618be183b293286fff1b206bChristian König
254ad4ed0e7f642a536618be183b293286fff1b206bChristian König   dec = (struct vl_mpeg12_decoder*)buf->base.decoder;
255ad4ed0e7f642a536618be183b293286fff1b206bChristian König   assert(dec);
256ad4ed0e7f642a536618be183b293286fff1b206bChristian König
257f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   cleanup_zscan_buffer(buf);
258f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
259ad4ed0e7f642a536618be183b293286fff1b206bChristian König   if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
260ad4ed0e7f642a536618be183b293286fff1b206bChristian König      cleanup_idct_buffer(buf);
261d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
26224d76d2966a5c666c9627034e6751621b17024c8Christian König   cleanup_mc_buffer(buf);
26324d76d2966a5c666c9627034e6751621b17024c8Christian König
264d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   vl_vb_cleanup(&buf->vertex_stream);
265d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
266d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   FREE(buf);
267d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König}
268d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
269d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königstatic void
270d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königvl_mpeg12_buffer_map(struct pipe_video_decode_buffer *buffer)
271d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König{
272d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
273d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   struct vl_mpeg12_decoder *dec;
2742e6274fc3b123e7de695038054b5cbd20b11559aChristian König
2752e6274fc3b123e7de695038054b5cbd20b11559aChristian König   struct pipe_sampler_view **sampler_views;
2762e6274fc3b123e7de695038054b5cbd20b11559aChristian König   unsigned i;
2772e6274fc3b123e7de695038054b5cbd20b11559aChristian König
278d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   assert(buf);
279d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
280d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   dec = (struct vl_mpeg12_decoder *)buf->base.decoder;
281d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   assert(dec);
282d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
283d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   vl_vb_map(&buf->vertex_stream, dec->pipe);
2842e6274fc3b123e7de695038054b5cbd20b11559aChristian König
2853ea7e2713c836f23d59c4034385609e371a94c8dChristian König   sampler_views = buf->zscan_source->get_sampler_view_planes(buf->zscan_source);
2862e6274fc3b123e7de695038054b5cbd20b11559aChristian König
2872e6274fc3b123e7de695038054b5cbd20b11559aChristian König   assert(sampler_views);
2882e6274fc3b123e7de695038054b5cbd20b11559aChristian König
2892e6274fc3b123e7de695038054b5cbd20b11559aChristian König   for (i = 0; i < VL_MAX_PLANES; ++i) {
2902e6274fc3b123e7de695038054b5cbd20b11559aChristian König      struct pipe_resource *tex = sampler_views[i]->texture;
2912e6274fc3b123e7de695038054b5cbd20b11559aChristian König      struct pipe_box rect =
2922e6274fc3b123e7de695038054b5cbd20b11559aChristian König      {
2932e6274fc3b123e7de695038054b5cbd20b11559aChristian König         0, 0, 0,
2942e6274fc3b123e7de695038054b5cbd20b11559aChristian König         tex->width0,
2952e6274fc3b123e7de695038054b5cbd20b11559aChristian König         tex->height0,
2962e6274fc3b123e7de695038054b5cbd20b11559aChristian König         1
2972e6274fc3b123e7de695038054b5cbd20b11559aChristian König      };
2982e6274fc3b123e7de695038054b5cbd20b11559aChristian König
2992e6274fc3b123e7de695038054b5cbd20b11559aChristian König      buf->tex_transfer[i] = dec->pipe->get_transfer
3002e6274fc3b123e7de695038054b5cbd20b11559aChristian König      (
3012e6274fc3b123e7de695038054b5cbd20b11559aChristian König         dec->pipe, tex,
3022e6274fc3b123e7de695038054b5cbd20b11559aChristian König         0, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
3032e6274fc3b123e7de695038054b5cbd20b11559aChristian König         &rect
3042e6274fc3b123e7de695038054b5cbd20b11559aChristian König      );
3052e6274fc3b123e7de695038054b5cbd20b11559aChristian König
3062e6274fc3b123e7de695038054b5cbd20b11559aChristian König      buf->texels[i] = dec->pipe->transfer_map(dec->pipe, buf->tex_transfer[i]);
3072e6274fc3b123e7de695038054b5cbd20b11559aChristian König   }
308c888fe027c338f337123de4da2de1ac73b0f7587Christian König
309c888fe027c338f337123de4da2de1ac73b0f7587Christian König   if (dec->base.entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM) {
310c888fe027c338f337123de4da2de1ac73b0f7587Christian König      struct pipe_ycbcr_block *ycbcr_stream[VL_MAX_PLANES];
311c888fe027c338f337123de4da2de1ac73b0f7587Christian König      struct pipe_motionvector *mv_stream[VL_MAX_REF_FRAMES];
312c888fe027c338f337123de4da2de1ac73b0f7587Christian König
313c888fe027c338f337123de4da2de1ac73b0f7587Christian König      for (i = 0; i < VL_MAX_PLANES; ++i)
314c888fe027c338f337123de4da2de1ac73b0f7587Christian König         ycbcr_stream[i] = vl_vb_get_ycbcr_stream(&buf->vertex_stream, i);
315c888fe027c338f337123de4da2de1ac73b0f7587Christian König
316c888fe027c338f337123de4da2de1ac73b0f7587Christian König      for (i = 0; i < VL_MAX_REF_FRAMES; ++i)
317c888fe027c338f337123de4da2de1ac73b0f7587Christian König         mv_stream[i] = vl_vb_get_mv_stream(&buf->vertex_stream, i);
318c888fe027c338f337123de4da2de1ac73b0f7587Christian König
319c888fe027c338f337123de4da2de1ac73b0f7587Christian König      vl_mpg12_bs_set_buffers(&buf->bs, ycbcr_stream, buf->texels, mv_stream);
3206ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   } else {
3216ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König      for (i = 0; i < VL_MAX_PLANES; ++i)
3226ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König         vl_zscan_set_layout(&buf->zscan[i], dec->zscan_linear);
323c888fe027c338f337123de4da2de1ac73b0f7587Christian König   }
324d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König}
325d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
3262e6274fc3b123e7de695038054b5cbd20b11559aChristian Königstatic struct pipe_ycbcr_block *
3272e6274fc3b123e7de695038054b5cbd20b11559aChristian Königvl_mpeg12_buffer_get_ycbcr_stream(struct pipe_video_decode_buffer *buffer, int component)
328b7acf83d523563cde613fe805bd8edaa02f64b53Christian König{
329b7acf83d523563cde613fe805bd8edaa02f64b53Christian König   struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
330b7acf83d523563cde613fe805bd8edaa02f64b53Christian König
331b7acf83d523563cde613fe805bd8edaa02f64b53Christian König   assert(buf);
332b7acf83d523563cde613fe805bd8edaa02f64b53Christian König
3332e6274fc3b123e7de695038054b5cbd20b11559aChristian König   return vl_vb_get_ycbcr_stream(&buf->vertex_stream, component);
334b7acf83d523563cde613fe805bd8edaa02f64b53Christian König}
335b7acf83d523563cde613fe805bd8edaa02f64b53Christian König
3362e6274fc3b123e7de695038054b5cbd20b11559aChristian Königstatic short *
3372e6274fc3b123e7de695038054b5cbd20b11559aChristian Königvl_mpeg12_buffer_get_ycbcr_buffer(struct pipe_video_decode_buffer *buffer, int component)
338b7acf83d523563cde613fe805bd8edaa02f64b53Christian König{
339b7acf83d523563cde613fe805bd8edaa02f64b53Christian König   struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
340b7acf83d523563cde613fe805bd8edaa02f64b53Christian König
341b7acf83d523563cde613fe805bd8edaa02f64b53Christian König   assert(buf);
3422e6274fc3b123e7de695038054b5cbd20b11559aChristian König   assert(component < VL_MAX_PLANES);
343b7acf83d523563cde613fe805bd8edaa02f64b53Christian König
3442e6274fc3b123e7de695038054b5cbd20b11559aChristian König   return buf->texels[component];
345b7acf83d523563cde613fe805bd8edaa02f64b53Christian König}
346b7acf83d523563cde613fe805bd8edaa02f64b53Christian König
3472e6274fc3b123e7de695038054b5cbd20b11559aChristian Königstatic unsigned
3482e6274fc3b123e7de695038054b5cbd20b11559aChristian Königvl_mpeg12_buffer_get_mv_stream_stride(struct pipe_video_decode_buffer *buffer)
349d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König{
350d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
351d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
352d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   assert(buf);
353d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
3542e6274fc3b123e7de695038054b5cbd20b11559aChristian König   return vl_vb_get_mv_stream_stride(&buf->vertex_stream);
3552e6274fc3b123e7de695038054b5cbd20b11559aChristian König}
356d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
3572e6274fc3b123e7de695038054b5cbd20b11559aChristian Königstatic struct pipe_motionvector *
3582e6274fc3b123e7de695038054b5cbd20b11559aChristian Königvl_mpeg12_buffer_get_mv_stream(struct pipe_video_decode_buffer *buffer, int ref_frame)
3592e6274fc3b123e7de695038054b5cbd20b11559aChristian König{
3602e6274fc3b123e7de695038054b5cbd20b11559aChristian König   struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
361d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
3622e6274fc3b123e7de695038054b5cbd20b11559aChristian König   assert(buf);
3632e6274fc3b123e7de695038054b5cbd20b11559aChristian König
3642e6274fc3b123e7de695038054b5cbd20b11559aChristian König   return vl_vb_get_mv_stream(&buf->vertex_stream, ref_frame);
365d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König}
366d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
367d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königstatic void
368c888fe027c338f337123de4da2de1ac73b0f7587Christian Königvl_mpeg12_buffer_decode_bitstream(struct pipe_video_decode_buffer *buffer,
369c888fe027c338f337123de4da2de1ac73b0f7587Christian König                                  unsigned num_bytes, const void *data,
370c888fe027c338f337123de4da2de1ac73b0f7587Christian König                                  struct pipe_mpeg12_picture_desc *picture,
371c888fe027c338f337123de4da2de1ac73b0f7587Christian König                                  unsigned num_ycbcr_blocks[3])
372c888fe027c338f337123de4da2de1ac73b0f7587Christian König{
373c888fe027c338f337123de4da2de1ac73b0f7587Christian König   struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
3746ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   struct vl_mpeg12_decoder *dec;
3756ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   unsigned i;
3766ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König
3776ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   assert(buf);
3786ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König
3796ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   dec = (struct vl_mpeg12_decoder *)buf->base.decoder;
3806ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   assert(dec);
3816ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König
3826ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   for (i = 0; i < VL_MAX_PLANES; ++i)
3836ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König      vl_zscan_set_layout(&buf->zscan[i], picture->alternate_scan ? dec->zscan_alternate : dec->zscan_normal);
384c888fe027c338f337123de4da2de1ac73b0f7587Christian König
385c888fe027c338f337123de4da2de1ac73b0f7587Christian König   vl_mpg12_bs_decode(&buf->bs, num_bytes, data, picture, num_ycbcr_blocks);
386c888fe027c338f337123de4da2de1ac73b0f7587Christian König}
387c888fe027c338f337123de4da2de1ac73b0f7587Christian König
388c888fe027c338f337123de4da2de1ac73b0f7587Christian Königstatic void
389d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königvl_mpeg12_buffer_unmap(struct pipe_video_decode_buffer *buffer)
390d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König{
391d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
392d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   struct vl_mpeg12_decoder *dec;
3932e6274fc3b123e7de695038054b5cbd20b11559aChristian König   unsigned i;
3942e6274fc3b123e7de695038054b5cbd20b11559aChristian König
395d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   assert(buf);
396d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
397d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   dec = (struct vl_mpeg12_decoder *)buf->base.decoder;
398d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   assert(dec);
399d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
400d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   vl_vb_unmap(&buf->vertex_stream, dec->pipe);
4012e6274fc3b123e7de695038054b5cbd20b11559aChristian König
4022e6274fc3b123e7de695038054b5cbd20b11559aChristian König   for (i = 0; i < VL_MAX_PLANES; ++i) {
4032e6274fc3b123e7de695038054b5cbd20b11559aChristian König      dec->pipe->transfer_unmap(dec->pipe, buf->tex_transfer[i]);
4042e6274fc3b123e7de695038054b5cbd20b11559aChristian König      dec->pipe->transfer_destroy(dec->pipe, buf->tex_transfer[i]);
4052e6274fc3b123e7de695038054b5cbd20b11559aChristian König   }
406d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König}
407d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
408d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königstatic void
409d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königvl_mpeg12_destroy(struct pipe_video_decoder *decoder)
410d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König{
411d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder*)decoder;
412d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
413d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   assert(decoder);
414d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
415d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   /* Asserted in softpipe_delete_fs_state() for some reason */
416d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   dec->pipe->bind_vs_state(dec->pipe, NULL);
417d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   dec->pipe->bind_fs_state(dec->pipe, NULL);
418d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
419d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   dec->pipe->delete_depth_stencil_alpha_state(dec->pipe, dec->dsa);
4207f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   dec->pipe->delete_sampler_state(dec->pipe, dec->sampler_ycbcr);
421d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
422ff210aea7c080600bd45eb18b29a6109468ed4dfChristian König   vl_mc_cleanup(&dec->mc_y);
423ff210aea7c080600bd45eb18b29a6109468ed4dfChristian König   vl_mc_cleanup(&dec->mc_c);
4240121aae967d3d1366cccc8946cf89ad22818365eChristian König   dec->mc_source->destroy(dec->mc_source);
425ff210aea7c080600bd45eb18b29a6109468ed4dfChristian König
426fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König   if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
427fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König      vl_idct_cleanup(&dec->idct_y);
428fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König      vl_idct_cleanup(&dec->idct_c);
4290121aae967d3d1366cccc8946cf89ad22818365eChristian König      dec->idct_source->destroy(dec->idct_source);
430fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König   }
431ff210aea7c080600bd45eb18b29a6109468ed4dfChristian König
432f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   vl_zscan_cleanup(&dec->zscan_y);
433f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   vl_zscan_cleanup(&dec->zscan_c);
434f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
435849bc838e81f930e6f090e6c6597bb92e822b4c9Christian König   dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves_ycbcr);
43638a315b7049946d124409b377e622994feccdcb7Christian König   dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves_mv);
43710c49b28752f5f2d822dfb1e2e6a1ec213cc44daChristian König
438d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   pipe_resource_reference(&dec->quads.buffer, NULL);
439b8a6e0e6fc451096d684a1e18529ab4879cdba0aChristian König   pipe_resource_reference(&dec->pos.buffer, NULL);
440d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
4416ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   pipe_sampler_view_reference(&dec->zscan_linear, NULL);
4426ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   pipe_sampler_view_reference(&dec->zscan_normal, NULL);
4436ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   pipe_sampler_view_reference(&dec->zscan_alternate, NULL);
4446ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König
445d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   FREE(dec);
446d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König}
447d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
448ad4ed0e7f642a536618be183b293286fff1b206bChristian Königstatic struct pipe_video_decode_buffer *
449ad4ed0e7f642a536618be183b293286fff1b206bChristian Königvl_mpeg12_create_buffer(struct pipe_video_decoder *decoder)
450ad4ed0e7f642a536618be183b293286fff1b206bChristian König{
451d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder*)decoder;
452d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   struct vl_mpeg12_buffer *buffer;
453d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
454d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   assert(dec);
455d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
456d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   buffer = CALLOC_STRUCT(vl_mpeg12_buffer);
457d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   if (buffer == NULL)
458d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      return NULL;
459d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
460d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   buffer->base.decoder = decoder;
461d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   buffer->base.destroy = vl_mpeg12_buffer_destroy;
462d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   buffer->base.map = vl_mpeg12_buffer_map;
4632e6274fc3b123e7de695038054b5cbd20b11559aChristian König   buffer->base.get_ycbcr_stream = vl_mpeg12_buffer_get_ycbcr_stream;
4642e6274fc3b123e7de695038054b5cbd20b11559aChristian König   buffer->base.get_ycbcr_buffer = vl_mpeg12_buffer_get_ycbcr_buffer;
465b7acf83d523563cde613fe805bd8edaa02f64b53Christian König   buffer->base.get_mv_stream_stride = vl_mpeg12_buffer_get_mv_stream_stride;
466b7acf83d523563cde613fe805bd8edaa02f64b53Christian König   buffer->base.get_mv_stream = vl_mpeg12_buffer_get_mv_stream;
467c888fe027c338f337123de4da2de1ac73b0f7587Christian König   buffer->base.decode_bitstream = vl_mpeg12_buffer_decode_bitstream;
468d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   buffer->base.unmap = vl_mpeg12_buffer_unmap;
469d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
47024d76d2966a5c666c9627034e6751621b17024c8Christian König   if (!vl_vb_init(&buffer->vertex_stream, dec->pipe,
47124d76d2966a5c666c9627034e6751621b17024c8Christian König                   dec->base.width / MACROBLOCK_WIDTH,
47224d76d2966a5c666c9627034e6751621b17024c8Christian König                   dec->base.height / MACROBLOCK_HEIGHT))
47324d76d2966a5c666c9627034e6751621b17024c8Christian König      goto error_vertex_buffer;
474d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
47524d76d2966a5c666c9627034e6751621b17024c8Christian König   if (!init_mc_buffer(buffer))
47624d76d2966a5c666c9627034e6751621b17024c8Christian König      goto error_mc;
477d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
478f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
479f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      if (!init_idct_buffer(buffer))
480f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König         goto error_idct;
481f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
482f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   if (!init_zscan_buffer(buffer))
483f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      goto error_zscan;
484f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
485c888fe027c338f337123de4da2de1ac73b0f7587Christian König   if (dec->base.entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM)
486e3789105fe3a289338821a53da499857aa924637Christian König      vl_mpg12_bs_init(&buffer->bs,
487e3789105fe3a289338821a53da499857aa924637Christian König                       dec->base.width / MACROBLOCK_WIDTH,
488e3789105fe3a289338821a53da499857aa924637Christian König                       dec->base.height / MACROBLOCK_HEIGHT);
489c888fe027c338f337123de4da2de1ac73b0f7587Christian König
490d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   return &buffer->base;
491d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
492f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königerror_zscan:
493fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König   if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
494ad4ed0e7f642a536618be183b293286fff1b206bChristian König      cleanup_idct_buffer(buffer);
495d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
496ad4ed0e7f642a536618be183b293286fff1b206bChristian Königerror_idct:
49724d76d2966a5c666c9627034e6751621b17024c8Christian König   cleanup_mc_buffer(buffer);
498fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König
49924d76d2966a5c666c9627034e6751621b17024c8Christian Königerror_mc:
500d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   vl_vb_cleanup(&buffer->vertex_stream);
501d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
50224d76d2966a5c666c9627034e6751621b17024c8Christian Königerror_vertex_buffer:
503d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   FREE(buffer);
504d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   return NULL;
505d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König}
506d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
507d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königstatic void
508d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königvl_mpeg12_decoder_flush_buffer(struct pipe_video_decode_buffer *buffer,
5092e6274fc3b123e7de695038054b5cbd20b11559aChristian König                               unsigned num_ycbcr_blocks[3],
510d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König                               struct pipe_video_buffer *refs[2],
511104ac0066394f8246d18c833bca4bcce271b5eefChristian König                               struct pipe_video_buffer *dst)
512d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König{
513d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer *)buffer;
514d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   struct vl_mpeg12_decoder *dec;
515d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
5163ea7e2713c836f23d59c4034385609e371a94c8dChristian König   struct pipe_sampler_view **sv[VL_MAX_REF_FRAMES], **mc_source_sv;
517d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   struct pipe_surface **surfaces;
518d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
519b8a6e0e6fc451096d684a1e18529ab4879cdba0aChristian König   struct pipe_vertex_buffer vb[3];
520b8a6e0e6fc451096d684a1e18529ab4879cdba0aChristian König
5213ea7e2713c836f23d59c4034385609e371a94c8dChristian König   unsigned i, j, component;
5223ea7e2713c836f23d59c4034385609e371a94c8dChristian König   unsigned nr_components;
523d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
524d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   assert(buf);
525d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
526d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   dec = (struct vl_mpeg12_decoder *)buf->base.decoder;
527d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   assert(dec);
528d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
52910c49b28752f5f2d822dfb1e2e6a1ec213cc44daChristian König   for (i = 0; i < 2; ++i)
5303ea7e2713c836f23d59c4034385609e371a94c8dChristian König      sv[i] = refs[i] ? refs[i]->get_sampler_view_planes(refs[i]) : NULL;
531d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
532b8a6e0e6fc451096d684a1e18529ab4879cdba0aChristian König   vb[0] = dec->quads;
533b8a6e0e6fc451096d684a1e18529ab4879cdba0aChristian König   vb[1] = dec->pos;
534d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
5353ea7e2713c836f23d59c4034385609e371a94c8dChristian König   surfaces = dst->get_surfaces(dst);
5363ea7e2713c836f23d59c4034385609e371a94c8dChristian König
53738a315b7049946d124409b377e622994feccdcb7Christian König   dec->pipe->bind_vertex_elements_state(dec->pipe, dec->ves_mv);
538d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   for (i = 0; i < VL_MAX_PLANES; ++i) {
5393ea7e2713c836f23d59c4034385609e371a94c8dChristian König      if (!surfaces[i]) continue;
5403ea7e2713c836f23d59c4034385609e371a94c8dChristian König
5415294ac62236bf05e1eaaca3399e539c28c0ccc4cChristian König      vl_mc_set_surface(&buf->mc[i], surfaces[i]);
54210c49b28752f5f2d822dfb1e2e6a1ec213cc44daChristian König
5433ea7e2713c836f23d59c4034385609e371a94c8dChristian König      for (j = 0; j < VL_MAX_REF_FRAMES; ++j) {
5443ea7e2713c836f23d59c4034385609e371a94c8dChristian König         if (!sv[j]) continue;
54510c49b28752f5f2d822dfb1e2e6a1ec213cc44daChristian König
546b8a6e0e6fc451096d684a1e18529ab4879cdba0aChristian König         vb[2] = vl_vb_get_mv(&buf->vertex_stream, j);;
547b8a6e0e6fc451096d684a1e18529ab4879cdba0aChristian König         dec->pipe->set_vertex_buffers(dec->pipe, 3, vb);
548b8a6e0e6fc451096d684a1e18529ab4879cdba0aChristian König
549b8a6e0e6fc451096d684a1e18529ab4879cdba0aChristian König         vl_mc_render_ref(&buf->mc[i], sv[j][i]);
55010c49b28752f5f2d822dfb1e2e6a1ec213cc44daChristian König      }
551b8a6e0e6fc451096d684a1e18529ab4879cdba0aChristian König   }
552b88fa924009b5cc572187d3ca6a395d5226aa1c3Christian König
553849bc838e81f930e6f090e6c6597bb92e822b4c9Christian König   dec->pipe->bind_vertex_elements_state(dec->pipe, dec->ves_ycbcr);
554b8a6e0e6fc451096d684a1e18529ab4879cdba0aChristian König   for (i = 0; i < VL_MAX_PLANES; ++i) {
5553ea7e2713c836f23d59c4034385609e371a94c8dChristian König      if (!num_ycbcr_blocks[i]) continue;
556849bc838e81f930e6f090e6c6597bb92e822b4c9Christian König
557849bc838e81f930e6f090e6c6597bb92e822b4c9Christian König      vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, i);
558849bc838e81f930e6f090e6c6597bb92e822b4c9Christian König      dec->pipe->set_vertex_buffers(dec->pipe, 2, vb);
559849bc838e81f930e6f090e6c6597bb92e822b4c9Christian König
5602e6274fc3b123e7de695038054b5cbd20b11559aChristian König      vl_zscan_render(&buf->zscan[i] , num_ycbcr_blocks[i]);
561f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
562fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König      if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
5632e6274fc3b123e7de695038054b5cbd20b11559aChristian König         vl_idct_flush(i == 0 ? &dec->idct_y : &dec->idct_c, &buf->idct[i], num_ycbcr_blocks[i]);
5643ea7e2713c836f23d59c4034385609e371a94c8dChristian König   }
5653ea7e2713c836f23d59c4034385609e371a94c8dChristian König
5660121aae967d3d1366cccc8946cf89ad22818365eChristian König   mc_source_sv = dec->mc_source->get_sampler_view_planes(dec->mc_source);
5673ea7e2713c836f23d59c4034385609e371a94c8dChristian König   for (i = 0, component = 0; i < VL_MAX_PLANES; ++i) {
5683ea7e2713c836f23d59c4034385609e371a94c8dChristian König      if (!surfaces[i]) continue;
569d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
5703ea7e2713c836f23d59c4034385609e371a94c8dChristian König      nr_components = util_format_get_nr_components(surfaces[i]->texture->format);
5713ea7e2713c836f23d59c4034385609e371a94c8dChristian König      for (j = 0; j < nr_components; ++j, ++component) {
5723ea7e2713c836f23d59c4034385609e371a94c8dChristian König         if (!num_ycbcr_blocks[i]) continue;
5733ea7e2713c836f23d59c4034385609e371a94c8dChristian König
5743ea7e2713c836f23d59c4034385609e371a94c8dChristian König         vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, component);
5753ea7e2713c836f23d59c4034385609e371a94c8dChristian König         dec->pipe->set_vertex_buffers(dec->pipe, 2, vb);
5767f04fe5338d0846ec9a6003033da5357d2785c8bChristian König
5777f04fe5338d0846ec9a6003033da5357d2785c8bChristian König         if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
5787f04fe5338d0846ec9a6003033da5357d2785c8bChristian König            vl_idct_prepare_stage2(component == 0 ? &dec->idct_y : &dec->idct_c, &buf->idct[component]);
5797f04fe5338d0846ec9a6003033da5357d2785c8bChristian König         else {
5807f04fe5338d0846ec9a6003033da5357d2785c8bChristian König            dec->pipe->set_fragment_sampler_views(dec->pipe, 1, &mc_source_sv[component]);
5817f04fe5338d0846ec9a6003033da5357d2785c8bChristian König            dec->pipe->bind_fragment_sampler_states(dec->pipe, 1, &dec->sampler_ycbcr);
5827f04fe5338d0846ec9a6003033da5357d2785c8bChristian König         }
5837f04fe5338d0846ec9a6003033da5357d2785c8bChristian König         vl_mc_render_ycbcr(&buf->mc[i], j, num_ycbcr_blocks[component]);
5843ea7e2713c836f23d59c4034385609e371a94c8dChristian König      }
585d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   }
586d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König}
587d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
588d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königstatic bool
589d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königinit_pipe_state(struct vl_mpeg12_decoder *dec)
590d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König{
591d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   struct pipe_depth_stencil_alpha_state dsa;
5927f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   struct pipe_sampler_state sampler;
593d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   unsigned i;
594d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
595d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   assert(dec);
596d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
597d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   memset(&dsa, 0, sizeof dsa);
598d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   dsa.depth.enabled = 0;
599d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   dsa.depth.writemask = 0;
600d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   dsa.depth.func = PIPE_FUNC_ALWAYS;
601d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   for (i = 0; i < 2; ++i) {
602d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      dsa.stencil[i].enabled = 0;
603d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      dsa.stencil[i].func = PIPE_FUNC_ALWAYS;
604d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP;
605d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP;
606d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP;
607d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      dsa.stencil[i].valuemask = 0;
608d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      dsa.stencil[i].writemask = 0;
609d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   }
610d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   dsa.alpha.enabled = 0;
611d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   dsa.alpha.func = PIPE_FUNC_ALWAYS;
612d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   dsa.alpha.ref_value = 0;
613d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   dec->dsa = dec->pipe->create_depth_stencil_alpha_state(dec->pipe, &dsa);
614d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   dec->pipe->bind_depth_stencil_alpha_state(dec->pipe, dec->dsa);
615d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
6167f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   memset(&sampler, 0, sizeof(sampler));
6177f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
6187f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
6197f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_BORDER;
6207f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
6217f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
6227f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
6237f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   sampler.compare_mode = PIPE_TEX_COMPARE_NONE;
6247f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   sampler.compare_func = PIPE_FUNC_ALWAYS;
6257f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   sampler.normalized_coords = 1;
6267f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   dec->sampler_ycbcr = dec->pipe->create_sampler_state(dec->pipe, &sampler);
6277f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   if (!dec->sampler_ycbcr)
6287f04fe5338d0846ec9a6003033da5357d2785c8bChristian König      return false;
6297f04fe5338d0846ec9a6003033da5357d2785c8bChristian König
630d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   return true;
631d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König}
632d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
633311eb749a1ab7ffd417bc456345d63eba75e3fecChristian Königstatic const struct format_config*
634311eb749a1ab7ffd417bc456345d63eba75e3fecChristian Königfind_format_config(struct vl_mpeg12_decoder *dec, const struct format_config configs[], unsigned num_configs)
635bad3085c7839de734f6b883088f91ae55db61a35Christian König{
636bad3085c7839de734f6b883088f91ae55db61a35Christian König   struct pipe_screen *screen;
637bad3085c7839de734f6b883088f91ae55db61a35Christian König   unsigned i;
638bad3085c7839de734f6b883088f91ae55db61a35Christian König
639bad3085c7839de734f6b883088f91ae55db61a35Christian König   assert(dec);
640bad3085c7839de734f6b883088f91ae55db61a35Christian König
641bad3085c7839de734f6b883088f91ae55db61a35Christian König   screen = dec->pipe->screen;
642bad3085c7839de734f6b883088f91ae55db61a35Christian König
643311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   for (i = 0; i < num_configs; ++i) {
644311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König      if (!screen->is_format_supported(screen, configs[i].zscan_source_format, PIPE_TEXTURE_2D,
645311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König                                       1, PIPE_BIND_SAMPLER_VIEW))
646311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König         continue;
647311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König
648311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König      if (configs[i].idct_source_format != PIPE_FORMAT_NONE) {
649311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König         if (!screen->is_format_supported(screen, configs[i].idct_source_format, PIPE_TEXTURE_2D,
650311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König                                          1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET))
651311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König            continue;
652311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König
653311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König         if (!screen->is_format_supported(screen, configs[i].mc_source_format, PIPE_TEXTURE_3D,
654311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König                                          1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET))
655311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König            continue;
656311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König      } else {
657311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König         if (!screen->is_format_supported(screen, configs[i].mc_source_format, PIPE_TEXTURE_2D,
658311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König                                          1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET))
659311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König            continue;
660311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König      }
661311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König      return &configs[i];
662311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   }
663bad3085c7839de734f6b883088f91ae55db61a35Christian König
664311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   return NULL;
665bad3085c7839de734f6b883088f91ae55db61a35Christian König}
666bad3085c7839de734f6b883088f91ae55db61a35Christian König
667d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königstatic bool
668311eb749a1ab7ffd417bc456345d63eba75e3fecChristian Königinit_zscan(struct vl_mpeg12_decoder *dec, const struct format_config* format_config)
669f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König{
670f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   unsigned num_channels;
671f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
672f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   assert(dec);
673f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
674f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   dec->blocks_per_line = 4;
675f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   dec->max_blocks =
676f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      (dec->base.width * dec->base.height) /
677f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      (BLOCK_WIDTH * BLOCK_HEIGHT);
678f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
679311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   dec->zscan_source_format = format_config->zscan_source_format;
6806ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   dec->zscan_linear = vl_zscan_layout(dec->pipe, vl_zscan_linear, dec->blocks_per_line);
6816ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   dec->zscan_normal = vl_zscan_layout(dec->pipe, vl_zscan_normal, dec->blocks_per_line);
6826ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   dec->zscan_alternate = vl_zscan_layout(dec->pipe, vl_zscan_alternate, dec->blocks_per_line);
683f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
684f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   num_channels = dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT ? 4 : 1;
685f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
686f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   if (!vl_zscan_init(&dec->zscan_y, dec->pipe, dec->base.width, dec->base.height,
687f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König                      dec->blocks_per_line, dec->max_blocks, num_channels))
688f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      return false;
689f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
690f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   if (!vl_zscan_init(&dec->zscan_c, dec->pipe, dec->chroma_width, dec->chroma_height,
691f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König                      dec->blocks_per_line, dec->max_blocks, num_channels))
692f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      return false;
693f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
694f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   return true;
695f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König}
696f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
697f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königstatic bool
698311eb749a1ab7ffd417bc456345d63eba75e3fecChristian Königinit_idct(struct vl_mpeg12_decoder *dec, const struct format_config* format_config)
699d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König{
7000121aae967d3d1366cccc8946cf89ad22818365eChristian König   unsigned nr_of_idct_render_targets;
7010121aae967d3d1366cccc8946cf89ad22818365eChristian König   enum pipe_format formats[3];
7020121aae967d3d1366cccc8946cf89ad22818365eChristian König
703311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   struct pipe_sampler_view *matrix = NULL;
704d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
7050121aae967d3d1366cccc8946cf89ad22818365eChristian König   nr_of_idct_render_targets = dec->pipe->screen->get_param(dec->pipe->screen, PIPE_CAP_MAX_RENDER_TARGETS);
706871d6d49c931739d94e646f2b0c3eb5db8a03d69Christian König
707871d6d49c931739d94e646f2b0c3eb5db8a03d69Christian König   // more than 4 render targets usually doesn't makes any seens
7080121aae967d3d1366cccc8946cf89ad22818365eChristian König   nr_of_idct_render_targets = MIN2(nr_of_idct_render_targets, 4);
709fcf765620d803b376582afb618b1f643242b641bChristian König
710311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   formats[0] = formats[1] = formats[2] = format_config->idct_source_format;
7110121aae967d3d1366cccc8946cf89ad22818365eChristian König   dec->idct_source = vl_video_buffer_init(dec->base.context, dec->pipe,
7120121aae967d3d1366cccc8946cf89ad22818365eChristian König                                           dec->base.width / 4, dec->base.height, 1,
7130121aae967d3d1366cccc8946cf89ad22818365eChristian König                                           dec->base.chroma_format,
7140121aae967d3d1366cccc8946cf89ad22818365eChristian König                                           formats, PIPE_USAGE_STATIC);
7150121aae967d3d1366cccc8946cf89ad22818365eChristian König   if (!dec->idct_source)
7160121aae967d3d1366cccc8946cf89ad22818365eChristian König      goto error_idct_source;
7170121aae967d3d1366cccc8946cf89ad22818365eChristian König
718311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   formats[0] = formats[1] = formats[2] = format_config->mc_source_format;
7190121aae967d3d1366cccc8946cf89ad22818365eChristian König   dec->mc_source = vl_video_buffer_init(dec->base.context, dec->pipe,
7200121aae967d3d1366cccc8946cf89ad22818365eChristian König                                         dec->base.width / nr_of_idct_render_targets,
7210121aae967d3d1366cccc8946cf89ad22818365eChristian König                                         dec->base.height / 4, nr_of_idct_render_targets,
7220121aae967d3d1366cccc8946cf89ad22818365eChristian König                                         dec->base.chroma_format,
7230121aae967d3d1366cccc8946cf89ad22818365eChristian König                                         formats, PIPE_USAGE_STATIC);
7240121aae967d3d1366cccc8946cf89ad22818365eChristian König
7250121aae967d3d1366cccc8946cf89ad22818365eChristian König   if (!dec->mc_source)
7260121aae967d3d1366cccc8946cf89ad22818365eChristian König      goto error_mc_source;
727ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian König
728311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   if (!(matrix = vl_idct_upload_matrix(dec->pipe, format_config->idct_scale)))
729ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian König      goto error_matrix;
730ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian König
731f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   if (!vl_idct_init(&dec->idct_y, dec->pipe, dec->base.width, dec->base.height,
732311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König                     nr_of_idct_render_targets, matrix, matrix))
733ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian König      goto error_y;
734d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
735f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   if(!vl_idct_init(&dec->idct_c, dec->pipe, dec->chroma_width, dec->chroma_height,
736311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König                    nr_of_idct_render_targets, matrix, matrix))
737ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian König      goto error_c;
738d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
739ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian König   pipe_sampler_view_reference(&matrix, NULL);
7400121aae967d3d1366cccc8946cf89ad22818365eChristian König
741d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   return true;
742d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
743ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian Königerror_c:
744d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   vl_idct_cleanup(&dec->idct_y);
745d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
746ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian Königerror_y:
747ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian König   pipe_sampler_view_reference(&matrix, NULL);
748d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
749ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian Königerror_matrix:
7500121aae967d3d1366cccc8946cf89ad22818365eChristian König   dec->mc_source->destroy(dec->mc_source);
7510121aae967d3d1366cccc8946cf89ad22818365eChristian König
7520121aae967d3d1366cccc8946cf89ad22818365eChristian Königerror_mc_source:
7530121aae967d3d1366cccc8946cf89ad22818365eChristian König   dec->idct_source->destroy(dec->idct_source);
7540121aae967d3d1366cccc8946cf89ad22818365eChristian König
7550121aae967d3d1366cccc8946cf89ad22818365eChristian Königerror_idct_source:
756d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   return false;
757d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König}
758d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
7590121aae967d3d1366cccc8946cf89ad22818365eChristian Königstatic bool
760311eb749a1ab7ffd417bc456345d63eba75e3fecChristian Königinit_mc_source_widthout_idct(struct vl_mpeg12_decoder *dec, const struct format_config* format_config)
7610121aae967d3d1366cccc8946cf89ad22818365eChristian König{
7620121aae967d3d1366cccc8946cf89ad22818365eChristian König   enum pipe_format formats[3];
7630121aae967d3d1366cccc8946cf89ad22818365eChristian König
764311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   formats[0] = formats[1] = formats[2] = format_config->mc_source_format;
7650121aae967d3d1366cccc8946cf89ad22818365eChristian König   dec->mc_source = vl_video_buffer_init(dec->base.context, dec->pipe,
7660121aae967d3d1366cccc8946cf89ad22818365eChristian König                                         dec->base.width, dec->base.height, 1,
7670121aae967d3d1366cccc8946cf89ad22818365eChristian König                                         dec->base.chroma_format,
7680121aae967d3d1366cccc8946cf89ad22818365eChristian König                                         formats, PIPE_USAGE_STATIC);
7690121aae967d3d1366cccc8946cf89ad22818365eChristian König
770311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   return dec->mc_source != NULL;
7710121aae967d3d1366cccc8946cf89ad22818365eChristian König}
7720121aae967d3d1366cccc8946cf89ad22818365eChristian König
7737f04fe5338d0846ec9a6003033da5357d2785c8bChristian Königstatic void
7747f04fe5338d0846ec9a6003033da5357d2785c8bChristian Königmc_vert_shader_callback(void *priv, struct vl_mc *mc,
7757f04fe5338d0846ec9a6003033da5357d2785c8bChristian König                        struct ureg_program *shader,
7767f04fe5338d0846ec9a6003033da5357d2785c8bChristian König                        unsigned first_output,
7777f04fe5338d0846ec9a6003033da5357d2785c8bChristian König                        struct ureg_dst tex)
7787f04fe5338d0846ec9a6003033da5357d2785c8bChristian König{
7797f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   struct vl_mpeg12_decoder *dec = priv;
7807f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   struct ureg_dst o_vtex;
7817f04fe5338d0846ec9a6003033da5357d2785c8bChristian König
7827f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   assert(priv && mc);
7837f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   assert(shader);
7847f04fe5338d0846ec9a6003033da5357d2785c8bChristian König
7857f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
7867f04fe5338d0846ec9a6003033da5357d2785c8bChristian König      struct vl_idct *idct = mc == &dec->mc_y ? &dec->idct_y : &dec->idct_c;
7877f04fe5338d0846ec9a6003033da5357d2785c8bChristian König      vl_idct_stage2_vert_shader(idct, shader, first_output, tex);
7887f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   } else {
7897f04fe5338d0846ec9a6003033da5357d2785c8bChristian König      o_vtex = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, first_output);
7907f04fe5338d0846ec9a6003033da5357d2785c8bChristian König      ureg_MOV(shader, ureg_writemask(o_vtex, TGSI_WRITEMASK_XY), ureg_src(tex));
7917f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   }
7927f04fe5338d0846ec9a6003033da5357d2785c8bChristian König}
7937f04fe5338d0846ec9a6003033da5357d2785c8bChristian König
7947f04fe5338d0846ec9a6003033da5357d2785c8bChristian Königstatic void
7957f04fe5338d0846ec9a6003033da5357d2785c8bChristian Königmc_frag_shader_callback(void *priv, struct vl_mc *mc,
7967f04fe5338d0846ec9a6003033da5357d2785c8bChristian König                        struct ureg_program *shader,
7977f04fe5338d0846ec9a6003033da5357d2785c8bChristian König                        unsigned first_input,
7987f04fe5338d0846ec9a6003033da5357d2785c8bChristian König                        struct ureg_dst dst)
7997f04fe5338d0846ec9a6003033da5357d2785c8bChristian König{
8007f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   struct vl_mpeg12_decoder *dec = priv;
8017f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   struct ureg_src src, sampler;
8027f04fe5338d0846ec9a6003033da5357d2785c8bChristian König
8037f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   assert(priv && mc);
8047f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   assert(shader);
8057f04fe5338d0846ec9a6003033da5357d2785c8bChristian König
8067f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
8077f04fe5338d0846ec9a6003033da5357d2785c8bChristian König      struct vl_idct *idct = mc == &dec->mc_y ? &dec->idct_y : &dec->idct_c;
8087f04fe5338d0846ec9a6003033da5357d2785c8bChristian König      vl_idct_stage2_frag_shader(idct, shader, first_input, dst);
8097f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   } else {
8107f04fe5338d0846ec9a6003033da5357d2785c8bChristian König      src = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, first_input, TGSI_INTERPOLATE_LINEAR);
8117f04fe5338d0846ec9a6003033da5357d2785c8bChristian König      sampler = ureg_DECL_sampler(shader, 0);
8127f04fe5338d0846ec9a6003033da5357d2785c8bChristian König      ureg_TEX(shader, dst, TGSI_TEXTURE_2D, src, sampler);
8137f04fe5338d0846ec9a6003033da5357d2785c8bChristian König   }
8147f04fe5338d0846ec9a6003033da5357d2785c8bChristian König}
8157f04fe5338d0846ec9a6003033da5357d2785c8bChristian König
816d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königstruct pipe_video_decoder *
817d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königvl_create_mpeg12_decoder(struct pipe_video_context *context,
818d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König                         struct pipe_context *pipe,
819d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König                         enum pipe_video_profile profile,
820fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König                         enum pipe_video_entrypoint entrypoint,
821d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König                         enum pipe_video_chroma_format chroma_format,
822d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König                         unsigned width, unsigned height)
823d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König{
824311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   const struct format_config *format_config;
825d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   struct vl_mpeg12_decoder *dec;
826d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
827d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12);
828d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
829d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   dec = CALLOC_STRUCT(vl_mpeg12_decoder);
830d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
831d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   if (!dec)
832d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      return NULL;
833d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
834d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   dec->base.context = context;
835d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   dec->base.profile = profile;
836fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König   dec->base.entrypoint = entrypoint;
837d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   dec->base.chroma_format = chroma_format;
838d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   dec->base.width = width;
839d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   dec->base.height = height;
840d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
841d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   dec->base.destroy = vl_mpeg12_destroy;
842d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   dec->base.create_buffer = vl_mpeg12_create_buffer;
843d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   dec->base.flush_buffer = vl_mpeg12_decoder_flush_buffer;
844d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
845d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   dec->pipe = pipe;
846d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
8473511780a43077d1359bd491eadb4ab9b3b86795aChristian König   dec->quads = vl_vb_upload_quads(dec->pipe);
848b8a6e0e6fc451096d684a1e18529ab4879cdba0aChristian König   dec->pos = vl_vb_upload_pos(
849b8a6e0e6fc451096d684a1e18529ab4879cdba0aChristian König      dec->pipe,
850b8a6e0e6fc451096d684a1e18529ab4879cdba0aChristian König      dec->base.width / MACROBLOCK_WIDTH,
851b8a6e0e6fc451096d684a1e18529ab4879cdba0aChristian König      dec->base.height / MACROBLOCK_HEIGHT
852b8a6e0e6fc451096d684a1e18529ab4879cdba0aChristian König   );
853b8a6e0e6fc451096d684a1e18529ab4879cdba0aChristian König
854849bc838e81f930e6f090e6c6597bb92e822b4c9Christian König   dec->ves_ycbcr = vl_vb_get_ves_ycbcr(dec->pipe);
85538a315b7049946d124409b377e622994feccdcb7Christian König   dec->ves_mv = vl_vb_get_ves_mv(dec->pipe);
856d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
857fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König   /* TODO: Implement 422, 444 */
858fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König   assert(dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
859d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
860f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
861f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      dec->chroma_width = dec->base.width / 2;
862f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      dec->chroma_height = dec->base.height / 2;
863f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   } else if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) {
864f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      dec->chroma_width = dec->base.width;
865f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      dec->chroma_height = dec->base.height / 2;
866f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   } else {
867f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      dec->chroma_width = dec->base.width;
868f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      dec->chroma_height = dec->base.height;
869f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   }
870f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
871311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   switch (entrypoint) {
872311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   case PIPE_VIDEO_ENTRYPOINT_BITSTREAM:
873311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König      format_config = find_format_config(dec, bitstream_format_config, num_bitstream_format_configs);
874311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König      break;
875311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König
876311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   case PIPE_VIDEO_ENTRYPOINT_IDCT:
877311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König      format_config = find_format_config(dec, idct_format_config, num_idct_format_configs);
878311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König      break;
879311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König
880311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   case PIPE_VIDEO_ENTRYPOINT_MC:
881311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König      format_config = find_format_config(dec, mc_format_config, num_mc_format_configs);
882311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König      break;
883311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König
884311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   default:
885311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König      assert(0);
886311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König      return NULL;
887311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   }
888311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König
889311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   if (!format_config)
890311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König      return NULL;
891311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König
892311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   if (!init_zscan(dec, format_config))
89324d76d2966a5c666c9627034e6751621b17024c8Christian König      goto error_zscan;
894f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
895ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian König   if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
896311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König      if (!init_idct(dec, format_config))
8970121aae967d3d1366cccc8946cf89ad22818365eChristian König         goto error_sources;
898ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian König   } else {
899311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König      if (!init_mc_source_widthout_idct(dec, format_config))
9000121aae967d3d1366cccc8946cf89ad22818365eChristian König         goto error_sources;
901ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian König   }
902ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian König
903311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   if (!vl_mc_init(&dec->mc_y, dec->pipe, dec->base.width, dec->base.height, MACROBLOCK_HEIGHT, format_config->mc_scale,
9047f04fe5338d0846ec9a6003033da5357d2785c8bChristian König                   mc_vert_shader_callback, mc_frag_shader_callback, dec))
905ff210aea7c080600bd45eb18b29a6109468ed4dfChristian König      goto error_mc_y;
906ff210aea7c080600bd45eb18b29a6109468ed4dfChristian König
907f1485e155a985df3100708f4bfb1a9d7c72217f4Christian König   // TODO
908311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König   if (!vl_mc_init(&dec->mc_c, dec->pipe, dec->base.width, dec->base.height, BLOCK_HEIGHT, format_config->mc_scale,
9097f04fe5338d0846ec9a6003033da5357d2785c8bChristian König                   mc_vert_shader_callback, mc_frag_shader_callback, dec))
910ff210aea7c080600bd45eb18b29a6109468ed4dfChristian König      goto error_mc_c;
911d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
912d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   if (!init_pipe_state(dec))
913d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      goto error_pipe_state;
914d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
915d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   return &dec->base;
916d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
917d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königerror_pipe_state:
918ff210aea7c080600bd45eb18b29a6109468ed4dfChristian König   vl_mc_cleanup(&dec->mc_c);
919ff210aea7c080600bd45eb18b29a6109468ed4dfChristian König
920ff210aea7c080600bd45eb18b29a6109468ed4dfChristian Königerror_mc_c:
921ff210aea7c080600bd45eb18b29a6109468ed4dfChristian König   vl_mc_cleanup(&dec->mc_y);
922d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
923ff210aea7c080600bd45eb18b29a6109468ed4dfChristian Königerror_mc_y:
924fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König   if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
925fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König      vl_idct_cleanup(&dec->idct_y);
926fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König      vl_idct_cleanup(&dec->idct_c);
9270121aae967d3d1366cccc8946cf89ad22818365eChristian König      dec->idct_source->destroy(dec->idct_source);
928fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König   }
9290121aae967d3d1366cccc8946cf89ad22818365eChristian König   dec->mc_source->destroy(dec->mc_source);
930d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
9310121aae967d3d1366cccc8946cf89ad22818365eChristian Königerror_sources:
93224d76d2966a5c666c9627034e6751621b17024c8Christian König   vl_zscan_cleanup(&dec->zscan_y);
93324d76d2966a5c666c9627034e6751621b17024c8Christian König   vl_zscan_cleanup(&dec->zscan_c);
93424d76d2966a5c666c9627034e6751621b17024c8Christian König
93524d76d2966a5c666c9627034e6751621b17024c8Christian Königerror_zscan:
936d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   FREE(dec);
937d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   return NULL;
938d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König}
939