Home | History | Annotate | Download | only in inc
      1 /*--------------------------------------------------------------------------
      2 Copyright (c) 2010-2012, Code Aurora Forum. 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 Code Aurora 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 OMX_CORE_720P_HEIGHT 720
     55 #define OMX_CORE_720P_WIDTH 1280
     56 
     57 #define PANSCAN_HDLR
     58 
     59 /* =======================================================================
     60 
     61                         DATA DECLARATIONS
     62 
     63 ========================================================================== */
     64 
     65 /* -----------------------------------------------------------------------
     66 ** Constant / Define Declarations
     67 ** ----------------------------------------------------------------------- */
     68 // Common format block header definitions
     69 #define MT_VIDEO_META_STREAM_HEADER             0x00
     70 #define MT_VIDEO_MEDIA_STREAM_HEADER            0x01
     71 #define MT_VIDEO_META_MEDIA_STREAM_HEADER       0x02
     72 
     73 // H.264 format block header definitions
     74 #define MT_VIDEO_H264_ACCESS_UNIT_FORMAT        0x00
     75 #define MT_VIDEO_H264_NAL_FORMT                 0x01
     76 #define MT_VIDEO_H264_BYTE_FORMAT               0x02
     77 #define MT_VIDEO_H264_BYTE_STREAM_FORMAT        0x00
     78 #define MT_VIDEO_H264_NAL_UNIT_STREAM_FORMAT    0x01
     79 #define MT_VIDEO_H264_FORMAT_BLOCK_HEADER_SIZE  18
     80 
     81 // MPEG-4 format block header definitions
     82 #define MT_VIDEO_MPEG4_VOP_FORMAT               0x00
     83 #define MT_VIDEO_MPEG4_SLICE_FORMAT             0x01
     84 #define MT_VIDEO_MPEG4_BYTE_FORMAT              0x02
     85 #define MT_VIDEO_MPEG4_FORMAT_BLOCK_HEADER_SIZE 15
     86 
     87 // H.263 format block header definitions
     88 #define MT_VIDEO_H263_PICTURE_FORMAT            0x00
     89 #define MT_VIDEO_H263_GOB_FORMAT                0x01
     90 #define MT_VIDEO_H263_SLICE_STRUCTURED_FORMAT   0x02
     91 #define MT_VIDEO_H263_BYTE_FORMAT               0x03
     92 #define MT_VIDEO_H263_FORMAT_BLOCK_HEADER_SIZE  16
     93 
     94 /* =======================================================================
     95 **                          Function Declarations
     96 ** ======================================================================= */
     97 
     98 /* -----------------------------------------------------------------------
     99 ** Type Declarations
    100 ** ----------------------------------------------------------------------- */
    101 
    102 // This type is used when parsing an H.264 bitstream to collect H.264 NAL
    103 // units that need to go in the meta data.
    104 struct H264ParamNalu {
    105     uint32 picSetID;
    106     uint32 seqSetID;
    107     uint32 picOrderCntType;
    108     bool frameMbsOnlyFlag;
    109     bool picOrderPresentFlag;
    110     uint32 picWidthInMbsMinus1;
    111     uint32 picHeightInMapUnitsMinus1;
    112     uint32 log2MaxFrameNumMinus4;
    113     uint32 log2MaxPicOrderCntLsbMinus4;
    114     bool deltaPicOrderAlwaysZeroFlag;
    115     //std::vector<uint8> nalu;
    116     uint32 nalu;
    117     uint32 crop_left;
    118     uint32 crop_right;
    119     uint32 crop_top;
    120     uint32 crop_bot;
    121 };
    122 //typedef map<uint32, H264ParamNalu> H264ParamNaluSet;
    123 typedef Map<uint32, H264ParamNalu *> H264ParamNaluSet;
    124 
    125 typedef enum {
    126   NALU_TYPE_UNSPECIFIED = 0,
    127   NALU_TYPE_NON_IDR,
    128   NALU_TYPE_PARTITION_A,
    129   NALU_TYPE_PARTITION_B,
    130   NALU_TYPE_PARTITION_C,
    131   NALU_TYPE_IDR,
    132   NALU_TYPE_SEI,
    133   NALU_TYPE_SPS,
    134   NALU_TYPE_PPS,
    135   NALU_TYPE_ACCESS_DELIM,
    136   NALU_TYPE_EOSEQ,
    137   NALU_TYPE_EOSTREAM,
    138   NALU_TYPE_FILLER_DATA,
    139   NALU_TYPE_RESERVED,
    140 } NALU_TYPE;
    141 
    142 // NAL header information
    143 typedef struct {
    144   uint32 nal_ref_idc;
    145   uint32 nalu_type;
    146   uint32 forbidden_zero_bit;
    147 } NALU;
    148 
    149 // This structure contains persistent information about an H.264 stream as it
    150 // is parsed.
    151 //struct H264StreamInfo {
    152 //    H264ParamNaluSet pic;
    153 //    H264ParamNaluSet seq;
    154 //};
    155 
    156 class extra_data_parser;
    157 
    158 class RbspParser
    159 /******************************************************************************
    160  ** This class is used to convert an H.264 NALU (network abstraction layer
    161  ** unit) into RBSP (raw byte sequence payload) and extract bits from it.
    162  *****************************************************************************/
    163 {
    164 public:
    165     RbspParser (const uint8 *begin, const uint8 *end);
    166 
    167     virtual ~RbspParser ();
    168 
    169     uint32 next ();
    170     void advance ();
    171     uint32 u (uint32 n);
    172     uint32 ue ();
    173     int32 se ();
    174 
    175 private:
    176     const     uint8 *begin, *end;
    177     int32     pos;
    178     uint32    bit;
    179     uint32    cursor;
    180     bool      advanceNeeded;
    181 };
    182 
    183 class H264_Utils
    184 {
    185 public:
    186     H264_Utils();
    187     ~H264_Utils();
    188     void initialize_frame_checking_environment();
    189     void allocate_rbsp_buffer(uint32 inputBufferSize);
    190     bool isNewFrame(OMX_BUFFERHEADERTYPE *p_buf_hdr,
    191                     OMX_IN OMX_U32 size_of_nal_length_field,
    192                     OMX_OUT OMX_BOOL &isNewFrame);
    193     uint32 nalu_type;
    194 
    195 private:
    196     boolean extract_rbsp(OMX_IN   OMX_U8  *buffer,
    197                          OMX_IN   OMX_U32 buffer_length,
    198                          OMX_IN   OMX_U32 size_of_nal_length_field,
    199                          OMX_OUT  OMX_U8  *rbsp_bistream,
    200                          OMX_OUT  OMX_U32 *rbsp_length,
    201                          OMX_OUT  NALU    *nal_unit);
    202 
    203     unsigned          m_height;
    204     unsigned          m_width;
    205     H264ParamNaluSet  pic;
    206     H264ParamNaluSet  seq;
    207     uint8             *m_rbspBytes;
    208     NALU              m_prv_nalu;
    209     bool              m_forceToStichNextNAL;
    210     bool              m_au_data;
    211 };
    212 
    213 class perf_metrics
    214 {
    215   public:
    216     perf_metrics() :
    217       start_time(0),
    218       proc_time(0),
    219       active(false)
    220     {
    221     };
    222     ~perf_metrics() {};
    223     void start();
    224     void stop();
    225     void end(OMX_U32 units_cntr = 0);
    226     void reset();
    227     OMX_U64 processing_time_us();
    228   private:
    229     inline OMX_U64 get_act_time();
    230     OMX_U64 start_time;
    231     OMX_U64 proc_time;
    232     bool active;
    233 };
    234 
    235 #define EMULATION_PREVENTION_THREE_BYTE 0x03
    236 #define MAX_CPB_COUNT     32
    237 #define NO_PAN_SCAN_BIT   0x00000100
    238 #define MAX_PAN_SCAN_RECT 3
    239 #define VALID_TS(ts)      ((ts < LLONG_MAX)? true : false)
    240 #define NALU_TYPE_VUI (NALU_TYPE_RESERVED + 1)
    241 
    242 enum SEI_PAYLOAD_TYPE
    243 {
    244   BUFFERING_PERIOD = 0,
    245   PIC_TIMING,
    246   PAN_SCAN_RECT,
    247   FILLER_PAYLOAD,
    248   USER_DATA_REGISTERED_ITU_T_T35,
    249   USER_DATA_UNREGISTERED,
    250   RECOVERY_POINT,
    251   DEC_REF_PIC_MARKING_REPETITION,
    252   SPARE_PIC,
    253   SCENE_INFO,
    254   SUB_SEQ_INFO,
    255   SUB_SEQ_LAYER_CHARACTERISTICS,
    256   SUB_SEQ_CHARACTERISTICS,
    257   FULL_FRAME_FREEZE,
    258   FULL_FRAME_FREEZE_RELEASE,
    259   FULL_FRAME_SNAPSHOT,
    260   PROGRESSIVE_REFINEMENT_SEGMENT_START,
    261   PROGRESSIVE_REFINEMENT_SEGMENT_END,
    262   SEI_PAYLOAD_FRAME_PACKING_ARRANGEMENT = 0x2D
    263 };
    264 
    265 typedef struct
    266 {
    267   OMX_U32  cpb_cnt;
    268   OMX_U8   bit_rate_scale;
    269   OMX_U8   cpb_size_scale;
    270   OMX_U32  bit_rate_value[MAX_CPB_COUNT];
    271   OMX_U32  cpb_size_value[MAX_CPB_COUNT];
    272   OMX_U8   cbr_flag[MAX_CPB_COUNT];
    273   OMX_U8   initial_cpb_removal_delay_length;
    274   OMX_U8   cpb_removal_delay_length;
    275   OMX_U8   dpb_output_delay_length;
    276   OMX_U8   time_offset_length;
    277 } h264_hrd_param;
    278 
    279 typedef struct
    280 {
    281   OMX_U32  aspect_ratio_idc;
    282   OMX_U32  aspect_ratio_x;
    283   OMX_U32  aspect_ratio_y;
    284 } h264_aspect_ratio_info;
    285 
    286 typedef struct
    287 {
    288   OMX_U8   aspect_ratio_info_present_flag;
    289   h264_aspect_ratio_info aspect_ratio_info;
    290   OMX_U8   timing_info_present_flag;
    291   OMX_U32  num_units_in_tick;
    292   OMX_U32  time_scale;
    293   OMX_U8   fixed_frame_rate_flag;
    294   OMX_U8   nal_hrd_parameters_present_flag;
    295   h264_hrd_param   nal_hrd_parameters;
    296   OMX_U8   vcl_hrd_parameters_present_flag;
    297   h264_hrd_param   vcl_hrd_parameters;
    298   OMX_U8   low_delay_hrd_flag;
    299   OMX_U8   pic_struct_present_flag;
    300   OMX_S64  fixed_fps_prev_ts;
    301 } h264_vui_param;
    302 
    303 typedef struct
    304 {
    305   OMX_U32 cpb_removal_delay;
    306   OMX_U32 dpb_output_delay;
    307   OMX_U8  pic_struct;
    308   OMX_U32 num_clock_ts;
    309   bool    clock_ts_flag;
    310   OMX_U8  ct_type;
    311   OMX_U32 nuit_field_based_flag;
    312   OMX_U8  counting_type;
    313   OMX_U8  full_timestamp_flag;
    314   OMX_U8  discontinuity_flag;
    315   OMX_U8  cnt_dropped_flag;
    316   OMX_U32 n_frames;
    317   OMX_U32 seconds_value;
    318   OMX_U32 minutes_value;
    319   OMX_U32 hours_value;
    320   OMX_S32 time_offset;
    321   bool    is_valid;
    322 } h264_sei_pic_timing;
    323 
    324 typedef struct
    325 {
    326   OMX_U32  initial_cpb_removal_delay[MAX_CPB_COUNT];
    327   OMX_U32  initial_cpb_removal_delay_offset[MAX_CPB_COUNT];
    328   OMX_U32  au_cntr;
    329   OMX_S64  reference_ts;
    330   bool     is_valid;
    331 } h264_sei_buf_period;
    332 
    333 typedef struct
    334 {
    335   OMX_U32  rect_id;
    336   OMX_U8   rect_cancel_flag;
    337   OMX_U32  cnt;
    338   OMX_S32  rect_left_offset[MAX_PAN_SCAN_RECT];
    339   OMX_S32  rect_right_offset[MAX_PAN_SCAN_RECT];
    340   OMX_S32  rect_top_offset[MAX_PAN_SCAN_RECT];
    341   OMX_S32  rect_bottom_offset[MAX_PAN_SCAN_RECT];
    342   OMX_U32  rect_repetition_period;
    343 } h264_pan_scan;
    344 
    345 #ifdef PANSCAN_HDLR
    346 template <class NODE_STRUCT>
    347 class omx_dl_list
    348 {
    349 public:
    350   omx_dl_list() { head = tail = NULL; } ;
    351   ~omx_dl_list() {};
    352   void add_multiple(NODE_STRUCT *data_arr, int data_num);
    353   NODE_STRUCT *remove_first();
    354   NODE_STRUCT *remove_last();
    355   void add_last(NODE_STRUCT *data_ptr);
    356   NODE_STRUCT *watch_first();
    357   NODE_STRUCT *watch_last();
    358 private:
    359   NODE_STRUCT *head, *tail;
    360 };
    361 
    362 class panscan_handler
    363 {
    364 public:
    365   panscan_handler();
    366   ~panscan_handler();
    367   bool initialize(int num_data);
    368   h264_pan_scan *get_free();
    369   h264_pan_scan *get_populated(OMX_S64 frame_ts);
    370   void update_last(OMX_S64 frame_ts);
    371 private:
    372   typedef struct PANSCAN_NODE
    373   {
    374     h264_pan_scan pan_scan_param;
    375     OMX_S64  start_ts, end_ts;
    376     bool active;
    377     PANSCAN_NODE *next, *prev;
    378   } PANSCAN_NODE;
    379   omx_dl_list<PANSCAN_NODE> panscan_used;
    380   omx_dl_list<PANSCAN_NODE> panscan_free;
    381   PANSCAN_NODE *panscan_data;
    382 };
    383 
    384 #if 1 // Debug panscan data
    385 
    386 #define PRINT_PANSCAN_PARAM(H264_PARAM)
    387 #define PRINT_PANSCAN_DATA(NODE)
    388 
    389 #else
    390 
    391 #define PRINT_PANSCAN_PARAM(H264_PARAM) \
    392 do {\
    393   ALOGE("%s(): left_off(%ld) right_off(%ld) top_off(%ld) bottom_off(%ld)",\
    394     __FUNCTION__,\
    395     (H264_PARAM).rect_left_offset[0],\
    396     (H264_PARAM).rect_right_offset[0],\
    397     (H264_PARAM).rect_top_offset[0],\
    398     (H264_PARAM).rect_bottom_offset[0]);\
    399 }while(0)
    400 
    401 #define PRINT_PANSCAN_DATA(NODE) \
    402 do {\
    403   if (NODE) {\
    404     ALOGE("%s(): PANSCAN DATA start_ts(%lld) end_ts(%lld)", __FUNCTION__,\
    405 	  (NODE)->start_ts, (NODE)->end_ts);\
    406 	PRINT_PANSCAN_PARAM(NODE->pan_scan_param);\
    407   }\
    408 }while(0)
    409 
    410 #endif // End debug panscan data
    411 
    412 #endif
    413 
    414 class h264_stream_parser
    415 {
    416   public:
    417     h264_stream_parser();
    418     ~h264_stream_parser();
    419     void reset();
    420     void fill_pan_scan_data(OMX_QCOM_PANSCAN *dest_pan_scan, OMX_S64 timestamp);
    421     void fill_aspect_ratio_info(OMX_QCOM_ASPECT_RATIO *dest_aspect_ratio);
    422     void parse_nal(OMX_U8* data_ptr, OMX_U32 data_len,
    423                    OMX_U32 nal_type = NALU_TYPE_UNSPECIFIED,
    424                    bool enable_emu_sc = true);
    425     OMX_S64 process_ts_with_sei_vui(OMX_S64 timestamp);
    426     void get_frame_pack_data(OMX_QCOM_FRAME_PACK_ARRANGEMENT *frame_pack);
    427     bool is_mbaff();
    428     void get_frame_rate(OMX_U32 *frame_rate);
    429 #ifdef PANSCAN_HDLR
    430     void update_panscan_data(OMX_S64 timestamp);
    431 #endif
    432   private:
    433     void init_bitstream(OMX_U8* data, OMX_U32 size);
    434     OMX_U32 extract_bits(OMX_U32 n);
    435     inline bool more_bits();
    436     void read_word();
    437     OMX_U32 uev();
    438     OMX_S32 sev();
    439     OMX_S32 iv(OMX_U32 n_bits);
    440     void parse_sps();
    441     void parse_vui(bool vui_in_extradata = true);
    442     void aspect_ratio_info();
    443     void hrd_parameters(h264_hrd_param *hrd_param);
    444     void parse_sei();
    445     void sei_buffering_period();
    446     void sei_picture_timing();
    447     void sei_pan_scan();
    448     void scaling_list(OMX_U32 size_of_scaling_list);
    449 
    450     void print_pan_data(h264_pan_scan *pan_scan_param);
    451     void print_frame_pack();
    452 
    453     OMX_U32 get_nal_unit_type(OMX_U32 *nal_unit_type);
    454     OMX_S64 calculate_buf_period_ts(OMX_S64 timestamp);
    455     OMX_S64 calculate_fixed_fps_ts(OMX_S64 timestamp, OMX_U32 DeltaTfiDivisor);
    456     void parse_frame_pack();
    457 
    458     OMX_U32 curr_32_bit;
    459     OMX_U32 bits_read;
    460     OMX_U32 zero_cntr;
    461     OMX_U32 emulation_code_skip_cntr;
    462     OMX_U8* bitstream;
    463     OMX_U32 bitstream_bytes;
    464     OMX_U32 frame_rate;
    465     bool    emulation_sc_enabled;
    466 
    467     h264_vui_param vui_param;
    468     h264_sei_buf_period sei_buf_period;
    469     h264_sei_pic_timing sei_pic_timing;
    470 #ifdef PANSCAN_HDLR
    471     panscan_handler *panscan_hdl;
    472 #else
    473     h264_pan_scan panscan_param;
    474 #endif
    475     OMX_QCOM_FRAME_PACK_ARRANGEMENT frame_packing_arrangement;
    476 	bool 	mbaff_flag;
    477 };
    478 
    479 #endif /* H264_UTILS_H */
    480