1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2014 Advanced Micro Devices, Inc. 4bf215546Sopenharmony_ci * All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 12bf215546Sopenharmony_ci * the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 16bf215546Sopenharmony_ci * of the Software. 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21bf215546Sopenharmony_ci * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR 22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci **************************************************************************/ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include "va_private.h" 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_civoid vlVaHandlePictureParameterBufferMPEG4(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) 31bf215546Sopenharmony_ci{ 32bf215546Sopenharmony_ci static const uint8_t default_intra_quant_matrix[64] = { 0 }; 33bf215546Sopenharmony_ci static const uint8_t default_non_intra_quant_matrix[64] = { 0 }; 34bf215546Sopenharmony_ci 35bf215546Sopenharmony_ci VAPictureParameterBufferMPEG4 *mpeg4 = buf->data; 36bf215546Sopenharmony_ci unsigned i; 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci assert(buf->size >= sizeof(VAPictureParameterBufferMPEG4) && buf->num_elements == 1); 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_ci context->mpeg4.pps = *mpeg4; 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_ci /* vop_width */ 43bf215546Sopenharmony_ci /* vop_height */ 44bf215546Sopenharmony_ci /* forward_reference_picture */ 45bf215546Sopenharmony_ci /* backward_reference_picture */ 46bf215546Sopenharmony_ci context->desc.mpeg4.short_video_header = 47bf215546Sopenharmony_ci mpeg4->vol_fields.bits.short_video_header; 48bf215546Sopenharmony_ci /* chroma_format */ 49bf215546Sopenharmony_ci context->desc.mpeg4.interlaced = mpeg4->vol_fields.bits.interlaced; 50bf215546Sopenharmony_ci /* obmc_disable */ 51bf215546Sopenharmony_ci /* sprite_enable */ 52bf215546Sopenharmony_ci /* sprite_warping_accuracy */ 53bf215546Sopenharmony_ci context->desc.mpeg4.quant_type = mpeg4->vol_fields.bits.quant_type; 54bf215546Sopenharmony_ci context->desc.mpeg4.quarter_sample = mpeg4->vol_fields.bits.quarter_sample; 55bf215546Sopenharmony_ci /* data_partitioned */ 56bf215546Sopenharmony_ci /* reversible_vlc */ 57bf215546Sopenharmony_ci context->desc.mpeg4.resync_marker_disable = 58bf215546Sopenharmony_ci mpeg4->vol_fields.bits.resync_marker_disable; 59bf215546Sopenharmony_ci /* no_of_sprite_warping_points */ 60bf215546Sopenharmony_ci /* sprite_trajectory_du */ 61bf215546Sopenharmony_ci /* sprite_trajectory_dv */ 62bf215546Sopenharmony_ci /* quant_precision */ 63bf215546Sopenharmony_ci context->desc.mpeg4.vop_coding_type = mpeg4->vop_fields.bits.vop_coding_type; 64bf215546Sopenharmony_ci /* backward_reference_vop_coding_type */ 65bf215546Sopenharmony_ci /* vop_rounding_type */ 66bf215546Sopenharmony_ci /* intra_dc_vlc_thr */ 67bf215546Sopenharmony_ci context->desc.mpeg4.top_field_first = 68bf215546Sopenharmony_ci mpeg4->vop_fields.bits.top_field_first; 69bf215546Sopenharmony_ci context->desc.mpeg4.alternate_vertical_scan_flag = 70bf215546Sopenharmony_ci mpeg4->vop_fields.bits.alternate_vertical_scan_flag; 71bf215546Sopenharmony_ci context->desc.mpeg4.vop_fcode_forward = mpeg4->vop_fcode_forward; 72bf215546Sopenharmony_ci context->desc.mpeg4.vop_fcode_backward = mpeg4->vop_fcode_backward; 73bf215546Sopenharmony_ci context->desc.mpeg4.vop_time_increment_resolution = 74bf215546Sopenharmony_ci mpeg4->vop_time_increment_resolution; 75bf215546Sopenharmony_ci /* num_gobs_in_vop */ 76bf215546Sopenharmony_ci /* num_macroblocks_in_gob */ 77bf215546Sopenharmony_ci context->desc.mpeg4.trb[0] = mpeg4->TRB; 78bf215546Sopenharmony_ci context->desc.mpeg4.trb[1] = mpeg4->TRB; 79bf215546Sopenharmony_ci context->desc.mpeg4.trd[0] = mpeg4->TRD; 80bf215546Sopenharmony_ci context->desc.mpeg4.trd[1] = mpeg4->TRD; 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_ci /* default [non-]intra quant matrix because mpv does not set these 83bf215546Sopenharmony_ci matrices */ 84bf215546Sopenharmony_ci if (!context->desc.mpeg4.intra_matrix) 85bf215546Sopenharmony_ci context->desc.mpeg4.intra_matrix = default_intra_quant_matrix; 86bf215546Sopenharmony_ci if (!context->desc.mpeg4.non_intra_matrix) 87bf215546Sopenharmony_ci context->desc.mpeg4.non_intra_matrix = default_non_intra_quant_matrix; 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_ci vlVaGetReferenceFrame(drv, mpeg4->forward_reference_picture, &context->desc.mpeg4.ref[0]); 90bf215546Sopenharmony_ci vlVaGetReferenceFrame(drv, mpeg4->backward_reference_picture, &context->desc.mpeg4.ref[1]); 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_ci context->mpeg4.vti_bits = 0; 93bf215546Sopenharmony_ci for (i = context->desc.mpeg4.vop_time_increment_resolution; i > 0; i /= 2) 94bf215546Sopenharmony_ci ++context->mpeg4.vti_bits; 95bf215546Sopenharmony_ci} 96bf215546Sopenharmony_ci 97bf215546Sopenharmony_civoid vlVaHandleIQMatrixBufferMPEG4(vlVaContext *context, vlVaBuffer *buf) 98bf215546Sopenharmony_ci{ 99bf215546Sopenharmony_ci VAIQMatrixBufferMPEG4 *mpeg4 = buf->data; 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ci assert(buf->size >= sizeof(VAIQMatrixBufferMPEG4) && buf->num_elements == 1); 102bf215546Sopenharmony_ci if (mpeg4->load_intra_quant_mat) 103bf215546Sopenharmony_ci context->desc.mpeg4.intra_matrix = mpeg4->intra_quant_mat; 104bf215546Sopenharmony_ci else 105bf215546Sopenharmony_ci context->desc.mpeg4.intra_matrix = NULL; 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci if (mpeg4->load_non_intra_quant_mat) 108bf215546Sopenharmony_ci context->desc.mpeg4.non_intra_matrix = mpeg4->non_intra_quant_mat; 109bf215546Sopenharmony_ci else 110bf215546Sopenharmony_ci context->desc.mpeg4.non_intra_matrix = NULL; 111bf215546Sopenharmony_ci} 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_civoid vlVaHandleSliceParameterBufferMPEG4(vlVaContext *context, vlVaBuffer *buf) 114bf215546Sopenharmony_ci{ 115bf215546Sopenharmony_ci VASliceParameterBufferMPEG4 *mpeg4 = buf->data; 116bf215546Sopenharmony_ci 117bf215546Sopenharmony_ci assert(buf->size >= sizeof(VASliceParameterBufferMPEG4) && buf->num_elements == 1); 118bf215546Sopenharmony_ci context->mpeg4.quant_scale = mpeg4->quant_scale; 119bf215546Sopenharmony_ci} 120bf215546Sopenharmony_ci 121bf215546Sopenharmony_cistruct bit_stream 122bf215546Sopenharmony_ci{ 123bf215546Sopenharmony_ci uint8_t *data; 124bf215546Sopenharmony_ci unsigned int length; /* bits */ 125bf215546Sopenharmony_ci unsigned int pos; /* bits */ 126bf215546Sopenharmony_ci}; 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_cistatic inline void 129bf215546Sopenharmony_ciwrite_bit(struct bit_stream *writer, unsigned int bit) 130bf215546Sopenharmony_ci{ 131bf215546Sopenharmony_ci assert(writer->length > (writer)->pos); 132bf215546Sopenharmony_ci writer->data[writer->pos>>3] |= ((bit & 1)<<(7 - (writer->pos & 7))); 133bf215546Sopenharmony_ci writer->pos++; 134bf215546Sopenharmony_ci} 135bf215546Sopenharmony_ci 136bf215546Sopenharmony_cistatic inline void 137bf215546Sopenharmony_ciwrite_bits(struct bit_stream *writer, unsigned int bits, unsigned int len) 138bf215546Sopenharmony_ci{ 139bf215546Sopenharmony_ci int i; 140bf215546Sopenharmony_ci assert(len <= sizeof(bits)*8); 141bf215546Sopenharmony_ci for (i = len - 1; i >= 0; i--) 142bf215546Sopenharmony_ci write_bit(writer, bits>>i); 143bf215546Sopenharmony_ci} 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_civoid vlVaDecoderFixMPEG4Startcode(vlVaContext *context) 146bf215546Sopenharmony_ci{ 147bf215546Sopenharmony_ci uint8_t vop[] = { 0x00, 0x00, 0x01, 0xb6, 0x00, 0x00, 0x00, 0x00, 0x00 }; 148bf215546Sopenharmony_ci struct bit_stream bs_vop = {vop, sizeof(vop)*8, 32}; 149bf215546Sopenharmony_ci unsigned int vop_time_inc; 150bf215546Sopenharmony_ci int mod_time; 151bf215546Sopenharmony_ci unsigned int vop_size; 152bf215546Sopenharmony_ci unsigned int vop_coding_type = context->desc.mpeg4.vop_coding_type; 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ci context->mpeg4.start_code_size = 0; 155bf215546Sopenharmony_ci memset(context->mpeg4.start_code, 0, sizeof(context->mpeg4.start_code)); 156bf215546Sopenharmony_ci if (vop_coding_type+1 == PIPE_MPEG12_PICTURE_CODING_TYPE_I) { 157bf215546Sopenharmony_ci unsigned int vop_time = context->mpeg4.frame_num/ 158bf215546Sopenharmony_ci context->desc.mpeg4.vop_time_increment_resolution; 159bf215546Sopenharmony_ci unsigned int vop_hour = vop_time / 3600; 160bf215546Sopenharmony_ci unsigned int vop_minute = (vop_time / 60) % 60; 161bf215546Sopenharmony_ci unsigned int vop_second = vop_time % 60; 162bf215546Sopenharmony_ci uint8_t group_of_vop[] = { 0x00, 0x00, 0x01, 0xb3, 0x00, 0x00, 0x00 }; 163bf215546Sopenharmony_ci struct bit_stream bs_gvop = {group_of_vop, sizeof(group_of_vop)*8, 32}; 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci write_bits(&bs_gvop, vop_hour, 5); 166bf215546Sopenharmony_ci write_bits(&bs_gvop, vop_minute, 6); 167bf215546Sopenharmony_ci write_bit(&bs_gvop, 1); /* marker_bit */ 168bf215546Sopenharmony_ci write_bits(&bs_gvop, vop_second, 6); 169bf215546Sopenharmony_ci write_bit(&bs_gvop, 0); /* closed_gov */ /* TODO replace magic */ 170bf215546Sopenharmony_ci write_bit(&bs_gvop, 0); /* broken_link */ 171bf215546Sopenharmony_ci write_bit(&bs_gvop, 0); /* padding */ 172bf215546Sopenharmony_ci write_bits(&bs_gvop, 7, 3); /* padding */ 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_ci memcpy(context->mpeg4.start_code, group_of_vop, sizeof(group_of_vop)); 175bf215546Sopenharmony_ci context->mpeg4.start_code_size += sizeof(group_of_vop); 176bf215546Sopenharmony_ci } 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_ci write_bits(&bs_vop, vop_coding_type, 2); 179bf215546Sopenharmony_ci mod_time = context->mpeg4.frame_num % 180bf215546Sopenharmony_ci context->desc.mpeg4.vop_time_increment_resolution == 0 && 181bf215546Sopenharmony_ci vop_coding_type+1 != PIPE_MPEG12_PICTURE_CODING_TYPE_I; 182bf215546Sopenharmony_ci while (mod_time--) 183bf215546Sopenharmony_ci write_bit(&bs_vop, 1); /* modulo_time_base */ 184bf215546Sopenharmony_ci write_bit(&bs_vop, 0); /* modulo_time_base */ 185bf215546Sopenharmony_ci 186bf215546Sopenharmony_ci write_bit(&bs_vop, 1); /* marker_bit */ 187bf215546Sopenharmony_ci vop_time_inc = context->mpeg4.frame_num % 188bf215546Sopenharmony_ci context->desc.mpeg4.vop_time_increment_resolution; 189bf215546Sopenharmony_ci write_bits(&bs_vop, vop_time_inc, context->mpeg4.vti_bits); 190bf215546Sopenharmony_ci write_bit(&bs_vop, 1); /* marker_bit */ 191bf215546Sopenharmony_ci write_bit(&bs_vop, 1); /* vop_coded */ 192bf215546Sopenharmony_ci if (vop_coding_type+1 == PIPE_MPEG12_PICTURE_CODING_TYPE_P) 193bf215546Sopenharmony_ci write_bit(&bs_vop, context->mpeg4.pps.vop_fields.bits.vop_rounding_type); 194bf215546Sopenharmony_ci write_bits(&bs_vop, context->mpeg4.pps.vop_fields.bits.intra_dc_vlc_thr, 3); 195bf215546Sopenharmony_ci if (context->mpeg4.pps.vol_fields.bits.interlaced) { 196bf215546Sopenharmony_ci write_bit(&bs_vop, context->mpeg4.pps.vop_fields.bits.top_field_first); 197bf215546Sopenharmony_ci write_bit(&bs_vop, context->mpeg4.pps.vop_fields.bits.alternate_vertical_scan_flag); 198bf215546Sopenharmony_ci } 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_ci write_bits(&bs_vop, context->mpeg4.quant_scale, context->mpeg4.pps.quant_precision); 201bf215546Sopenharmony_ci if (vop_coding_type+1 != PIPE_MPEG12_PICTURE_CODING_TYPE_I) 202bf215546Sopenharmony_ci write_bits(&bs_vop, context->desc.mpeg4.vop_fcode_forward, 3); 203bf215546Sopenharmony_ci if (vop_coding_type+1 == PIPE_MPEG12_PICTURE_CODING_TYPE_B) 204bf215546Sopenharmony_ci write_bits(&bs_vop, context->desc.mpeg4.vop_fcode_backward, 3); 205bf215546Sopenharmony_ci 206bf215546Sopenharmony_ci vop_size = bs_vop.pos/8; 207bf215546Sopenharmony_ci memcpy(context->mpeg4.start_code + context->mpeg4.start_code_size, vop, vop_size); 208bf215546Sopenharmony_ci context->mpeg4.start_code_size += vop_size; 209bf215546Sopenharmony_ci} 210