diff options
Diffstat (limited to 'msmcobalt/mm-video-v4l2/vidc/vdec/inc/h264_utils.h')
-rw-r--r-- | msmcobalt/mm-video-v4l2/vidc/vdec/inc/h264_utils.h | 480 |
1 files changed, 480 insertions, 0 deletions
diff --git a/msmcobalt/mm-video-v4l2/vidc/vdec/inc/h264_utils.h b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/h264_utils.h new file mode 100644 index 0000000..ad05a9e --- /dev/null +++ b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/h264_utils.h @@ -0,0 +1,480 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#ifndef H264_UTILS_H +#define H264_UTILS_H + +/*======================================================================== + + O p e n M M + 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 + +*//** @file H264_Utils.h +This module contains H264 video decoder utilities and helper routines. + +*//*====================================================================== */ + +/* ======================================================================= + + INCLUDE FILES FOR MODULE + +========================================================================== */ +#include <stdio.h> +#include "Map.h" +#include "qtypes.h" +#include "OMX_Core.h" +#include "OMX_QCOMExtns.h" + +#define STD_MIN(x,y) (((x) < (y)) ? (x) : (y)) + +#define OMX_CORE_720P_HEIGHT 720 +#define OMX_CORE_720P_WIDTH 1280 + +#define SIZE_NAL_FIELD_MAX 4 +#define BASELINE_PROFILE 66 +#define MAIN_PROFILE 77 +#define HIGH_PROFILE 100 + +#define PANSCAN_HDLR + +/* ======================================================================= + + DATA DECLARATIONS + + ========================================================================== */ + +/* ----------------------------------------------------------------------- + ** Constant / Define Declarations + ** ----------------------------------------------------------------------- */ +// Common format block header definitions +#define MT_VIDEO_META_STREAM_HEADER 0x00 +#define MT_VIDEO_MEDIA_STREAM_HEADER 0x01 +#define MT_VIDEO_META_MEDIA_STREAM_HEADER 0x02 + +// H.264 format block header definitions +#define MT_VIDEO_H264_ACCESS_UNIT_FORMAT 0x00 +#define MT_VIDEO_H264_NAL_FORMT 0x01 +#define MT_VIDEO_H264_BYTE_FORMAT 0x02 +#define MT_VIDEO_H264_BYTE_STREAM_FORMAT 0x00 +#define MT_VIDEO_H264_NAL_UNIT_STREAM_FORMAT 0x01 +#define MT_VIDEO_H264_FORMAT_BLOCK_HEADER_SIZE 18 + +// MPEG-4 format block header definitions +#define MT_VIDEO_MPEG4_VOP_FORMAT 0x00 +#define MT_VIDEO_MPEG4_SLICE_FORMAT 0x01 +#define MT_VIDEO_MPEG4_BYTE_FORMAT 0x02 +#define MT_VIDEO_MPEG4_FORMAT_BLOCK_HEADER_SIZE 15 + +// H.263 format block header definitions +#define MT_VIDEO_H263_PICTURE_FORMAT 0x00 +#define MT_VIDEO_H263_GOB_FORMAT 0x01 +#define MT_VIDEO_H263_SLICE_STRUCTURED_FORMAT 0x02 +#define MT_VIDEO_H263_BYTE_FORMAT 0x03 +#define MT_VIDEO_H263_FORMAT_BLOCK_HEADER_SIZE 16 + +/* ======================================================================= + ** Function Declarations + ** ======================================================================= */ + +/* ----------------------------------------------------------------------- + ** Type Declarations + ** ----------------------------------------------------------------------- */ + +// This type is used when parsing an H.264 bitstream to collect H.264 NAL +// units that need to go in the meta data. +struct H264ParamNalu { + uint32 picSetID; + uint32 seqSetID; + uint32 picOrderCntType; + bool frameMbsOnlyFlag; + bool picOrderPresentFlag; + uint32 picWidthInMbsMinus1; + uint32 picHeightInMapUnitsMinus1; + uint32 log2MaxFrameNumMinus4; + uint32 log2MaxPicOrderCntLsbMinus4; + bool deltaPicOrderAlwaysZeroFlag; + //std::vector<uint8> nalu; + uint32 nalu; + uint32 crop_left; + uint32 crop_right; + uint32 crop_top; + uint32 crop_bot; +}; +//typedef map<uint32, H264ParamNalu> H264ParamNaluSet; +typedef Map<uint32, H264ParamNalu *> H264ParamNaluSet; + +typedef enum { + NALU_TYPE_UNSPECIFIED = 0, + NALU_TYPE_NON_IDR, + NALU_TYPE_PARTITION_A, + NALU_TYPE_PARTITION_B, + NALU_TYPE_PARTITION_C, + NALU_TYPE_IDR, + NALU_TYPE_SEI, + NALU_TYPE_SPS, + NALU_TYPE_PPS, + NALU_TYPE_ACCESS_DELIM, + NALU_TYPE_EOSEQ, + NALU_TYPE_EOSTREAM, + NALU_TYPE_FILLER_DATA, + NALU_TYPE_RESERVED, +} NALU_TYPE; + +// NAL header information +typedef struct { + uint32 nal_ref_idc; + uint32 nalu_type; + uint32 forbidden_zero_bit; +} NALU; + +// This structure contains persistent information about an H.264 stream as it +// is parsed. +//struct H264StreamInfo { +// H264ParamNaluSet pic; +// H264ParamNaluSet seq; +//}; + +class extra_data_parser; + +class RbspParser +/****************************************************************************** + ** This class is used to convert an H.264 NALU (network abstraction layer + ** unit) into RBSP (raw byte sequence payload) and extract bits from it. + *****************************************************************************/ +{ + public: + RbspParser (const uint8 *begin, const uint8 *end); + + virtual ~RbspParser (); + + uint32 next (); + void advance (); + uint32 u (uint32 n); + uint32 ue (); + int32 se (); + + private: + const uint8 *begin, *end; + int32 pos; + uint32 bit; + uint32 cursor; + bool advanceNeeded; +}; + +class H264_Utils +{ + public: + H264_Utils(); + ~H264_Utils(); + void initialize_frame_checking_environment(); + void allocate_rbsp_buffer(uint32 inputBufferSize); + bool isNewFrame(OMX_BUFFERHEADERTYPE *p_buf_hdr, + OMX_IN OMX_U32 size_of_nal_length_field, + OMX_OUT OMX_BOOL &isNewFrame); + uint32 nalu_type; + + private: + boolean extract_rbsp(OMX_IN OMX_U8 *buffer, + OMX_IN OMX_U32 buffer_length, + OMX_IN OMX_U32 size_of_nal_length_field, + OMX_OUT OMX_U8 *rbsp_bistream, + OMX_OUT OMX_U32 *rbsp_length, + OMX_OUT NALU *nal_unit); + + unsigned m_height; + unsigned m_width; + H264ParamNaluSet pic; + H264ParamNaluSet seq; + uint8 *m_rbspBytes; + NALU m_prv_nalu; + bool m_forceToStichNextNAL; + bool m_au_data; +}; + +class perf_metrics +{ + public: + perf_metrics() : + start_time(0), + proc_time(0), + active(false) { + }; + ~perf_metrics() {}; + void start(); + void stop(); + void end(OMX_U32 units_cntr = 0); + void reset(); + OMX_U64 processing_time_us(); + private: + inline OMX_U64 get_act_time(); + OMX_U64 start_time; + OMX_U64 proc_time; + bool active; +}; + +#define EMULATION_PREVENTION_THREE_BYTE 0x03 +#define MAX_CPB_COUNT 32 +#define NO_PAN_SCAN_BIT 0x00000100 +#define MAX_PAN_SCAN_RECT 3 +#define VALID_TS(ts) ((ts < LLONG_MAX)? true : false) +#define NALU_TYPE_VUI (NALU_TYPE_RESERVED + 1) + +enum SEI_PAYLOAD_TYPE { + BUFFERING_PERIOD = 0, + PIC_TIMING, + PAN_SCAN_RECT, + FILLER_PAYLOAD, + USER_DATA_REGISTERED_ITU_T_T35, + USER_DATA_UNREGISTERED, + RECOVERY_POINT, + DEC_REF_PIC_MARKING_REPETITION, + SPARE_PIC, + SCENE_INFO, + SUB_SEQ_INFO, + SUB_SEQ_LAYER_CHARACTERISTICS, + SUB_SEQ_CHARACTERISTICS, + FULL_FRAME_FREEZE, + FULL_FRAME_FREEZE_RELEASE, + FULL_FRAME_SNAPSHOT, + PROGRESSIVE_REFINEMENT_SEGMENT_START, + PROGRESSIVE_REFINEMENT_SEGMENT_END, + SEI_PAYLOAD_FRAME_PACKING_ARRANGEMENT = 0x2D +}; + +typedef struct { + OMX_U32 cpb_cnt; + OMX_U8 bit_rate_scale; + OMX_U8 cpb_size_scale; + OMX_U32 bit_rate_value[MAX_CPB_COUNT]; + OMX_U32 cpb_size_value[MAX_CPB_COUNT]; + OMX_U8 cbr_flag[MAX_CPB_COUNT]; + OMX_U8 initial_cpb_removal_delay_length; + OMX_U8 cpb_removal_delay_length; + OMX_U8 dpb_output_delay_length; + OMX_U8 time_offset_length; +} h264_hrd_param; + +typedef struct { + OMX_U32 aspect_ratio_idc; + OMX_U32 aspect_ratio_x; + OMX_U32 aspect_ratio_y; +} h264_aspect_ratio_info; + +typedef struct { + OMX_U8 aspect_ratio_info_present_flag; + h264_aspect_ratio_info aspect_ratio_info; + OMX_U8 timing_info_present_flag; + OMX_U32 num_units_in_tick; + OMX_U32 time_scale; + OMX_U8 fixed_frame_rate_flag; + OMX_U8 nal_hrd_parameters_present_flag; + h264_hrd_param nal_hrd_parameters; + OMX_U8 vcl_hrd_parameters_present_flag; + h264_hrd_param vcl_hrd_parameters; + OMX_U8 low_delay_hrd_flag; + OMX_U8 pic_struct_present_flag; + OMX_S64 fixed_fps_prev_ts; +} h264_vui_param; + +typedef struct { + OMX_U32 cpb_removal_delay; + OMX_U32 dpb_output_delay; + OMX_U8 pic_struct; + OMX_U32 num_clock_ts; + bool clock_ts_flag; + OMX_U8 ct_type; + OMX_U32 nuit_field_based_flag; + OMX_U8 counting_type; + OMX_U8 full_timestamp_flag; + OMX_U8 discontinuity_flag; + OMX_U8 cnt_dropped_flag; + OMX_U32 n_frames; + OMX_U32 seconds_value; + OMX_U32 minutes_value; + OMX_U32 hours_value; + OMX_S32 time_offset; + bool is_valid; +} h264_sei_pic_timing; + +typedef struct { + OMX_U32 initial_cpb_removal_delay[MAX_CPB_COUNT]; + OMX_U32 initial_cpb_removal_delay_offset[MAX_CPB_COUNT]; + OMX_U32 au_cntr; + OMX_S64 reference_ts; + bool is_valid; +} h264_sei_buf_period; + +typedef struct { + OMX_U32 rect_id; + OMX_U8 rect_cancel_flag; + OMX_U32 cnt; + OMX_S32 rect_left_offset[MAX_PAN_SCAN_RECT]; + OMX_S32 rect_right_offset[MAX_PAN_SCAN_RECT]; + OMX_S32 rect_top_offset[MAX_PAN_SCAN_RECT]; + OMX_S32 rect_bottom_offset[MAX_PAN_SCAN_RECT]; + OMX_U32 rect_repetition_period; +} h264_pan_scan; + +#ifdef PANSCAN_HDLR +template <class NODE_STRUCT> +class omx_dl_list +{ + public: + omx_dl_list() { + head = tail = NULL; + } ; + ~omx_dl_list() {}; + void add_multiple(NODE_STRUCT *data_arr, int data_num); + NODE_STRUCT *remove_first(); + NODE_STRUCT *remove_last(); + void add_last(NODE_STRUCT *data_ptr); + NODE_STRUCT *watch_first(); + NODE_STRUCT *watch_last(); + private: + NODE_STRUCT *head, *tail; +}; + +class panscan_handler +{ + public: + panscan_handler(); + ~panscan_handler(); + bool initialize(int num_data); + h264_pan_scan *get_free(); + h264_pan_scan *get_populated(OMX_S64 frame_ts); + void update_last(OMX_S64 frame_ts); + private: + typedef struct PANSCAN_NODE { + h264_pan_scan pan_scan_param; + OMX_S64 start_ts, end_ts; + bool active; + PANSCAN_NODE *next, *prev; + } PANSCAN_NODE; + omx_dl_list<PANSCAN_NODE> panscan_used; + omx_dl_list<PANSCAN_NODE> panscan_free; + PANSCAN_NODE *panscan_data; +}; + +#if 1 // Debug panscan data + +#define PRINT_PANSCAN_PARAM(H264_PARAM) +#define PRINT_PANSCAN_DATA(NODE) + +#else + +#define PRINT_PANSCAN_PARAM(H264_PARAM) \ + do {\ + ALOGE("%s(): left_off(%ld) right_off(%ld) top_off(%ld) bottom_off(%ld)",\ + __FUNCTION__,\ + (H264_PARAM).rect_left_offset[0],\ + (H264_PARAM).rect_right_offset[0],\ + (H264_PARAM).rect_top_offset[0],\ + (H264_PARAM).rect_bottom_offset[0]);\ + }while(0) + +#define PRINT_PANSCAN_DATA(NODE) \ + do {\ + if (NODE) {\ + ALOGE("%s(): PANSCAN DATA start_ts(%lld) end_ts(%lld)", __FUNCTION__,\ + (NODE)->start_ts, (NODE)->end_ts);\ + PRINT_PANSCAN_PARAM(NODE->pan_scan_param);\ + }\ + }while(0) + +#endif // End debug panscan data + +#endif + +class h264_stream_parser +{ + public: + h264_stream_parser(); + ~h264_stream_parser(); + void reset(); + void fill_pan_scan_data(OMX_QCOM_PANSCAN *dest_pan_scan, OMX_S64 timestamp); + void fill_aspect_ratio_info(OMX_QCOM_ASPECT_RATIO *dest_aspect_ratio); + void parse_nal(OMX_U8* data_ptr, OMX_U32 data_len, + OMX_U32 nal_type = NALU_TYPE_UNSPECIFIED, + bool enable_emu_sc = true); + OMX_S64 process_ts_with_sei_vui(OMX_S64 timestamp); + void get_frame_pack_data(OMX_QCOM_FRAME_PACK_ARRANGEMENT *frame_pack); + bool is_mbaff(); + void get_frame_rate(OMX_U32 *frame_rate); + OMX_U32 get_profile(); +#ifdef PANSCAN_HDLR + void update_panscan_data(OMX_S64 timestamp); +#endif + + private: + void init_bitstream(OMX_U8* data, OMX_U32 size); + OMX_U32 extract_bits(OMX_U32 n); + inline bool more_bits(); + void read_word(); + OMX_U32 uev(); + OMX_S32 sev(); + OMX_S32 iv(OMX_U32 n_bits); + void parse_sps(); + void parse_vui(bool vui_in_extradata = true); + void aspect_ratio_info(); + void hrd_parameters(h264_hrd_param *hrd_param); + void parse_sei(); + void sei_buffering_period(); + void sei_picture_timing(); + void sei_pan_scan(); + void scaling_list(OMX_U32 size_of_scaling_list); + + void print_pan_data(h264_pan_scan *pan_scan_param); + void print_frame_pack(); + + OMX_U32 get_nal_unit_type(OMX_U32 *nal_unit_type); + OMX_S64 calculate_buf_period_ts(OMX_S64 timestamp); + OMX_S64 calculate_fixed_fps_ts(OMX_S64 timestamp, OMX_U32 DeltaTfiDivisor); + void parse_frame_pack(); + + OMX_U32 curr_32_bit; + OMX_U32 bits_read; + OMX_U32 profile; + OMX_U32 zero_cntr; + OMX_U32 emulation_code_skip_cntr; + OMX_U8* bitstream; + OMX_U32 bitstream_bytes; + OMX_U32 frame_rate; + bool emulation_sc_enabled; + + h264_vui_param vui_param; + h264_sei_buf_period sei_buf_period; + h264_sei_pic_timing sei_pic_timing; +#ifdef PANSCAN_HDLR + panscan_handler *panscan_hdl; +#else + h264_pan_scan panscan_param; +#endif + OMX_QCOM_FRAME_PACK_ARRANGEMENT frame_packing_arrangement; + bool mbaff_flag; +}; + +#endif /* H264_UTILS_H */ |