1/*--------------------------------------------------------------------------
2Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
3
4Redistribution and use in source and binary forms, with or without
5modification, 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
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26ADVISED 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
37This 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.
104struct 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;
123typedef Map<uint32, H264ParamNalu *> H264ParamNaluSet;
124
125typedef 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
143typedef 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
156class extra_data_parser;
157
158class 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{
164public:
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
175private:
176    const     uint8 *begin, *end;
177    int32     pos;
178    uint32    bit;
179    uint32    cursor;
180    bool      advanceNeeded;
181};
182
183class H264_Utils
184{
185public:
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
195private:
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
213class 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
242enum 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
265typedef 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
279typedef 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
286typedef 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
303typedef 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
324typedef 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
333typedef 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
346template <class NODE_STRUCT>
347class omx_dl_list
348{
349public:
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();
358private:
359  NODE_STRUCT *head, *tail;
360};
361
362class panscan_handler
363{
364public:
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);
371private:
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) \
392do {\
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) \
402do {\
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
414class 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