1 /*-------------------------------------------------------------------------- 2 Copyright (c) 2010-2013, 2018, The Linux Foundation. All rights reserved. 3 4 Redistribution and use in source and binary forms, with or without 5 modification, are permitted provided that the following conditions are met: 6 * Redistributions of source code must retain the above copyright 7 notice, this list of conditions and the following disclaimer. 8 * Redistributions in binary form must reproduce the above copyright 9 notice, this list of conditions and the following disclaimer in the 10 documentation and/or other materials provided with the distribution. 11 * Neither the name of The Linux Foundation nor 12 the names of its contributors may be used to endorse or promote 13 products derived from this software without specific prior written 14 permission. 15 16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 --------------------------------------------------------------------------*/ 28 #ifndef H264_UTILS_H 29 #define H264_UTILS_H 30 31 /*======================================================================== 32 33 O p e n M M 34 U t i l i t i e s a n d H e l p e r R o u t i n e s 35 36 *//** @file H264_Utils.h 37 This module contains H264 video decoder utilities and helper routines. 38 39 *//*====================================================================== */ 40 41 /* ======================================================================= 42 43 INCLUDE FILES FOR MODULE 44 45 ========================================================================== */ 46 #include <stdio.h> 47 #include "Map.h" 48 #include "qtypes.h" 49 #include "OMX_Core.h" 50 #include "OMX_QCOMExtns.h" 51 52 #define STD_MIN(x,y) (((x) < (y)) ? (x) : (y)) 53 54 #define PANSCAN_HDLR 55 56 /* ======================================================================= 57 58 DATA DECLARATIONS 59 60 ========================================================================== */ 61 62 /* ----------------------------------------------------------------------- 63 ** Constant / Define Declarations 64 ** ----------------------------------------------------------------------- */ 65 66 /* ======================================================================= 67 ** Function Declarations 68 ** ======================================================================= */ 69 70 /* ----------------------------------------------------------------------- 71 ** Type Declarations 72 ** ----------------------------------------------------------------------- */ 73 74 // This type is used when parsing an H.264 bitstream to collect H.264 NAL 75 // units that need to go in the meta data. 76 struct H264ParamNalu { 77 uint32 picSetID; 78 uint32 seqSetID; 79 uint32 picOrderCntType; 80 bool frameMbsOnlyFlag; 81 bool picOrderPresentFlag; 82 uint32 picWidthInMbsMinus1; 83 uint32 picHeightInMapUnitsMinus1; 84 uint32 log2MaxFrameNumMinus4; 85 uint32 log2MaxPicOrderCntLsbMinus4; 86 bool deltaPicOrderAlwaysZeroFlag; 87 uint32 nalu; 88 uint32 crop_left; 89 uint32 crop_right; 90 uint32 crop_top; 91 uint32 crop_bot; 92 }; 93 //typedef map<uint32, H264ParamNalu> H264ParamNaluSet; 94 typedef Map<uint32, H264ParamNalu *> H264ParamNaluSet; 95 96 typedef enum { 97 NALU_TYPE_UNSPECIFIED = 0, 98 NALU_TYPE_NON_IDR, 99 NALU_TYPE_PARTITION_A, 100 NALU_TYPE_PARTITION_B, 101 NALU_TYPE_PARTITION_C, 102 NALU_TYPE_IDR, 103 NALU_TYPE_SEI, 104 NALU_TYPE_SPS, 105 NALU_TYPE_PPS, 106 NALU_TYPE_ACCESS_DELIM, 107 NALU_TYPE_EOSEQ, 108 NALU_TYPE_EOSTREAM, 109 NALU_TYPE_FILLER_DATA, 110 NALU_TYPE_RESERVED, 111 } NALU_TYPE; 112 113 // NAL header information 114 typedef struct { 115 uint32 nal_ref_idc; 116 uint32 nalu_type; 117 uint32 forbidden_zero_bit; 118 } NALU; 119 120 class RbspParser 121 /****************************************************************************** 122 ** This class is used to convert an H.264 NALU (network abstraction layer 123 ** unit) into RBSP (raw byte sequence payload) and extract bits from it. 124 *****************************************************************************/ 125 { 126 public: 127 RbspParser (const uint8 *begin, const uint8 *end); 128 129 virtual ~RbspParser (); 130 131 uint32 next (); 132 void advance (); 133 uint32 u (uint32 n); 134 uint32 ue (); 135 int32 se (); 136 137 private: 138 const uint8 *begin, *end; 139 int32 pos; 140 uint32 bit; 141 uint32 cursor; 142 bool advanceNeeded; 143 }; 144 145 class H264_Utils 146 { 147 public: 148 H264_Utils(); 149 ~H264_Utils(); 150 void initialize_frame_checking_environment(); 151 void allocate_rbsp_buffer(uint32 inputBufferSize); 152 bool isNewFrame(OMX_BUFFERHEADERTYPE *p_buf_hdr, 153 OMX_IN OMX_U32 size_of_nal_length_field, 154 OMX_OUT OMX_BOOL &isNewFrame); 155 uint32 nalu_type; 156 157 private: 158 boolean extract_rbsp(OMX_IN OMX_U8 *buffer, 159 OMX_IN OMX_U32 buffer_length, 160 OMX_IN OMX_U32 size_of_nal_length_field, 161 OMX_OUT OMX_U8 *rbsp_bistream, 162 OMX_OUT OMX_U32 *rbsp_length, 163 OMX_OUT NALU *nal_unit); 164 165 unsigned m_height; 166 unsigned m_width; 167 H264ParamNaluSet pic; 168 H264ParamNaluSet seq; 169 uint8 *m_rbspBytes; 170 NALU m_prv_nalu; 171 bool m_forceToStichNextNAL; 172 bool m_au_data; 173 }; 174 175 class perf_metrics 176 { 177 public: perf_metrics()178 perf_metrics() : 179 start_time(0), 180 proc_time(0), 181 active(false) { 182 }; ~perf_metrics()183 ~perf_metrics() {}; 184 void start(); 185 void stop(); 186 void end(OMX_U32 units_cntr = 0); 187 void reset(); 188 OMX_U64 processing_time_us(); 189 private: 190 inline OMX_U64 get_act_time(); 191 OMX_U64 start_time; 192 OMX_U64 proc_time; 193 bool active; 194 }; 195 196 #define EMULATION_PREVENTION_THREE_BYTE 0x03 197 #define MAX_CPB_COUNT 32 198 #define NO_PAN_SCAN_BIT 0x00000100 199 #define MAX_PAN_SCAN_RECT 3 200 #define VALID_TS(ts) ((ts < LLONG_MAX)? true : false) 201 #define NALU_TYPE_VUI (NALU_TYPE_RESERVED + 1) 202 203 enum SEI_PAYLOAD_TYPE { 204 BUFFERING_PERIOD = 0, 205 PIC_TIMING, 206 PAN_SCAN_RECT, 207 FILLER_PAYLOAD, 208 USER_DATA_REGISTERED_ITU_T_T35, 209 USER_DATA_UNREGISTERED, 210 RECOVERY_POINT, 211 DEC_REF_PIC_MARKING_REPETITION, 212 SPARE_PIC, 213 SCENE_INFO, 214 SUB_SEQ_INFO, 215 SUB_SEQ_LAYER_CHARACTERISTICS, 216 SUB_SEQ_CHARACTERISTICS, 217 FULL_FRAME_FREEZE, 218 FULL_FRAME_FREEZE_RELEASE, 219 FULL_FRAME_SNAPSHOT, 220 PROGRESSIVE_REFINEMENT_SEGMENT_START, 221 PROGRESSIVE_REFINEMENT_SEGMENT_END, 222 SEI_PAYLOAD_FRAME_PACKING_ARRANGEMENT = 0x2D 223 }; 224 225 typedef struct { 226 OMX_U32 cpb_cnt; 227 OMX_U8 bit_rate_scale; 228 OMX_U8 cpb_size_scale; 229 OMX_U32 bit_rate_value[MAX_CPB_COUNT]; 230 OMX_U32 cpb_size_value[MAX_CPB_COUNT]; 231 OMX_U8 cbr_flag[MAX_CPB_COUNT]; 232 OMX_U8 initial_cpb_removal_delay_length; 233 OMX_U8 cpb_removal_delay_length; 234 OMX_U8 dpb_output_delay_length; 235 OMX_U8 time_offset_length; 236 } h264_hrd_param; 237 238 typedef struct { 239 OMX_U32 aspect_ratio_idc; 240 OMX_U32 aspect_ratio_x; 241 OMX_U32 aspect_ratio_y; 242 } h264_aspect_ratio_info; 243 244 typedef struct { 245 OMX_U8 aspect_ratio_info_present_flag; 246 h264_aspect_ratio_info aspect_ratio_info; 247 OMX_U8 timing_info_present_flag; 248 OMX_U32 num_units_in_tick; 249 OMX_U32 time_scale; 250 OMX_U8 fixed_frame_rate_flag; 251 OMX_U8 nal_hrd_parameters_present_flag; 252 h264_hrd_param nal_hrd_parameters; 253 OMX_U8 vcl_hrd_parameters_present_flag; 254 h264_hrd_param vcl_hrd_parameters; 255 OMX_U8 low_delay_hrd_flag; 256 OMX_U8 pic_struct_present_flag; 257 OMX_S64 fixed_fps_prev_ts; 258 } h264_vui_param; 259 260 typedef struct { 261 OMX_U32 cpb_removal_delay; 262 OMX_U32 dpb_output_delay; 263 OMX_U8 pic_struct; 264 OMX_U32 num_clock_ts; 265 bool clock_ts_flag; 266 OMX_U8 ct_type; 267 OMX_U32 nuit_field_based_flag; 268 OMX_U8 counting_type; 269 OMX_U8 full_timestamp_flag; 270 OMX_U8 discontinuity_flag; 271 OMX_U8 cnt_dropped_flag; 272 OMX_U32 n_frames; 273 OMX_U32 seconds_value; 274 OMX_U32 minutes_value; 275 OMX_U32 hours_value; 276 OMX_S32 time_offset; 277 bool is_valid; 278 } h264_sei_pic_timing; 279 280 typedef struct { 281 OMX_U32 initial_cpb_removal_delay[MAX_CPB_COUNT]; 282 OMX_U32 initial_cpb_removal_delay_offset[MAX_CPB_COUNT]; 283 OMX_U32 au_cntr; 284 OMX_S64 reference_ts; 285 bool is_valid; 286 } h264_sei_buf_period; 287 288 typedef struct { 289 OMX_U32 rect_id; 290 OMX_U8 rect_cancel_flag; 291 OMX_U32 cnt; 292 OMX_S32 rect_left_offset[MAX_PAN_SCAN_RECT]; 293 OMX_S32 rect_right_offset[MAX_PAN_SCAN_RECT]; 294 OMX_S32 rect_top_offset[MAX_PAN_SCAN_RECT]; 295 OMX_S32 rect_bottom_offset[MAX_PAN_SCAN_RECT]; 296 OMX_U32 rect_repetition_period; 297 } h264_pan_scan; 298 299 #ifdef PANSCAN_HDLR 300 template <class NODE_STRUCT> 301 class omx_dl_list 302 { 303 public: omx_dl_list()304 omx_dl_list() { 305 head = tail = NULL; 306 } ; ~omx_dl_list()307 ~omx_dl_list() {}; 308 void add_multiple(NODE_STRUCT *data_arr, int data_num); 309 NODE_STRUCT *remove_first(); 310 NODE_STRUCT *remove_last(); 311 void add_last(NODE_STRUCT *data_ptr); 312 NODE_STRUCT *watch_first(); 313 NODE_STRUCT *watch_last(); 314 private: 315 NODE_STRUCT *head, *tail; 316 }; 317 318 class panscan_handler 319 { 320 public: 321 panscan_handler(); 322 ~panscan_handler(); 323 bool initialize(int num_data); 324 h264_pan_scan *get_free(); 325 h264_pan_scan *get_populated(OMX_S64 frame_ts); 326 void update_last(OMX_S64 frame_ts); 327 private: 328 typedef struct PANSCAN_NODE { 329 h264_pan_scan pan_scan_param; 330 OMX_S64 start_ts, end_ts; 331 bool active; 332 PANSCAN_NODE *next, *prev; 333 } PANSCAN_NODE; 334 omx_dl_list<PANSCAN_NODE> panscan_used; 335 omx_dl_list<PANSCAN_NODE> panscan_free; 336 PANSCAN_NODE *panscan_data; 337 }; 338 339 #ifndef DEBUG_PANSCAN_DATA 340 341 #define PRINT_PANSCAN_PARAM(H264_PARAM) 342 #define PRINT_PANSCAN_DATA(NODE) 343 344 #else 345 346 #define PRINT_PANSCAN_PARAM(H264_PARAM) \ 347 do {\ 348 DEBUG_PRINT_ERROR("%s(): left_off(%ld) right_off(%ld) top_off(%ld) bottom_off(%ld)",\ 349 __FUNCTION__,\ 350 (H264_PARAM).rect_left_offset[0],\ 351 (H264_PARAM).rect_right_offset[0],\ 352 (H264_PARAM).rect_top_offset[0],\ 353 (H264_PARAM).rect_bottom_offset[0]);\ 354 }while(0) 355 356 #define PRINT_PANSCAN_DATA(NODE) \ 357 do {\ 358 if (NODE) {\ 359 DEBUG_PRINT_ERROR("%s(): PANSCAN DATA start_ts(%lld) end_ts(%lld)", __FUNCTION__,\ 360 (NODE)->start_ts, (NODE)->end_ts);\ 361 PRINT_PANSCAN_PARAM(NODE->pan_scan_param);\ 362 }\ 363 }while(0) 364 365 #endif // End debug panscan data 366 367 #endif 368 369 class h264_stream_parser 370 { 371 public: 372 h264_stream_parser(); 373 ~h264_stream_parser(); 374 void reset(); 375 void fill_pan_scan_data(OMX_QCOM_PANSCAN *dest_pan_scan, OMX_S64 timestamp); 376 void fill_aspect_ratio_info(OMX_QCOM_ASPECT_RATIO *dest_aspect_ratio); 377 void parse_nal(OMX_U8* data_ptr, OMX_U32 data_len, 378 OMX_U32 nal_type = NALU_TYPE_UNSPECIFIED, 379 bool enable_emu_sc = true); 380 OMX_S64 process_ts_with_sei_vui(OMX_S64 timestamp); 381 void get_frame_pack_data(OMX_QCOM_FRAME_PACK_ARRANGEMENT *frame_pack); 382 bool is_mbaff(); 383 void get_frame_rate(OMX_U32 *frame_rate); 384 #ifdef PANSCAN_HDLR 385 void update_panscan_data(OMX_S64 timestamp); 386 #endif 387 private: 388 void init_bitstream(OMX_U8* data, OMX_U32 size); 389 OMX_U32 extract_bits(OMX_U32 n); 390 inline bool more_bits(); 391 void read_word(); 392 OMX_U32 uev(); 393 OMX_S32 sev(); 394 OMX_S32 iv(OMX_U32 n_bits); 395 void parse_sps(); 396 void parse_vui(bool vui_in_extradata = true); 397 void aspect_ratio_info(); 398 void hrd_parameters(h264_hrd_param *hrd_param); 399 void parse_sei(); 400 void sei_buffering_period(); 401 void sei_picture_timing(); 402 void sei_pan_scan(); 403 void scaling_list(OMX_U32 size_of_scaling_list); 404 405 void print_pan_data(h264_pan_scan *pan_scan_param); 406 void print_frame_pack(); 407 408 OMX_U32 get_nal_unit_type(OMX_U32 *nal_unit_type); 409 OMX_S64 calculate_buf_period_ts(OMX_S64 timestamp); 410 OMX_S64 calculate_fixed_fps_ts(OMX_S64 timestamp, OMX_U32 DeltaTfiDivisor); 411 void parse_frame_pack(); 412 413 OMX_U32 curr_32_bit; 414 OMX_U32 bits_read; 415 OMX_U32 zero_cntr; 416 OMX_U32 emulation_code_skip_cntr; 417 OMX_U8* bitstream; 418 OMX_U32 bitstream_bytes; 419 OMX_U32 frame_rate; 420 bool emulation_sc_enabled; 421 422 h264_vui_param vui_param; 423 h264_sei_buf_period sei_buf_period; 424 h264_sei_pic_timing sei_pic_timing; 425 #ifdef PANSCAN_HDLR 426 panscan_handler *panscan_hdl; 427 #else 428 h264_pan_scan panscan_param; 429 #endif 430 OMX_QCOM_FRAME_PACK_ARRANGEMENT frame_packing_arrangement; 431 bool mbaff_flag; 432 }; 433 434 #endif /* H264_UTILS_H */ 435