Path: blob/21.2-virgl/src/gallium/frontends/omx/bellagio/vid_dec_mpeg12.c
4565 views
/**************************************************************************1*2* Copyright 2013 Advanced Micro Devices, Inc.3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* The above copyright notice and this permission notice (including the14* next paragraph) shall be included in all copies or substantial portions15* of the Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS18* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.20* IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR21* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,22* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE23* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.24*25**************************************************************************/2627/*28* Authors:29* Christian König <[email protected]>30*31*/3233#include "pipe/p_video_codec.h"34#include "vl/vl_vlc.h"35#include "vl/vl_zscan.h"3637#include "vid_dec.h"3839static uint8_t default_intra_matrix[64] = {408, 16, 19, 22, 26, 27, 29, 34,4116, 16, 22, 24, 27, 29, 34, 37,4219, 22, 26, 27, 29, 34, 34, 38,4322, 22, 26, 27, 29, 34, 37, 40,4422, 26, 27, 29, 32, 35, 40, 48,4526, 27, 29, 32, 35, 40, 48, 58,4626, 27, 29, 34, 38, 46, 56, 69,4727, 29, 35, 38, 46, 56, 69, 8348};4950static uint8_t default_non_intra_matrix[64] = {5116, 16, 16, 16, 16, 16, 16, 16,5216, 16, 16, 16, 16, 16, 16, 16,5316, 16, 16, 16, 16, 16, 16, 16,5416, 16, 16, 16, 16, 16, 16, 16,5516, 16, 16, 16, 16, 16, 16, 16,5616, 16, 16, 16, 16, 16, 16, 16,5716, 16, 16, 16, 16, 16, 16, 16,5816, 16, 16, 16, 16, 16, 16, 1659};6061static void vid_dec_mpeg12_Decode(vid_dec_PrivateType *priv, struct vl_vlc *vlc, unsigned min_bits_left);62static void vid_dec_mpeg12_EndFrame(vid_dec_PrivateType *priv);63static struct pipe_video_buffer *vid_dec_mpeg12_Flush(vid_dec_PrivateType *priv, OMX_TICKS *timestamp);6465void vid_dec_mpeg12_Init(vid_dec_PrivateType *priv)66{67struct pipe_video_codec templat = {};68omx_base_video_PortType *port;6970port = (omx_base_video_PortType *)priv->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];71templat.profile = priv->profile;72templat.entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM;73templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420;74templat.max_references = 2;75templat.expect_chunked_decode = true;76templat.width = port->sPortParam.format.video.nFrameWidth;77templat.height = port->sPortParam.format.video.nFrameHeight;7879priv->codec = priv->pipe->create_video_codec(priv->pipe, &templat);8081priv->picture.base.profile = PIPE_VIDEO_PROFILE_MPEG2_MAIN;82priv->picture.mpeg12.intra_matrix = default_intra_matrix;83priv->picture.mpeg12.non_intra_matrix = default_non_intra_matrix;8485priv->Decode = vid_dec_mpeg12_Decode;86priv->EndFrame = vid_dec_mpeg12_EndFrame;87priv->Flush = vid_dec_mpeg12_Flush;88}8990static void BeginFrame(vid_dec_PrivateType *priv)91{92if (priv->picture.mpeg12.picture_coding_type != PIPE_MPEG12_PICTURE_CODING_TYPE_B) {93priv->picture.mpeg12.ref[0] = priv->picture.mpeg12.ref[1];94priv->picture.mpeg12.ref[1] = NULL;95}9697if (priv->target == priv->picture.mpeg12.ref[0]) {98struct pipe_video_buffer *tmp = priv->target;99priv->target = priv->shadow;100priv->shadow = tmp;101}102103vid_dec_NeedTarget(priv);104105priv->codec->begin_frame(priv->codec, priv->target, &priv->picture.base);106priv->frame_started = true;107}108109static void vid_dec_mpeg12_EndFrame(vid_dec_PrivateType *priv)110{111struct pipe_video_buffer *done;112113priv->codec->end_frame(priv->codec, priv->target, &priv->picture.base);114priv->frame_started = false;115116if (priv->picture.mpeg12.picture_coding_type != PIPE_MPEG12_PICTURE_CODING_TYPE_B) {117118priv->picture.mpeg12.ref[1] = priv->target;119done = priv->picture.mpeg12.ref[0];120if (!done) {121priv->target = NULL;122return;123}124125} else126done = priv->target;127128priv->frame_finished = true;129priv->target = priv->in_buffers[0]->pInputPortPrivate;130priv->in_buffers[0]->pInputPortPrivate = done;131}132133static struct pipe_video_buffer *vid_dec_mpeg12_Flush(vid_dec_PrivateType *priv, OMX_TICKS *timestamp)134{135struct pipe_video_buffer *result = priv->picture.mpeg12.ref[1];136priv->picture.mpeg12.ref[1] = NULL;137if (timestamp)138*timestamp = OMX_VID_DEC_TIMESTAMP_INVALID;139return result;140}141142static void vid_dec_mpeg12_Decode(vid_dec_PrivateType *priv, struct vl_vlc *vlc, unsigned min_bits_left)143{144uint8_t code;145unsigned i;146147if (!vl_vlc_search_byte(vlc, vl_vlc_bits_left(vlc) - min_bits_left, 0x00))148return;149150if (vl_vlc_peekbits(vlc, 24) != 0x000001) {151vl_vlc_eatbits(vlc, 8);152return;153}154155if (priv->slice) {156unsigned bytes = priv->bytes_left - (vl_vlc_bits_left(vlc) / 8);157priv->codec->decode_bitstream(priv->codec, priv->target, &priv->picture.base,1581, &priv->slice, &bytes);159priv->slice = NULL;160}161162vl_vlc_eatbits(vlc, 24);163code = vl_vlc_get_uimsbf(vlc, 8);164165if (priv->frame_started && (code == 0x00 || code > 0xAF))166vid_dec_mpeg12_EndFrame(priv);167168if (code == 0xB3) {169/* sequence header code */170vl_vlc_fillbits(vlc);171172/* horizontal_size_value */173vl_vlc_get_uimsbf(vlc, 12);174175/* vertical_size_value */176vl_vlc_get_uimsbf(vlc, 12);177178/* aspect_ratio_information */179vl_vlc_get_uimsbf(vlc, 4);180181/* frame_rate_code */182vl_vlc_get_uimsbf(vlc, 4);183184vl_vlc_fillbits(vlc);185186/* bit_rate_value */187vl_vlc_get_uimsbf(vlc, 18);188189/* marker_bit */190vl_vlc_get_uimsbf(vlc, 1);191192/* vbv_buffer_size_value */193vl_vlc_get_uimsbf(vlc, 10);194195/* constrained_parameters_flag */196vl_vlc_get_uimsbf(vlc, 1);197198vl_vlc_fillbits(vlc);199200/* load_intra_quantiser_matrix */201if (vl_vlc_get_uimsbf(vlc, 1)) {202/* intra_quantiser_matrix */203priv->picture.mpeg12.intra_matrix = priv->codec_data.mpeg12.intra_matrix;204for (i = 0; i < 64; ++i) {205priv->codec_data.mpeg12.intra_matrix[vl_zscan_normal[i]] = vl_vlc_get_uimsbf(vlc, 8);206vl_vlc_fillbits(vlc);207}208} else209priv->picture.mpeg12.intra_matrix = default_intra_matrix;210211/* load_non_intra_quantiser_matrix */212if (vl_vlc_get_uimsbf(vlc, 1)) {213/* non_intra_quantiser_matrix */214priv->picture.mpeg12.non_intra_matrix = priv->codec_data.mpeg12.non_intra_matrix;215for (i = 0; i < 64; ++i) {216priv->codec_data.mpeg12.non_intra_matrix[i] = vl_vlc_get_uimsbf(vlc, 8);217vl_vlc_fillbits(vlc);218}219} else220priv->picture.mpeg12.non_intra_matrix = default_non_intra_matrix;221222} else if (code == 0x00) {223/* picture start code */224vl_vlc_fillbits(vlc);225226/* temporal_reference */227vl_vlc_get_uimsbf(vlc, 10);228229priv->picture.mpeg12.picture_coding_type = vl_vlc_get_uimsbf(vlc, 3);230231/* vbv_delay */232vl_vlc_get_uimsbf(vlc, 16);233234vl_vlc_fillbits(vlc);235if (priv->picture.mpeg12.picture_coding_type == 2 ||236priv->picture.mpeg12.picture_coding_type == 3) {237priv->picture.mpeg12.full_pel_forward_vector = vl_vlc_get_uimsbf(vlc, 1);238/* forward_f_code */239priv->picture.mpeg12.f_code[0][0] = vl_vlc_get_uimsbf(vlc, 3) - 1;240priv->picture.mpeg12.f_code[0][1] = priv->picture.mpeg12.f_code[0][0];241} else {242priv->picture.mpeg12.full_pel_forward_vector = 0;243priv->picture.mpeg12.f_code[0][1] = priv->picture.mpeg12.f_code[0][0] = 14;244}245246if (priv->picture.mpeg12.picture_coding_type == 3) {247priv->picture.mpeg12.full_pel_backward_vector = vl_vlc_get_uimsbf(vlc, 1);248/* backward_f_code */249priv->picture.mpeg12.f_code[1][0] = vl_vlc_get_uimsbf(vlc, 3) - 1;250priv->picture.mpeg12.f_code[1][1] = priv->picture.mpeg12.f_code[1][0];251} else {252priv->picture.mpeg12.full_pel_backward_vector = 0;253priv->picture.mpeg12.f_code[0][1] = priv->picture.mpeg12.f_code[0][0] = 14;254}255256/* extra_bit_picture */257while (vl_vlc_get_uimsbf(vlc, 1)) {258/* extra_information_picture */259vl_vlc_get_uimsbf(vlc, 8);260vl_vlc_fillbits(vlc);261}262263} else if (code == 0xB5) {264/* extension start code */265vl_vlc_fillbits(vlc);266267/* extension_start_code_identifier */268switch (vl_vlc_get_uimsbf(vlc, 4)) {269case 0x3: /* quant matrix extension */270271/* load_intra_quantiser_matrix */272if (vl_vlc_get_uimsbf(vlc, 1)) {273/* intra_quantiser_matrix */274priv->picture.mpeg12.intra_matrix = priv->codec_data.mpeg12.intra_matrix;275for (i = 0; i < 64; ++i) {276priv->codec_data.mpeg12.intra_matrix[vl_zscan_normal[i]] = vl_vlc_get_uimsbf(vlc, 8);277vl_vlc_fillbits(vlc);278}279} else280priv->picture.mpeg12.intra_matrix = default_intra_matrix;281282/* load_non_intra_quantiser_matrix */283if (vl_vlc_get_uimsbf(vlc, 1)) {284/* non_intra_quantiser_matrix */285priv->picture.mpeg12.non_intra_matrix = priv->codec_data.mpeg12.non_intra_matrix;286for (i = 0; i < 64; ++i) {287priv->codec_data.mpeg12.non_intra_matrix[i] = vl_vlc_get_uimsbf(vlc, 8);288vl_vlc_fillbits(vlc);289}290} else291priv->picture.mpeg12.intra_matrix = default_non_intra_matrix;292293break;294295case 0x8: /* picture coding extension */296297priv->picture.mpeg12.f_code[0][0] = vl_vlc_get_uimsbf(vlc, 4) - 1;298priv->picture.mpeg12.f_code[0][1] = vl_vlc_get_uimsbf(vlc, 4) - 1;299priv->picture.mpeg12.f_code[1][0] = vl_vlc_get_uimsbf(vlc, 4) - 1;300priv->picture.mpeg12.f_code[1][1] = vl_vlc_get_uimsbf(vlc, 4) - 1;301priv->picture.mpeg12.intra_dc_precision = vl_vlc_get_uimsbf(vlc, 2);302priv->picture.mpeg12.picture_structure = vl_vlc_get_uimsbf(vlc, 2);303priv->picture.mpeg12.top_field_first = vl_vlc_get_uimsbf(vlc, 1);304priv->picture.mpeg12.frame_pred_frame_dct = vl_vlc_get_uimsbf(vlc, 1);305priv->picture.mpeg12.concealment_motion_vectors = vl_vlc_get_uimsbf(vlc, 1);306priv->picture.mpeg12.q_scale_type = vl_vlc_get_uimsbf(vlc, 1);307priv->picture.mpeg12.intra_vlc_format = vl_vlc_get_uimsbf(vlc, 1);308priv->picture.mpeg12.alternate_scan = vl_vlc_get_uimsbf(vlc, 1);309310/* repeat_first_field */311vl_vlc_get_uimsbf(vlc, 1);312313/* chroma_420_type */314vl_vlc_get_uimsbf(vlc, 1);315316vl_vlc_fillbits(vlc);317318/* progressive_frame */319vl_vlc_get_uimsbf(vlc, 1);320321/* composite_display_flag */322if (vl_vlc_get_uimsbf(vlc, 1)) {323324/* v_axis */325vl_vlc_get_uimsbf(vlc, 1);326327/* field_sequence */328vl_vlc_get_uimsbf(vlc, 3);329330/* sub_carrier */331vl_vlc_get_uimsbf(vlc, 1);332333/* burst_amplitude */334vl_vlc_get_uimsbf(vlc, 7);335336/* sub_carrier_phase */337vl_vlc_get_uimsbf(vlc, 8);338}339break;340}341342} else if (code <= 0xAF) {343/* slice start */344unsigned bytes = (vl_vlc_valid_bits(vlc) / 8) + 4;345uint8_t buf[12];346const void *ptr = buf;347unsigned i;348349if (!priv->frame_started)350BeginFrame(priv);351352buf[0] = 0x00;353buf[1] = 0x00;354buf[2] = 0x01;355buf[3] = code;356for (i = 4; i < bytes; ++i)357buf[i] = vl_vlc_get_uimsbf(vlc, 8);358359priv->codec->decode_bitstream(priv->codec, priv->target, &priv->picture.base,3601, &ptr, &bytes);361362priv->bytes_left = vl_vlc_bits_left(vlc) / 8;363priv->slice = vlc->data;364365} else if (code == 0xB2) {366/* user data start */367368} else if (code == 0xB4) {369/* sequence error */370} else if (code == 0xB7) {371/* sequence end */372} else if (code == 0xB8) {373/* group start */374} else if (code >= 0xB9) {375/* system start */376} else {377/* reserved */378}379380/* resync to byte boundary */381vl_vlc_eatbits(vlc, vl_vlc_valid_bits(vlc) % 8);382}383384385