Path: blob/21.2-virgl/src/gallium/frontends/omx/vid_dec_h264_common.c
4561 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#if ENABLE_ST_OMX_TIZONIA28#include <tizkernel.h>29#endif3031#include "util/u_memory.h"3233#include "vid_dec_h264_common.h"3435static void vid_dec_h264_BeginFrame(vid_dec_PrivateType *priv)36{37//TODO: sane buffer handling3839if (priv->frame_started)40return;4142if (!priv->codec) {43struct pipe_video_codec templat = {};44templat.profile = priv->profile;45templat.entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM;46templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420;47templat.max_references = priv->picture.h264.num_ref_frames;48templat.expect_chunked_decode = true;49#if ENABLE_ST_OMX_BELLAGIO50omx_base_video_PortType *port;51port = (omx_base_video_PortType *)priv->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];52templat.width = port->sPortParam.format.video.nFrameWidth;53templat.height = port->sPortParam.format.video.nFrameHeight;54#else55templat.width = priv->out_port_def_.format.video.nFrameWidth;56templat.height = priv->out_port_def_.format.video.nFrameHeight;57#endif58templat.level = priv->picture.h264.pps->sps->level_idc;5960priv->codec = priv->pipe->create_video_codec(priv->pipe, &templat);61}6263vid_dec_NeedTarget(priv);6465if (priv->first_buf_in_frame)66priv->timestamp = priv->timestamps[0];67priv->first_buf_in_frame = false;6869priv->picture.h264.num_ref_frames = priv->picture.h264.pps->sps->max_num_ref_frames;7071priv->picture.h264.slice_count = 0;72priv->codec->begin_frame(priv->codec, priv->target, &priv->picture.base);73priv->frame_started = true;74}7576struct pipe_video_buffer *vid_dec_h264_Flush(vid_dec_PrivateType *priv,77OMX_TICKS *timestamp)78{79struct dpb_list *entry, *result = NULL;80struct pipe_video_buffer *buf;8182/* search for the lowest poc and break on zeros */83LIST_FOR_EACH_ENTRY(entry, &priv->codec_data.h264.dpb_list, list) {8485if (result && entry->poc == 0)86break;8788if (!result || entry->poc < result->poc)89result = entry;90}9192if (!result)93return NULL;9495buf = result->buffer;96if (timestamp)97*timestamp = result->timestamp;9899--priv->codec_data.h264.dpb_num;100list_del(&result->list);101FREE(result);102103return buf;104}105106void vid_dec_h264_EndFrame(vid_dec_PrivateType *priv)107{108struct dpb_list *entry;109struct pipe_video_buffer *tmp;110bool top_field_first;111OMX_TICKS timestamp = 0;112113if (!priv->frame_started)114return;115116priv->codec->end_frame(priv->codec, priv->target, &priv->picture.base);117priv->frame_started = false;118119// TODO: implement frame number handling120priv->picture.h264.frame_num_list[0] = priv->picture.h264.frame_num;121priv->picture.h264.field_order_cnt_list[0][0] = priv->picture.h264.frame_num;122priv->picture.h264.field_order_cnt_list[0][1] = priv->picture.h264.frame_num;123124top_field_first = priv->picture.h264.field_order_cnt[0] < priv->picture.h264.field_order_cnt[1];125126if (priv->picture.h264.field_pic_flag && priv->picture.h264.bottom_field_flag != top_field_first)127return;128129/* add the decoded picture to the dpb list */130entry = CALLOC_STRUCT(dpb_list);131if (!entry)132return;133134priv->first_buf_in_frame = true;135entry->buffer = priv->target;136entry->timestamp = priv->timestamp;137entry->poc = MIN2(priv->picture.h264.field_order_cnt[0], priv->picture.h264.field_order_cnt[1]);138list_addtail(&entry->list, &priv->codec_data.h264.dpb_list);139++priv->codec_data.h264.dpb_num;140priv->target = NULL;141priv->picture.h264.field_order_cnt[0] = priv->picture.h264.field_order_cnt[1] = INT_MAX;142143if (priv->codec_data.h264.dpb_num <= DPB_MAX_SIZE)144return;145146tmp = priv->in_buffers[0]->pInputPortPrivate;147priv->in_buffers[0]->pInputPortPrivate = vid_dec_h264_Flush(priv, ×tamp);148priv->in_buffers[0]->nTimeStamp = timestamp;149priv->target = tmp;150priv->frame_finished = priv->in_buffers[0]->pInputPortPrivate != NULL;151}152153static void vui_parameters(struct vl_rbsp *rbsp)154{155// TODO156}157158static void scaling_list(struct vl_rbsp *rbsp, uint8_t *scalingList, unsigned sizeOfScalingList,159const uint8_t *defaultList, const uint8_t *fallbackList)160{161unsigned lastScale = 8, nextScale = 8;162const int *list;163unsigned i;164165/* (pic|seq)_scaling_list_present_flag[i] */166if (!vl_rbsp_u(rbsp, 1)) {167if (fallbackList)168memcpy(scalingList, fallbackList, sizeOfScalingList);169return;170}171172list = (sizeOfScalingList == 16) ? vl_zscan_normal_16 : vl_zscan_normal;173for (i = 0; i < sizeOfScalingList; ++i ) {174175if (nextScale != 0) {176signed delta_scale = vl_rbsp_se(rbsp);177nextScale = (lastScale + delta_scale + 256) % 256;178if (i == 0 && nextScale == 0) {179memcpy(scalingList, defaultList, sizeOfScalingList);180return;181}182}183scalingList[list[i]] = nextScale == 0 ? lastScale : nextScale;184lastScale = scalingList[list[i]];185}186}187188static struct pipe_h264_sps *seq_parameter_set_id(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp)189{190unsigned id = vl_rbsp_ue(rbsp);191if (id >= ARRAY_SIZE(priv->codec_data.h264.sps))192return NULL; /* invalid seq_parameter_set_id */193194return &priv->codec_data.h264.sps[id];195}196197static void seq_parameter_set(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp)198{199struct pipe_h264_sps *sps;200unsigned profile_idc, level_idc;201unsigned i;202203/* Sequence parameter set */204profile_idc = vl_rbsp_u(rbsp, 8);205206/* constraint_set0_flag */207vl_rbsp_u(rbsp, 1);208209/* constraint_set1_flag */210vl_rbsp_u(rbsp, 1);211212/* constraint_set2_flag */213vl_rbsp_u(rbsp, 1);214215/* constraint_set3_flag */216vl_rbsp_u(rbsp, 1);217218/* constraint_set4_flag */219vl_rbsp_u(rbsp, 1);220221/* constraint_set5_flag */222vl_rbsp_u(rbsp, 1);223224/* reserved_zero_2bits */225vl_rbsp_u(rbsp, 2);226227/* level_idc */228level_idc = vl_rbsp_u(rbsp, 8);229230sps = seq_parameter_set_id(priv, rbsp);231if (!sps)232return;233234memset(sps, 0, sizeof(*sps));235memset(sps->ScalingList4x4, 16, sizeof(sps->ScalingList4x4));236memset(sps->ScalingList8x8, 16, sizeof(sps->ScalingList8x8));237238sps->level_idc = level_idc;239240if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 || profile_idc == 244 ||241profile_idc == 44 || profile_idc == 83 || profile_idc == 86 || profile_idc == 118 ||242profile_idc == 128 || profile_idc == 138) {243244sps->chroma_format_idc = vl_rbsp_ue(rbsp);245246if (sps->chroma_format_idc == 3)247sps->separate_colour_plane_flag = vl_rbsp_u(rbsp, 1);248249sps->bit_depth_luma_minus8 = vl_rbsp_ue(rbsp);250251sps->bit_depth_chroma_minus8 = vl_rbsp_ue(rbsp);252253/* qpprime_y_zero_transform_bypass_flag */254vl_rbsp_u(rbsp, 1);255256sps->seq_scaling_matrix_present_flag = vl_rbsp_u(rbsp, 1);257if (sps->seq_scaling_matrix_present_flag) {258259scaling_list(rbsp, sps->ScalingList4x4[0], 16, Default_4x4_Intra, Default_4x4_Intra);260scaling_list(rbsp, sps->ScalingList4x4[1], 16, Default_4x4_Intra, sps->ScalingList4x4[0]);261scaling_list(rbsp, sps->ScalingList4x4[2], 16, Default_4x4_Intra, sps->ScalingList4x4[1]);262scaling_list(rbsp, sps->ScalingList4x4[3], 16, Default_4x4_Inter, Default_4x4_Inter);263scaling_list(rbsp, sps->ScalingList4x4[4], 16, Default_4x4_Inter, sps->ScalingList4x4[3]);264scaling_list(rbsp, sps->ScalingList4x4[5], 16, Default_4x4_Inter, sps->ScalingList4x4[4]);265266scaling_list(rbsp, sps->ScalingList8x8[0], 64, Default_8x8_Intra, Default_8x8_Intra);267scaling_list(rbsp, sps->ScalingList8x8[1], 64, Default_8x8_Inter, Default_8x8_Inter);268if (sps->chroma_format_idc == 3) {269scaling_list(rbsp, sps->ScalingList8x8[2], 64, Default_8x8_Intra, sps->ScalingList8x8[0]);270scaling_list(rbsp, sps->ScalingList8x8[3], 64, Default_8x8_Inter, sps->ScalingList8x8[1]);271scaling_list(rbsp, sps->ScalingList8x8[4], 64, Default_8x8_Intra, sps->ScalingList8x8[2]);272scaling_list(rbsp, sps->ScalingList8x8[5], 64, Default_8x8_Inter, sps->ScalingList8x8[3]);273}274}275} else if (profile_idc == 183)276sps->chroma_format_idc = 0;277else278sps->chroma_format_idc = 1;279280sps->log2_max_frame_num_minus4 = vl_rbsp_ue(rbsp);281282sps->pic_order_cnt_type = vl_rbsp_ue(rbsp);283284if (sps->pic_order_cnt_type == 0)285sps->log2_max_pic_order_cnt_lsb_minus4 = vl_rbsp_ue(rbsp);286else if (sps->pic_order_cnt_type == 1) {287sps->delta_pic_order_always_zero_flag = vl_rbsp_u(rbsp, 1);288289sps->offset_for_non_ref_pic = vl_rbsp_se(rbsp);290291sps->offset_for_top_to_bottom_field = vl_rbsp_se(rbsp);292293sps->num_ref_frames_in_pic_order_cnt_cycle = vl_rbsp_ue(rbsp);294295for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; ++i)296sps->offset_for_ref_frame[i] = vl_rbsp_se(rbsp);297}298299sps->max_num_ref_frames = vl_rbsp_ue(rbsp);300301/* gaps_in_frame_num_value_allowed_flag */302vl_rbsp_u(rbsp, 1);303304/* pic_width_in_mbs_minus1 */305ASSERTED int pic_width_in_samplesl = (vl_rbsp_ue(rbsp) + 1) * 16;306assert(pic_width_in_samplesl);307308/* pic_height_in_map_units_minus1 */309ASSERTED int pic_height_in_map_units = vl_rbsp_ue(rbsp) + 1;310assert(pic_height_in_map_units);311312sps->frame_mbs_only_flag = vl_rbsp_u(rbsp, 1);313if (!sps->frame_mbs_only_flag)314sps->mb_adaptive_frame_field_flag = vl_rbsp_u(rbsp, 1);315316sps->direct_8x8_inference_flag = vl_rbsp_u(rbsp, 1);317318#if ENABLE_ST_OMX_TIZONIA319priv->stream_info.width = pic_width_in_samplesl;320321int frame_height_in_mbs = (2 - sps->frame_mbs_only_flag) * pic_height_in_map_units;322int pic_height_in_mbs = frame_height_in_mbs / ( 1 + priv->picture.h264.field_pic_flag );323int pic_height_in_samplesl = pic_height_in_mbs * 16;324priv->stream_info.height = pic_height_in_samplesl;325326327/* frame_cropping_flag */328if (vl_rbsp_u(rbsp, 1)) {329unsigned frame_crop_left_offset = vl_rbsp_ue(rbsp);330unsigned frame_crop_right_offset = vl_rbsp_ue(rbsp);331unsigned frame_crop_top_offset = vl_rbsp_ue(rbsp);332unsigned frame_crop_bottom_offset = vl_rbsp_ue(rbsp);333334priv->stream_info.width -= (frame_crop_left_offset + frame_crop_right_offset) * 2;335priv->stream_info.height -= (frame_crop_top_offset + frame_crop_bottom_offset) * 2;336}337#else338/* frame_cropping_flag */339if (vl_rbsp_u(rbsp, 1)) {340/* frame_crop_left_offset */341vl_rbsp_ue(rbsp);342343/* frame_crop_right_offset */344vl_rbsp_ue(rbsp);345346/* frame_crop_top_offset */347vl_rbsp_ue(rbsp);348349/* frame_crop_bottom_offset */350vl_rbsp_ue(rbsp);351}352#endif353354/* vui_parameters_present_flag */355if (vl_rbsp_u(rbsp, 1))356vui_parameters(rbsp);357}358359static struct pipe_h264_pps *pic_parameter_set_id(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp)360{361unsigned id = vl_rbsp_ue(rbsp);362if (id >= ARRAY_SIZE(priv->codec_data.h264.pps))363return NULL; /* invalid pic_parameter_set_id */364365return &priv->codec_data.h264.pps[id];366}367368static void picture_parameter_set(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp)369{370struct pipe_h264_sps *sps;371struct pipe_h264_pps *pps;372unsigned i;373374pps = pic_parameter_set_id(priv, rbsp);375if (!pps)376return;377378memset(pps, 0, sizeof(*pps));379380sps = pps->sps = seq_parameter_set_id(priv, rbsp);381if (!sps)382return;383384memcpy(pps->ScalingList4x4, sps->ScalingList4x4, sizeof(pps->ScalingList4x4));385memcpy(pps->ScalingList8x8, sps->ScalingList8x8, sizeof(pps->ScalingList8x8));386387pps->entropy_coding_mode_flag = vl_rbsp_u(rbsp, 1);388389pps->bottom_field_pic_order_in_frame_present_flag = vl_rbsp_u(rbsp, 1);390391pps->num_slice_groups_minus1 = vl_rbsp_ue(rbsp);392if (pps->num_slice_groups_minus1 > 0) {393pps->slice_group_map_type = vl_rbsp_ue(rbsp);394395if (pps->slice_group_map_type == 0) {396397for (i = 0; i <= pps->num_slice_groups_minus1; ++i)398/* run_length_minus1[i] */399vl_rbsp_ue(rbsp);400401} else if (pps->slice_group_map_type == 2) {402403for (i = 0; i <= pps->num_slice_groups_minus1; ++i) {404/* top_left[i] */405vl_rbsp_ue(rbsp);406407/* bottom_right[i] */408vl_rbsp_ue(rbsp);409}410411} else if (pps->slice_group_map_type >= 3 && pps->slice_group_map_type <= 5) {412413/* slice_group_change_direction_flag */414vl_rbsp_u(rbsp, 1);415416pps->slice_group_change_rate_minus1 = vl_rbsp_ue(rbsp);417418} else if (pps->slice_group_map_type == 6) {419420unsigned pic_size_in_map_units_minus1;421422pic_size_in_map_units_minus1 = vl_rbsp_ue(rbsp);423424for (i = 0; i <= pic_size_in_map_units_minus1; ++i)425/* slice_group_id[i] */426vl_rbsp_u(rbsp, log2(pps->num_slice_groups_minus1 + 1));427}428}429430pps->num_ref_idx_l0_default_active_minus1 = vl_rbsp_ue(rbsp);431432pps->num_ref_idx_l1_default_active_minus1 = vl_rbsp_ue(rbsp);433434pps->weighted_pred_flag = vl_rbsp_u(rbsp, 1);435436pps->weighted_bipred_idc = vl_rbsp_u(rbsp, 2);437438pps->pic_init_qp_minus26 = vl_rbsp_se(rbsp);439440/* pic_init_qs_minus26 */441vl_rbsp_se(rbsp);442443pps->chroma_qp_index_offset = vl_rbsp_se(rbsp);444445pps->deblocking_filter_control_present_flag = vl_rbsp_u(rbsp, 1);446447pps->constrained_intra_pred_flag = vl_rbsp_u(rbsp, 1);448449pps->redundant_pic_cnt_present_flag = vl_rbsp_u(rbsp, 1);450451if (vl_rbsp_more_data(rbsp)) {452pps->transform_8x8_mode_flag = vl_rbsp_u(rbsp, 1);453454/* pic_scaling_matrix_present_flag */455if (vl_rbsp_u(rbsp, 1)) {456457scaling_list(rbsp, pps->ScalingList4x4[0], 16, Default_4x4_Intra,458sps->seq_scaling_matrix_present_flag ? NULL : Default_4x4_Intra);459scaling_list(rbsp, pps->ScalingList4x4[1], 16, Default_4x4_Intra, pps->ScalingList4x4[0]);460scaling_list(rbsp, pps->ScalingList4x4[2], 16, Default_4x4_Intra, pps->ScalingList4x4[1]);461scaling_list(rbsp, pps->ScalingList4x4[3], 16, Default_4x4_Inter,462sps->seq_scaling_matrix_present_flag ? NULL : Default_4x4_Inter);463scaling_list(rbsp, pps->ScalingList4x4[4], 16, Default_4x4_Inter, pps->ScalingList4x4[3]);464scaling_list(rbsp, pps->ScalingList4x4[5], 16, Default_4x4_Inter, pps->ScalingList4x4[4]);465466if (pps->transform_8x8_mode_flag) {467scaling_list(rbsp, pps->ScalingList8x8[0], 64, Default_8x8_Intra,468sps->seq_scaling_matrix_present_flag ? NULL : Default_8x8_Intra);469scaling_list(rbsp, pps->ScalingList8x8[1], 64, Default_8x8_Inter,470sps->seq_scaling_matrix_present_flag ? NULL : Default_8x8_Inter);471if (sps->chroma_format_idc == 3) {472scaling_list(rbsp, pps->ScalingList8x8[2], 64, Default_8x8_Intra, pps->ScalingList8x8[0]);473scaling_list(rbsp, pps->ScalingList8x8[3], 64, Default_8x8_Inter, pps->ScalingList8x8[1]);474scaling_list(rbsp, pps->ScalingList8x8[4], 64, Default_8x8_Intra, pps->ScalingList8x8[2]);475scaling_list(rbsp, pps->ScalingList8x8[5], 64, Default_8x8_Inter, pps->ScalingList8x8[3]);476}477}478}479480pps->second_chroma_qp_index_offset = vl_rbsp_se(rbsp);481}482}483484static void ref_pic_list_mvc_modification(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp)485{486// TODO487assert(0);488}489490static void ref_pic_list_modification(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp,491enum pipe_h264_slice_type slice_type)492{493unsigned modification_of_pic_nums_idc;494495if (slice_type != 2 && slice_type != 4) {496/* ref_pic_list_modification_flag_l0 */497if (vl_rbsp_u(rbsp, 1)) {498do {499modification_of_pic_nums_idc = vl_rbsp_ue(rbsp);500if (modification_of_pic_nums_idc == 0 ||501modification_of_pic_nums_idc == 1)502/* abs_diff_pic_num_minus1 */503vl_rbsp_ue(rbsp);504else if (modification_of_pic_nums_idc == 2)505/* long_term_pic_num */506vl_rbsp_ue(rbsp);507} while (modification_of_pic_nums_idc != 3);508}509}510511if (slice_type == 1) {512/* ref_pic_list_modification_flag_l1 */513if (vl_rbsp_u(rbsp, 1)) {514do {515modification_of_pic_nums_idc = vl_rbsp_ue(rbsp);516if (modification_of_pic_nums_idc == 0 ||517modification_of_pic_nums_idc == 1)518/* abs_diff_pic_num_minus1 */519vl_rbsp_ue(rbsp);520else if (modification_of_pic_nums_idc == 2)521/* long_term_pic_num */522vl_rbsp_ue(rbsp);523} while (modification_of_pic_nums_idc != 3);524}525}526}527528static void pred_weight_table(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp,529struct pipe_h264_sps *sps, enum pipe_h264_slice_type slice_type)530{531unsigned ChromaArrayType = sps->separate_colour_plane_flag ? 0 : sps->chroma_format_idc;532unsigned i, j;533534/* luma_log2_weight_denom */535vl_rbsp_ue(rbsp);536537if (ChromaArrayType != 0)538/* chroma_log2_weight_denom */539vl_rbsp_ue(rbsp);540541for (i = 0; i <= priv->picture.h264.num_ref_idx_l0_active_minus1; ++i) {542/* luma_weight_l0_flag */543if (vl_rbsp_u(rbsp, 1)) {544/* luma_weight_l0[i] */545vl_rbsp_se(rbsp);546/* luma_offset_l0[i] */547vl_rbsp_se(rbsp);548}549if (ChromaArrayType != 0) {550/* chroma_weight_l0_flag */551if (vl_rbsp_u(rbsp, 1)) {552for (j = 0; j < 2; ++j) {553/* chroma_weight_l0[i][j] */554vl_rbsp_se(rbsp);555/* chroma_offset_l0[i][j] */556vl_rbsp_se(rbsp);557}558}559}560}561562if (slice_type == 1) {563for (i = 0; i <= priv->picture.h264.num_ref_idx_l1_active_minus1; ++i) {564/* luma_weight_l1_flag */565if (vl_rbsp_u(rbsp, 1)) {566/* luma_weight_l1[i] */567vl_rbsp_se(rbsp);568/* luma_offset_l1[i] */569vl_rbsp_se(rbsp);570}571if (ChromaArrayType != 0) {572/* chroma_weight_l1_flag */573if (vl_rbsp_u(rbsp, 1)) {574for (j = 0; j < 2; ++j) {575/* chroma_weight_l1[i][j] */576vl_rbsp_se(rbsp);577/* chroma_offset_l1[i][j] */578vl_rbsp_se(rbsp);579}580}581}582}583}584}585586static void dec_ref_pic_marking(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp,587bool IdrPicFlag)588{589unsigned memory_management_control_operation;590591if (IdrPicFlag) {592/* no_output_of_prior_pics_flag */593vl_rbsp_u(rbsp, 1);594/* long_term_reference_flag */595vl_rbsp_u(rbsp, 1);596} else {597/* adaptive_ref_pic_marking_mode_flag */598if (vl_rbsp_u(rbsp, 1)) {599do {600memory_management_control_operation = vl_rbsp_ue(rbsp);601602if (memory_management_control_operation == 1 ||603memory_management_control_operation == 3)604/* difference_of_pic_nums_minus1 */605vl_rbsp_ue(rbsp);606607if (memory_management_control_operation == 2)608/* long_term_pic_num */609vl_rbsp_ue(rbsp);610611if (memory_management_control_operation == 3 ||612memory_management_control_operation == 6)613/* long_term_frame_idx */614vl_rbsp_ue(rbsp);615616if (memory_management_control_operation == 4)617/* max_long_term_frame_idx_plus1 */618vl_rbsp_ue(rbsp);619} while (memory_management_control_operation != 0);620}621}622}623624static void slice_header(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp,625unsigned nal_ref_idc, unsigned nal_unit_type)626{627enum pipe_h264_slice_type slice_type;628struct pipe_h264_pps *pps;629struct pipe_h264_sps *sps;630unsigned frame_num, prevFrameNum;631bool IdrPicFlag = nal_unit_type == 5;632633if (IdrPicFlag != priv->codec_data.h264.IdrPicFlag)634vid_dec_h264_EndFrame(priv);635636priv->codec_data.h264.IdrPicFlag = IdrPicFlag;637638/* first_mb_in_slice */639vl_rbsp_ue(rbsp);640641slice_type = vl_rbsp_ue(rbsp) % 5;642643/* get picture parameter set */644pps = pic_parameter_set_id(priv, rbsp);645if (!pps)646return;647648/* get sequence parameter set */649sps = pps->sps;650if (!sps)651return;652653if (pps != priv->picture.h264.pps)654vid_dec_h264_EndFrame(priv);655656priv->picture.h264.pps = pps;657658if (sps->separate_colour_plane_flag == 1 )659/* colour_plane_id */660vl_rbsp_u(rbsp, 2);661662/* frame number handling */663frame_num = vl_rbsp_u(rbsp, sps->log2_max_frame_num_minus4 + 4);664665if (frame_num != priv->picture.h264.frame_num)666vid_dec_h264_EndFrame(priv);667668prevFrameNum = priv->picture.h264.frame_num;669priv->picture.h264.frame_num = frame_num;670671priv->picture.h264.field_pic_flag = 0;672priv->picture.h264.bottom_field_flag = 0;673674if (!sps->frame_mbs_only_flag) {675unsigned field_pic_flag = vl_rbsp_u(rbsp, 1);676677if (!field_pic_flag && field_pic_flag != priv->picture.h264.field_pic_flag)678vid_dec_h264_EndFrame(priv);679680priv->picture.h264.field_pic_flag = field_pic_flag;681682if (priv->picture.h264.field_pic_flag) {683unsigned bottom_field_flag = vl_rbsp_u(rbsp, 1);684685if (bottom_field_flag != priv->picture.h264.bottom_field_flag)686vid_dec_h264_EndFrame(priv);687688priv->picture.h264.bottom_field_flag = bottom_field_flag;689}690}691692if (IdrPicFlag) {693/* set idr_pic_id */694unsigned idr_pic_id = vl_rbsp_ue(rbsp);695696if (idr_pic_id != priv->codec_data.h264.idr_pic_id)697vid_dec_h264_EndFrame(priv);698699priv->codec_data.h264.idr_pic_id = idr_pic_id;700}701702if (sps->pic_order_cnt_type == 0) {703/* pic_order_cnt_lsb */704unsigned log2_max_pic_order_cnt_lsb = sps->log2_max_pic_order_cnt_lsb_minus4 + 4;705unsigned max_pic_order_cnt_lsb = 1 << log2_max_pic_order_cnt_lsb;706int pic_order_cnt_lsb = vl_rbsp_u(rbsp, log2_max_pic_order_cnt_lsb);707int pic_order_cnt_msb;708709if (pic_order_cnt_lsb != priv->codec_data.h264.pic_order_cnt_lsb)710vid_dec_h264_EndFrame(priv);711712if (IdrPicFlag) {713priv->codec_data.h264.pic_order_cnt_msb = 0;714priv->codec_data.h264.pic_order_cnt_lsb = 0;715}716717if ((pic_order_cnt_lsb < priv->codec_data.h264.pic_order_cnt_lsb) &&718(priv->codec_data.h264.pic_order_cnt_lsb - pic_order_cnt_lsb) >= (max_pic_order_cnt_lsb / 2))719pic_order_cnt_msb = priv->codec_data.h264.pic_order_cnt_msb + max_pic_order_cnt_lsb;720721else if ((pic_order_cnt_lsb > priv->codec_data.h264.pic_order_cnt_lsb) &&722(pic_order_cnt_lsb - priv->codec_data.h264.pic_order_cnt_lsb) > (max_pic_order_cnt_lsb / 2))723pic_order_cnt_msb = priv->codec_data.h264.pic_order_cnt_msb - max_pic_order_cnt_lsb;724725else726pic_order_cnt_msb = priv->codec_data.h264.pic_order_cnt_msb;727728priv->codec_data.h264.pic_order_cnt_msb = pic_order_cnt_msb;729priv->codec_data.h264.pic_order_cnt_lsb = pic_order_cnt_lsb;730731if (pps->bottom_field_pic_order_in_frame_present_flag && !priv->picture.h264.field_pic_flag) {732/* delta_pic_oreder_cnt_bottom */733unsigned delta_pic_order_cnt_bottom = vl_rbsp_se(rbsp);734735if (delta_pic_order_cnt_bottom != priv->codec_data.h264.delta_pic_order_cnt_bottom)736vid_dec_h264_EndFrame(priv);737738priv->codec_data.h264.delta_pic_order_cnt_bottom = delta_pic_order_cnt_bottom;739}740741if (!priv->picture.h264.field_pic_flag) {742priv->picture.h264.field_order_cnt[0] = pic_order_cnt_msb + pic_order_cnt_lsb;743priv->picture.h264.field_order_cnt[1] = priv->picture.h264.field_order_cnt [0] +744priv->codec_data.h264.delta_pic_order_cnt_bottom;745} else if (!priv->picture.h264.bottom_field_flag)746priv->picture.h264.field_order_cnt[0] = pic_order_cnt_msb + pic_order_cnt_lsb;747else748priv->picture.h264.field_order_cnt[1] = pic_order_cnt_msb + pic_order_cnt_lsb;749750} else if (sps->pic_order_cnt_type == 1) {751/* delta_pic_order_cnt[0] */752unsigned MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);753unsigned FrameNumOffset, absFrameNum, expectedPicOrderCnt;754755if (!sps->delta_pic_order_always_zero_flag) {756unsigned delta_pic_order_cnt[2];757758delta_pic_order_cnt[0] = vl_rbsp_se(rbsp);759760if (delta_pic_order_cnt[0] != priv->codec_data.h264.delta_pic_order_cnt[0])761vid_dec_h264_EndFrame(priv);762763priv->codec_data.h264.delta_pic_order_cnt[0] = delta_pic_order_cnt[0];764765if (pps->bottom_field_pic_order_in_frame_present_flag && !priv->picture.h264.field_pic_flag) {766/* delta_pic_order_cnt[1] */767delta_pic_order_cnt[1] = vl_rbsp_se(rbsp);768769if (delta_pic_order_cnt[1] != priv->codec_data.h264.delta_pic_order_cnt[1])770vid_dec_h264_EndFrame(priv);771772priv->codec_data.h264.delta_pic_order_cnt[1] = delta_pic_order_cnt[1];773}774}775776if (IdrPicFlag)777FrameNumOffset = 0;778else if (prevFrameNum > frame_num)779FrameNumOffset = priv->codec_data.h264.prevFrameNumOffset + MaxFrameNum;780else781FrameNumOffset = priv->codec_data.h264.prevFrameNumOffset;782783priv->codec_data.h264.prevFrameNumOffset = FrameNumOffset;784785if (sps->num_ref_frames_in_pic_order_cnt_cycle != 0)786absFrameNum = FrameNumOffset + frame_num;787else788absFrameNum = 0;789790if (nal_ref_idc == 0 && absFrameNum > 0)791absFrameNum = absFrameNum - 1;792793if (absFrameNum > 0) {794unsigned picOrderCntCycleCnt = (absFrameNum - 1) / sps->num_ref_frames_in_pic_order_cnt_cycle;795unsigned frameNumInPicOrderCntCycle = (absFrameNum - 1) % sps->num_ref_frames_in_pic_order_cnt_cycle;796signed ExpectedDeltaPerPicOrderCntCycle = 0;797unsigned i;798799for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; ++i)800ExpectedDeltaPerPicOrderCntCycle += sps->offset_for_ref_frame[i];801802expectedPicOrderCnt = picOrderCntCycleCnt * ExpectedDeltaPerPicOrderCntCycle;803for (i = 0; i <= frameNumInPicOrderCntCycle; ++i)804expectedPicOrderCnt += sps->offset_for_ref_frame[i];805806} else807expectedPicOrderCnt = 0;808809if (nal_ref_idc == 0)810expectedPicOrderCnt += sps->offset_for_non_ref_pic;811812if (!priv->picture.h264.field_pic_flag) {813priv->picture.h264.field_order_cnt[0] = expectedPicOrderCnt + priv->codec_data.h264.delta_pic_order_cnt[0];814priv->picture.h264.field_order_cnt[1] = priv->picture.h264.field_order_cnt[0] +815sps->offset_for_top_to_bottom_field + priv->codec_data.h264.delta_pic_order_cnt[1];816817} else if (!priv->picture.h264.bottom_field_flag)818priv->picture.h264.field_order_cnt[0] = expectedPicOrderCnt + priv->codec_data.h264.delta_pic_order_cnt[0];819else820priv->picture.h264.field_order_cnt[1] = expectedPicOrderCnt + sps->offset_for_top_to_bottom_field +821priv->codec_data.h264.delta_pic_order_cnt[0];822823} else if (sps->pic_order_cnt_type == 2) {824unsigned MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);825unsigned FrameNumOffset, tempPicOrderCnt;826827if (IdrPicFlag)828FrameNumOffset = 0;829else if (prevFrameNum > frame_num)830FrameNumOffset = priv->codec_data.h264.prevFrameNumOffset + MaxFrameNum;831else832FrameNumOffset = priv->codec_data.h264.prevFrameNumOffset;833834priv->codec_data.h264.prevFrameNumOffset = FrameNumOffset;835836if (IdrPicFlag)837tempPicOrderCnt = 0;838else if (nal_ref_idc == 0)839tempPicOrderCnt = 2 * (FrameNumOffset + frame_num) - 1;840else841tempPicOrderCnt = 2 * (FrameNumOffset + frame_num);842843if (!priv->picture.h264.field_pic_flag) {844priv->picture.h264.field_order_cnt[0] = tempPicOrderCnt;845priv->picture.h264.field_order_cnt[1] = tempPicOrderCnt;846847} else if (!priv->picture.h264.bottom_field_flag)848priv->picture.h264.field_order_cnt[0] = tempPicOrderCnt;849else850priv->picture.h264.field_order_cnt[1] = tempPicOrderCnt;851}852853if (pps->redundant_pic_cnt_present_flag)854/* redundant_pic_cnt */855vl_rbsp_ue(rbsp);856857if (slice_type == PIPE_H264_SLICE_TYPE_B)858/* direct_spatial_mv_pred_flag */859vl_rbsp_u(rbsp, 1);860861priv->picture.h264.num_ref_idx_l0_active_minus1 = pps->num_ref_idx_l0_default_active_minus1;862priv->picture.h264.num_ref_idx_l1_active_minus1 = pps->num_ref_idx_l1_default_active_minus1;863864if (slice_type == PIPE_H264_SLICE_TYPE_P ||865slice_type == PIPE_H264_SLICE_TYPE_SP ||866slice_type == PIPE_H264_SLICE_TYPE_B) {867868/* num_ref_idx_active_override_flag */869if (vl_rbsp_u(rbsp, 1)) {870priv->picture.h264.num_ref_idx_l0_active_minus1 = vl_rbsp_ue(rbsp);871872if (slice_type == PIPE_H264_SLICE_TYPE_B)873priv->picture.h264.num_ref_idx_l1_active_minus1 = vl_rbsp_ue(rbsp);874}875}876877if (nal_unit_type == 20 || nal_unit_type == 21)878ref_pic_list_mvc_modification(priv, rbsp);879else880ref_pic_list_modification(priv, rbsp, slice_type);881882if ((pps->weighted_pred_flag && (slice_type == PIPE_H264_SLICE_TYPE_P || slice_type == PIPE_H264_SLICE_TYPE_SP)) ||883(pps->weighted_bipred_idc == 1 && slice_type == PIPE_H264_SLICE_TYPE_B))884pred_weight_table(priv, rbsp, sps, slice_type);885886if (nal_ref_idc != 0)887dec_ref_pic_marking(priv, rbsp, IdrPicFlag);888889if (pps->entropy_coding_mode_flag && slice_type != PIPE_H264_SLICE_TYPE_I && slice_type != PIPE_H264_SLICE_TYPE_SI)890/* cabac_init_idc */891vl_rbsp_ue(rbsp);892893/* slice_qp_delta */894vl_rbsp_se(rbsp);895896if (slice_type == PIPE_H264_SLICE_TYPE_SP || slice_type == PIPE_H264_SLICE_TYPE_SI) {897if (slice_type == PIPE_H264_SLICE_TYPE_SP)898/* sp_for_switch_flag */899vl_rbsp_u(rbsp, 1);900901/*slice_qs_delta */902vl_rbsp_se(rbsp);903}904905if (pps->deblocking_filter_control_present_flag) {906unsigned disable_deblocking_filter_idc = vl_rbsp_ue(rbsp);907908if (disable_deblocking_filter_idc != 1) {909/* slice_alpha_c0_offset_div2 */910vl_rbsp_se(rbsp);911912/* slice_beta_offset_div2 */913vl_rbsp_se(rbsp);914}915}916917if (pps->num_slice_groups_minus1 > 0 && pps->slice_group_map_type >= 3 && pps->slice_group_map_type <= 5)918/* slice_group_change_cycle */919vl_rbsp_u(rbsp, 2);920}921922#if ENABLE_ST_OMX_TIZONIA923static OMX_ERRORTYPE update_port_parameters(vid_dec_PrivateType* priv) {924OMX_VIDEO_PORTDEFINITIONTYPE * p_def = NULL; /* Output port info */925h264d_stream_info_t * i_def = NULL; /* Info read from stream */926OMX_ERRORTYPE err = OMX_ErrorNone;927928assert(priv);929930p_def = &(priv->out_port_def_.format.video);931i_def = &(priv->stream_info);932933/* Handle dynamic resolution change */934if ((p_def->nFrameWidth == i_def->width) && p_def->nFrameHeight == i_def->height)935return err;936937p_def->nFrameWidth = i_def->width;938p_def->nFrameHeight = i_def->height;939p_def->nStride = i_def->width;940p_def->nSliceHeight = i_def->height;941942err = tiz_krn_SetParameter_internal(tiz_get_krn(handleOf(priv)), handleOf(priv),943OMX_IndexParamPortDefinition, &(priv->out_port_def_));944if (err == OMX_ErrorNone) {945tiz_port_t * p_obj = tiz_krn_get_port(tiz_get_krn(handleOf(priv)), OMX_VID_DEC_AVC_INPUT_PORT_INDEX);946947/* Set desired buffer size that will be used when allocating input buffers */948p_obj->portdef_.nBufferSize = p_def->nFrameWidth * p_def->nFrameHeight * 512 / (16*16);949950/* Get a locally copy of port def. Useful for the early return above */951tiz_check_omx(tiz_api_GetParameter(tiz_get_krn(handleOf(priv)), handleOf(priv),952OMX_IndexParamPortDefinition, &(priv->out_port_def_)));953954tiz_srv_issue_event((OMX_PTR) priv, OMX_EventPortSettingsChanged,955OMX_VID_DEC_AVC_OUTPUT_PORT_INDEX,956OMX_IndexParamPortDefinition,957NULL);958}959960return err;961}962#endif963964void vid_dec_h264_Decode(vid_dec_PrivateType *priv, struct vl_vlc *vlc, unsigned min_bits_left)965{966unsigned nal_ref_idc, nal_unit_type;967968if (!vl_vlc_search_byte(vlc, vl_vlc_bits_left(vlc) - min_bits_left, 0x00))969return;970971if (vl_vlc_peekbits(vlc, 24) != 0x000001) {972vl_vlc_eatbits(vlc, 8);973return;974}975976if (priv->slice) {977unsigned bytes = priv->bytes_left - (vl_vlc_bits_left(vlc) / 8);978++priv->picture.h264.slice_count;979priv->codec->decode_bitstream(priv->codec, priv->target, &priv->picture.base,9801, &priv->slice, &bytes);981priv->slice = NULL;982}983984vl_vlc_eatbits(vlc, 24);985986/* forbidden_zero_bit */987vl_vlc_eatbits(vlc, 1);988989nal_ref_idc = vl_vlc_get_uimsbf(vlc, 2);990991if (nal_ref_idc != priv->codec_data.h264.nal_ref_idc &&992(nal_ref_idc * priv->codec_data.h264.nal_ref_idc) == 0)993vid_dec_h264_EndFrame(priv);994995priv->codec_data.h264.nal_ref_idc = nal_ref_idc;996997nal_unit_type = vl_vlc_get_uimsbf(vlc, 5);998999if (nal_unit_type != 1 && nal_unit_type != 5)1000vid_dec_h264_EndFrame(priv);10011002if (nal_unit_type == 7) {1003struct vl_rbsp rbsp;1004vl_rbsp_init(&rbsp, vlc, ~0);1005seq_parameter_set(priv, &rbsp);1006#if ENABLE_ST_OMX_TIZONIA1007update_port_parameters(priv);1008#endif10091010} else if (nal_unit_type == 8) {1011struct vl_rbsp rbsp;1012vl_rbsp_init(&rbsp, vlc, ~0);1013picture_parameter_set(priv, &rbsp);10141015} else if (nal_unit_type == 1 || nal_unit_type == 5) {1016/* Coded slice of a non-IDR or IDR picture */1017unsigned bits = vl_vlc_valid_bits(vlc);1018unsigned bytes = bits / 8 + 4;1019struct vl_rbsp rbsp;1020uint8_t buf[8];1021const void *ptr = buf;1022unsigned i;10231024buf[0] = 0x0;1025buf[1] = 0x0;1026buf[2] = 0x1;1027buf[3] = (nal_ref_idc << 5) | nal_unit_type;1028for (i = 4; i < bytes; ++i)1029buf[i] = vl_vlc_peekbits(vlc, bits) >> ((bytes - i - 1) * 8);10301031priv->bytes_left = (vl_vlc_bits_left(vlc) - bits) / 8;1032priv->slice = vlc->data;10331034vl_rbsp_init(&rbsp, vlc, 128);1035slice_header(priv, &rbsp, nal_ref_idc, nal_unit_type);10361037vid_dec_h264_BeginFrame(priv);10381039++priv->picture.h264.slice_count;1040priv->codec->decode_bitstream(priv->codec, priv->target, &priv->picture.base,10411, &ptr, &bytes);1042}10431044/* resync to byte boundary */1045vl_vlc_eatbits(vlc, vl_vlc_valid_bits(vlc) % 8);1046}10471048void vid_dec_FreeInputPortPrivate(OMX_BUFFERHEADERTYPE *buf)1049{1050struct pipe_video_buffer *vbuf = buf->pInputPortPrivate;1051if (!vbuf)1052return;10531054vbuf->destroy(vbuf);1055buf->pInputPortPrivate = NULL;1056}10571058void vid_dec_FrameDecoded_common(vid_dec_PrivateType* priv, OMX_BUFFERHEADERTYPE* input,1059OMX_BUFFERHEADERTYPE* output)1060{1061#if ENABLE_ST_OMX_BELLAGIO1062bool eos = !!(input->nFlags & OMX_BUFFERFLAG_EOS);1063#else1064bool eos = priv->eos_;1065#endif1066OMX_TICKS timestamp;10671068if (!input->pInputPortPrivate) {1069#if ENABLE_ST_OMX_BELLAGIO1070input->pInputPortPrivate = priv->Flush(priv, ×tamp);1071#else1072input->pInputPortPrivate = vid_dec_h264_Flush(priv, ×tamp);1073#endif1074if (timestamp != OMX_VID_DEC_AVC_TIMESTAMP_INVALID)1075input->nTimeStamp = timestamp;1076}10771078if (input->pInputPortPrivate) {1079if (output->pInputPortPrivate && !priv->disable_tunnel) {1080struct pipe_video_buffer *tmp, *vbuf, *new_vbuf;10811082tmp = output->pOutputPortPrivate;1083vbuf = input->pInputPortPrivate;1084if (vbuf->interlaced) {1085/* re-allocate the progressive buffer */1086struct pipe_video_buffer templat = {};1087struct u_rect src_rect, dst_rect;10881089#if ENABLE_ST_OMX_BELLAGIO1090omx_base_video_PortType *port;1091port = (omx_base_video_PortType *)1092priv->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];1093#else1094tiz_port_t *port;1095port = tiz_krn_get_port(tiz_get_krn(handleOf (priv)), OMX_VID_DEC_AVC_INPUT_PORT_INDEX);1096#endif1097memset(&templat, 0, sizeof(templat));1098#if ENABLE_ST_OMX_BELLAGIO1099templat.width = port->sPortParam.format.video.nFrameWidth;1100templat.height = port->sPortParam.format.video.nFrameHeight;1101#else1102templat.width = port->portdef_.format.video.nFrameWidth;1103templat.height = port->portdef_.format.video.nFrameHeight;1104#endif1105templat.buffer_format = PIPE_FORMAT_NV12;1106templat.interlaced = false;1107new_vbuf = priv->pipe->create_video_buffer(priv->pipe, &templat);11081109/* convert the interlaced to the progressive */1110src_rect.x0 = dst_rect.x0 = 0;1111src_rect.x1 = dst_rect.x1 = templat.width;1112src_rect.y0 = dst_rect.y0 = 0;1113src_rect.y1 = dst_rect.y1 = templat.height;11141115vl_compositor_yuv_deint_full(&priv->cstate, &priv->compositor,1116input->pInputPortPrivate, new_vbuf,1117&src_rect, &dst_rect, VL_COMPOSITOR_WEAVE);11181119/* set the progrssive buffer for next round */1120vbuf->destroy(vbuf);1121input->pInputPortPrivate = new_vbuf;1122}1123output->pOutputPortPrivate = input->pInputPortPrivate;1124input->pInputPortPrivate = tmp;1125} else {1126vid_dec_FillOutput(priv, input->pInputPortPrivate, output);1127}1128output->nFilledLen = output->nAllocLen;1129output->nTimeStamp = input->nTimeStamp;1130}11311132if (eos && input->pInputPortPrivate)1133vid_dec_FreeInputPortPrivate(input);1134else1135input->nFilledLen = 0;1136}113711381139