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