Home | History | Annotate | Download | only in omx
      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 Knig <christian.koenig (at) 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, OMX_TICKS *timestamp);
     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, OMX_TICKS *timestamp)
    135 {
    136    struct pipe_video_buffer *result = priv->picture.mpeg12.ref[1];
    137    priv->picture.mpeg12.ref[1] = NULL;
    138    if (timestamp)
    139       *timestamp = OMX_VID_DEC_TIMESTAMP_INVALID;
    140    return result;
    141 }
    142 
    143 static void vid_dec_mpeg12_Decode(vid_dec_PrivateType *priv, struct vl_vlc *vlc, unsigned min_bits_left)
    144 {
    145    uint8_t code;
    146    unsigned i;
    147 
    148    if (!vl_vlc_search_byte(vlc, vl_vlc_bits_left(vlc) - min_bits_left, 0x00))
    149       return;
    150 
    151    if (vl_vlc_peekbits(vlc, 24) != 0x000001) {
    152       vl_vlc_eatbits(vlc, 8);
    153       return;
    154    }
    155 
    156    if (priv->slice) {
    157       unsigned bytes = priv->bytes_left - (vl_vlc_bits_left(vlc) / 8);
    158       priv->codec->decode_bitstream(priv->codec, priv->target, &priv->picture.base,
    159                                     1, &priv->slice, &bytes);
    160       priv->slice = NULL;
    161    }
    162 
    163    vl_vlc_eatbits(vlc, 24);
    164    code = vl_vlc_get_uimsbf(vlc, 8);
    165 
    166    if (priv->frame_started && (code == 0x00 || code > 0xAF))
    167       vid_dec_mpeg12_EndFrame(priv);
    168 
    169    if (code == 0xB3) {
    170       /* sequence header code */
    171       vl_vlc_fillbits(vlc);
    172 
    173       /* horizontal_size_value */
    174       vl_vlc_get_uimsbf(vlc, 12);
    175 
    176       /* vertical_size_value */
    177       vl_vlc_get_uimsbf(vlc, 12);
    178 
    179       /* aspect_ratio_information */
    180       vl_vlc_get_uimsbf(vlc, 4);
    181 
    182       /* frame_rate_code */
    183       vl_vlc_get_uimsbf(vlc, 4);
    184 
    185       vl_vlc_fillbits(vlc);
    186 
    187       /* bit_rate_value */
    188       vl_vlc_get_uimsbf(vlc, 18);
    189 
    190       /* marker_bit */
    191       vl_vlc_get_uimsbf(vlc, 1);
    192 
    193       /* vbv_buffer_size_value */
    194       vl_vlc_get_uimsbf(vlc, 10);
    195 
    196       /* constrained_parameters_flag */
    197       vl_vlc_get_uimsbf(vlc, 1);
    198 
    199       vl_vlc_fillbits(vlc);
    200 
    201       /* load_intra_quantiser_matrix */
    202       if (vl_vlc_get_uimsbf(vlc, 1)) {
    203          /* intra_quantiser_matrix */
    204          priv->picture.mpeg12.intra_matrix = priv->codec_data.mpeg12.intra_matrix;
    205          for (i = 0; i < 64; ++i) {
    206             priv->codec_data.mpeg12.intra_matrix[vl_zscan_normal[i]] = vl_vlc_get_uimsbf(vlc, 8);
    207             vl_vlc_fillbits(vlc);
    208          }
    209       } else
    210          priv->picture.mpeg12.intra_matrix = default_intra_matrix;
    211 
    212       /* load_non_intra_quantiser_matrix */
    213       if (vl_vlc_get_uimsbf(vlc, 1)) {
    214          /* non_intra_quantiser_matrix */
    215          priv->picture.mpeg12.non_intra_matrix = priv->codec_data.mpeg12.non_intra_matrix;
    216          for (i = 0; i < 64; ++i) {
    217             priv->codec_data.mpeg12.non_intra_matrix[i] = vl_vlc_get_uimsbf(vlc, 8);
    218             vl_vlc_fillbits(vlc);
    219          }
    220       } else
    221          priv->picture.mpeg12.non_intra_matrix = default_non_intra_matrix;
    222 
    223    } else if (code == 0x00) {
    224       /* picture start code */
    225       vl_vlc_fillbits(vlc);
    226 
    227       /* temporal_reference */
    228       vl_vlc_get_uimsbf(vlc, 10);
    229 
    230       priv->picture.mpeg12.picture_coding_type = vl_vlc_get_uimsbf(vlc, 3);
    231 
    232       /* vbv_delay */
    233       vl_vlc_get_uimsbf(vlc, 16);
    234 
    235       vl_vlc_fillbits(vlc);
    236       if (priv->picture.mpeg12.picture_coding_type == 2 ||
    237           priv->picture.mpeg12.picture_coding_type == 3) {
    238          priv->picture.mpeg12.full_pel_forward_vector = vl_vlc_get_uimsbf(vlc, 1);
    239          /* forward_f_code */
    240          priv->picture.mpeg12.f_code[0][0] = vl_vlc_get_uimsbf(vlc, 3) - 1;
    241          priv->picture.mpeg12.f_code[0][1] = priv->picture.mpeg12.f_code[0][0];
    242       } else {
    243          priv->picture.mpeg12.full_pel_forward_vector = 0;
    244          priv->picture.mpeg12.f_code[0][1] = priv->picture.mpeg12.f_code[0][0] = 14;
    245       }
    246 
    247       if (priv->picture.mpeg12.picture_coding_type == 3) {
    248          priv->picture.mpeg12.full_pel_backward_vector = vl_vlc_get_uimsbf(vlc, 1);
    249          /* backward_f_code */
    250          priv->picture.mpeg12.f_code[1][0] = vl_vlc_get_uimsbf(vlc, 3) - 1;
    251          priv->picture.mpeg12.f_code[1][1] = priv->picture.mpeg12.f_code[1][0];
    252       } else {
    253          priv->picture.mpeg12.full_pel_backward_vector = 0;
    254          priv->picture.mpeg12.f_code[0][1] = priv->picture.mpeg12.f_code[0][0] = 14;
    255       }
    256 
    257       /* extra_bit_picture */
    258       while (vl_vlc_get_uimsbf(vlc, 1)) {
    259          /* extra_information_picture */
    260          vl_vlc_get_uimsbf(vlc, 8);
    261          vl_vlc_fillbits(vlc);
    262       }
    263 
    264    } else if (code == 0xB5) {
    265       /* extension start code */
    266       vl_vlc_fillbits(vlc);
    267 
    268       /* extension_start_code_identifier */
    269       switch (vl_vlc_get_uimsbf(vlc, 4)) {
    270       case 0x3: /* quant matrix extension */
    271 
    272          /* load_intra_quantiser_matrix */
    273          if (vl_vlc_get_uimsbf(vlc, 1)) {
    274             /* intra_quantiser_matrix */
    275             priv->picture.mpeg12.intra_matrix = priv->codec_data.mpeg12.intra_matrix;
    276             for (i = 0; i < 64; ++i) {
    277                priv->codec_data.mpeg12.intra_matrix[vl_zscan_normal[i]] = vl_vlc_get_uimsbf(vlc, 8);
    278                vl_vlc_fillbits(vlc);
    279             }
    280          } else
    281             priv->picture.mpeg12.intra_matrix = default_intra_matrix;
    282 
    283          /* load_non_intra_quantiser_matrix */
    284          if (vl_vlc_get_uimsbf(vlc, 1)) {
    285             /* non_intra_quantiser_matrix */
    286             priv->picture.mpeg12.non_intra_matrix = priv->codec_data.mpeg12.non_intra_matrix;
    287             for (i = 0; i < 64; ++i) {
    288                priv->codec_data.mpeg12.non_intra_matrix[i] = vl_vlc_get_uimsbf(vlc, 8);
    289                vl_vlc_fillbits(vlc);
    290             }
    291          } else
    292             priv->picture.mpeg12.intra_matrix = default_non_intra_matrix;
    293 
    294          break;
    295 
    296       case 0x8: /* picture coding extension */
    297 
    298          priv->picture.mpeg12.f_code[0][0] = vl_vlc_get_uimsbf(vlc, 4) - 1;
    299          priv->picture.mpeg12.f_code[0][1] = vl_vlc_get_uimsbf(vlc, 4) - 1;
    300          priv->picture.mpeg12.f_code[1][0] = vl_vlc_get_uimsbf(vlc, 4) - 1;
    301          priv->picture.mpeg12.f_code[1][1] = vl_vlc_get_uimsbf(vlc, 4) - 1;
    302          priv->picture.mpeg12.intra_dc_precision = vl_vlc_get_uimsbf(vlc, 2);
    303          priv->picture.mpeg12.picture_structure = vl_vlc_get_uimsbf(vlc, 2);
    304          priv->picture.mpeg12.top_field_first = vl_vlc_get_uimsbf(vlc, 1);
    305          priv->picture.mpeg12.frame_pred_frame_dct = vl_vlc_get_uimsbf(vlc, 1);
    306          priv->picture.mpeg12.concealment_motion_vectors = vl_vlc_get_uimsbf(vlc, 1);
    307          priv->picture.mpeg12.q_scale_type = vl_vlc_get_uimsbf(vlc, 1);
    308          priv->picture.mpeg12.intra_vlc_format = vl_vlc_get_uimsbf(vlc, 1);
    309          priv->picture.mpeg12.alternate_scan = vl_vlc_get_uimsbf(vlc, 1);
    310 
    311          /* repeat_first_field */
    312          vl_vlc_get_uimsbf(vlc, 1);
    313 
    314          /* chroma_420_type */
    315          vl_vlc_get_uimsbf(vlc, 1);
    316 
    317          vl_vlc_fillbits(vlc);
    318 
    319          /* progressive_frame */
    320          vl_vlc_get_uimsbf(vlc, 1);
    321 
    322          /* composite_display_flag */
    323          if (vl_vlc_get_uimsbf(vlc, 1)) {
    324 
    325             /* v_axis */
    326             vl_vlc_get_uimsbf(vlc, 1);
    327 
    328             /* field_sequence */
    329             vl_vlc_get_uimsbf(vlc, 3);
    330 
    331             /* sub_carrier */
    332             vl_vlc_get_uimsbf(vlc, 1);
    333 
    334             /* burst_amplitude */
    335             vl_vlc_get_uimsbf(vlc, 7);
    336 
    337             /* sub_carrier_phase */
    338             vl_vlc_get_uimsbf(vlc, 8);
    339          }
    340          break;
    341       }
    342 
    343    } else if (code <= 0xAF) {
    344       /* slice start */
    345       unsigned bytes = (vl_vlc_valid_bits(vlc) / 8) + 4;
    346       uint8_t buf[12];
    347       const void *ptr = buf;
    348       unsigned i;
    349 
    350       if (!priv->frame_started)
    351          BeginFrame(priv);
    352 
    353       buf[0] = 0x00;
    354       buf[1] = 0x00;
    355       buf[2] = 0x01;
    356       buf[3] = code;
    357       for (i = 4; i < bytes; ++i)
    358          buf[i] = vl_vlc_get_uimsbf(vlc, 8);
    359 
    360       priv->codec->decode_bitstream(priv->codec, priv->target, &priv->picture.base,
    361                                     1, &ptr, &bytes);
    362 
    363       priv->bytes_left = vl_vlc_bits_left(vlc) / 8;
    364       priv->slice = vlc->data;
    365 
    366    } else if (code == 0xB2) {
    367       /* user data start */
    368 
    369    } else if (code == 0xB4) {
    370       /* sequence error */
    371    } else if (code == 0xB7) {
    372       /* sequence end */
    373    } else if (code == 0xB8) {
    374       /* group start */
    375    } else if (code >= 0xB9) {
    376       /* system start */
    377    } else {
    378       /* reserved */
    379    }
    380 
    381    /* resync to byte boundary */
    382    vl_vlc_eatbits(vlc, vl_vlc_valid_bits(vlc) % 8);
    383 }
    384