Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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_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. }
  1158.