1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
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 */
|