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