Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3770 Serge 1
/**************************************************************************
2
 *
3
 * Copyright 2009 Younes Manton.
4
 * All Rights Reserved.
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the
8
 * "Software"), to deal in the Software without restriction, including
9
 * without limitation the rights to use, copy, modify, merge, publish,
10
 * distribute, sub license, and/or sell copies of the Software, and to
11
 * permit persons to whom the Software is furnished to do so, subject to
12
 * the following conditions:
13
 *
14
 * The above copyright notice and this permission notice (including the
15
 * next paragraph) shall be included in all copies or substantial portions
16
 * of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21
 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
 *
26
 **************************************************************************/
27
 
28
#include 
29
#include 
30
 
31
#include "util/u_memory.h"
32
#include "util/u_rect.h"
33
#include "util/u_sampler.h"
34
#include "util/u_video.h"
35
 
36
#include "vl_mpeg12_decoder.h"
37
#include "vl_defines.h"
38
 
39
#define SCALE_FACTOR_SNORM (32768.0f / 256.0f)
40
#define SCALE_FACTOR_SSCALED (1.0f / 256.0f)
41
 
42
struct format_config {
43
   enum pipe_format zscan_source_format;
44
   enum pipe_format idct_source_format;
45
   enum pipe_format mc_source_format;
46
 
47
   float idct_scale;
48
   float mc_scale;
49
};
50
 
51
static const struct format_config bitstream_format_config[] = {
52
//   { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SSCALED },
53
//   { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, 1.0f, SCALE_FACTOR_SSCALED },
54
   { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SNORM },
55
   { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, 1.0f, SCALE_FACTOR_SNORM }
56
};
57
 
58
static const unsigned num_bitstream_format_configs =
59
   sizeof(bitstream_format_config) / sizeof(struct format_config);
60
 
61
static const struct format_config idct_format_config[] = {
62
//   { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SSCALED },
63
//   { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, 1.0f, SCALE_FACTOR_SSCALED },
64
   { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SNORM },
65
   { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, 1.0f, SCALE_FACTOR_SNORM }
66
};
67
 
68
static const unsigned num_idct_format_configs =
69
   sizeof(idct_format_config) / sizeof(struct format_config);
70
 
71
static const struct format_config mc_format_config[] = {
72
   //{ PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_NONE, PIPE_FORMAT_R16_SSCALED, 0.0f, SCALE_FACTOR_SSCALED },
73
   { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_NONE, PIPE_FORMAT_R16_SNORM, 0.0f, SCALE_FACTOR_SNORM }
74
};
75
 
76
static const unsigned num_mc_format_configs =
77
   sizeof(mc_format_config) / sizeof(struct format_config);
78
 
79
static const unsigned const_empty_block_mask_420[3][2][2] = {
80
   { { 0x20, 0x10 },  { 0x08, 0x04 } },
81
   { { 0x02, 0x02 },  { 0x02, 0x02 } },
82
   { { 0x01, 0x01 },  { 0x01, 0x01 } }
83
};
84
 
85
static bool
86
init_zscan_buffer(struct vl_mpeg12_decoder *dec, struct vl_mpeg12_buffer *buffer)
87
{
88
   struct pipe_resource *res, res_tmpl;
89
   struct pipe_sampler_view sv_tmpl;
90
   struct pipe_surface **destination;
91
 
92
   unsigned i;
93
 
94
   assert(dec && buffer);
95
 
96
   memset(&res_tmpl, 0, sizeof(res_tmpl));
97
   res_tmpl.target = PIPE_TEXTURE_2D;
98
   res_tmpl.format = dec->zscan_source_format;
99
   res_tmpl.width0 = dec->blocks_per_line * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT;
100
   res_tmpl.height0 = align(dec->num_blocks, dec->blocks_per_line) / dec->blocks_per_line;
101
   res_tmpl.depth0 = 1;
102
   res_tmpl.array_size = 1;
103
   res_tmpl.usage = PIPE_USAGE_STREAM;
104
   res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW;
105
 
106
   res = dec->base.context->screen->resource_create(dec->base.context->screen, &res_tmpl);
107
   if (!res)
108
      goto error_source;
109
 
110
 
111
   memset(&sv_tmpl, 0, sizeof(sv_tmpl));
112
   u_sampler_view_default_template(&sv_tmpl, res, res->format);
113
   sv_tmpl.swizzle_r = sv_tmpl.swizzle_g = sv_tmpl.swizzle_b = sv_tmpl.swizzle_a = PIPE_SWIZZLE_RED;
114
   buffer->zscan_source = dec->base.context->create_sampler_view(dec->base.context, res, &sv_tmpl);
115
   pipe_resource_reference(&res, NULL);
116
   if (!buffer->zscan_source)
117
      goto error_sampler;
118
 
119
   if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
120
      destination = dec->idct_source->get_surfaces(dec->idct_source);
121
   else
122
      destination = dec->mc_source->get_surfaces(dec->mc_source);
123
 
124
   if (!destination)
125
      goto error_surface;
126
 
127
   for (i = 0; i < VL_NUM_COMPONENTS; ++i)
128
      if (!vl_zscan_init_buffer(i == 0 ? &dec->zscan_y : &dec->zscan_c,
129
                                &buffer->zscan[i], buffer->zscan_source, destination[i]))
130
         goto error_plane;
131
 
132
   return true;
133
 
134
error_plane:
135
   for (; i > 0; --i)
136
      vl_zscan_cleanup_buffer(&buffer->zscan[i - 1]);
137
 
138
error_surface:
139
error_sampler:
140
   pipe_sampler_view_reference(&buffer->zscan_source, NULL);
141
 
142
error_source:
143
   return false;
144
}
145
 
146
static void
147
cleanup_zscan_buffer(struct vl_mpeg12_buffer *buffer)
148
{
149
   unsigned i;
150
 
151
   assert(buffer);
152
 
153
   for (i = 0; i < VL_NUM_COMPONENTS; ++i)
154
      vl_zscan_cleanup_buffer(&buffer->zscan[i]);
155
 
156
   pipe_sampler_view_reference(&buffer->zscan_source, NULL);
157
}
158
 
159
static bool
160
init_idct_buffer(struct vl_mpeg12_decoder *dec, struct vl_mpeg12_buffer *buffer)
161
{
162
   struct pipe_sampler_view **idct_source_sv, **mc_source_sv;
163
 
164
   unsigned i;
165
 
166
   assert(dec && buffer);
167
 
168
   idct_source_sv = dec->idct_source->get_sampler_view_planes(dec->idct_source);
169
   if (!idct_source_sv)
170
      goto error_source_sv;
171
 
172
   mc_source_sv = dec->mc_source->get_sampler_view_planes(dec->mc_source);
173
   if (!mc_source_sv)
174
      goto error_mc_source_sv;
175
 
176
   for (i = 0; i < 3; ++i)
177
      if (!vl_idct_init_buffer(i == 0 ? &dec->idct_y : &dec->idct_c,
178
                               &buffer->idct[i], idct_source_sv[i],
179
                               mc_source_sv[i]))
180
         goto error_plane;
181
 
182
   return true;
183
 
184
error_plane:
185
   for (; i > 0; --i)
186
      vl_idct_cleanup_buffer(&buffer->idct[i - 1]);
187
 
188
error_mc_source_sv:
189
error_source_sv:
190
   return false;
191
}
192
 
193
static void
194
cleanup_idct_buffer(struct vl_mpeg12_buffer *buf)
195
{
196
   unsigned i;
197
 
198
   assert(buf);
199
 
200
   for (i = 0; i < 3; ++i)
201
      vl_idct_cleanup_buffer(&buf->idct[0]);
202
}
203
 
204
static bool
205
init_mc_buffer(struct vl_mpeg12_decoder *dec, struct vl_mpeg12_buffer *buf)
206
{
207
   assert(dec && buf);
208
 
209
   if(!vl_mc_init_buffer(&dec->mc_y, &buf->mc[0]))
210
      goto error_mc_y;
211
 
212
   if(!vl_mc_init_buffer(&dec->mc_c, &buf->mc[1]))
213
      goto error_mc_cb;
214
 
215
   if(!vl_mc_init_buffer(&dec->mc_c, &buf->mc[2]))
216
      goto error_mc_cr;
217
 
218
   return true;
219
 
220
error_mc_cr:
221
   vl_mc_cleanup_buffer(&buf->mc[1]);
222
 
223
error_mc_cb:
224
   vl_mc_cleanup_buffer(&buf->mc[0]);
225
 
226
error_mc_y:
227
   return false;
228
}
229
 
230
static void
231
cleanup_mc_buffer(struct vl_mpeg12_buffer *buf)
232
{
233
   unsigned i;
234
 
235
   assert(buf);
236
 
237
   for (i = 0; i < VL_NUM_COMPONENTS; ++i)
238
      vl_mc_cleanup_buffer(&buf->mc[i]);
239
}
240
 
241
static INLINE void
242
MacroBlockTypeToPipeWeights(const struct pipe_mpeg12_macroblock *mb, unsigned weights[2])
243
{
244
   assert(mb);
245
 
246
   switch (mb->macroblock_type & (PIPE_MPEG12_MB_TYPE_MOTION_FORWARD | PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD)) {
247
   case PIPE_MPEG12_MB_TYPE_MOTION_FORWARD:
248
      weights[0] = PIPE_VIDEO_MV_WEIGHT_MAX;
249
      weights[1] = PIPE_VIDEO_MV_WEIGHT_MIN;
250
      break;
251
 
252
   case (PIPE_MPEG12_MB_TYPE_MOTION_FORWARD | PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD):
253
      weights[0] = PIPE_VIDEO_MV_WEIGHT_HALF;
254
      weights[1] = PIPE_VIDEO_MV_WEIGHT_HALF;
255
      break;
256
 
257
   case PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD:
258
      weights[0] = PIPE_VIDEO_MV_WEIGHT_MIN;
259
      weights[1] = PIPE_VIDEO_MV_WEIGHT_MAX;
260
      break;
261
 
262
   default:
263
      if (mb->macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA) {
264
         weights[0] = PIPE_VIDEO_MV_WEIGHT_MIN;
265
         weights[1] = PIPE_VIDEO_MV_WEIGHT_MIN;
266
      } else {
267
         /* no motion vector, but also not intra mb ->
268
            just copy the old frame content */
269
         weights[0] = PIPE_VIDEO_MV_WEIGHT_MAX;
270
         weights[1] = PIPE_VIDEO_MV_WEIGHT_MIN;
271
      }
272
      break;
273
   }
274
}
275
 
276
static INLINE struct vl_motionvector
277
MotionVectorToPipe(const struct pipe_mpeg12_macroblock *mb, unsigned vector,
278
                   unsigned field_select_mask, unsigned weight)
279
{
280
   struct vl_motionvector mv;
281
 
282
   assert(mb);
283
 
284
   if (mb->macroblock_type & (PIPE_MPEG12_MB_TYPE_MOTION_FORWARD | PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD)) {
285
      switch (mb->macroblock_modes.bits.frame_motion_type) {
286
      case PIPE_MPEG12_MO_TYPE_FRAME:
287
         mv.top.x = mb->PMV[0][vector][0];
288
         mv.top.y = mb->PMV[0][vector][1];
289
         mv.top.field_select = PIPE_VIDEO_FRAME;
290
         mv.top.weight = weight;
291
 
292
         mv.bottom.x = mb->PMV[0][vector][0];
293
         mv.bottom.y = mb->PMV[0][vector][1];
294
         mv.bottom.weight = weight;
295
         mv.bottom.field_select = PIPE_VIDEO_FRAME;
296
         break;
297
 
298
      case PIPE_MPEG12_MO_TYPE_FIELD:
299
         mv.top.x = mb->PMV[0][vector][0];
300
         mv.top.y = mb->PMV[0][vector][1];
301
         mv.top.field_select = (mb->motion_vertical_field_select & field_select_mask) ?
302
            PIPE_VIDEO_BOTTOM_FIELD : PIPE_VIDEO_TOP_FIELD;
303
         mv.top.weight = weight;
304
 
305
         mv.bottom.x = mb->PMV[1][vector][0];
306
         mv.bottom.y = mb->PMV[1][vector][1];
307
         mv.bottom.field_select = (mb->motion_vertical_field_select & (field_select_mask << 2)) ?
308
            PIPE_VIDEO_BOTTOM_FIELD : PIPE_VIDEO_TOP_FIELD;
309
         mv.bottom.weight = weight;
310
         break;
311
 
312
      default: // TODO: Support DUALPRIME and 16x8
313
         break;
314
      }
315
   } else {
316
      mv.top.x = mv.top.y = 0;
317
      mv.top.field_select = PIPE_VIDEO_FRAME;
318
      mv.top.weight = weight;
319
 
320
      mv.bottom.x = mv.bottom.y = 0;
321
      mv.bottom.field_select = PIPE_VIDEO_FRAME;
322
      mv.bottom.weight = weight;
323
   }
324
   return mv;
325
}
326
 
327
static INLINE void
328
UploadYcbcrBlocks(struct vl_mpeg12_decoder *dec,
329
                  struct vl_mpeg12_buffer *buf,
330
                  const struct pipe_mpeg12_macroblock *mb)
331
{
332
   unsigned intra;
333
   unsigned tb, x, y, num_blocks = 0;
334
 
335
   assert(dec && buf);
336
   assert(mb);
337
 
338
   if (!mb->coded_block_pattern)
339
      return;
340
 
341
   intra = mb->macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA ? 1 : 0;
342
 
343
   for (y = 0; y < 2; ++y) {
344
      for (x = 0; x < 2; ++x) {
345
         if (mb->coded_block_pattern & const_empty_block_mask_420[0][y][x]) {
346
 
347
            struct vl_ycbcr_block *stream = buf->ycbcr_stream[0];
348
            stream->x = mb->x * 2 + x;
349
            stream->y = mb->y * 2 + y;
350
            stream->intra = intra;
351
            stream->coding = mb->macroblock_modes.bits.dct_type;
352
            stream->block_num = buf->block_num++;
353
 
354
            buf->num_ycbcr_blocks[0]++;
355
            buf->ycbcr_stream[0]++;
356
 
357
            num_blocks++;
358
         }
359
      }
360
   }
361
 
362
   /* TODO: Implement 422, 444 */
363
   //assert(ctx->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
364
 
365
   for (tb = 1; tb < 3; ++tb) {
366
      if (mb->coded_block_pattern & const_empty_block_mask_420[tb][0][0]) {
367
 
368
         struct vl_ycbcr_block *stream = buf->ycbcr_stream[tb];
369
         stream->x = mb->x;
370
         stream->y = mb->y;
371
         stream->intra = intra;
372
         stream->coding = 0;
373
         stream->block_num = buf->block_num++;
374
 
375
         buf->num_ycbcr_blocks[tb]++;
376
         buf->ycbcr_stream[tb]++;
377
 
378
         num_blocks++;
379
      }
380
   }
381
 
382
   memcpy(buf->texels, mb->blocks, 64 * sizeof(short) * num_blocks);
383
   buf->texels += 64 * num_blocks;
384
}
385
 
386
static void
387
vl_mpeg12_destroy_buffer(void *buffer)
388
{
389
   struct vl_mpeg12_buffer *buf = buffer;
390
 
391
   assert(buf);
392
 
393
   cleanup_zscan_buffer(buf);
394
   cleanup_idct_buffer(buf);
395
   cleanup_mc_buffer(buf);
396
   vl_vb_cleanup(&buf->vertex_stream);
397
 
398
   FREE(buf);
399
}
400
 
401
static void
402
vl_mpeg12_destroy(struct pipe_video_decoder *decoder)
403
{
404
   struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder*)decoder;
405
   unsigned i;
406
 
407
   assert(decoder);
408
 
409
   /* Asserted in softpipe_delete_fs_state() for some reason */
410
   dec->base.context->bind_vs_state(dec->base.context, NULL);
411
   dec->base.context->bind_fs_state(dec->base.context, NULL);
412
 
413
   dec->base.context->delete_depth_stencil_alpha_state(dec->base.context, dec->dsa);
414
   dec->base.context->delete_sampler_state(dec->base.context, dec->sampler_ycbcr);
415
 
416
   vl_mc_cleanup(&dec->mc_y);
417
   vl_mc_cleanup(&dec->mc_c);
418
   dec->mc_source->destroy(dec->mc_source);
419
 
420
   if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
421
      vl_idct_cleanup(&dec->idct_y);
422
      vl_idct_cleanup(&dec->idct_c);
423
      dec->idct_source->destroy(dec->idct_source);
424
   }
425
 
426
   vl_zscan_cleanup(&dec->zscan_y);
427
   vl_zscan_cleanup(&dec->zscan_c);
428
 
429
   dec->base.context->delete_vertex_elements_state(dec->base.context, dec->ves_ycbcr);
430
   dec->base.context->delete_vertex_elements_state(dec->base.context, dec->ves_mv);
431
 
432
   pipe_resource_reference(&dec->quads.buffer, NULL);
433
   pipe_resource_reference(&dec->pos.buffer, NULL);
434
 
435
   pipe_sampler_view_reference(&dec->zscan_linear, NULL);
436
   pipe_sampler_view_reference(&dec->zscan_normal, NULL);
437
   pipe_sampler_view_reference(&dec->zscan_alternate, NULL);
438
 
439
   for (i = 0; i < 4; ++i)
440
      if (dec->dec_buffers[i])
441
         vl_mpeg12_destroy_buffer(dec->dec_buffers[i]);
442
 
443
   FREE(dec);
444
}
445
 
446
static struct vl_mpeg12_buffer *
447
vl_mpeg12_get_decode_buffer(struct vl_mpeg12_decoder *dec, struct pipe_video_buffer *target)
448
{
449
   struct vl_mpeg12_buffer *buffer;
450
 
451
   assert(dec);
452
 
453
   buffer = vl_video_buffer_get_associated_data(target, &dec->base);
454
   if (buffer)
455
      return buffer;
456
 
457
   buffer = dec->dec_buffers[dec->current_buffer];
458
   if (buffer)
459
      return buffer;
460
 
461
   buffer = CALLOC_STRUCT(vl_mpeg12_buffer);
462
   if (buffer == NULL)
463
      return NULL;
464
 
465
   if (!vl_vb_init(&buffer->vertex_stream, dec->base.context,
466
                   dec->base.width / VL_MACROBLOCK_WIDTH,
467
                   dec->base.height / VL_MACROBLOCK_HEIGHT))
468
      goto error_vertex_buffer;
469
 
470
   if (!init_mc_buffer(dec, buffer))
471
      goto error_mc;
472
 
473
   if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
474
      if (!init_idct_buffer(dec, buffer))
475
         goto error_idct;
476
 
477
   if (!init_zscan_buffer(dec, buffer))
478
      goto error_zscan;
479
 
480
   if (dec->base.entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM)
481
      vl_mpg12_bs_init(&buffer->bs, &dec->base);
482
 
483
   if (dec->expect_chunked_decode)
484
      vl_video_buffer_set_associated_data(target, &dec->base,
485
                                          buffer, vl_mpeg12_destroy_buffer);
486
   else
487
      dec->dec_buffers[dec->current_buffer] = buffer;
488
 
489
   return buffer;
490
 
491
error_zscan:
492
   cleanup_idct_buffer(buffer);
493
 
494
error_idct:
495
   cleanup_mc_buffer(buffer);
496
 
497
error_mc:
498
   vl_vb_cleanup(&buffer->vertex_stream);
499
 
500
error_vertex_buffer:
501
   FREE(buffer);
502
   return NULL;
503
}
504
 
505
static void
506
vl_mpeg12_begin_frame(struct pipe_video_decoder *decoder,
507
                      struct pipe_video_buffer *target,
508
                      struct pipe_picture_desc *picture)
509
{
510
   struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder *)decoder;
511
   struct pipe_mpeg12_picture_desc *desc = (struct pipe_mpeg12_picture_desc *)picture;
512
   struct vl_mpeg12_buffer *buf;
513
 
514
   struct pipe_resource *tex;
515
   struct pipe_box rect = { 0, 0, 0, 1, 1, 1 };
516
 
517
   uint8_t intra_matrix[64];
518
   uint8_t non_intra_matrix[64];
519
 
520
   unsigned i;
521
 
522
   assert(dec && target && picture);
523
 
524
   buf = vl_mpeg12_get_decode_buffer(dec, target);
525
   assert(buf);
526
 
527
   if (dec->base.entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM) {
528
      memcpy(intra_matrix, desc->intra_matrix, sizeof(intra_matrix));
529
      memcpy(non_intra_matrix, desc->non_intra_matrix, sizeof(non_intra_matrix));
530
      intra_matrix[0] = 1 << (7 - desc->intra_dc_precision);
531
   } else {
532
      memset(intra_matrix, 0x10, sizeof(intra_matrix));
533
      memset(non_intra_matrix, 0x10, sizeof(non_intra_matrix));
534
   }
535
 
536
   for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
537
      struct vl_zscan *zscan = i == 0 ? &dec->zscan_y : &dec->zscan_c;
538
      vl_zscan_upload_quant(zscan, &buf->zscan[i], intra_matrix, true);
539
      vl_zscan_upload_quant(zscan, &buf->zscan[i], non_intra_matrix, false);
540
   }
541
 
542
   vl_vb_map(&buf->vertex_stream, dec->base.context);
543
 
544
   tex = buf->zscan_source->texture;
545
   rect.width = tex->width0;
546
   rect.height = tex->height0;
547
 
548
   buf->texels =
549
      dec->base.context->transfer_map(dec->base.context, tex, 0,
550
                                      PIPE_TRANSFER_WRITE |
551
                                      PIPE_TRANSFER_DISCARD_RANGE,
552
                                      &rect, &buf->tex_transfer);
553
 
554
   buf->block_num = 0;
555
 
556
   for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
557
      buf->ycbcr_stream[i] = vl_vb_get_ycbcr_stream(&buf->vertex_stream, i);
558
      buf->num_ycbcr_blocks[i] = 0;
559
   }
560
 
561
   for (i = 0; i < VL_MAX_REF_FRAMES; ++i)
562
      buf->mv_stream[i] = vl_vb_get_mv_stream(&buf->vertex_stream, i);
563
 
564
   if (dec->base.entrypoint >= PIPE_VIDEO_ENTRYPOINT_IDCT) {
565
      for (i = 0; i < VL_NUM_COMPONENTS; ++i)
566
         vl_zscan_set_layout(&buf->zscan[i], dec->zscan_linear);
567
   }
568
}
569
 
570
static void
571
vl_mpeg12_decode_macroblock(struct pipe_video_decoder *decoder,
572
                            struct pipe_video_buffer *target,
573
                            struct pipe_picture_desc *picture,
574
                            const struct pipe_macroblock *macroblocks,
575
                            unsigned num_macroblocks)
576
{
577
   struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder *)decoder;
578
   const struct pipe_mpeg12_macroblock *mb = (const struct pipe_mpeg12_macroblock *)macroblocks;
579
   struct pipe_mpeg12_picture_desc *desc = (struct pipe_mpeg12_picture_desc *)picture;
580
   struct vl_mpeg12_buffer *buf;
581
 
582
   unsigned i, j, mv_weights[2];
583
 
584
   assert(dec && target && picture);
585
   assert(macroblocks && macroblocks->codec == PIPE_VIDEO_CODEC_MPEG12);
586
 
587
   buf = vl_mpeg12_get_decode_buffer(dec, target);
588
   assert(buf);
589
 
590
   for (; num_macroblocks > 0; --num_macroblocks) {
591
      unsigned mb_addr = mb->y * dec->width_in_macroblocks + mb->x;
592
 
593
      if (mb->macroblock_type & (PIPE_MPEG12_MB_TYPE_PATTERN | PIPE_MPEG12_MB_TYPE_INTRA))
594
         UploadYcbcrBlocks(dec, buf, mb);
595
 
596
      MacroBlockTypeToPipeWeights(mb, mv_weights);
597
 
598
      for (i = 0; i < 2; ++i) {
599
          if (!desc->ref[i]) continue;
600
 
601
         buf->mv_stream[i][mb_addr] = MotionVectorToPipe
602
         (
603
            mb, i,
604
            i ? PIPE_MPEG12_FS_FIRST_BACKWARD : PIPE_MPEG12_FS_FIRST_FORWARD,
605
            mv_weights[i]
606
         );
607
      }
608
 
609
      /* see section 7.6.6 of the spec */
610
      if (mb->num_skipped_macroblocks > 0) {
611
         struct vl_motionvector skipped_mv[2];
612
 
613
         if (desc->ref[0] && !desc->ref[1]) {
614
            skipped_mv[0].top.x = skipped_mv[0].top.y = 0;
615
            skipped_mv[0].top.weight = PIPE_VIDEO_MV_WEIGHT_MAX;
616
         } else {
617
           skipped_mv[0] = buf->mv_stream[0][mb_addr];
618
           skipped_mv[1] = buf->mv_stream[1][mb_addr];
619
         }
620
         skipped_mv[0].top.field_select = PIPE_VIDEO_FRAME;
621
         skipped_mv[1].top.field_select = PIPE_VIDEO_FRAME;
622
 
623
         skipped_mv[0].bottom = skipped_mv[0].top;
624
         skipped_mv[1].bottom = skipped_mv[1].top;
625
 
626
         ++mb_addr;
627
         for (i = 0; i < mb->num_skipped_macroblocks; ++i, ++mb_addr) {
628
            for (j = 0; j < 2; ++j) {
629
               if (!desc->ref[j]) continue;
630
               buf->mv_stream[j][mb_addr] = skipped_mv[j];
631
 
632
            }
633
         }
634
      }
635
 
636
      ++mb;
637
   }
638
}
639
 
640
static void
641
vl_mpeg12_decode_bitstream(struct pipe_video_decoder *decoder,
642
                           struct pipe_video_buffer *target,
643
                           struct pipe_picture_desc *picture,
644
                           unsigned num_buffers,
645
                           const void * const *buffers,
646
                           const unsigned *sizes)
647
{
648
   struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder *)decoder;
649
   struct pipe_mpeg12_picture_desc *desc = (struct pipe_mpeg12_picture_desc *)picture;
650
   struct vl_mpeg12_buffer *buf;
651
 
652
   unsigned i;
653
 
654
   assert(dec && target && picture);
655
 
656
   buf = vl_mpeg12_get_decode_buffer(dec, target);
657
   assert(buf);
658
 
659
   for (i = 0; i < VL_NUM_COMPONENTS; ++i)
660
      vl_zscan_set_layout(&buf->zscan[i], desc->alternate_scan ?
661
                          dec->zscan_alternate : dec->zscan_normal);
662
 
663
   vl_mpg12_bs_decode(&buf->bs, target, desc, num_buffers, buffers, sizes);
664
}
665
 
666
static void
667
vl_mpeg12_end_frame(struct pipe_video_decoder *decoder,
668
                    struct pipe_video_buffer *target,
669
                    struct pipe_picture_desc *picture)
670
{
671
   struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder *)decoder;
672
   struct pipe_mpeg12_picture_desc *desc = (struct pipe_mpeg12_picture_desc *)picture;
673
   struct pipe_sampler_view **ref_frames[2];
674
   struct pipe_sampler_view **mc_source_sv;
675
   struct pipe_surface **target_surfaces;
676
   struct pipe_vertex_buffer vb[3];
677
   struct vl_mpeg12_buffer *buf;
678
 
679
   const unsigned *plane_order;
680
   unsigned i, j, component;
681
   unsigned nr_components;
682
 
683
   assert(dec && target && picture);
684
   assert(!target->interlaced);
685
 
686
   buf = vl_mpeg12_get_decode_buffer(dec, target);
687
 
688
   vl_vb_unmap(&buf->vertex_stream, dec->base.context);
689
 
690
   dec->base.context->transfer_unmap(dec->base.context, buf->tex_transfer);
691
 
692
   vb[0] = dec->quads;
693
   vb[1] = dec->pos;
694
 
695
   target_surfaces = target->get_surfaces(target);
696
 
697
   for (i = 0; i < VL_MAX_REF_FRAMES; ++i) {
698
      if (desc->ref[i])
699
         ref_frames[i] = desc->ref[i]->get_sampler_view_planes(desc->ref[i]);
700
      else
701
         ref_frames[i] = NULL;
702
   }
703
 
704
   dec->base.context->bind_vertex_elements_state(dec->base.context, dec->ves_mv);
705
   for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
706
      if (!target_surfaces[i]) continue;
707
 
708
      vl_mc_set_surface(&buf->mc[i], target_surfaces[i]);
709
 
710
      for (j = 0; j < VL_MAX_REF_FRAMES; ++j) {
711
         if (!ref_frames[j] || !ref_frames[j][i]) continue;
712
 
713
         vb[2] = vl_vb_get_mv(&buf->vertex_stream, j);;
714
         dec->base.context->set_vertex_buffers(dec->base.context, 0, 3, vb);
715
 
716
         vl_mc_render_ref(i ? &dec->mc_c : &dec->mc_y, &buf->mc[i], ref_frames[j][i]);
717
      }
718
   }
719
 
720
   dec->base.context->bind_vertex_elements_state(dec->base.context, dec->ves_ycbcr);
721
   for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
722
      if (!buf->num_ycbcr_blocks[i]) continue;
723
 
724
      vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, i);
725
      dec->base.context->set_vertex_buffers(dec->base.context, 0, 2, vb);
726
 
727
      vl_zscan_render(i ? &dec->zscan_c : & dec->zscan_y, &buf->zscan[i] , buf->num_ycbcr_blocks[i]);
728
 
729
      if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
730
         vl_idct_flush(i ? &dec->idct_c : &dec->idct_y, &buf->idct[i], buf->num_ycbcr_blocks[i]);
731
   }
732
 
733
   plane_order = vl_video_buffer_plane_order(target->buffer_format);
734
   mc_source_sv = dec->mc_source->get_sampler_view_planes(dec->mc_source);
735
   for (i = 0, component = 0; component < VL_NUM_COMPONENTS; ++i) {
736
      if (!target_surfaces[i]) continue;
737
 
738
      nr_components = util_format_get_nr_components(target_surfaces[i]->texture->format);
739
      for (j = 0; j < nr_components; ++j, ++component) {
740
         unsigned plane = plane_order[component];
741
         if (!buf->num_ycbcr_blocks[plane]) continue;
742
 
743
         vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, plane);
744
         dec->base.context->set_vertex_buffers(dec->base.context, 0, 2, vb);
745
 
746
         if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
747
            vl_idct_prepare_stage2(i ? &dec->idct_c : &dec->idct_y, &buf->idct[plane]);
748
         else {
749
            dec->base.context->set_fragment_sampler_views(dec->base.context, 1, &mc_source_sv[plane]);
750
            dec->base.context->bind_fragment_sampler_states(dec->base.context, 1, &dec->sampler_ycbcr);
751
         }
752
         vl_mc_render_ycbcr(i ? &dec->mc_c : &dec->mc_y, &buf->mc[i], j, buf->num_ycbcr_blocks[plane]);
753
      }
754
   }
755
   ++dec->current_buffer;
756
   dec->current_buffer %= 4;
757
}
758
 
759
static void
760
vl_mpeg12_flush(struct pipe_video_decoder *decoder)
761
{
762
   assert(decoder);
763
 
764
   //Noop, for shaders it is much faster to flush everything in end_frame
765
}
766
 
767
static bool
768
init_pipe_state(struct vl_mpeg12_decoder *dec)
769
{
770
   struct pipe_depth_stencil_alpha_state dsa;
771
   struct pipe_sampler_state sampler;
772
   unsigned i;
773
 
774
   assert(dec);
775
 
776
   memset(&dsa, 0, sizeof dsa);
777
   dsa.depth.enabled = 0;
778
   dsa.depth.writemask = 0;
779
   dsa.depth.func = PIPE_FUNC_ALWAYS;
780
   for (i = 0; i < 2; ++i) {
781
      dsa.stencil[i].enabled = 0;
782
      dsa.stencil[i].func = PIPE_FUNC_ALWAYS;
783
      dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP;
784
      dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP;
785
      dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP;
786
      dsa.stencil[i].valuemask = 0;
787
      dsa.stencil[i].writemask = 0;
788
   }
789
   dsa.alpha.enabled = 0;
790
   dsa.alpha.func = PIPE_FUNC_ALWAYS;
791
   dsa.alpha.ref_value = 0;
792
   dec->dsa = dec->base.context->create_depth_stencil_alpha_state(dec->base.context, &dsa);
793
   dec->base.context->bind_depth_stencil_alpha_state(dec->base.context, dec->dsa);
794
 
795
   memset(&sampler, 0, sizeof(sampler));
796
   sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
797
   sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
798
   sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_BORDER;
799
   sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
800
   sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
801
   sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
802
   sampler.compare_mode = PIPE_TEX_COMPARE_NONE;
803
   sampler.compare_func = PIPE_FUNC_ALWAYS;
804
   sampler.normalized_coords = 1;
805
   dec->sampler_ycbcr = dec->base.context->create_sampler_state(dec->base.context, &sampler);
806
   if (!dec->sampler_ycbcr)
807
      return false;
808
 
809
   return true;
810
}
811
 
812
static const struct format_config*
813
find_format_config(struct vl_mpeg12_decoder *dec, const struct format_config configs[], unsigned num_configs)
814
{
815
   struct pipe_screen *screen;
816
   unsigned i;
817
 
818
   assert(dec);
819
 
820
   screen = dec->base.context->screen;
821
 
822
   for (i = 0; i < num_configs; ++i) {
823
      if (!screen->is_format_supported(screen, configs[i].zscan_source_format, PIPE_TEXTURE_2D,
824
                                       1, PIPE_BIND_SAMPLER_VIEW))
825
         continue;
826
 
827
      if (configs[i].idct_source_format != PIPE_FORMAT_NONE) {
828
         if (!screen->is_format_supported(screen, configs[i].idct_source_format, PIPE_TEXTURE_2D,
829
                                          1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET))
830
            continue;
831
 
832
         if (!screen->is_format_supported(screen, configs[i].mc_source_format, PIPE_TEXTURE_3D,
833
                                          1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET))
834
            continue;
835
      } else {
836
         if (!screen->is_format_supported(screen, configs[i].mc_source_format, PIPE_TEXTURE_2D,
837
                                          1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET))
838
            continue;
839
      }
840
      return &configs[i];
841
   }
842
 
843
   return NULL;
844
}
845
 
846
static bool
847
init_zscan(struct vl_mpeg12_decoder *dec, const struct format_config* format_config)
848
{
849
   unsigned num_channels;
850
 
851
   assert(dec);
852
 
853
   dec->zscan_source_format = format_config->zscan_source_format;
854
   dec->zscan_linear = vl_zscan_layout(dec->base.context, vl_zscan_linear, dec->blocks_per_line);
855
   dec->zscan_normal = vl_zscan_layout(dec->base.context, vl_zscan_normal, dec->blocks_per_line);
856
   dec->zscan_alternate = vl_zscan_layout(dec->base.context, vl_zscan_alternate, dec->blocks_per_line);
857
 
858
   num_channels = dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT ? 4 : 1;
859
 
860
   if (!vl_zscan_init(&dec->zscan_y, dec->base.context, dec->base.width, dec->base.height,
861
                      dec->blocks_per_line, dec->num_blocks, num_channels))
862
      return false;
863
 
864
   if (!vl_zscan_init(&dec->zscan_c, dec->base.context, dec->chroma_width, dec->chroma_height,
865
                      dec->blocks_per_line, dec->num_blocks, num_channels))
866
      return false;
867
 
868
   return true;
869
}
870
 
871
static bool
872
init_idct(struct vl_mpeg12_decoder *dec, const struct format_config* format_config)
873
{
874
   unsigned nr_of_idct_render_targets, max_inst;
875
   enum pipe_format formats[3];
876
   struct pipe_video_buffer templat;
877
 
878
   struct pipe_sampler_view *matrix = NULL;
879
 
880
   nr_of_idct_render_targets = dec->base.context->screen->get_param
881
   (
882
      dec->base.context->screen, PIPE_CAP_MAX_RENDER_TARGETS
883
   );
884
 
885
   max_inst = dec->base.context->screen->get_shader_param
886
   (
887
      dec->base.context->screen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_INSTRUCTIONS
888
   );
889
 
890
   // Just assume we need 32 inst per render target, not 100% true, but should work in most cases
891
   if (nr_of_idct_render_targets >= 4 && max_inst >= 32*4)
892
      // more than 4 render targets usually doesn't makes any seens
893
      nr_of_idct_render_targets = 4;
894
   else
895
      nr_of_idct_render_targets = 1;
896
 
897
   formats[0] = formats[1] = formats[2] = format_config->idct_source_format;
898
   memset(&templat, 0, sizeof(templat));
899
   templat.width = dec->base.width / 4;
900
   templat.height = dec->base.height;
901
   templat.chroma_format = dec->base.chroma_format;
902
   dec->idct_source = vl_video_buffer_create_ex
903
   (
904
      dec->base.context, &templat,
905
      formats, 1, 1, PIPE_USAGE_STATIC
906
   );
907
 
908
   if (!dec->idct_source)
909
      goto error_idct_source;
910
 
911
   formats[0] = formats[1] = formats[2] = format_config->mc_source_format;
912
   memset(&templat, 0, sizeof(templat));
913
   templat.width = dec->base.width / nr_of_idct_render_targets;
914
   templat.height = dec->base.height / 4;
915
   templat.chroma_format = dec->base.chroma_format;
916
   dec->mc_source = vl_video_buffer_create_ex
917
   (
918
      dec->base.context, &templat,
919
      formats, nr_of_idct_render_targets, 1, PIPE_USAGE_STATIC
920
   );
921
 
922
   if (!dec->mc_source)
923
      goto error_mc_source;
924
 
925
   if (!(matrix = vl_idct_upload_matrix(dec->base.context, format_config->idct_scale)))
926
      goto error_matrix;
927
 
928
   if (!vl_idct_init(&dec->idct_y, dec->base.context, dec->base.width, dec->base.height,
929
                     nr_of_idct_render_targets, matrix, matrix))
930
      goto error_y;
931
 
932
   if(!vl_idct_init(&dec->idct_c, dec->base.context, dec->chroma_width, dec->chroma_height,
933
                    nr_of_idct_render_targets, matrix, matrix))
934
      goto error_c;
935
 
936
   pipe_sampler_view_reference(&matrix, NULL);
937
 
938
   return true;
939
 
940
error_c:
941
   vl_idct_cleanup(&dec->idct_y);
942
 
943
error_y:
944
   pipe_sampler_view_reference(&matrix, NULL);
945
 
946
error_matrix:
947
   dec->mc_source->destroy(dec->mc_source);
948
 
949
error_mc_source:
950
   dec->idct_source->destroy(dec->idct_source);
951
 
952
error_idct_source:
953
   return false;
954
}
955
 
956
static bool
957
init_mc_source_widthout_idct(struct vl_mpeg12_decoder *dec, const struct format_config* format_config)
958
{
959
   enum pipe_format formats[3];
960
   struct pipe_video_buffer templat;
961
 
962
   formats[0] = formats[1] = formats[2] = format_config->mc_source_format;
963
   memset(&templat, 0, sizeof(templat));
964
   templat.width = dec->base.width;
965
   templat.height = dec->base.height;
966
   templat.chroma_format = dec->base.chroma_format;
967
   dec->mc_source = vl_video_buffer_create_ex
968
   (
969
      dec->base.context, &templat,
970
      formats, 1, 1, PIPE_USAGE_STATIC
971
   );
972
 
973
   return dec->mc_source != NULL;
974
}
975
 
976
static void
977
mc_vert_shader_callback(void *priv, struct vl_mc *mc,
978
                        struct ureg_program *shader,
979
                        unsigned first_output,
980
                        struct ureg_dst tex)
981
{
982
   struct vl_mpeg12_decoder *dec = priv;
983
   struct ureg_dst o_vtex;
984
 
985
   assert(priv && mc);
986
   assert(shader);
987
 
988
   if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
989
      struct vl_idct *idct = mc == &dec->mc_y ? &dec->idct_y : &dec->idct_c;
990
      vl_idct_stage2_vert_shader(idct, shader, first_output, tex);
991
   } else {
992
      o_vtex = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, first_output);
993
      ureg_MOV(shader, ureg_writemask(o_vtex, TGSI_WRITEMASK_XY), ureg_src(tex));
994
   }
995
}
996
 
997
static void
998
mc_frag_shader_callback(void *priv, struct vl_mc *mc,
999
                        struct ureg_program *shader,
1000
                        unsigned first_input,
1001
                        struct ureg_dst dst)
1002
{
1003
   struct vl_mpeg12_decoder *dec = priv;
1004
   struct ureg_src src, sampler;
1005
 
1006
   assert(priv && mc);
1007
   assert(shader);
1008
 
1009
   if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
1010
      struct vl_idct *idct = mc == &dec->mc_y ? &dec->idct_y : &dec->idct_c;
1011
      vl_idct_stage2_frag_shader(idct, shader, first_input, dst);
1012
   } else {
1013
      src = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, first_input, TGSI_INTERPOLATE_LINEAR);
1014
      sampler = ureg_DECL_sampler(shader, 0);
1015
      ureg_TEX(shader, dst, TGSI_TEXTURE_2D, src, sampler);
1016
   }
1017
}
1018
 
1019
struct pipe_video_decoder *
1020
vl_create_mpeg12_decoder(struct pipe_context *context,
1021
                         enum pipe_video_profile profile,
1022
                         enum pipe_video_entrypoint entrypoint,
1023
                         enum pipe_video_chroma_format chroma_format,
1024
                         unsigned width, unsigned height, unsigned max_references,
1025
                         bool expect_chunked_decode)
1026
{
1027
   const unsigned block_size_pixels = VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT;
1028
   const struct format_config *format_config;
1029
   struct vl_mpeg12_decoder *dec;
1030
 
1031
   assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12);
1032
 
1033
   dec = CALLOC_STRUCT(vl_mpeg12_decoder);
1034
 
1035
   if (!dec)
1036
      return NULL;
1037
 
1038
   dec->base.context = context;
1039
   dec->base.profile = profile;
1040
   dec->base.entrypoint = entrypoint;
1041
   dec->base.chroma_format = chroma_format;
1042
   dec->base.width = width;
1043
   dec->base.height = height;
1044
   dec->base.max_references = max_references;
1045
 
1046
   dec->base.destroy = vl_mpeg12_destroy;
1047
   dec->base.begin_frame = vl_mpeg12_begin_frame;
1048
   dec->base.decode_macroblock = vl_mpeg12_decode_macroblock;
1049
   dec->base.decode_bitstream = vl_mpeg12_decode_bitstream;
1050
   dec->base.end_frame = vl_mpeg12_end_frame;
1051
   dec->base.flush = vl_mpeg12_flush;
1052
 
1053
   dec->blocks_per_line = MAX2(util_next_power_of_two(dec->base.width) / block_size_pixels, 4);
1054
   dec->num_blocks = (dec->base.width * dec->base.height) / block_size_pixels;
1055
   dec->width_in_macroblocks = align(dec->base.width, VL_MACROBLOCK_WIDTH) / VL_MACROBLOCK_WIDTH;
1056
   dec->expect_chunked_decode = expect_chunked_decode;
1057
 
1058
   /* TODO: Implement 422, 444 */
1059
   assert(dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
1060
 
1061
   if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
1062
      dec->chroma_width = dec->base.width / 2;
1063
      dec->chroma_height = dec->base.height / 2;
1064
      dec->num_blocks = dec->num_blocks * 2;
1065
   } else if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) {
1066
      dec->chroma_width = dec->base.width;
1067
      dec->chroma_height = dec->base.height / 2;
1068
      dec->num_blocks = dec->num_blocks * 2 + dec->num_blocks;
1069
   } else {
1070
      dec->chroma_width = dec->base.width;
1071
      dec->chroma_height = dec->base.height;
1072
      dec->num_blocks = dec->num_blocks * 3;
1073
   }
1074
 
1075
   dec->quads = vl_vb_upload_quads(dec->base.context);
1076
   dec->pos = vl_vb_upload_pos(
1077
      dec->base.context,
1078
      dec->base.width / VL_MACROBLOCK_WIDTH,
1079
      dec->base.height / VL_MACROBLOCK_HEIGHT
1080
   );
1081
 
1082
   dec->ves_ycbcr = vl_vb_get_ves_ycbcr(dec->base.context);
1083
   dec->ves_mv = vl_vb_get_ves_mv(dec->base.context);
1084
 
1085
   switch (entrypoint) {
1086
   case PIPE_VIDEO_ENTRYPOINT_BITSTREAM:
1087
      format_config = find_format_config(dec, bitstream_format_config, num_bitstream_format_configs);
1088
      break;
1089
 
1090
   case PIPE_VIDEO_ENTRYPOINT_IDCT:
1091
      format_config = find_format_config(dec, idct_format_config, num_idct_format_configs);
1092
      break;
1093
 
1094
   case PIPE_VIDEO_ENTRYPOINT_MC:
1095
      format_config = find_format_config(dec, mc_format_config, num_mc_format_configs);
1096
      break;
1097
 
1098
   default:
1099
      assert(0);
1100
      FREE(dec);
1101
      return NULL;
1102
   }
1103
 
1104
   if (!format_config) {
1105
      FREE(dec);
1106
      return NULL;
1107
   }
1108
 
1109
   if (!init_zscan(dec, format_config))
1110
      goto error_zscan;
1111
 
1112
   if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
1113
      if (!init_idct(dec, format_config))
1114
         goto error_sources;
1115
   } else {
1116
      if (!init_mc_source_widthout_idct(dec, format_config))
1117
         goto error_sources;
1118
   }
1119
 
1120
   if (!vl_mc_init(&dec->mc_y, dec->base.context, dec->base.width, dec->base.height,
1121
                   VL_MACROBLOCK_HEIGHT, format_config->mc_scale,
1122
                   mc_vert_shader_callback, mc_frag_shader_callback, dec))
1123
      goto error_mc_y;
1124
 
1125
   // TODO
1126
   if (!vl_mc_init(&dec->mc_c, dec->base.context, dec->base.width, dec->base.height,
1127
                   VL_BLOCK_HEIGHT, format_config->mc_scale,
1128
                   mc_vert_shader_callback, mc_frag_shader_callback, dec))
1129
      goto error_mc_c;
1130
 
1131
   if (!init_pipe_state(dec))
1132
      goto error_pipe_state;
1133
 
1134
   return &dec->base;
1135
 
1136
error_pipe_state:
1137
   vl_mc_cleanup(&dec->mc_c);
1138
 
1139
error_mc_c:
1140
   vl_mc_cleanup(&dec->mc_y);
1141
 
1142
error_mc_y:
1143
   if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
1144
      vl_idct_cleanup(&dec->idct_y);
1145
      vl_idct_cleanup(&dec->idct_c);
1146
      dec->idct_source->destroy(dec->idct_source);
1147
   }
1148
   dec->mc_source->destroy(dec->mc_source);
1149
 
1150
error_sources:
1151
   vl_zscan_cleanup(&dec->zscan_y);
1152
   vl_zscan_cleanup(&dec->zscan_c);
1153
 
1154
error_zscan:
1155
   FREE(dec);
1156
   return NULL;
1157
}