vl_mpeg12_decoder.c revision 912dc8ff09cd7c28926762c2e562de5a99d3e27a
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 <math.h>
29#include <assert.h>
30
31#include <util/u_memory.h>
32#include <util/u_rect.h>
33#include <util/u_video.h>
34
35#include "vl_mpeg12_decoder.h"
36#include "vl_defines.h"
37
38#define SCALE_FACTOR_SNORM (32768.0f / 256.0f)
39#define SCALE_FACTOR_SSCALED (1.0f / 256.0f)
40
41struct format_config {
42   enum pipe_format zscan_source_format;
43   enum pipe_format idct_source_format;
44   enum pipe_format mc_source_format;
45
46   float idct_scale;
47   float mc_scale;
48};
49
50static const struct format_config bitstream_format_config[] = {
51   { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SSCALED },
52   { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, 1.0f, SCALE_FACTOR_SSCALED },
53   { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SNORM },
54   { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, 1.0f, SCALE_FACTOR_SNORM }
55};
56
57static const unsigned num_bitstream_format_configs =
58   sizeof(bitstream_format_config) / sizeof(struct format_config);
59
60static const struct format_config idct_format_config[] = {
61   { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SSCALED },
62   { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, 1.0f, SCALE_FACTOR_SSCALED },
63   { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SNORM },
64   { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, 1.0f, SCALE_FACTOR_SNORM }
65};
66
67static const unsigned num_idct_format_configs =
68   sizeof(idct_format_config) / sizeof(struct format_config);
69
70static const struct format_config mc_format_config[] = {
71   //{ PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_NONE, PIPE_FORMAT_R16_SSCALED, 0.0f, SCALE_FACTOR_SSCALED },
72   { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_NONE, PIPE_FORMAT_R16_SNORM, 0.0f, SCALE_FACTOR_SNORM }
73};
74
75static const unsigned num_mc_format_configs =
76   sizeof(mc_format_config) / sizeof(struct format_config);
77
78static bool
79init_zscan_buffer(struct vl_mpeg12_buffer *buffer)
80{
81   enum pipe_format formats[3];
82
83   struct pipe_sampler_view **source;
84   struct pipe_surface **destination;
85
86   struct vl_mpeg12_decoder *dec;
87
88   unsigned i;
89
90   assert(buffer);
91
92   dec = (struct vl_mpeg12_decoder*)buffer->base.decoder;
93
94   formats[0] = formats[1] = formats[2] = dec->zscan_source_format;
95   buffer->zscan_source = vl_video_buffer_init(dec->base.context, dec->pipe,
96                                               dec->blocks_per_line * BLOCK_WIDTH * BLOCK_HEIGHT,
97                                               dec->max_blocks / dec->blocks_per_line,
98                                               1, PIPE_VIDEO_CHROMA_FORMAT_444,
99                                               formats, PIPE_USAGE_STATIC);
100   if (!buffer->zscan_source)
101      goto error_source;
102
103   source = buffer->zscan_source->get_sampler_view_planes(buffer->zscan_source);
104   if (!source)
105      goto error_sampler;
106
107   if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
108      destination = dec->idct_source->get_surfaces(dec->idct_source);
109   else
110      destination = dec->mc_source->get_surfaces(dec->mc_source);
111
112   if (!destination)
113      goto error_surface;
114
115   for (i = 0; i < VL_MAX_PLANES; ++i)
116      if (!vl_zscan_init_buffer(i == 0 ? &dec->zscan_y : &dec->zscan_c,
117                                &buffer->zscan[i], source[i], destination[i]))
118         goto error_plane;
119
120   return true;
121
122error_plane:
123   for (; i > 0; --i)
124      vl_zscan_cleanup_buffer(&buffer->zscan[i - 1]);
125
126error_surface:
127error_sampler:
128   buffer->zscan_source->destroy(buffer->zscan_source);
129
130error_source:
131   return false;
132}
133
134static void
135cleanup_zscan_buffer(struct vl_mpeg12_buffer *buffer)
136{
137   unsigned i;
138
139   assert(buffer);
140
141   for (i = 0; i < VL_MAX_PLANES; ++i)
142      vl_zscan_cleanup_buffer(&buffer->zscan[i]);
143   buffer->zscan_source->destroy(buffer->zscan_source);
144}
145
146static bool
147init_idct_buffer(struct vl_mpeg12_buffer *buffer)
148{
149   struct pipe_sampler_view **idct_source_sv, **mc_source_sv;
150
151   struct vl_mpeg12_decoder *dec;
152
153   unsigned i;
154
155   assert(buffer);
156
157   dec = (struct vl_mpeg12_decoder*)buffer->base.decoder;
158
159   idct_source_sv = dec->idct_source->get_sampler_view_planes(dec->idct_source);
160   if (!idct_source_sv)
161      goto error_source_sv;
162
163   mc_source_sv = dec->mc_source->get_sampler_view_planes(dec->mc_source);
164   if (!mc_source_sv)
165      goto error_mc_source_sv;
166
167   for (i = 0; i < 3; ++i)
168      if (!vl_idct_init_buffer(i == 0 ? &dec->idct_y : &dec->idct_c,
169                               &buffer->idct[i], idct_source_sv[i],
170                               mc_source_sv[i]))
171         goto error_plane;
172
173   return true;
174
175error_plane:
176   for (; i > 0; --i)
177      vl_idct_cleanup_buffer(i == 1 ? &dec->idct_c : &dec->idct_y, &buffer->idct[i - 1]);
178
179error_mc_source_sv:
180error_source_sv:
181   return false;
182}
183
184static void
185cleanup_idct_buffer(struct vl_mpeg12_buffer *buf)
186{
187   struct vl_mpeg12_decoder *dec;
188   assert(buf);
189
190   dec = (struct vl_mpeg12_decoder*)buf->base.decoder;
191   assert(dec);
192
193   vl_idct_cleanup_buffer(&dec->idct_y, &buf->idct[0]);
194   vl_idct_cleanup_buffer(&dec->idct_c, &buf->idct[1]);
195   vl_idct_cleanup_buffer(&dec->idct_c, &buf->idct[2]);
196}
197
198static bool
199init_mc_buffer(struct vl_mpeg12_buffer *buf)
200{
201   struct vl_mpeg12_decoder *dec;
202
203   assert(buf);
204
205   dec = (struct vl_mpeg12_decoder*)buf->base.decoder;
206   assert(dec);
207
208   if(!vl_mc_init_buffer(&dec->mc_y, &buf->mc[0]))
209      goto error_mc_y;
210
211   if(!vl_mc_init_buffer(&dec->mc_c, &buf->mc[1]))
212      goto error_mc_cb;
213
214   if(!vl_mc_init_buffer(&dec->mc_c, &buf->mc[2]))
215      goto error_mc_cr;
216
217   return true;
218
219error_mc_cr:
220   vl_mc_cleanup_buffer(&buf->mc[1]);
221
222error_mc_cb:
223   vl_mc_cleanup_buffer(&buf->mc[0]);
224
225error_mc_y:
226   return false;
227}
228
229static void
230cleanup_mc_buffer(struct vl_mpeg12_buffer *buf)
231{
232   unsigned i;
233
234   assert(buf);
235
236   for (i = 0; i < VL_MAX_PLANES; ++i)
237      vl_mc_cleanup_buffer(&buf->mc[i]);
238}
239
240static void
241vl_mpeg12_buffer_destroy(struct pipe_video_decode_buffer *buffer)
242{
243   struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
244   struct vl_mpeg12_decoder *dec;
245
246   assert(buf);
247
248   dec = (struct vl_mpeg12_decoder*)buf->base.decoder;
249   assert(dec);
250
251   cleanup_zscan_buffer(buf);
252
253   if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
254      cleanup_idct_buffer(buf);
255
256   cleanup_mc_buffer(buf);
257
258   vl_vb_cleanup(&buf->vertex_stream);
259
260   FREE(buf);
261}
262
263static void
264vl_mpeg12_buffer_map(struct pipe_video_decode_buffer *buffer)
265{
266   struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
267   struct vl_mpeg12_decoder *dec;
268
269   struct pipe_sampler_view **sampler_views;
270   unsigned i;
271
272   assert(buf);
273
274   dec = (struct vl_mpeg12_decoder *)buf->base.decoder;
275   assert(dec);
276
277   vl_vb_map(&buf->vertex_stream, dec->pipe);
278
279   sampler_views = buf->zscan_source->get_sampler_view_planes(buf->zscan_source);
280
281   assert(sampler_views);
282
283   for (i = 0; i < VL_MAX_PLANES; ++i) {
284      struct pipe_resource *tex = sampler_views[i]->texture;
285      struct pipe_box rect =
286      {
287         0, 0, 0,
288         tex->width0,
289         tex->height0,
290         1
291      };
292
293      buf->tex_transfer[i] = dec->pipe->get_transfer
294      (
295         dec->pipe, tex,
296         0, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
297         &rect
298      );
299
300      buf->texels[i] = dec->pipe->transfer_map(dec->pipe, buf->tex_transfer[i]);
301   }
302
303   if (dec->base.entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM) {
304      struct pipe_ycbcr_block *ycbcr_stream[VL_MAX_PLANES];
305      struct pipe_motionvector *mv_stream[VL_MAX_REF_FRAMES];
306
307      for (i = 0; i < VL_MAX_PLANES; ++i)
308         ycbcr_stream[i] = vl_vb_get_ycbcr_stream(&buf->vertex_stream, i);
309
310      for (i = 0; i < VL_MAX_REF_FRAMES; ++i)
311         mv_stream[i] = vl_vb_get_mv_stream(&buf->vertex_stream, i);
312
313      vl_mpg12_bs_set_buffers(&buf->bs, ycbcr_stream, buf->texels, mv_stream);
314   } else {
315      static const uint8_t dummy_quant[64] = {
316         0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
317         0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
318         0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
319         0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
320         0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
321         0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
322         0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
323         0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10
324      };
325
326      for (i = 0; i < VL_MAX_PLANES; ++i) {
327         vl_zscan_set_layout(&buf->zscan[i], dec->zscan_linear);
328         vl_zscan_upload_quant(&buf->zscan[i], dummy_quant, dummy_quant);
329      }
330   }
331}
332
333static struct pipe_ycbcr_block *
334vl_mpeg12_buffer_get_ycbcr_stream(struct pipe_video_decode_buffer *buffer, int component)
335{
336   struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
337
338   assert(buf);
339
340   return vl_vb_get_ycbcr_stream(&buf->vertex_stream, component);
341}
342
343static short *
344vl_mpeg12_buffer_get_ycbcr_buffer(struct pipe_video_decode_buffer *buffer, int component)
345{
346   struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
347
348   assert(buf);
349   assert(component < VL_MAX_PLANES);
350
351   return buf->texels[component];
352}
353
354static unsigned
355vl_mpeg12_buffer_get_mv_stream_stride(struct pipe_video_decode_buffer *buffer)
356{
357   struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
358
359   assert(buf);
360
361   return vl_vb_get_mv_stream_stride(&buf->vertex_stream);
362}
363
364static struct pipe_motionvector *
365vl_mpeg12_buffer_get_mv_stream(struct pipe_video_decode_buffer *buffer, int ref_frame)
366{
367   struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
368
369   assert(buf);
370
371   return vl_vb_get_mv_stream(&buf->vertex_stream, ref_frame);
372}
373
374static void
375vl_mpeg12_buffer_decode_bitstream(struct pipe_video_decode_buffer *buffer,
376                                  unsigned num_bytes, const void *data,
377                                  struct pipe_mpeg12_picture_desc *picture,
378                                  unsigned num_ycbcr_blocks[3])
379{
380   struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
381   uint8_t intra_quantizer_matrix[64];
382   struct vl_mpeg12_decoder *dec;
383   unsigned i;
384
385   assert(buf);
386
387   dec = (struct vl_mpeg12_decoder *)buf->base.decoder;
388   assert(dec);
389
390   memcpy(intra_quantizer_matrix, picture->intra_quantizer_matrix, sizeof(intra_quantizer_matrix));
391   intra_quantizer_matrix[0] = 1 << (7 - picture->intra_dc_precision);
392
393   for (i = 0; i < VL_MAX_PLANES; ++i) {
394      vl_zscan_set_layout(&buf->zscan[i], picture->alternate_scan ? dec->zscan_alternate : dec->zscan_normal);
395      vl_zscan_upload_quant(&buf->zscan[i], intra_quantizer_matrix, picture->non_intra_quantizer_matrix);
396   }
397
398   vl_mpg12_bs_decode(&buf->bs, num_bytes, data, picture, num_ycbcr_blocks);
399}
400
401static void
402vl_mpeg12_buffer_unmap(struct pipe_video_decode_buffer *buffer)
403{
404   struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
405   struct vl_mpeg12_decoder *dec;
406   unsigned i;
407
408   assert(buf);
409
410   dec = (struct vl_mpeg12_decoder *)buf->base.decoder;
411   assert(dec);
412
413   vl_vb_unmap(&buf->vertex_stream, dec->pipe);
414
415   for (i = 0; i < VL_MAX_PLANES; ++i) {
416      dec->pipe->transfer_unmap(dec->pipe, buf->tex_transfer[i]);
417      dec->pipe->transfer_destroy(dec->pipe, buf->tex_transfer[i]);
418   }
419}
420
421static void
422vl_mpeg12_destroy(struct pipe_video_decoder *decoder)
423{
424   struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder*)decoder;
425
426   assert(decoder);
427
428   /* Asserted in softpipe_delete_fs_state() for some reason */
429   dec->pipe->bind_vs_state(dec->pipe, NULL);
430   dec->pipe->bind_fs_state(dec->pipe, NULL);
431
432   dec->pipe->delete_depth_stencil_alpha_state(dec->pipe, dec->dsa);
433   dec->pipe->delete_sampler_state(dec->pipe, dec->sampler_ycbcr);
434
435   vl_mc_cleanup(&dec->mc_y);
436   vl_mc_cleanup(&dec->mc_c);
437   dec->mc_source->destroy(dec->mc_source);
438
439   if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
440      vl_idct_cleanup(&dec->idct_y);
441      vl_idct_cleanup(&dec->idct_c);
442      dec->idct_source->destroy(dec->idct_source);
443   }
444
445   vl_zscan_cleanup(&dec->zscan_y);
446   vl_zscan_cleanup(&dec->zscan_c);
447
448   dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves_ycbcr);
449   dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves_mv);
450
451   pipe_resource_reference(&dec->quads.buffer, NULL);
452   pipe_resource_reference(&dec->pos.buffer, NULL);
453
454   pipe_sampler_view_reference(&dec->zscan_linear, NULL);
455   pipe_sampler_view_reference(&dec->zscan_normal, NULL);
456   pipe_sampler_view_reference(&dec->zscan_alternate, NULL);
457
458   FREE(dec);
459}
460
461static struct pipe_video_decode_buffer *
462vl_mpeg12_create_buffer(struct pipe_video_decoder *decoder)
463{
464   struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder*)decoder;
465   struct vl_mpeg12_buffer *buffer;
466
467   assert(dec);
468
469   buffer = CALLOC_STRUCT(vl_mpeg12_buffer);
470   if (buffer == NULL)
471      return NULL;
472
473   buffer->base.decoder = decoder;
474   buffer->base.destroy = vl_mpeg12_buffer_destroy;
475   buffer->base.map = vl_mpeg12_buffer_map;
476   buffer->base.get_ycbcr_stream = vl_mpeg12_buffer_get_ycbcr_stream;
477   buffer->base.get_ycbcr_buffer = vl_mpeg12_buffer_get_ycbcr_buffer;
478   buffer->base.get_mv_stream_stride = vl_mpeg12_buffer_get_mv_stream_stride;
479   buffer->base.get_mv_stream = vl_mpeg12_buffer_get_mv_stream;
480   buffer->base.decode_bitstream = vl_mpeg12_buffer_decode_bitstream;
481   buffer->base.unmap = vl_mpeg12_buffer_unmap;
482
483   if (!vl_vb_init(&buffer->vertex_stream, dec->pipe,
484                   dec->base.width / MACROBLOCK_WIDTH,
485                   dec->base.height / MACROBLOCK_HEIGHT))
486      goto error_vertex_buffer;
487
488   if (!init_mc_buffer(buffer))
489      goto error_mc;
490
491   if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
492      if (!init_idct_buffer(buffer))
493         goto error_idct;
494
495   if (!init_zscan_buffer(buffer))
496      goto error_zscan;
497
498   if (dec->base.entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM)
499      vl_mpg12_bs_init(&buffer->bs,
500                       dec->base.width / MACROBLOCK_WIDTH,
501                       dec->base.height / MACROBLOCK_HEIGHT);
502
503   return &buffer->base;
504
505error_zscan:
506   if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
507      cleanup_idct_buffer(buffer);
508
509error_idct:
510   cleanup_mc_buffer(buffer);
511
512error_mc:
513   vl_vb_cleanup(&buffer->vertex_stream);
514
515error_vertex_buffer:
516   FREE(buffer);
517   return NULL;
518}
519
520static void
521vl_mpeg12_decoder_flush_buffer(struct pipe_video_decode_buffer *buffer,
522                               unsigned num_ycbcr_blocks[3],
523                               struct pipe_video_buffer *refs[2],
524                               struct pipe_video_buffer *dst)
525{
526   struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer *)buffer;
527   struct vl_mpeg12_decoder *dec;
528
529   struct pipe_sampler_view **sv[VL_MAX_REF_FRAMES], **mc_source_sv;
530   struct pipe_surface **surfaces;
531
532   struct pipe_vertex_buffer vb[3];
533
534   unsigned i, j, component;
535   unsigned nr_components;
536
537   assert(buf);
538
539   dec = (struct vl_mpeg12_decoder *)buf->base.decoder;
540   assert(dec);
541
542   for (i = 0; i < 2; ++i)
543      sv[i] = refs[i] ? refs[i]->get_sampler_view_planes(refs[i]) : NULL;
544
545   vb[0] = dec->quads;
546   vb[1] = dec->pos;
547
548   surfaces = dst->get_surfaces(dst);
549
550   dec->pipe->bind_vertex_elements_state(dec->pipe, dec->ves_mv);
551   for (i = 0; i < VL_MAX_PLANES; ++i) {
552      if (!surfaces[i]) continue;
553
554      vl_mc_set_surface(&buf->mc[i], surfaces[i]);
555
556      for (j = 0; j < VL_MAX_REF_FRAMES; ++j) {
557         if (!sv[j]) continue;
558
559         vb[2] = vl_vb_get_mv(&buf->vertex_stream, j);;
560         dec->pipe->set_vertex_buffers(dec->pipe, 3, vb);
561
562         vl_mc_render_ref(&buf->mc[i], sv[j][i]);
563      }
564   }
565
566   dec->pipe->bind_vertex_elements_state(dec->pipe, dec->ves_ycbcr);
567   for (i = 0; i < VL_MAX_PLANES; ++i) {
568      if (!num_ycbcr_blocks[i]) continue;
569
570      vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, i);
571      dec->pipe->set_vertex_buffers(dec->pipe, 2, vb);
572
573      vl_zscan_render(&buf->zscan[i] , num_ycbcr_blocks[i]);
574
575      if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
576         vl_idct_flush(i == 0 ? &dec->idct_y : &dec->idct_c, &buf->idct[i], num_ycbcr_blocks[i]);
577   }
578
579   mc_source_sv = dec->mc_source->get_sampler_view_planes(dec->mc_source);
580   for (i = 0, component = 0; i < VL_MAX_PLANES; ++i) {
581      if (!surfaces[i]) continue;
582
583      nr_components = util_format_get_nr_components(surfaces[i]->texture->format);
584      for (j = 0; j < nr_components; ++j, ++component) {
585         if (!num_ycbcr_blocks[i]) continue;
586
587         vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, component);
588         dec->pipe->set_vertex_buffers(dec->pipe, 2, vb);
589
590         if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
591            vl_idct_prepare_stage2(component == 0 ? &dec->idct_y : &dec->idct_c, &buf->idct[component]);
592         else {
593            dec->pipe->set_fragment_sampler_views(dec->pipe, 1, &mc_source_sv[component]);
594            dec->pipe->bind_fragment_sampler_states(dec->pipe, 1, &dec->sampler_ycbcr);
595         }
596         vl_mc_render_ycbcr(&buf->mc[i], j, num_ycbcr_blocks[component]);
597      }
598   }
599}
600
601static bool
602init_pipe_state(struct vl_mpeg12_decoder *dec)
603{
604   struct pipe_depth_stencil_alpha_state dsa;
605   struct pipe_sampler_state sampler;
606   unsigned i;
607
608   assert(dec);
609
610   memset(&dsa, 0, sizeof dsa);
611   dsa.depth.enabled = 0;
612   dsa.depth.writemask = 0;
613   dsa.depth.func = PIPE_FUNC_ALWAYS;
614   for (i = 0; i < 2; ++i) {
615      dsa.stencil[i].enabled = 0;
616      dsa.stencil[i].func = PIPE_FUNC_ALWAYS;
617      dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP;
618      dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP;
619      dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP;
620      dsa.stencil[i].valuemask = 0;
621      dsa.stencil[i].writemask = 0;
622   }
623   dsa.alpha.enabled = 0;
624   dsa.alpha.func = PIPE_FUNC_ALWAYS;
625   dsa.alpha.ref_value = 0;
626   dec->dsa = dec->pipe->create_depth_stencil_alpha_state(dec->pipe, &dsa);
627   dec->pipe->bind_depth_stencil_alpha_state(dec->pipe, dec->dsa);
628
629   memset(&sampler, 0, sizeof(sampler));
630   sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
631   sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
632   sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_BORDER;
633   sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
634   sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
635   sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
636   sampler.compare_mode = PIPE_TEX_COMPARE_NONE;
637   sampler.compare_func = PIPE_FUNC_ALWAYS;
638   sampler.normalized_coords = 1;
639   dec->sampler_ycbcr = dec->pipe->create_sampler_state(dec->pipe, &sampler);
640   if (!dec->sampler_ycbcr)
641      return false;
642
643   return true;
644}
645
646static const struct format_config*
647find_format_config(struct vl_mpeg12_decoder *dec, const struct format_config configs[], unsigned num_configs)
648{
649   struct pipe_screen *screen;
650   unsigned i;
651
652   assert(dec);
653
654   screen = dec->pipe->screen;
655
656   for (i = 0; i < num_configs; ++i) {
657      if (!screen->is_format_supported(screen, configs[i].zscan_source_format, PIPE_TEXTURE_2D,
658                                       1, PIPE_BIND_SAMPLER_VIEW))
659         continue;
660
661      if (configs[i].idct_source_format != PIPE_FORMAT_NONE) {
662         if (!screen->is_format_supported(screen, configs[i].idct_source_format, PIPE_TEXTURE_2D,
663                                          1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET))
664            continue;
665
666         if (!screen->is_format_supported(screen, configs[i].mc_source_format, PIPE_TEXTURE_3D,
667                                          1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET))
668            continue;
669      } else {
670         if (!screen->is_format_supported(screen, configs[i].mc_source_format, PIPE_TEXTURE_2D,
671                                          1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET))
672            continue;
673      }
674      return &configs[i];
675   }
676
677   return NULL;
678}
679
680static bool
681init_zscan(struct vl_mpeg12_decoder *dec, const struct format_config* format_config)
682{
683   unsigned num_channels;
684
685   assert(dec);
686
687   dec->blocks_per_line = 4;
688   dec->max_blocks =
689      (dec->base.width * dec->base.height) /
690      (BLOCK_WIDTH * BLOCK_HEIGHT);
691
692   dec->zscan_source_format = format_config->zscan_source_format;
693   dec->zscan_linear = vl_zscan_layout(dec->pipe, vl_zscan_linear, dec->blocks_per_line);
694   dec->zscan_normal = vl_zscan_layout(dec->pipe, vl_zscan_normal, dec->blocks_per_line);
695   dec->zscan_alternate = vl_zscan_layout(dec->pipe, vl_zscan_alternate, dec->blocks_per_line);
696
697   num_channels = dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT ? 4 : 1;
698
699   if (!vl_zscan_init(&dec->zscan_y, dec->pipe, dec->base.width, dec->base.height,
700                      dec->blocks_per_line, dec->max_blocks, num_channels))
701      return false;
702
703   if (!vl_zscan_init(&dec->zscan_c, dec->pipe, dec->chroma_width, dec->chroma_height,
704                      dec->blocks_per_line, dec->max_blocks, num_channels))
705      return false;
706
707   return true;
708}
709
710static bool
711init_idct(struct vl_mpeg12_decoder *dec, const struct format_config* format_config)
712{
713   unsigned nr_of_idct_render_targets;
714   enum pipe_format formats[3];
715
716   struct pipe_sampler_view *matrix = NULL;
717
718   nr_of_idct_render_targets = dec->pipe->screen->get_param(dec->pipe->screen, PIPE_CAP_MAX_RENDER_TARGETS);
719
720   // more than 4 render targets usually doesn't makes any seens
721   nr_of_idct_render_targets = MIN2(nr_of_idct_render_targets, 4);
722
723   formats[0] = formats[1] = formats[2] = format_config->idct_source_format;
724   dec->idct_source = vl_video_buffer_init(dec->base.context, dec->pipe,
725                                           dec->base.width / 4, dec->base.height, 1,
726                                           dec->base.chroma_format,
727                                           formats, PIPE_USAGE_STATIC);
728   if (!dec->idct_source)
729      goto error_idct_source;
730
731   formats[0] = formats[1] = formats[2] = format_config->mc_source_format;
732   dec->mc_source = vl_video_buffer_init(dec->base.context, dec->pipe,
733                                         dec->base.width / nr_of_idct_render_targets,
734                                         dec->base.height / 4, nr_of_idct_render_targets,
735                                         dec->base.chroma_format,
736                                         formats, PIPE_USAGE_STATIC);
737
738   if (!dec->mc_source)
739      goto error_mc_source;
740
741   if (!(matrix = vl_idct_upload_matrix(dec->pipe, format_config->idct_scale)))
742      goto error_matrix;
743
744   if (!vl_idct_init(&dec->idct_y, dec->pipe, dec->base.width, dec->base.height,
745                     nr_of_idct_render_targets, matrix, matrix))
746      goto error_y;
747
748   if(!vl_idct_init(&dec->idct_c, dec->pipe, dec->chroma_width, dec->chroma_height,
749                    nr_of_idct_render_targets, matrix, matrix))
750      goto error_c;
751
752   pipe_sampler_view_reference(&matrix, NULL);
753
754   return true;
755
756error_c:
757   vl_idct_cleanup(&dec->idct_y);
758
759error_y:
760   pipe_sampler_view_reference(&matrix, NULL);
761
762error_matrix:
763   dec->mc_source->destroy(dec->mc_source);
764
765error_mc_source:
766   dec->idct_source->destroy(dec->idct_source);
767
768error_idct_source:
769   return false;
770}
771
772static bool
773init_mc_source_widthout_idct(struct vl_mpeg12_decoder *dec, const struct format_config* format_config)
774{
775   enum pipe_format formats[3];
776
777   formats[0] = formats[1] = formats[2] = format_config->mc_source_format;
778   dec->mc_source = vl_video_buffer_init(dec->base.context, dec->pipe,
779                                         dec->base.width, dec->base.height, 1,
780                                         dec->base.chroma_format,
781                                         formats, PIPE_USAGE_STATIC);
782
783   return dec->mc_source != NULL;
784}
785
786static void
787mc_vert_shader_callback(void *priv, struct vl_mc *mc,
788                        struct ureg_program *shader,
789                        unsigned first_output,
790                        struct ureg_dst tex)
791{
792   struct vl_mpeg12_decoder *dec = priv;
793   struct ureg_dst o_vtex;
794
795   assert(priv && mc);
796   assert(shader);
797
798   if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
799      struct vl_idct *idct = mc == &dec->mc_y ? &dec->idct_y : &dec->idct_c;
800      vl_idct_stage2_vert_shader(idct, shader, first_output, tex);
801   } else {
802      o_vtex = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, first_output);
803      ureg_MOV(shader, ureg_writemask(o_vtex, TGSI_WRITEMASK_XY), ureg_src(tex));
804   }
805}
806
807static void
808mc_frag_shader_callback(void *priv, struct vl_mc *mc,
809                        struct ureg_program *shader,
810                        unsigned first_input,
811                        struct ureg_dst dst)
812{
813   struct vl_mpeg12_decoder *dec = priv;
814   struct ureg_src src, sampler;
815
816   assert(priv && mc);
817   assert(shader);
818
819   if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
820      struct vl_idct *idct = mc == &dec->mc_y ? &dec->idct_y : &dec->idct_c;
821      vl_idct_stage2_frag_shader(idct, shader, first_input, dst);
822   } else {
823      src = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, first_input, TGSI_INTERPOLATE_LINEAR);
824      sampler = ureg_DECL_sampler(shader, 0);
825      ureg_TEX(shader, dst, TGSI_TEXTURE_2D, src, sampler);
826   }
827}
828
829struct pipe_video_decoder *
830vl_create_mpeg12_decoder(struct pipe_video_context *context,
831                         struct pipe_context *pipe,
832                         enum pipe_video_profile profile,
833                         enum pipe_video_entrypoint entrypoint,
834                         enum pipe_video_chroma_format chroma_format,
835                         unsigned width, unsigned height)
836{
837   const struct format_config *format_config;
838   struct vl_mpeg12_decoder *dec;
839
840   assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12);
841
842   dec = CALLOC_STRUCT(vl_mpeg12_decoder);
843
844   if (!dec)
845      return NULL;
846
847   dec->base.context = context;
848   dec->base.profile = profile;
849   dec->base.entrypoint = entrypoint;
850   dec->base.chroma_format = chroma_format;
851   dec->base.width = width;
852   dec->base.height = height;
853
854   dec->base.destroy = vl_mpeg12_destroy;
855   dec->base.create_buffer = vl_mpeg12_create_buffer;
856   dec->base.flush_buffer = vl_mpeg12_decoder_flush_buffer;
857
858   dec->pipe = pipe;
859
860   dec->quads = vl_vb_upload_quads(dec->pipe);
861   dec->pos = vl_vb_upload_pos(
862      dec->pipe,
863      dec->base.width / MACROBLOCK_WIDTH,
864      dec->base.height / MACROBLOCK_HEIGHT
865   );
866
867   dec->ves_ycbcr = vl_vb_get_ves_ycbcr(dec->pipe);
868   dec->ves_mv = vl_vb_get_ves_mv(dec->pipe);
869
870   /* TODO: Implement 422, 444 */
871   assert(dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
872
873   if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
874      dec->chroma_width = dec->base.width / 2;
875      dec->chroma_height = dec->base.height / 2;
876   } else if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) {
877      dec->chroma_width = dec->base.width;
878      dec->chroma_height = dec->base.height / 2;
879   } else {
880      dec->chroma_width = dec->base.width;
881      dec->chroma_height = dec->base.height;
882   }
883
884   switch (entrypoint) {
885   case PIPE_VIDEO_ENTRYPOINT_BITSTREAM:
886      format_config = find_format_config(dec, bitstream_format_config, num_bitstream_format_configs);
887      break;
888
889   case PIPE_VIDEO_ENTRYPOINT_IDCT:
890      format_config = find_format_config(dec, idct_format_config, num_idct_format_configs);
891      break;
892
893   case PIPE_VIDEO_ENTRYPOINT_MC:
894      format_config = find_format_config(dec, mc_format_config, num_mc_format_configs);
895      break;
896
897   default:
898      assert(0);
899      return NULL;
900   }
901
902   if (!format_config)
903      return NULL;
904
905   if (!init_zscan(dec, format_config))
906      goto error_zscan;
907
908   if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
909      if (!init_idct(dec, format_config))
910         goto error_sources;
911   } else {
912      if (!init_mc_source_widthout_idct(dec, format_config))
913         goto error_sources;
914   }
915
916   if (!vl_mc_init(&dec->mc_y, dec->pipe, dec->base.width, dec->base.height, MACROBLOCK_HEIGHT, format_config->mc_scale,
917                   mc_vert_shader_callback, mc_frag_shader_callback, dec))
918      goto error_mc_y;
919
920   // TODO
921   if (!vl_mc_init(&dec->mc_c, dec->pipe, dec->base.width, dec->base.height, BLOCK_HEIGHT, format_config->mc_scale,
922                   mc_vert_shader_callback, mc_frag_shader_callback, dec))
923      goto error_mc_c;
924
925   if (!init_pipe_state(dec))
926      goto error_pipe_state;
927
928   return &dec->base;
929
930error_pipe_state:
931   vl_mc_cleanup(&dec->mc_c);
932
933error_mc_c:
934   vl_mc_cleanup(&dec->mc_y);
935
936error_mc_y:
937   if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
938      vl_idct_cleanup(&dec->idct_y);
939      vl_idct_cleanup(&dec->idct_c);
940      dec->idct_source->destroy(dec->idct_source);
941   }
942   dec->mc_source->destroy(dec->mc_source);
943
944error_sources:
945   vl_zscan_cleanup(&dec->zscan_y);
946   vl_zscan_cleanup(&dec->zscan_c);
947
948error_zscan:
949   FREE(dec);
950   return NULL;
951}
952