Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2013 Advanced Micro Devices, Inc.
  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 THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. /*
  29.  * Authors:
  30.  *      Christian König <christian.koenig@amd.com>
  31.  *
  32.  */
  33.  
  34. #include "pipe/p_video_codec.h"
  35. #include "vl/vl_vlc.h"
  36. #include "vl/vl_zscan.h"
  37.  
  38. #include "vid_dec.h"
  39.  
  40. static uint8_t default_intra_matrix[64] = {
  41.     8, 16, 19, 22, 26, 27, 29, 34,
  42.    16, 16, 19, 22, 22, 22, 22, 26,
  43.    26, 27, 22, 26, 26, 27, 29, 24,
  44.    27, 27, 29, 32, 27, 29, 29, 32,
  45.    35, 29, 34, 34, 35, 40, 34, 34,
  46.    37, 40, 48, 37, 38, 40, 48, 58,
  47.    26, 27, 29, 34, 38, 46, 56, 69,
  48.    27, 29, 35, 38, 46, 56, 69, 83
  49. };
  50.  
  51. static uint8_t default_non_intra_matrix[64] = {
  52.    16, 16, 16, 16, 16, 16, 16, 16,
  53.    16, 16, 16, 16, 16, 16, 16, 16,
  54.    16, 16, 16, 16, 16, 16, 16, 16,
  55.    16, 16, 16, 16, 16, 16, 16, 16,
  56.    16, 16, 16, 16, 16, 16, 16, 16,
  57.    16, 16, 16, 16, 16, 16, 16, 16,
  58.    16, 16, 16, 16, 16, 16, 16, 16,
  59.    16, 16, 16, 16, 16, 16, 16, 16
  60. };
  61.  
  62. static void vid_dec_mpeg12_Decode(vid_dec_PrivateType *priv, struct vl_vlc *vlc, unsigned min_bits_left);
  63. static void vid_dec_mpeg12_EndFrame(vid_dec_PrivateType *priv);
  64. static struct pipe_video_buffer *vid_dec_mpeg12_Flush(vid_dec_PrivateType *priv);
  65.  
  66. void vid_dec_mpeg12_Init(vid_dec_PrivateType *priv)
  67. {
  68.    struct pipe_video_codec templat = {};
  69.    omx_base_video_PortType *port;
  70.  
  71.    port = (omx_base_video_PortType *)priv->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];
  72.    templat.profile = priv->profile;
  73.    templat.entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM;
  74.    templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420;
  75.    templat.max_references = 2;
  76.    templat.expect_chunked_decode = true;
  77.    templat.width = port->sPortParam.format.video.nFrameWidth;
  78.    templat.height = port->sPortParam.format.video.nFrameHeight;
  79.  
  80.    priv->codec = priv->pipe->create_video_codec(priv->pipe, &templat);
  81.  
  82.    priv->picture.base.profile = PIPE_VIDEO_PROFILE_MPEG2_MAIN;
  83.    priv->picture.mpeg12.intra_matrix = default_intra_matrix;
  84.    priv->picture.mpeg12.non_intra_matrix = default_non_intra_matrix;
  85.  
  86.    priv->Decode = vid_dec_mpeg12_Decode;
  87.    priv->EndFrame = vid_dec_mpeg12_EndFrame;
  88.    priv->Flush = vid_dec_mpeg12_Flush;
  89. }
  90.  
  91. static void BeginFrame(vid_dec_PrivateType *priv)
  92. {
  93.    if (priv->picture.mpeg12.picture_coding_type != PIPE_MPEG12_PICTURE_CODING_TYPE_B) {
  94.       priv->picture.mpeg12.ref[0] = priv->picture.mpeg12.ref[1];
  95.       priv->picture.mpeg12.ref[1] = NULL;
  96.    }
  97.  
  98.    if (priv->target == priv->picture.mpeg12.ref[0]) {
  99.       struct pipe_video_buffer *tmp = priv->target;
  100.       priv->target = priv->shadow;
  101.       priv->shadow = tmp;
  102.    }
  103.  
  104.    vid_dec_NeedTarget(priv);
  105.  
  106.    priv->codec->begin_frame(priv->codec, priv->target, &priv->picture.base);
  107.    priv->frame_started = true;
  108. }
  109.  
  110. static void vid_dec_mpeg12_EndFrame(vid_dec_PrivateType *priv)
  111. {
  112.    struct pipe_video_buffer *done;
  113.  
  114.    priv->codec->end_frame(priv->codec, priv->target, &priv->picture.base);
  115.    priv->frame_started = false;
  116.  
  117.    if (priv->picture.mpeg12.picture_coding_type != PIPE_MPEG12_PICTURE_CODING_TYPE_B) {
  118.  
  119.       priv->picture.mpeg12.ref[1] = priv->target;
  120.       done = priv->picture.mpeg12.ref[0];
  121.       if (!done) {
  122.          priv->target = NULL;
  123.          return;
  124.       }
  125.  
  126.    } else
  127.       done = priv->target;
  128.  
  129.    priv->frame_finished = true;
  130.    priv->target = priv->in_buffers[0]->pInputPortPrivate;
  131.    priv->in_buffers[0]->pInputPortPrivate = done;
  132. }
  133.  
  134. static struct pipe_video_buffer *vid_dec_mpeg12_Flush(vid_dec_PrivateType *priv)
  135. {
  136.    struct pipe_video_buffer *result = priv->picture.mpeg12.ref[1];
  137.    priv->picture.mpeg12.ref[1] = NULL;
  138.    return result;
  139. }
  140.  
  141. static void vid_dec_mpeg12_Decode(vid_dec_PrivateType *priv, struct vl_vlc *vlc, unsigned min_bits_left)
  142. {
  143.    uint8_t code;
  144.    unsigned i;
  145.  
  146.    if (!vl_vlc_search_byte(vlc, vl_vlc_bits_left(vlc) - min_bits_left, 0x00))
  147.       return;
  148.  
  149.    if (vl_vlc_peekbits(vlc, 24) != 0x000001) {
  150.       vl_vlc_eatbits(vlc, 8);
  151.       return;
  152.    }
  153.  
  154.    if (priv->slice) {
  155.       unsigned bytes = priv->bytes_left - (vl_vlc_bits_left(vlc) / 8);
  156.       priv->codec->decode_bitstream(priv->codec, priv->target, &priv->picture.base,
  157.                                     1, &priv->slice, &bytes);
  158.       priv->slice = NULL;
  159.    }
  160.  
  161.    vl_vlc_eatbits(vlc, 24);
  162.    code = vl_vlc_get_uimsbf(vlc, 8);
  163.  
  164.    if (priv->frame_started && (code == 0x00 || code > 0xAF))
  165.       vid_dec_mpeg12_EndFrame(priv);
  166.  
  167.    if (code == 0xB3) {
  168.       /* sequence header code */
  169.       vl_vlc_fillbits(vlc);
  170.  
  171.       /* horizontal_size_value */
  172.       vl_vlc_get_uimsbf(vlc, 12);
  173.  
  174.       /* vertical_size_value */
  175.       vl_vlc_get_uimsbf(vlc, 12);
  176.  
  177.       /* aspect_ratio_information */
  178.       vl_vlc_get_uimsbf(vlc, 4);
  179.  
  180.       /* frame_rate_code */
  181.       vl_vlc_get_uimsbf(vlc, 4);
  182.  
  183.       vl_vlc_fillbits(vlc);
  184.  
  185.       /* bit_rate_value */
  186.       vl_vlc_get_uimsbf(vlc, 18);
  187.  
  188.       /* marker_bit */
  189.       vl_vlc_get_uimsbf(vlc, 1);
  190.  
  191.       /* vbv_buffer_size_value */
  192.       vl_vlc_get_uimsbf(vlc, 10);
  193.  
  194.       /* constrained_parameters_flag */
  195.       vl_vlc_get_uimsbf(vlc, 1);
  196.  
  197.       vl_vlc_fillbits(vlc);
  198.  
  199.       /* load_intra_quantiser_matrix */
  200.       if (vl_vlc_get_uimsbf(vlc, 1)) {
  201.          /* intra_quantiser_matrix */
  202.          priv->picture.mpeg12.intra_matrix = priv->codec_data.mpeg12.intra_matrix;
  203.          for (i = 0; i < 64; ++i) {
  204.             priv->codec_data.mpeg12.intra_matrix[vl_zscan_normal[i]] = vl_vlc_get_uimsbf(vlc, 8);
  205.             vl_vlc_fillbits(vlc);
  206.          }
  207.       } else
  208.          priv->picture.mpeg12.intra_matrix = default_intra_matrix;
  209.  
  210.       /* load_non_intra_quantiser_matrix */
  211.       if (vl_vlc_get_uimsbf(vlc, 1)) {
  212.          /* non_intra_quantiser_matrix */
  213.          priv->picture.mpeg12.non_intra_matrix = priv->codec_data.mpeg12.non_intra_matrix;
  214.          for (i = 0; i < 64; ++i) {
  215.             priv->codec_data.mpeg12.non_intra_matrix[i] = vl_vlc_get_uimsbf(vlc, 8);
  216.             vl_vlc_fillbits(vlc);
  217.          }
  218.       } else
  219.          priv->picture.mpeg12.non_intra_matrix = default_non_intra_matrix;
  220.  
  221.    } else if (code == 0x00) {
  222.       /* picture start code */
  223.       vl_vlc_fillbits(vlc);
  224.  
  225.       /* temporal_reference */
  226.       vl_vlc_get_uimsbf(vlc, 10);
  227.  
  228.       priv->picture.mpeg12.picture_coding_type = vl_vlc_get_uimsbf(vlc, 3);
  229.  
  230.       /* vbv_delay */
  231.       vl_vlc_get_uimsbf(vlc, 16);
  232.  
  233.       vl_vlc_fillbits(vlc);
  234.       if (priv->picture.mpeg12.picture_coding_type == 2 ||
  235.           priv->picture.mpeg12.picture_coding_type == 3) {
  236.          priv->picture.mpeg12.full_pel_forward_vector = vl_vlc_get_uimsbf(vlc, 1);
  237.          /* forward_f_code */
  238.          priv->picture.mpeg12.f_code[0][0] = vl_vlc_get_uimsbf(vlc, 3) - 1;
  239.          priv->picture.mpeg12.f_code[0][1] = priv->picture.mpeg12.f_code[0][0];
  240.       } else {
  241.          priv->picture.mpeg12.full_pel_forward_vector = 0;
  242.          priv->picture.mpeg12.f_code[0][1] = priv->picture.mpeg12.f_code[0][0] = 14;
  243.       }
  244.  
  245.       if (priv->picture.mpeg12.picture_coding_type == 3) {
  246.          priv->picture.mpeg12.full_pel_backward_vector = vl_vlc_get_uimsbf(vlc, 1);
  247.          /* backward_f_code */
  248.          priv->picture.mpeg12.f_code[1][0] = vl_vlc_get_uimsbf(vlc, 3) - 1;
  249.          priv->picture.mpeg12.f_code[1][1] = priv->picture.mpeg12.f_code[1][0];
  250.       } else {
  251.          priv->picture.mpeg12.full_pel_backward_vector = 0;
  252.          priv->picture.mpeg12.f_code[0][1] = priv->picture.mpeg12.f_code[0][0] = 14;
  253.       }
  254.  
  255.       /* extra_bit_picture */
  256.       while (vl_vlc_get_uimsbf(vlc, 1)) {
  257.          /* extra_information_picture */
  258.          vl_vlc_get_uimsbf(vlc, 8);
  259.          vl_vlc_fillbits(vlc);
  260.       }
  261.  
  262.    } else if (code == 0xB5) {
  263.       /* extension start code */
  264.       vl_vlc_fillbits(vlc);
  265.  
  266.       /* extension_start_code_identifier */
  267.       switch (vl_vlc_get_uimsbf(vlc, 4)) {
  268.       case 0x3: /* quant matrix extension */
  269.  
  270.          /* load_intra_quantiser_matrix */
  271.          if (vl_vlc_get_uimsbf(vlc, 1)) {
  272.             /* intra_quantiser_matrix */
  273.             priv->picture.mpeg12.intra_matrix = priv->codec_data.mpeg12.intra_matrix;
  274.             for (i = 0; i < 64; ++i) {
  275.                priv->codec_data.mpeg12.intra_matrix[vl_zscan_normal[i]] = vl_vlc_get_uimsbf(vlc, 8);
  276.                vl_vlc_fillbits(vlc);
  277.             }
  278.          } else
  279.             priv->picture.mpeg12.intra_matrix = default_intra_matrix;
  280.  
  281.          /* load_non_intra_quantiser_matrix */
  282.          if (vl_vlc_get_uimsbf(vlc, 1)) {
  283.             /* non_intra_quantiser_matrix */
  284.             priv->picture.mpeg12.non_intra_matrix = priv->codec_data.mpeg12.non_intra_matrix;
  285.             for (i = 0; i < 64; ++i) {
  286.                priv->codec_data.mpeg12.non_intra_matrix[i] = vl_vlc_get_uimsbf(vlc, 8);
  287.                vl_vlc_fillbits(vlc);
  288.             }
  289.          } else
  290.             priv->picture.mpeg12.intra_matrix = default_non_intra_matrix;
  291.  
  292.          break;
  293.  
  294.       case 0x8: /* picture coding extension */
  295.  
  296.          priv->picture.mpeg12.f_code[0][0] = vl_vlc_get_uimsbf(vlc, 4) - 1;
  297.          priv->picture.mpeg12.f_code[0][1] = vl_vlc_get_uimsbf(vlc, 4) - 1;
  298.          priv->picture.mpeg12.f_code[1][0] = vl_vlc_get_uimsbf(vlc, 4) - 1;
  299.          priv->picture.mpeg12.f_code[1][1] = vl_vlc_get_uimsbf(vlc, 4) - 1;
  300.          priv->picture.mpeg12.intra_dc_precision = vl_vlc_get_uimsbf(vlc, 2);
  301.          priv->picture.mpeg12.picture_structure = vl_vlc_get_uimsbf(vlc, 2);
  302.          priv->picture.mpeg12.top_field_first = vl_vlc_get_uimsbf(vlc, 1);
  303.          priv->picture.mpeg12.frame_pred_frame_dct = vl_vlc_get_uimsbf(vlc, 1);
  304.          priv->picture.mpeg12.concealment_motion_vectors = vl_vlc_get_uimsbf(vlc, 1);
  305.          priv->picture.mpeg12.q_scale_type = vl_vlc_get_uimsbf(vlc, 1);
  306.          priv->picture.mpeg12.intra_vlc_format = vl_vlc_get_uimsbf(vlc, 1);
  307.          priv->picture.mpeg12.alternate_scan = vl_vlc_get_uimsbf(vlc, 1);
  308.  
  309.          /* repeat_first_field */
  310.          vl_vlc_get_uimsbf(vlc, 1);
  311.  
  312.          /* chroma_420_type */
  313.          vl_vlc_get_uimsbf(vlc, 1);
  314.  
  315.          vl_vlc_fillbits(vlc);
  316.  
  317.          /* progressive_frame */
  318.          vl_vlc_get_uimsbf(vlc, 1);
  319.  
  320.          /* composite_display_flag */
  321.          if (vl_vlc_get_uimsbf(vlc, 1)) {
  322.  
  323.             /* v_axis */
  324.             vl_vlc_get_uimsbf(vlc, 1);
  325.  
  326.             /* field_sequence */
  327.             vl_vlc_get_uimsbf(vlc, 3);
  328.  
  329.             /* sub_carrier */
  330.             vl_vlc_get_uimsbf(vlc, 1);
  331.  
  332.             /* burst_amplitude */
  333.             vl_vlc_get_uimsbf(vlc, 7);
  334.  
  335.             /* sub_carrier_phase */
  336.             vl_vlc_get_uimsbf(vlc, 8);
  337.          }
  338.          break;
  339.       }
  340.  
  341.    } else if (code <= 0xAF) {
  342.       /* slice start */
  343.       unsigned bytes = (vl_vlc_valid_bits(vlc) / 8) + 4;
  344.       uint8_t buf[12];
  345.       const void *ptr = buf;
  346.       unsigned i;
  347.  
  348.       if (!priv->frame_started)
  349.          BeginFrame(priv);
  350.  
  351.       buf[0] = 0x00;
  352.       buf[1] = 0x00;
  353.       buf[2] = 0x01;
  354.       buf[3] = code;
  355.       for (i = 4; i < bytes; ++i)
  356.          buf[i] = vl_vlc_get_uimsbf(vlc, 8);
  357.  
  358.       priv->codec->decode_bitstream(priv->codec, priv->target, &priv->picture.base,
  359.                                     1, &ptr, &bytes);
  360.  
  361.       priv->bytes_left = vl_vlc_bits_left(vlc) / 8;
  362.       priv->slice = vlc->data;
  363.  
  364.    } else if (code == 0xB2) {
  365.       /* user data start */
  366.  
  367.    } else if (code == 0xB4) {
  368.       /* sequence error */
  369.    } else if (code == 0xB7) {
  370.       /* sequence end */
  371.    } else if (code == 0xB8) {
  372.       /* group start */
  373.    } else if (code >= 0xB9) {
  374.       /* system start */
  375.    } else {
  376.       /* reserved */
  377.    }
  378.  
  379.    /* resync to byte boundary */
  380.    vl_vlc_eatbits(vlc, vl_vlc_valid_bits(vlc) % 8);
  381. }
  382.