/* * * Copyright 2015 Rockchip Electronics Co. LTD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * @file h265d_sei.c * @brief * @author csy(csy@rock-chips.com) * @version 1.0.0 * @history * 2015.7.15 : Create */ #define MODULE_TAG "h265d_sei" #include "h265d_parser.h" static RK_S32 decode_nal_sei_decoded_picture_hash(HEVCContext *s) { RK_S32 cIdx, i; RK_U8 hash_type; //uint16_t picture_crc; //RK_U32 picture_checksum; BitReadCtx_t*gb = &s->HEVClc->gb; READ_BITS(gb, 8, &hash_type); for (cIdx = 0; cIdx < 3/*((s->sps->chroma_format_idc == 0) ? 1 : 3)*/; cIdx++) { if (hash_type == 0) { //s->is_md5 = 1; for (i = 0; i < 16; i++) SKIP_BITS(gb, 8); } else if (hash_type == 1) { SKIP_BITS(gb, 16); } else if (hash_type == 2) { SKIP_BITS(gb, 32); } } return 0; __BITREAD_ERR: return MPP_ERR_STREAM; } static RK_S32 decode_nal_sei_frame_packing_arrangement(HEVCContext *s) { BitReadCtx_t *gb = &s->HEVClc->gb; RK_S32 value = 0; READ_UE(gb, &value); // frame_packing_arrangement_id READ_ONEBIT(gb, &value); s->sei_frame_packing_present = !value; if (s->sei_frame_packing_present) { READ_BITS(gb, 7, &s->frame_packing_arrangement_type); READ_ONEBIT(gb, &s->quincunx_subsampling); READ_BITS(gb, 6, &s->content_interpretation_type); // the following skips spatial_flipping_flag frame0_flipped_flag // field_views_flag current_frame_is_frame0_flag // frame0_self_contained_flag frame1_self_contained_flag SKIP_BITS(gb, 6); if (!s->quincunx_subsampling && s->frame_packing_arrangement_type != 5) SKIP_BITS(gb, 16); // frame[01]_grid_position_[xy] SKIP_BITS(gb, 8); // frame_packing_arrangement_reserved_byte SKIP_BITS(gb, 1); // frame_packing_arrangement_persistance_flag } SKIP_BITS(gb, 1); // upsampled_aspect_ratio_flag return 0; __BITREAD_ERR: return MPP_ERR_STREAM; } static RK_S32 decode_pic_timing(HEVCContext *s) { BitReadCtx_t *gb = &s->HEVClc->gb; HEVCSPS *sps; if (!s->sps_list[s->active_seq_parameter_set_id]) return MPP_ERR_NOMEM; sps = (HEVCSPS*)s->sps_list[s->active_seq_parameter_set_id]; s->picture_struct = MPP_PICTURE_STRUCTURE_UNKNOWN; if (sps->vui.frame_field_info_present_flag) { READ_BITS(gb, 4, &s->picture_struct); switch (s->picture_struct) { case 0 : s->picture_struct = MPP_PICTURE_STRUCTURE_FRAME; h265d_dbg(H265D_DBG_SEI, "(progressive) frame \n"); break; case 1 : s->picture_struct = MPP_PICTURE_STRUCTURE_TOP_FIELD; h265d_dbg(H265D_DBG_SEI, "top field\n"); break; case 2 : s->picture_struct = MPP_PICTURE_STRUCTURE_BOTTOM_FIELD; h265d_dbg(H265D_DBG_SEI, "bottom field\n"); break; case 3 : s->picture_struct = MPP_PICTURE_STRUCTURE_FRAME; h265d_dbg(H265D_DBG_SEI, "top field, bottom field, in that order\n"); break; case 4 : s->picture_struct = MPP_PICTURE_STRUCTURE_FRAME; h265d_dbg(H265D_DBG_SEI, "bottom field, top field, in that order\n"); break; case 5 : s->picture_struct = MPP_PICTURE_STRUCTURE_FRAME; h265d_dbg(H265D_DBG_SEI, "top field, bottom field, top field repeated, in that order\n"); break; case 6 : s->picture_struct = MPP_PICTURE_STRUCTURE_FRAME; h265d_dbg(H265D_DBG_SEI, "bottom field, top field, bottom field repeated, in that order\n"); break; case 7 : s->picture_struct = MPP_PICTURE_STRUCTURE_FRAME; h265d_dbg(H265D_DBG_SEI, "frame doubling\n"); break; case 8 : s->picture_struct = MPP_PICTURE_STRUCTURE_FRAME; h265d_dbg(H265D_DBG_SEI, "frame tripling\n"); break; case 9 : s->picture_struct = MPP_PICTURE_STRUCTURE_TOP_FIELD; h265d_dbg(H265D_DBG_SEI, "top field paired with previous bottom field in output order\n"); break; case 10 : s->picture_struct = MPP_PICTURE_STRUCTURE_BOTTOM_FIELD; h265d_dbg(H265D_DBG_SEI, "bottom field paired with previous top field in output order\n"); break; case 11 : s->picture_struct = MPP_PICTURE_STRUCTURE_TOP_FIELD; h265d_dbg(H265D_DBG_SEI, "top field paired with next bottom field in output order\n"); break; case 12 : s->picture_struct = MPP_PICTURE_STRUCTURE_BOTTOM_FIELD; h265d_dbg(H265D_DBG_SEI, "bottom field paired with next top field in output order\n"); break; } SKIP_BITS(gb, 2); // source_scan_type SKIP_BITS(gb, 1); // duplicate_flag } return 1; __BITREAD_ERR: return MPP_ERR_STREAM; } static RK_S32 active_parameter_sets(HEVCContext *s) { BitReadCtx_t *gb = &s->HEVClc->gb; RK_S32 num_sps_ids_minus1; RK_S32 i, value; RK_U32 active_seq_parameter_set_id; SKIP_BITS(gb, 4); // active_video_parameter_set_id SKIP_BITS(gb, 1); // self_contained_cvs_flag SKIP_BITS(gb, 1); // num_sps_ids_minus1 READ_UE(gb, &num_sps_ids_minus1); // num_sps_ids_minus1 READ_UE(gb, &active_seq_parameter_set_id); if (active_seq_parameter_set_id >= MAX_SPS_COUNT) { mpp_err( "active_parameter_set_id %d invalid\n", active_seq_parameter_set_id); return MPP_ERR_STREAM; } s->active_seq_parameter_set_id = active_seq_parameter_set_id; for (i = 1; i <= num_sps_ids_minus1; i++) READ_UE(gb, &value); // active_seq_parameter_set_id[i] return 0; __BITREAD_ERR: return MPP_ERR_STREAM; } static RK_S32 mastering_display_colour_volume(HEVCContext *s) { RK_S32 i = 0; RK_U16 value = 0; RK_U32 lum = 0; BitReadCtx_t *gb = &s->HEVClc->gb; for (i = 0; i < 3; i++) { READ_BITS(gb, 16, &value); s->mastering_display.display_primaries[i][0] = value; READ_BITS(gb, 16, &value); s->mastering_display.display_primaries[i][1] = value; } READ_BITS(gb, 16, &value); s->mastering_display.white_point[0] = value; READ_BITS(gb, 16, &value); s->mastering_display.white_point[1] = value; mpp_read_longbits(gb, 32, &lum); s->mastering_display.max_luminance = lum; mpp_read_longbits(gb, 32, &lum); s->mastering_display.min_luminance = lum; return 0; __BITREAD_ERR: return MPP_ERR_STREAM; } static RK_S32 content_light_info(HEVCContext *s) { RK_U32 value = 0; BitReadCtx_t *gb = &s->HEVClc->gb; mpp_read_longbits(gb, 16, &value); s->content_light.MaxCLL = value; mpp_read_longbits(gb, 16, &value); s->content_light.MaxFALL = value; return 0; } static RK_S32 colour_remapping_info(HEVCContext *s) { RK_U32 i = 0, j = 0; RK_U32 value = 0; RK_U32 in_bit_depth = 0; RK_U32 out_bit_depth = 0; BitReadCtx_t *gb = &s->HEVClc->gb; READ_UE(gb, &value); //colour_remap ID READ_ONEBIT(gb, &value); //colour_remap_cancel_flag if (!value) { READ_ONEBIT(gb, &value); //colour_remap_persistence_flag READ_ONEBIT(gb, &value); //colour_remap_video_signal_info_present_flag if (value) { READ_ONEBIT(gb, &value); //colour_remap_full_rang_flag READ_BITS(gb, 8, &value); //colour_remap_primaries READ_BITS(gb, 8, &value); //colour_remap_transfer_function READ_BITS(gb, 8, &value); //colour_remap_matries_coefficients } READ_BITS(gb, 8, &in_bit_depth); //colour_remap_input_bit_depth READ_BITS(gb, 8, &out_bit_depth); //colour_remap_bit_depth for (i = 0; i < 3; i++) { RK_U32 pre_lut_num_val_minus1 = 0; RK_U32 in_bit = ((in_bit_depth + 7) >> 3) << 3; RK_U32 out_bit = ((out_bit_depth + 7) >> 3) << 3; READ_BITS(gb, 8, &pre_lut_num_val_minus1); //pre_lut_num_val_minus1 if (pre_lut_num_val_minus1 > 0) { for (j = 0; j <= pre_lut_num_val_minus1; j++) { READ_BITS(gb, in_bit, &value); //pre_lut_coded_value READ_BITS(gb, out_bit, &value); //pre_lut_target_value } } } READ_ONEBIT(gb, &value); //colour_remap_matrix_present_flag if (value) { READ_BITS(gb, 4, &value); //log2_matrix_denom for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) READ_SE(gb, &value); //colour_remap_coeffs } } for (i = 0; i < 3; i++) { RK_U32 post_lut_num_val_minus1 = 0; RK_U32 in_bit = ((in_bit_depth + 7) >> 3) << 3; RK_U32 out_bit = ((out_bit_depth + 7) >> 3) << 3; READ_BITS(gb, 8, &post_lut_num_val_minus1); //post_lut_num_val_minus1 if (post_lut_num_val_minus1 > 0) { for (j = 0; j <= post_lut_num_val_minus1; j++) { READ_BITS(gb, in_bit, &value); //post_lut_coded_value READ_BITS(gb, out_bit, &value); //post_lut_target_value } } } } __BITREAD_ERR: return MPP_ERR_STREAM; } static RK_S32 tone_mapping_info(HEVCContext *s) { RK_U32 i = 0; RK_U32 value = 0; RK_U32 codec_bit_depth = 0; RK_U32 target_bit_depth = 0; BitReadCtx_t *gb = &s->HEVClc->gb; READ_UE(gb, &value); //tone_map ID READ_ONEBIT(gb, &value); //tone_map_cancel_flag if (!value) { RK_U32 tone_map_model_id; READ_ONEBIT(gb, &value); //tone_map_persistence_flag READ_BITS(gb, 8, &codec_bit_depth); //coded_data_bit_depth READ_BITS(gb, 8, &target_bit_depth); //target_bit_depth READ_UE(gb, &tone_map_model_id); //tone_map_model_id switch (tone_map_model_id) { case 0: { mpp_read_longbits(gb, 32, &value); //min_value mpp_read_longbits(gb, 32, &value); //max_value break; } case 1: { mpp_read_longbits(gb, 32, &value); //sigmoid_midpoint mpp_read_longbits(gb, 32, &value); //sigmoid_width break; } case 2: { RK_U32 in_bit = ((codec_bit_depth + 7) >> 3) << 3; for (i = 0; i < (RK_U32)(1 << target_bit_depth); i++) { READ_BITS(gb, in_bit, &value); } break; } case 3: { RK_U32 num_pivots; RK_U32 in_bit = ((codec_bit_depth + 7) >> 3) << 3; RK_U32 out_bit = ((target_bit_depth + 7) >> 3) << 3; READ_BITS(gb, 16, &num_pivots); //num_pivots for (i = 0; i < num_pivots; i++) { READ_BITS(gb, in_bit, &value); READ_BITS(gb, out_bit, &value); } break; } case 4: { RK_U32 camera_iso_speed_idc; RK_U32 exposure_index_idc; READ_BITS(gb, 8, &camera_iso_speed_idc); if (camera_iso_speed_idc == 255) { mpp_read_longbits(gb, 32, &value); //camera_iso_speed_value } READ_BITS(gb, 8, &exposure_index_idc); if (exposure_index_idc == 255) { mpp_read_longbits(gb, 32, &value); //exposure_index_value } READ_ONEBIT(gb, &value); //exposure_compensation_value_sign_flag READ_BITS(gb, 16, &value); //exposure_compensation_value_numerator READ_BITS(gb, 16, &value); //exposure_compensation_value_denom_idc READ_BITS(gb, 32, &value); //ref_screen_luminance_white READ_BITS(gb, 32, &value); //extended_range_white_level READ_BITS(gb, 16, &value); //nominal_black_level_code_value READ_BITS(gb, 16, &value); //nominal_white_level_code_value READ_BITS(gb, 16, &value); //extended_white_level_code_value break; } default: break; } } __BITREAD_ERR: return MPP_ERR_STREAM; } static RK_S32 decode_nal_sei_message(HEVCContext *s) { BitReadCtx_t *gb = &s->HEVClc->gb; int payload_type = 0; int payload_size = 0; int byte = 0xFF; h265d_dbg(H265D_DBG_SEI, "Decoding SEI\n"); while (byte == 0xFF) { READ_BITS(gb, 8, &byte); payload_type += byte; } byte = 0xFF; while (byte == 0xFF) { READ_BITS(gb, 8, &byte); payload_size += byte; } h265d_dbg(H265D_DBG_SEI, "s->nal_unit_type %d payload_type %d payload_size %d\n", s->nal_unit_type, payload_type, payload_size); if (s->nal_unit_type == NAL_SEI_PREFIX) { if (payload_type == 256 /*&& s->decode_checksum_sei*/) { decode_nal_sei_decoded_picture_hash(s); return 1; } else if (payload_type == 45) { decode_nal_sei_frame_packing_arrangement(s); return 1; } else if (payload_type == 1) { int ret = decode_pic_timing(s); h265d_dbg(H265D_DBG_SEI, "Skipped PREFIX SEI %d\n", payload_type); SKIP_BITS(gb, 8 * payload_size); return ret; } else if (payload_type == 129) { active_parameter_sets(s); h265d_dbg(H265D_DBG_SEI, "Skipped PREFIX SEI %d\n", payload_type); return 1; } else if (payload_type == 137) { h265d_dbg(H265D_DBG_SEI, "mastering_display_colour_volume in\n"); mastering_display_colour_volume(s); return 1; } else if (payload_type == 144) { h265d_dbg(H265D_DBG_SEI, "content_light_info in\n"); content_light_info(s); return 1; } else if (payload_type == 143) { h265d_dbg(H265D_DBG_SEI, "colour_remapping_info in\n"); colour_remapping_info(s); return 1; } else if (payload_type == 23) { h265d_dbg(H265D_DBG_SEI, "tone_mapping_info in\n"); tone_mapping_info(s); return 1; } else { h265d_dbg(H265D_DBG_SEI, "Skipped PREFIX SEI %d\n", payload_type); SKIP_BITS(gb, 8 * payload_size); return 1; } } else { /* nal_unit_type == NAL_SEI_SUFFIX */ if (payload_type == 132 /* && s->decode_checksum_sei */) decode_nal_sei_decoded_picture_hash(s); else { h265d_dbg(H265D_DBG_SEI, "Skipped SUFFIX SEI %d\n", payload_type); SKIP_BITS(gb, 8 * payload_size); } return 1; } __BITREAD_ERR: return MPP_ERR_STREAM; } static RK_S32 more_rbsp_data(BitReadCtx_t *gb) { return gb->bytes_left_ > 1 && gb->data_[0] != 0x80; } RK_S32 mpp_hevc_decode_nal_sei(HEVCContext *s) { RK_S32 ret; do { ret = decode_nal_sei_message(s); if (ret < 0) return MPP_ERR_NOMEM; } while (more_rbsp_data(&s->HEVClc->gb)); return 1; }