1 /*--------------------------------------------------------------------------
2 Copyright (c) 2010 - 2015, 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 /*========================================================================
29
30 O p e n M M
31 V i d e o U t i l i t i e s
32
33 *//** @file VideoUtils.cpp
34 This module contains utilities and helper routines.
35
36 @par EXTERNALIZED FUNCTIONS
37
38 @par INITIALIZATION AND SEQUENCING REQUIREMENTS
39 (none)
40
41 *//*====================================================================== */
42
43 /* =======================================================================
44
45 INCLUDE FILES FOR MODULE
46
47 ========================================================================== */
48 #include "h264_utils.h"
49 #include "extra_data_handler.h"
50 #include <string.h>
51 #include <stdlib.h>
52 #include <limits.h>
53 #include <sys/time.h>
54 #ifdef _ANDROID_
55 #include <cutils/properties.h>
56 extern "C" {
57 #include<utils/Log.h>
58 }
59
60 #endif
61
62 /* =======================================================================
63
64 DEFINITIONS AND DECLARATIONS FOR MODULE
65
66 This section contains definitions for constants, macros, types, variables
67 and other items needed by this module.
68
69 ========================================================================== */
70
71
72 #define MAX_SUPPORTED_LEVEL 32
73
RbspParser(const uint8 * _begin,const uint8 * _end)74 RbspParser::RbspParser (const uint8 *_begin, const uint8 *_end)
75 : begin (_begin), end(_end), pos (- 1), bit (0),
76 cursor (0xFFFFFF), advanceNeeded (true)
77 {
78 }
79
80 // Destructor
81 /*lint -e{1540} Pointer member neither freed nor zeroed by destructor
82 * No problem
83 */
~RbspParser()84 RbspParser::~RbspParser () {}
85
86 // Return next RBSP byte as a word
next()87 uint32 RbspParser::next ()
88 {
89 if (advanceNeeded) advance ();
90 //return static_cast<uint32> (*pos);
91 return static_cast<uint32> (begin[pos]);
92 }
93
94 // Advance RBSP decoder to next byte
advance()95 void RbspParser::advance ()
96 {
97 ++pos;
98 //if (pos >= stop)
99 if (begin + pos == end) {
100 /*lint -e{730} Boolean argument to function
101 * I don't see a problem here
102 */
103 //throw false;
104 ALOGV("H264Parser-->NEED TO THROW THE EXCEPTION...");
105 }
106 cursor <<= 8;
107 //cursor |= static_cast<uint32> (*pos);
108 cursor |= static_cast<uint32> (begin[pos]);
109 if ((cursor & 0xFFFFFF) == 0x000003) {
110 advance ();
111 }
112 advanceNeeded = false;
113 }
114
115 // Decode unsigned integer
u(uint32 n)116 uint32 RbspParser::u (uint32 n)
117 {
118 uint32 i, s, x = 0;
119 for (i = 0; i < n; i += s) {
120 s = static_cast<uint32>STD_MIN(static_cast<int>(8 - bit),
121 static_cast<int>(n - i));
122 x <<= s;
123
124 x |= ((next () >> ((8 - static_cast<uint32>(bit)) - s)) &
125 ((1 << s) - 1));
126
127 bit = (bit + s) % 8;
128 if (!bit) {
129 advanceNeeded = true;
130 }
131 }
132 return x;
133 }
134
135 // Decode unsigned integer Exp-Golomb-coded syntax element
ue()136 uint32 RbspParser::ue ()
137 {
138 int leadingZeroBits = -1;
139 for (uint32 b = 0; !b; ++leadingZeroBits) {
140 b = u (1);
141 }
142 return ((1 << leadingZeroBits) - 1) +
143 u (static_cast<uint32>(leadingZeroBits));
144 }
145
146 // Decode signed integer Exp-Golomb-coded syntax element
se()147 int32 RbspParser::se ()
148 {
149 const uint32 x = ue ();
150 if (!x) return 0;
151 else if (x & 1) return static_cast<int32> ((x >> 1) + 1);
152 else return - static_cast<int32> (x >> 1);
153 }
154
allocate_rbsp_buffer(uint32 inputBufferSize)155 void H264_Utils::allocate_rbsp_buffer(uint32 inputBufferSize)
156 {
157 m_rbspBytes = (byte *) calloc(1,inputBufferSize);
158 m_prv_nalu.nal_ref_idc = 0;
159 m_prv_nalu.nalu_type = NALU_TYPE_UNSPECIFIED;
160 }
161
H264_Utils()162 H264_Utils::H264_Utils(): m_height(0),
163 m_width(0),
164 m_rbspBytes(NULL),
165 m_au_data (false)
166 {
167 initialize_frame_checking_environment();
168 }
169
~H264_Utils()170 H264_Utils::~H264_Utils()
171 {
172 /* if(m_pbits)
173 {
174 delete(m_pbits);
175 m_pbits = NULL;
176 }
177 */
178 if (m_rbspBytes) {
179 free(m_rbspBytes);
180 m_rbspBytes = NULL;
181 }
182 }
183
184 /***********************************************************************/
185 /*
186 FUNCTION:
187 H264_Utils::initialize_frame_checking_environment
188
189 DESCRIPTION:
190 Extract RBSP data from a NAL
191
192 INPUT/OUTPUT PARAMETERS:
193 None
194
195 RETURN VALUE:
196 boolean
197
198 SIDE EFFECTS:
199 None.
200 */
201 /***********************************************************************/
initialize_frame_checking_environment()202 void H264_Utils::initialize_frame_checking_environment()
203 {
204 m_forceToStichNextNAL = false;
205 m_au_data = false;
206 m_prv_nalu.nal_ref_idc = 0;
207 m_prv_nalu.nalu_type = NALU_TYPE_UNSPECIFIED;
208 }
209
210 /***********************************************************************/
211 /*
212 FUNCTION:
213 H264_Utils::extract_rbsp
214
215 DESCRIPTION:
216 Extract RBSP data from a NAL
217
218 INPUT/OUTPUT PARAMETERS:
219 <In>
220 buffer : buffer containing start code or nal length + NAL units
221 buffer_length : the length of the NAL buffer
222 start_code : If true, start code is detected,
223 otherwise size nal length is detected
224 size_of_nal_length_field: size of nal length field
225
226 <Out>
227 rbsp_bistream : extracted RBSP bistream
228 rbsp_length : the length of the RBSP bitstream
229 nal_unit : decoded NAL header information
230
231 RETURN VALUE:
232 boolean
233
234 SIDE EFFECTS:
235 None.
236 */
237 /***********************************************************************/
238
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)239 boolean H264_Utils::extract_rbsp(OMX_IN OMX_U8 *buffer,
240 OMX_IN OMX_U32 buffer_length,
241 OMX_IN OMX_U32 size_of_nal_length_field,
242 OMX_OUT OMX_U8 *rbsp_bistream,
243 OMX_OUT OMX_U32 *rbsp_length,
244 OMX_OUT NALU *nal_unit)
245 {
246 byte coef1, coef2, coef3;
247 uint32 pos = 0;
248 uint32 nal_len = buffer_length;
249 uint32 sizeofNalLengthField = 0;
250 uint32 zero_count;
251 boolean eRet = true;
252 boolean start_code = (size_of_nal_length_field==0)?true:false;
253
254 if (start_code) {
255 // Search start_code_prefix_one_3bytes (0x000001)
256 coef2 = buffer[pos++];
257 coef3 = buffer[pos++];
258 do {
259 if (pos >= buffer_length) {
260 ALOGE("ERROR: In %s() - line %d", __func__, __LINE__);
261 return false;
262 }
263
264 coef1 = coef2;
265 coef2 = coef3;
266 coef3 = buffer[pos++];
267 } while (coef1 || coef2 || coef3 != 1);
268 } else if (size_of_nal_length_field) {
269 /* This is the case to play multiple NAL units inside each access unit*/
270 /* Extract the NAL length depending on sizeOfNALength field */
271 sizeofNalLengthField = size_of_nal_length_field;
272 nal_len = 0;
273 while (size_of_nal_length_field--) {
274 nal_len |= buffer[pos++]<<(size_of_nal_length_field<<3);
275 }
276 if (nal_len >= buffer_length) {
277 ALOGE("ERROR: In %s() - line %d", __func__, __LINE__);
278 return false;
279 }
280 }
281
282 if (nal_len > buffer_length) {
283 ALOGE("ERROR: In %s() - line %d", __func__, __LINE__);
284 return false;
285 }
286 if (pos + 1 > (nal_len + sizeofNalLengthField)) {
287 ALOGE("ERROR: In %s() - line %d", __func__, __LINE__);
288 return false;
289 }
290 if ((nal_unit->forbidden_zero_bit = (buffer[pos] & 0x80)) != 0) {
291 ALOGE("ERROR: In %s() - line %d", __func__, __LINE__);
292 }
293 nal_unit->nal_ref_idc = (buffer[pos] & 0x60) >> 5;
294 nal_unit->nalu_type = buffer[pos++] & 0x1f;
295 ALOGV("@#@# Pos = %x NalType = %x buflen = %d",
296 pos-1, nal_unit->nalu_type, buffer_length);
297 *rbsp_length = 0;
298
299
300 if ( nal_unit->nalu_type == NALU_TYPE_EOSEQ ||
301 nal_unit->nalu_type == NALU_TYPE_EOSTREAM)
302 return (nal_len + sizeofNalLengthField);
303
304 zero_count = 0;
305 while (pos < (nal_len+sizeofNalLengthField)) { //similar to for in p-42
306 if ( zero_count == 2 ) {
307 if ( buffer[pos] == 0x03 ) {
308 pos ++;
309 zero_count = 0;
310 continue;
311 }
312 if ( buffer[pos] <= 0x01 ) {
313 if ( start_code ) {
314 *rbsp_length -= 2;
315 pos -= 2;
316 return pos;
317 }
318 }
319 zero_count = 0;
320 }
321 zero_count ++;
322 if ( buffer[pos] != 0 )
323 zero_count = 0;
324
325 rbsp_bistream[(*rbsp_length)++] = buffer[pos++];
326 }
327
328 return eRet;
329 }
330
331 /*===========================================================================
332 FUNCTION:
333 H264_Utils::iSNewFrame
334
335 DESCRIPTION:
336 Returns true if NAL parsing successfull otherwise false.
337
338 INPUT/OUTPUT PARAMETERS:
339 <In>
340 buffer : buffer containing start code or nal length + NAL units
341 buffer_length : the length of the NAL buffer
342 start_code : If true, start code is detected,
343 otherwise size nal length is detected
344 size_of_nal_length_field: size of nal length field
345 <out>
346 isNewFrame: true if the NAL belongs to a differenet frame
347 false if the NAL belongs to a current frame
348
349 RETURN VALUE:
350 boolean true, if nal parsing is successful
351 false, if the nal parsing has errors
352
353 SIDE EFFECTS:
354 None.
355 ===========================================================================*/
isNewFrame(OMX_BUFFERHEADERTYPE * p_buf_hdr,OMX_IN OMX_U32 size_of_nal_length_field,OMX_OUT OMX_BOOL & isNewFrame)356 bool H264_Utils::isNewFrame(OMX_BUFFERHEADERTYPE *p_buf_hdr,
357 OMX_IN OMX_U32 size_of_nal_length_field,
358 OMX_OUT OMX_BOOL &isNewFrame)
359 {
360 NALU nal_unit;
361 uint16 first_mb_in_slice = 0;
362 OMX_IN OMX_U32 numBytesInRBSP = 0;
363 OMX_IN OMX_U8 *buffer = p_buf_hdr->pBuffer;
364 OMX_IN OMX_U32 buffer_length = p_buf_hdr->nFilledLen;
365 bool eRet = true;
366
367 ALOGV("isNewFrame: buffer %p buffer_length %d "
368 "size_of_nal_length_field %d", buffer, buffer_length,
369 size_of_nal_length_field);
370
371 if ( false == extract_rbsp(buffer, buffer_length, size_of_nal_length_field,
372 m_rbspBytes, &numBytesInRBSP, &nal_unit) ) {
373 ALOGE("ERROR: In %s() - extract_rbsp() failed", __func__);
374 isNewFrame = OMX_FALSE;
375 eRet = false;
376 } else {
377 nalu_type = nal_unit.nalu_type;
378 switch (nal_unit.nalu_type) {
379 case NALU_TYPE_IDR:
380 case NALU_TYPE_NON_IDR: {
381 ALOGV("AU Boundary with NAL type %d ",nal_unit.nalu_type);
382 if (m_forceToStichNextNAL) {
383 isNewFrame = OMX_FALSE;
384 } else {
385 RbspParser rbsp_parser(m_rbspBytes, (m_rbspBytes+numBytesInRBSP));
386 first_mb_in_slice = rbsp_parser.ue();
387
388 if ((!first_mb_in_slice) || /*(slice.prv_frame_num != slice.frame_num ) ||*/
389 ( (m_prv_nalu.nal_ref_idc != nal_unit.nal_ref_idc) && ( nal_unit.nal_ref_idc * m_prv_nalu.nal_ref_idc == 0 ) ) ||
390 /*( ((m_prv_nalu.nalu_type == NALU_TYPE_IDR) && (nal_unit.nalu_type == NALU_TYPE_IDR)) && (slice.idr_pic_id != slice.prv_idr_pic_id) ) || */
391 ( (m_prv_nalu.nalu_type != nal_unit.nalu_type ) && ((m_prv_nalu.nalu_type == NALU_TYPE_IDR) || (nal_unit.nalu_type == NALU_TYPE_IDR)) ) ) {
392 //ALOGV("Found a New Frame due to NALU_TYPE_IDR/NALU_TYPE_NON_IDR");
393 isNewFrame = OMX_TRUE;
394 } else {
395 isNewFrame = OMX_FALSE;
396 }
397 }
398 m_au_data = true;
399 m_forceToStichNextNAL = false;
400 break;
401 }
402 case NALU_TYPE_SPS:
403 case NALU_TYPE_PPS:
404 case NALU_TYPE_SEI: {
405 ALOGV("Non-AU boundary with NAL type %d", nal_unit.nalu_type);
406 if (m_au_data) {
407 isNewFrame = OMX_TRUE;
408 m_au_data = false;
409 } else {
410 isNewFrame = OMX_FALSE;
411 }
412
413 m_forceToStichNextNAL = true;
414 break;
415 }
416 case NALU_TYPE_ACCESS_DELIM:
417 case NALU_TYPE_UNSPECIFIED:
418 case NALU_TYPE_EOSEQ:
419 case NALU_TYPE_EOSTREAM:
420 default: {
421 isNewFrame = OMX_FALSE;
422 // Do not update m_forceToStichNextNAL
423 break;
424 }
425 } // end of switch
426 } // end of if
427 m_prv_nalu = nal_unit;
428 ALOGV("get_h264_nal_type - newFrame value %d",isNewFrame);
429 return eRet;
430 }
431
start()432 void perf_metrics::start()
433 {
434 if (!active) {
435 start_time = get_act_time();
436 active = true;
437 }
438 }
439
stop()440 void perf_metrics::stop()
441 {
442 OMX_U64 stop_time = get_act_time();
443 if (active) {
444 proc_time += (stop_time - start_time);
445 active = false;
446 }
447 }
448
end(OMX_U32 units_cntr)449 void perf_metrics::end(OMX_U32 units_cntr)
450 {
451 stop();
452 ALOGV("--> Processing time : [%.2f] Sec", (float)proc_time / 1e6);
453 if (units_cntr) {
454 ALOGV("--> Avrg proc time : [%.2f] mSec", proc_time / (float)(units_cntr * 1e3));
455 }
456 }
457
reset()458 void perf_metrics::reset()
459 {
460 start_time = 0;
461 proc_time = 0;
462 active = false;
463 }
464
get_act_time()465 OMX_U64 perf_metrics::get_act_time()
466 {
467 struct timeval act_time = {0, 0};
468 gettimeofday(&act_time, NULL);
469 return (act_time.tv_usec + act_time.tv_sec * 1e6);
470 }
471
processing_time_us()472 OMX_U64 perf_metrics::processing_time_us()
473 {
474 return proc_time;
475 }
476
h264_stream_parser()477 h264_stream_parser::h264_stream_parser()
478 {
479 reset();
480 #ifdef PANSCAN_HDLR
481 panscan_hdl = new panscan_handler();
482 if (!panscan_hdl) {
483 ALOGE("ERROR: Panscan hdl was not allocated!");
484 } else if (!panscan_hdl->initialize(10)) {
485 ALOGE("ERROR: Allocating memory for panscan!");
486 delete panscan_hdl;
487 panscan_hdl = NULL;
488 }
489 #else
490 memset(&panscan_param, 0, sizeof(panscan_param));
491 panscan_param.rect_id = NO_PAN_SCAN_BIT;
492 #endif
493 }
494
~h264_stream_parser()495 h264_stream_parser::~h264_stream_parser()
496 {
497 #ifdef PANSCAN_HDLR
498 if (panscan_hdl) {
499 delete panscan_hdl;
500 panscan_hdl = NULL;
501 }
502 #endif
503 }
504
reset()505 void h264_stream_parser::reset()
506 {
507 curr_32_bit = 0;
508 bits_read = 0;
509 zero_cntr = 0;
510 emulation_code_skip_cntr = 0;
511 emulation_sc_enabled = true;
512 bitstream = NULL;
513 bitstream_bytes = 0;
514 memset(&vui_param, 0, sizeof(vui_param));
515 vui_param.fixed_fps_prev_ts = LLONG_MAX;
516 memset(&sei_buf_period, 0, sizeof(sei_buf_period));
517 memset(&sei_pic_timing, 0, sizeof(sei_pic_timing));
518 memset(&frame_packing_arrangement,0,sizeof(frame_packing_arrangement));
519 frame_packing_arrangement.cancel_flag = 1;
520 mbaff_flag = 0;
521 }
522
init_bitstream(OMX_U8 * data,OMX_U32 size)523 void h264_stream_parser::init_bitstream(OMX_U8* data, OMX_U32 size)
524 {
525 bitstream = data;
526 bitstream_bytes = size;
527 curr_32_bit = 0;
528 bits_read = 0;
529 zero_cntr = 0;
530 emulation_code_skip_cntr = 0;
531 }
532
parse_vui(bool vui_in_extradata)533 void h264_stream_parser::parse_vui(bool vui_in_extradata)
534 {
535 OMX_U32 value = 0;
536 ALOGV("parse_vui: IN");
537 if (vui_in_extradata)
538 while (!extract_bits(1) && more_bits()); // Discard VUI enable flag
539 if (!more_bits())
540 return;
541
542 vui_param.aspect_ratio_info_present_flag = extract_bits(1); //aspect_ratio_info_present_flag
543 if (vui_param.aspect_ratio_info_present_flag) {
544 ALOGV("Aspect Ratio Info present!");
545 aspect_ratio_info();
546 }
547
548 if (extract_bits(1)) //overscan_info_present_flag
549 extract_bits(1); //overscan_appropriate_flag
550 if (extract_bits(1)) { //video_signal_type_present_flag
551 extract_bits(3); //video_format
552 extract_bits(1); //video_full_range_flag
553 if (extract_bits(1)) { //colour_description_present_flag
554 extract_bits(8); //colour_primaries
555 extract_bits(8); //transfer_characteristics
556 extract_bits(8); //matrix_coefficients
557 }
558 }
559 if (extract_bits(1)) { //chroma_location_info_present_flag
560 uev(); //chroma_sample_loc_type_top_field
561 uev(); //chroma_sample_loc_type_bottom_field
562 }
563 vui_param.timing_info_present_flag = extract_bits(1);
564 if (vui_param.timing_info_present_flag) {
565 vui_param.num_units_in_tick = extract_bits(32);
566 vui_param.time_scale = extract_bits(32);
567 vui_param.fixed_frame_rate_flag = extract_bits(1);
568 ALOGV("Timing info present in VUI!");
569 ALOGV(" num units in tick : %u", vui_param.num_units_in_tick);
570 ALOGV(" time scale : %u", vui_param.time_scale);
571 ALOGV(" fixed frame rate : %u", vui_param.fixed_frame_rate_flag);
572 }
573 vui_param.nal_hrd_parameters_present_flag = extract_bits(1);
574 if (vui_param.nal_hrd_parameters_present_flag) {
575 ALOGV("nal hrd params present!");
576 hrd_parameters(&vui_param.nal_hrd_parameters);
577 }
578 vui_param.vcl_hrd_parameters_present_flag = extract_bits(1);
579 if (vui_param.vcl_hrd_parameters_present_flag) {
580 ALOGV("vcl hrd params present!");
581 hrd_parameters(&vui_param.vcl_hrd_parameters);
582 }
583 if (vui_param.nal_hrd_parameters_present_flag ||
584 vui_param.vcl_hrd_parameters_present_flag)
585 vui_param.low_delay_hrd_flag = extract_bits(1);
586 vui_param.pic_struct_present_flag = extract_bits(1);
587 ALOGV("pic_struct_present_flag : %u", vui_param.pic_struct_present_flag);
588 if (extract_bits(1)) { //bitstream_restriction_flag
589 extract_bits(1); //motion_vectors_over_pic_boundaries_flag
590 uev(); //max_bytes_per_pic_denom
591 uev(); //max_bits_per_mb_denom
592 uev(); //log2_max_mv_length_vertical
593 uev(); //log2_max_mv_length_horizontal
594 uev(); //num_reorder_frames
595 uev(); //max_dec_frame_buffering
596 }
597 ALOGV("parse_vui: OUT");
598 }
599
aspect_ratio_info()600 void h264_stream_parser::aspect_ratio_info()
601 {
602 ALOGV("aspect_ratio_info: IN");
603 OMX_U32 aspect_ratio_idc = 0;
604 OMX_U32 aspect_ratio_x = 0;
605 OMX_U32 aspect_ratio_y = 0;
606 aspect_ratio_idc = extract_bits(8); //aspect_ratio_idc
607 switch (aspect_ratio_idc) {
608 case 1:
609 aspect_ratio_x = 1;
610 aspect_ratio_y = 1;
611 break;
612 case 2:
613 aspect_ratio_x = 12;
614 aspect_ratio_y = 11;
615 break;
616 case 3:
617 aspect_ratio_x = 10;
618 aspect_ratio_y = 11;
619 break;
620 case 4:
621 aspect_ratio_x = 16;
622 aspect_ratio_y = 11;
623 break;
624 case 5:
625 aspect_ratio_x = 40;
626 aspect_ratio_y = 33;
627 break;
628 case 6:
629 aspect_ratio_x = 24;
630 aspect_ratio_y = 11;
631 break;
632 case 7:
633 aspect_ratio_x = 20;
634 aspect_ratio_y = 11;
635 break;
636 case 8:
637 aspect_ratio_x = 32;
638 aspect_ratio_y = 11;
639 break;
640 case 9:
641 aspect_ratio_x = 80;
642 aspect_ratio_y = 33;
643 break;
644 case 10:
645 aspect_ratio_x = 18;
646 aspect_ratio_y = 11;
647 break;
648 case 11:
649 aspect_ratio_x = 15;
650 aspect_ratio_y = 11;
651 break;
652 case 12:
653 aspect_ratio_x = 64;
654 aspect_ratio_y = 33;
655 break;
656 case 13:
657 aspect_ratio_x = 160;
658 aspect_ratio_y = 99;
659 break;
660 case 14:
661 aspect_ratio_x = 4;
662 aspect_ratio_y = 3;
663 break;
664 case 15:
665 aspect_ratio_x = 3;
666 aspect_ratio_y = 2;
667 break;
668 case 16:
669 aspect_ratio_x = 2;
670 aspect_ratio_y = 1;
671 break;
672 case 255:
673 aspect_ratio_x = extract_bits(16); //sar_width
674 aspect_ratio_y = extract_bits(16); //sar_height
675 break;
676 default:
677 ALOGV("-->aspect_ratio_idc: Reserved Value ");
678 break;
679 }
680 ALOGV("-->aspect_ratio_idc : %u", aspect_ratio_idc);
681 ALOGV("-->aspect_ratio_x : %u", aspect_ratio_x);
682 ALOGV("-->aspect_ratio_y : %u", aspect_ratio_y);
683 vui_param.aspect_ratio_info.aspect_ratio_idc = aspect_ratio_idc;
684 vui_param.aspect_ratio_info.aspect_ratio_x = aspect_ratio_x;
685 vui_param.aspect_ratio_info.aspect_ratio_y = aspect_ratio_y;
686 ALOGV("aspect_ratio_info: OUT");
687 }
688
hrd_parameters(h264_hrd_param * hrd_param)689 void h264_stream_parser::hrd_parameters(h264_hrd_param *hrd_param)
690 {
691 OMX_U32 idx;
692 ALOGV("hrd_parameters: IN");
693 hrd_param->cpb_cnt = uev() + 1;
694 hrd_param->bit_rate_scale = extract_bits(4);
695 hrd_param->cpb_size_scale = extract_bits(4);
696 ALOGV("-->cpb_cnt : %u", hrd_param->cpb_cnt);
697 ALOGV("-->bit_rate_scale : %u", hrd_param->bit_rate_scale);
698 ALOGV("-->cpb_size_scale : %u", hrd_param->cpb_size_scale);
699 if (hrd_param->cpb_cnt > MAX_CPB_COUNT) {
700 ALOGV("ERROR: Invalid hrd_param->cpb_cnt [%u]!", hrd_param->cpb_cnt);
701 return;
702 }
703 for (idx = 0; idx < hrd_param->cpb_cnt && more_bits(); idx++) {
704 hrd_param->bit_rate_value[idx] = uev() + 1;
705 hrd_param->cpb_size_value[idx] = uev() + 1;
706 hrd_param->cbr_flag[idx] = extract_bits(1);
707 ALOGV("-->bit_rate_value [%d] : %u", idx, hrd_param->bit_rate_value[idx]);
708 ALOGV("-->cpb_size_value [%d] : %u", idx, hrd_param->cpb_size_value[idx]);
709 ALOGV("-->cbr_flag [%d] : %u", idx, hrd_param->cbr_flag[idx]);
710 }
711 hrd_param->initial_cpb_removal_delay_length = extract_bits(5) + 1;
712 hrd_param->cpb_removal_delay_length = extract_bits(5) + 1;
713 hrd_param->dpb_output_delay_length = extract_bits(5) + 1;
714 hrd_param->time_offset_length = extract_bits(5);
715 ALOGV("-->initial_cpb_removal_delay_length : %u", hrd_param->initial_cpb_removal_delay_length);
716 ALOGV("-->cpb_removal_delay_length : %u", hrd_param->cpb_removal_delay_length);
717 ALOGV("-->dpb_output_delay_length : %u", hrd_param->dpb_output_delay_length);
718 ALOGV("-->time_offset_length : %u", hrd_param->time_offset_length);
719 ALOGV("hrd_parameters: OUT");
720 }
721
parse_sei()722 void h264_stream_parser::parse_sei()
723 {
724 OMX_U32 value = 0, processed_bytes = 0;
725 OMX_U8 *sei_msg_start = bitstream;
726 OMX_U32 sei_unit_size = bitstream_bytes;
727 ALOGV("@@parse_sei: IN sei_unit_size(%u)", sei_unit_size);
728 while ((processed_bytes + 2) < sei_unit_size && more_bits()) {
729 init_bitstream(sei_msg_start + processed_bytes, sei_unit_size - processed_bytes);
730 ALOGV("-->NALU_TYPE_SEI");
731 OMX_U32 payload_type = 0, payload_size = 0, aux = 0;
732 do {
733 value = extract_bits(8);
734 payload_type += value;
735 processed_bytes++;
736 } while (value == 0xFF);
737 ALOGV("-->payload_type : %u", payload_type);
738 do {
739 value = extract_bits(8);
740 payload_size += value;
741 processed_bytes++;
742 } while (value == 0xFF);
743 ALOGV("-->payload_size : %u", payload_size);
744 if (payload_size > 0) {
745 switch (payload_type) {
746 case BUFFERING_PERIOD:
747 sei_buffering_period();
748 break;
749 case PIC_TIMING:
750 sei_picture_timing();
751 break;
752 case PAN_SCAN_RECT:
753 sei_pan_scan();
754 break;
755 case SEI_PAYLOAD_FRAME_PACKING_ARRANGEMENT:
756 parse_frame_pack();
757 break;
758 default:
759 ALOGV("-->SEI payload type [%u] not implemented! size[%u]", payload_type, payload_size);
760 }
761 }
762 processed_bytes += (payload_size + emulation_code_skip_cntr);
763 ALOGV("-->SEI processed_bytes[%u]", processed_bytes);
764 }
765 ALOGV("@@parse_sei: OUT");
766 }
767
sei_buffering_period()768 void h264_stream_parser::sei_buffering_period()
769 {
770 OMX_U32 idx;
771 OMX_U32 value = 0;
772 h264_hrd_param *hrd_param = NULL;
773 ALOGV("@@sei_buffering_period: IN");
774 value = uev(); // seq_parameter_set_id
775 ALOGV("-->seq_parameter_set_id : %u", value);
776 if (value > 31) {
777 ALOGV("ERROR: Invalid seq_parameter_set_id [%u]!", value);
778 return;
779 }
780 sei_buf_period.is_valid = false;
781 if (vui_param.nal_hrd_parameters_present_flag) {
782 hrd_param = &vui_param.nal_hrd_parameters;
783 if (hrd_param->cpb_cnt > MAX_CPB_COUNT) {
784 ALOGV("ERROR: Invalid hrd_param->cpb_cnt [%u]!", hrd_param->cpb_cnt);
785 return;
786 }
787 for (idx = 0; idx < hrd_param->cpb_cnt ; idx++) {
788 sei_buf_period.is_valid = true;
789 sei_buf_period.initial_cpb_removal_delay[idx] = extract_bits(hrd_param->initial_cpb_removal_delay_length);
790 sei_buf_period.initial_cpb_removal_delay_offset[idx] = extract_bits(hrd_param->initial_cpb_removal_delay_length);
791 ALOGV("-->initial_cpb_removal_delay : %u", sei_buf_period.initial_cpb_removal_delay[idx]);
792 ALOGV("-->initial_cpb_removal_delay_offset : %u", sei_buf_period.initial_cpb_removal_delay_offset[idx]);
793 }
794 }
795 if (vui_param.vcl_hrd_parameters_present_flag) {
796 hrd_param = &vui_param.vcl_hrd_parameters;
797 if (hrd_param->cpb_cnt > MAX_CPB_COUNT) {
798 ALOGV("ERROR: Invalid hrd_param->cpb_cnt [%u]!", hrd_param->cpb_cnt);
799 return;
800 }
801 for (idx = 0; idx < hrd_param->cpb_cnt ; idx++) {
802 sei_buf_period.is_valid = true;
803 sei_buf_period.initial_cpb_removal_delay[idx] = extract_bits(hrd_param->initial_cpb_removal_delay_length);
804 sei_buf_period.initial_cpb_removal_delay_offset[idx] = extract_bits(hrd_param->initial_cpb_removal_delay_length);
805 ALOGV("-->initial_cpb_removal_delay : %u", sei_buf_period.initial_cpb_removal_delay[idx]);
806 ALOGV("-->initial_cpb_removal_delay_offset : %u", sei_buf_period.initial_cpb_removal_delay_offset[idx]);
807 }
808 }
809 sei_buf_period.au_cntr = 0;
810 ALOGV("@@sei_buffering_period: OUT");
811 }
812
sei_picture_timing()813 void h264_stream_parser::sei_picture_timing()
814 {
815 ALOGV("@@sei_picture_timing: IN");
816 OMX_U32 time_offset_len = 0, cpb_removal_len = 24, dpb_output_len = 24;
817 OMX_U8 cbr_flag = 0;
818 sei_pic_timing.is_valid = true;
819 if (vui_param.nal_hrd_parameters_present_flag) {
820 cpb_removal_len = vui_param.nal_hrd_parameters.cpb_removal_delay_length;
821 dpb_output_len = vui_param.nal_hrd_parameters.dpb_output_delay_length;
822 time_offset_len = vui_param.nal_hrd_parameters.time_offset_length;
823 cbr_flag = vui_param.nal_hrd_parameters.cbr_flag[0];
824 } else if (vui_param.vcl_hrd_parameters_present_flag) {
825 cpb_removal_len = vui_param.vcl_hrd_parameters.cpb_removal_delay_length;
826 dpb_output_len = vui_param.vcl_hrd_parameters.dpb_output_delay_length;
827 time_offset_len = vui_param.vcl_hrd_parameters.time_offset_length;
828 cbr_flag = vui_param.vcl_hrd_parameters.cbr_flag[0];
829 }
830 sei_pic_timing.cpb_removal_delay = extract_bits(cpb_removal_len);
831 sei_pic_timing.dpb_output_delay = extract_bits(dpb_output_len);
832 ALOGV("-->cpb_removal_len : %u", cpb_removal_len);
833 ALOGV("-->dpb_output_len : %u", dpb_output_len);
834 ALOGV("-->cpb_removal_delay : %u", sei_pic_timing.cpb_removal_delay);
835 ALOGV("-->dpb_output_delay : %u", sei_pic_timing.dpb_output_delay);
836 if (vui_param.pic_struct_present_flag) {
837 sei_pic_timing.pic_struct = extract_bits(4);
838 sei_pic_timing.num_clock_ts = 0;
839 switch (sei_pic_timing.pic_struct) {
840 case 0:
841 case 1:
842 case 2:
843 sei_pic_timing.num_clock_ts = 1;
844 break;
845 case 3:
846 case 4:
847 case 7:
848 sei_pic_timing.num_clock_ts = 2;
849 break;
850 case 5:
851 case 6:
852 case 8:
853 sei_pic_timing.num_clock_ts = 3;
854 break;
855 default:
856 ALOGE("sei_picture_timing: pic_struct invalid!");
857 }
858 ALOGV("-->num_clock_ts : %u", sei_pic_timing.num_clock_ts);
859 for (OMX_U32 i = 0; i < sei_pic_timing.num_clock_ts && more_bits(); i++) {
860 sei_pic_timing.clock_ts_flag = extract_bits(1);
861 if (sei_pic_timing.clock_ts_flag) {
862 ALOGV("-->clock_timestamp present!");
863 sei_pic_timing.ct_type = extract_bits(2);
864 sei_pic_timing.nuit_field_based_flag = extract_bits(1);
865 sei_pic_timing.counting_type = extract_bits(5);
866 sei_pic_timing.full_timestamp_flag = extract_bits(1);
867 sei_pic_timing.discontinuity_flag = extract_bits(1);
868 sei_pic_timing.cnt_dropped_flag = extract_bits(1);
869 sei_pic_timing.n_frames = extract_bits(8);
870 ALOGV("-->f_timestamp_flg : %u", sei_pic_timing.full_timestamp_flag);
871 ALOGV("-->n_frames : %u", sei_pic_timing.n_frames);
872 sei_pic_timing.seconds_value = 0;
873 sei_pic_timing.minutes_value = 0;
874 sei_pic_timing.hours_value = 0;
875 if (sei_pic_timing.full_timestamp_flag) {
876 sei_pic_timing.seconds_value = extract_bits(6);
877 sei_pic_timing.minutes_value = extract_bits(6);
878 sei_pic_timing.hours_value = extract_bits(5);
879 } else if (extract_bits(1)) {
880 ALOGV("-->seconds_flag enabled!");
881 sei_pic_timing.seconds_value = extract_bits(6);
882 if (extract_bits(1)) {
883 ALOGV("-->minutes_flag enabled!");
884 sei_pic_timing.minutes_value = extract_bits(6);
885 if (extract_bits(1)) {
886 ALOGV("-->hours_flag enabled!");
887 sei_pic_timing.hours_value = extract_bits(5);
888 }
889 }
890 }
891 sei_pic_timing.time_offset = 0;
892 if (time_offset_len > 0)
893 sei_pic_timing.time_offset = iv(time_offset_len);
894 ALOGV("-->seconds_value : %u", sei_pic_timing.seconds_value);
895 ALOGV("-->minutes_value : %u", sei_pic_timing.minutes_value);
896 ALOGV("-->hours_value : %u", sei_pic_timing.hours_value);
897 ALOGV("-->time_offset : %d", sei_pic_timing.time_offset);
898 }
899 }
900 }
901 ALOGV("@@sei_picture_timing: OUT");
902 }
903
sei_pan_scan()904 void h264_stream_parser::sei_pan_scan()
905 {
906 #ifdef _ANDROID_
907 char property_value[PROPERTY_VALUE_MAX] = {0};
908 OMX_S32 enable_panscan_log = 0;
909 property_get("vidc.dec.debug.panframedata", property_value, "0");
910 enable_panscan_log = atoi(property_value);
911 #endif
912 #ifdef PANSCAN_HDLR
913 h264_pan_scan *pan_scan_param = panscan_hdl->get_free();
914 #else
915 h264_pan_scan *pan_scan_param = &panscan_param;
916 #endif
917
918 if (!pan_scan_param) {
919 ALOGE("sei_pan_scan: ERROR: Invalid pointer!");
920 return;
921 }
922
923 pan_scan_param->rect_id = uev();
924 if (pan_scan_param->rect_id > 0xFF) {
925 ALOGE("sei_pan_scan: ERROR: Invalid rect_id[%u]!", (unsigned int)pan_scan_param->rect_id);
926 pan_scan_param->rect_id = NO_PAN_SCAN_BIT;
927 return;
928 }
929
930 pan_scan_param->rect_cancel_flag = extract_bits(1);
931
932 if (pan_scan_param->rect_cancel_flag)
933 pan_scan_param->rect_id = NO_PAN_SCAN_BIT;
934 else {
935 pan_scan_param->cnt = uev() + 1;
936 if (pan_scan_param->cnt > MAX_PAN_SCAN_RECT) {
937 ALOGE("sei_pan_scan: ERROR: Invalid num of rect [%u]!", (unsigned int)pan_scan_param->cnt);
938 pan_scan_param->rect_id = NO_PAN_SCAN_BIT;
939 return;
940 }
941
942 for (OMX_U32 i = 0; i < pan_scan_param->cnt; i++) {
943 pan_scan_param->rect_left_offset[i] = sev();
944 pan_scan_param->rect_right_offset[i] = sev();
945 pan_scan_param->rect_top_offset[i] = sev();
946 pan_scan_param->rect_bottom_offset[i] = sev();
947
948 }
949 pan_scan_param->rect_repetition_period = uev();
950 #ifdef PANSCAN_HDLR
951 if (pan_scan_param->rect_repetition_period > 1)
952 // Repetition period is decreased by 2 each time panscan data is used
953 pan_scan_param->rect_repetition_period *= 2;
954 #endif
955 #ifdef _ANDROID_
956 if (enable_panscan_log) {
957 print_pan_data(pan_scan_param);
958 }
959 #endif
960 }
961 }
962
print_pan_data(h264_pan_scan * pan_scan_param)963 void h264_stream_parser::print_pan_data(h264_pan_scan *pan_scan_param)
964 {
965 ALOGE("@@print_pan_data: IN");
966
967 ALOGE("-->rect_id : %u", (unsigned int)pan_scan_param->rect_id);
968 ALOGE("-->rect_cancel_flag : %u", pan_scan_param->rect_cancel_flag);
969
970 ALOGE("-->cnt : %u", (unsigned int)pan_scan_param->cnt);
971
972 for (OMX_U32 i = 0; i < pan_scan_param->cnt; i++) {
973 ALOGE("-->rect_left_offset : %d", (int)pan_scan_param->rect_left_offset[i]);
974 ALOGE("-->rect_right_offset : %d", (int)pan_scan_param->rect_right_offset[i]);
975 ALOGE("-->rect_top_offset : %d", (int)pan_scan_param->rect_top_offset[i]);
976 ALOGE("-->rect_bottom_offset : %d", (int)pan_scan_param->rect_bottom_offset[i]);
977 }
978 ALOGE("-->repetition_period : %u", (unsigned int)pan_scan_param->rect_repetition_period);
979
980 ALOGE("@@print_pan_data: OUT");
981 }
982
parse_sps()983 void h264_stream_parser::parse_sps()
984 {
985 OMX_U32 value = 0, scaling_matrix_limit;
986 ALOGV("@@parse_sps: IN");
987 value = extract_bits(8); //profile_idc
988 profile = value;
989 extract_bits(8); //constraint flags and reserved bits
990 extract_bits(8); //level_idc
991 uev(); //sps id
992 if (value == 100 || value == 110 || value == 122 || value == 244 ||
993 value == 44 || value == 83 || value == 86 || value == 118) {
994 if (uev() == 3) { //chroma_format_idc
995 extract_bits(1); //separate_colour_plane_flag
996 scaling_matrix_limit = 12;
997 } else
998 scaling_matrix_limit = 12;
999 uev(); //bit_depth_luma_minus8
1000 uev(); //bit_depth_chroma_minus8
1001 extract_bits(1); //qpprime_y_zero_transform_bypass_flag
1002 if (extract_bits(1)) { //seq_scaling_matrix_present_flag
1003 for (unsigned int i = 0; i < scaling_matrix_limit && more_bits(); i++) {
1004 if (extract_bits(1)) { ////seq_scaling_list_present_flag[ i ]
1005 if (i < 6)
1006 scaling_list(16);
1007 else
1008 scaling_list(64);
1009 }
1010 }
1011 }
1012 }
1013 uev(); //log2_max_frame_num_minus4
1014 value = uev(); //pic_order_cnt_type
1015 if (value == 0)
1016 uev(); //log2_max_pic_order_cnt_lsb_minus4
1017 else if (value == 1) {
1018 extract_bits(1); //delta_pic_order_always_zero_flag
1019 sev(); //offset_for_non_ref_pic
1020 sev(); //offset_for_top_to_bottom_field
1021 value = uev(); // num_ref_frames_in_pic_order_cnt_cycle
1022 for (unsigned int i = 0; i < value; i++)
1023 sev(); //offset_for_ref_frame[ i ]
1024 }
1025 uev(); //max_num_ref_frames
1026 extract_bits(1); //gaps_in_frame_num_value_allowed_flag
1027 value = uev(); //pic_width_in_mbs_minus1
1028 value = uev(); //pic_height_in_map_units_minus1
1029 if (!extract_bits(1)) //frame_mbs_only_flag
1030 mbaff_flag = extract_bits(1); //mb_adaptive_frame_field_flag
1031 extract_bits(1); //direct_8x8_inference_flag
1032 if (extract_bits(1)) { //frame_cropping_flag
1033 uev(); //frame_crop_left_offset
1034 uev(); //frame_crop_right_offset
1035 uev(); //frame_crop_top_offset
1036 uev(); //frame_crop_bottom_offset
1037 }
1038 if (extract_bits(1)) //vui_parameters_present_flag
1039 parse_vui(false);
1040 ALOGV("@@parse_sps: OUT");
1041 }
1042
scaling_list(OMX_U32 size_of_scaling_list)1043 void h264_stream_parser::scaling_list(OMX_U32 size_of_scaling_list)
1044 {
1045 OMX_S32 last_scale = 8, next_scale = 8, delta_scale;
1046 for (unsigned int j = 0; j < size_of_scaling_list; j++) {
1047 if (next_scale != 0) {
1048 delta_scale = sev();
1049 next_scale = (last_scale + delta_scale + 256) % 256;
1050 }
1051 last_scale = (next_scale == 0)? last_scale : next_scale;
1052 }
1053 }
1054
extract_bits(OMX_U32 n)1055 OMX_U32 h264_stream_parser::extract_bits(OMX_U32 n)
1056 {
1057 OMX_U32 value = 0;
1058 if (n > 32) {
1059 ALOGE("ERROR: extract_bits limit to 32 bits!");
1060 return value;
1061 }
1062 value = curr_32_bit >> (32 - n);
1063 if (bits_read < n) {
1064 n -= bits_read;
1065 read_word();
1066 value |= (curr_32_bit >> (32 - n));
1067 if (bits_read < n) {
1068 ALOGV("ERROR: extract_bits underflow!");
1069 value >>= (n - bits_read);
1070 n = bits_read;
1071 }
1072 }
1073 bits_read -= n;
1074 curr_32_bit <<= n;
1075 return value;
1076 }
1077
read_word()1078 void h264_stream_parser::read_word()
1079 {
1080 curr_32_bit = 0;
1081 bits_read = 0;
1082 while (bitstream_bytes && bits_read < 32) {
1083 if (*bitstream == EMULATION_PREVENTION_THREE_BYTE &&
1084 zero_cntr >= 2 && emulation_sc_enabled) {
1085 ALOGV("EMULATION_PREVENTION_THREE_BYTE: Skip 0x03 byte aligned!");
1086 emulation_code_skip_cntr++;
1087 } else {
1088 curr_32_bit <<= 8;
1089 curr_32_bit |= *bitstream;
1090 bits_read += 8;
1091 }
1092 if (*bitstream == 0)
1093 zero_cntr++;
1094 else
1095 zero_cntr = 0;
1096 bitstream++;
1097 bitstream_bytes--;
1098 }
1099 curr_32_bit <<= (32 - bits_read);
1100 }
1101
uev()1102 OMX_U32 h264_stream_parser::uev()
1103 {
1104 OMX_U32 lead_zero_bits = 0, code_num = 0;
1105 while (!extract_bits(1) && more_bits())
1106 lead_zero_bits++;
1107 code_num = lead_zero_bits == 0 ? 0 :
1108 (1 << lead_zero_bits) - 1 + extract_bits(lead_zero_bits);
1109 return code_num;
1110 }
1111
more_bits()1112 bool h264_stream_parser::more_bits()
1113 {
1114 return (bitstream_bytes > 0 || bits_read > 0);
1115 }
1116
sev()1117 OMX_S32 h264_stream_parser::sev()
1118 {
1119 OMX_U32 code_num = uev();
1120 OMX_S32 ret;
1121 ret = (code_num + 1) >> 1;
1122 return ((code_num & 1) ? ret : -ret);
1123 }
1124
iv(OMX_U32 n_bits)1125 OMX_S32 h264_stream_parser::iv(OMX_U32 n_bits)
1126 {
1127 OMX_U32 code_num = extract_bits(n_bits);
1128 OMX_S32 ret = (code_num >> (n_bits - 1))? (-1)*(~(code_num & ~(0x1 << (n_bits - 1))) + 1) : code_num;
1129 return ret;
1130 }
1131
get_nal_unit_type(OMX_U32 * nal_unit_type)1132 OMX_U32 h264_stream_parser::get_nal_unit_type(OMX_U32 *nal_unit_type)
1133 {
1134 OMX_U32 value = 0, consumed_bytes = 3;
1135 *nal_unit_type = NALU_TYPE_UNSPECIFIED;
1136 ALOGV("-->get_nal_unit_type: IN");
1137 value = extract_bits(24);
1138 while (value != 0x00000001 && more_bits()) {
1139 value <<= 8;
1140 value |= extract_bits(8);
1141 consumed_bytes++;
1142 }
1143 if (value != 0x00000001) {
1144 ALOGE("ERROR in get_nal_unit_type: Start code not found!");
1145 } else {
1146 if (extract_bits(1)) { // forbidden_zero_bit
1147 ALOGE("WARNING: forbidden_zero_bit should be zero!");
1148 }
1149 value = extract_bits(2);
1150 ALOGV("-->nal_ref_idc : %x", value);
1151 *nal_unit_type = extract_bits(5);
1152 ALOGV("-->nal_unit_type : %x", *nal_unit_type);
1153 consumed_bytes++;
1154 if (consumed_bytes > 5) {
1155 ALOGE("-->WARNING: Startcode was found after the first 4 bytes!");
1156 }
1157 }
1158 ALOGV("-->get_nal_unit_type: OUT");
1159 return consumed_bytes;
1160 }
1161
get_profile()1162 OMX_U32 h264_stream_parser::get_profile()
1163 {
1164 return profile;
1165 }
1166
calculate_buf_period_ts(OMX_S64 timestamp)1167 OMX_S64 h264_stream_parser::calculate_buf_period_ts(OMX_S64 timestamp)
1168 {
1169 OMX_S64 clock_ts = timestamp;
1170 ALOGV("calculate_ts(): IN");
1171 if (sei_buf_period.au_cntr == 0)
1172 clock_ts = sei_buf_period.reference_ts = timestamp;
1173 else if (sei_pic_timing.is_valid && VALID_TS(sei_buf_period.reference_ts)) {
1174 clock_ts = sei_buf_period.reference_ts + sei_pic_timing.cpb_removal_delay *
1175 1e6 * vui_param.num_units_in_tick / vui_param.time_scale;
1176 }
1177 sei_buf_period.au_cntr++;
1178 ALOGV("calculate_ts(): OUT");
1179 return clock_ts;
1180 }
1181
calculate_fixed_fps_ts(OMX_S64 timestamp,OMX_U32 DeltaTfiDivisor)1182 OMX_S64 h264_stream_parser::calculate_fixed_fps_ts(OMX_S64 timestamp, OMX_U32 DeltaTfiDivisor)
1183 {
1184 if (VALID_TS(timestamp))
1185 vui_param.fixed_fps_prev_ts = timestamp;
1186 else if (VALID_TS(vui_param.fixed_fps_prev_ts))
1187 vui_param.fixed_fps_prev_ts += DeltaTfiDivisor * 1e6 *
1188 vui_param.num_units_in_tick / vui_param.time_scale;
1189 return vui_param.fixed_fps_prev_ts;
1190 }
1191
parse_frame_pack()1192 void h264_stream_parser::parse_frame_pack()
1193 {
1194 #ifdef _ANDROID_
1195 char property_value[PROPERTY_VALUE_MAX] = {0};
1196 OMX_S32 enable_framepack_log = 0;
1197
1198 property_get("vidc.dec.debug.panframedata", property_value, "0");
1199 enable_framepack_log = atoi(property_value);
1200 #endif
1201 ALOGV("%s:%d parse_frame_pack", __func__, __LINE__);
1202
1203 frame_packing_arrangement.id = uev();
1204
1205 frame_packing_arrangement.cancel_flag = extract_bits(1);
1206 if (!frame_packing_arrangement.cancel_flag) {
1207 frame_packing_arrangement.type = extract_bits(7);
1208 frame_packing_arrangement.quincunx_sampling_flag = extract_bits(1);
1209 frame_packing_arrangement.content_interpretation_type = extract_bits(6);
1210 frame_packing_arrangement.spatial_flipping_flag = extract_bits(1);
1211 frame_packing_arrangement.frame0_flipped_flag = extract_bits(1);
1212 frame_packing_arrangement.field_views_flag = extract_bits(1);
1213 frame_packing_arrangement.current_frame_is_frame0_flag = extract_bits(1);
1214 frame_packing_arrangement.frame0_self_contained_flag = extract_bits(1);
1215 frame_packing_arrangement.frame1_self_contained_flag = extract_bits(1);
1216
1217 if (!frame_packing_arrangement.quincunx_sampling_flag &&
1218 frame_packing_arrangement.type != 5) {
1219 frame_packing_arrangement.frame0_grid_position_x = extract_bits(4);
1220 frame_packing_arrangement.frame0_grid_position_y = extract_bits(4);
1221 frame_packing_arrangement.frame1_grid_position_x = extract_bits(4);
1222 frame_packing_arrangement.frame1_grid_position_y = extract_bits(4);
1223 }
1224 frame_packing_arrangement.reserved_byte = extract_bits(8);
1225 frame_packing_arrangement.repetition_period = uev();
1226 }
1227 frame_packing_arrangement.extension_flag = extract_bits(1);
1228
1229 #ifdef _ANDROID_
1230 if (enable_framepack_log) {
1231 print_frame_pack();
1232 }
1233 #endif
1234 }
1235
print_frame_pack()1236 void h264_stream_parser::print_frame_pack()
1237 {
1238 ALOGV("## frame_packing_arrangement.id = %u", frame_packing_arrangement.id);
1239 ALOGV("## frame_packing_arrangement.cancel_flag = %u",
1240 frame_packing_arrangement.cancel_flag);
1241 if (!frame_packing_arrangement.cancel_flag) {
1242 ALOGV("## frame_packing_arrangement.type = %u",
1243 frame_packing_arrangement.type);
1244 ALOGV("## frame_packing_arrangement.quincunx_sampling_flag = %u",
1245 frame_packing_arrangement.quincunx_sampling_flag);
1246 ALOGV("## frame_packing_arrangement.content_interpretation_type = %u",
1247 frame_packing_arrangement.content_interpretation_type);
1248 ALOGV("## frame_packing_arrangement.spatial_flipping_flag = %u",
1249 frame_packing_arrangement.spatial_flipping_flag);
1250 ALOGV("## frame_packing_arrangement.frame0_flipped_flag = %u",
1251 frame_packing_arrangement.frame0_flipped_flag);
1252 ALOGV("## frame_packing_arrangement.field_views_flag = %u",
1253 frame_packing_arrangement.field_views_flag);
1254 ALOGV("## frame_packing_arrangement.current_frame_is_frame0_flag = %u",
1255 frame_packing_arrangement.current_frame_is_frame0_flag);
1256 ALOGV("## frame_packing_arrangement.frame0_self_contained_flag = %u",
1257 frame_packing_arrangement.frame0_self_contained_flag);
1258 ALOGV("## frame_packing_arrangement.frame1_self_contained_flag = %u",
1259 frame_packing_arrangement.frame1_self_contained_flag);
1260 ALOGV("## frame_packing_arrangement.reserved_byte = %u",
1261 frame_packing_arrangement.reserved_byte);
1262 ALOGV("## frame_packing_arrangement.repetition_period = %u",
1263 frame_packing_arrangement.repetition_period);
1264 ALOGV("## frame_packing_arrangement.extension_flag = %u",
1265 frame_packing_arrangement.extension_flag);
1266 }
1267 }
1268 /* API'S EXPOSED TO OMX COMPONENT */
1269
get_frame_pack_data(OMX_QCOM_FRAME_PACK_ARRANGEMENT * frame_pack)1270 void h264_stream_parser::get_frame_pack_data(
1271 OMX_QCOM_FRAME_PACK_ARRANGEMENT *frame_pack)
1272 {
1273 ALOGV("%s:%d get frame data", __func__, __LINE__);
1274 memcpy(&frame_pack->id,&frame_packing_arrangement.id,
1275 FRAME_PACK_SIZE*sizeof(OMX_U32));
1276 return;
1277 }
1278
1279
is_mbaff()1280 bool h264_stream_parser::is_mbaff()
1281 {
1282 ALOGV("%s:%d MBAFF flag=%d", __func__, __LINE__,mbaff_flag);
1283 return mbaff_flag;
1284 }
1285
get_frame_rate(OMX_U32 * frame_rate)1286 void h264_stream_parser::get_frame_rate(OMX_U32 *frame_rate)
1287 {
1288 if (vui_param.num_units_in_tick != 0)
1289 *frame_rate = vui_param.time_scale / (2 * vui_param.num_units_in_tick);
1290 }
1291
parse_nal(OMX_U8 * data_ptr,OMX_U32 data_len,OMX_U32 nal_type,bool enable_emu_sc)1292 void h264_stream_parser::parse_nal(OMX_U8* data_ptr, OMX_U32 data_len, OMX_U32 nal_type, bool enable_emu_sc)
1293 {
1294 OMX_U32 nal_unit_type = NALU_TYPE_UNSPECIFIED, cons_bytes = 0;
1295 ALOGV("parse_nal(): IN nal_type(%u)", nal_type);
1296 if (!data_len)
1297 return;
1298 init_bitstream(data_ptr, data_len);
1299 emulation_sc_enabled = enable_emu_sc;
1300 if (nal_type != NALU_TYPE_VUI) {
1301 cons_bytes = get_nal_unit_type(&nal_unit_type);
1302 if (nal_type != nal_unit_type && nal_type != NALU_TYPE_UNSPECIFIED) {
1303 ALOGV("Unexpected nal_type(%x) expected(%x)", nal_unit_type, nal_type);
1304 return;
1305 }
1306 }
1307 switch (nal_type) {
1308 case NALU_TYPE_SPS:
1309 if (more_bits())
1310 parse_sps();
1311 #ifdef PANSCAN_HDLR
1312 panscan_hdl->get_free();
1313 #endif
1314 break;
1315 case NALU_TYPE_SEI:
1316 init_bitstream(data_ptr + cons_bytes, data_len - cons_bytes);
1317 parse_sei();
1318 break;
1319 case NALU_TYPE_VUI:
1320 parse_vui(true);
1321 break;
1322 default:
1323 ALOGV("nal_unit_type received : %u", nal_type);
1324 }
1325 ALOGV("parse_nal(): OUT");
1326 }
1327
1328 #ifdef PANSCAN_HDLR
update_panscan_data(OMX_S64 timestamp)1329 void h264_stream_parser::update_panscan_data(OMX_S64 timestamp)
1330 {
1331 panscan_hdl->update_last(timestamp);
1332 }
1333 #endif
1334
fill_aspect_ratio_info(OMX_QCOM_ASPECT_RATIO * dest_aspect_ratio)1335 void h264_stream_parser::fill_aspect_ratio_info(OMX_QCOM_ASPECT_RATIO *dest_aspect_ratio)
1336 {
1337 if (dest_aspect_ratio && vui_param.aspect_ratio_info_present_flag) {
1338 dest_aspect_ratio->aspectRatioX = vui_param.aspect_ratio_info.aspect_ratio_x;
1339 dest_aspect_ratio->aspectRatioY = vui_param.aspect_ratio_info.aspect_ratio_y;
1340 }
1341 }
1342
fill_pan_scan_data(OMX_QCOM_PANSCAN * dest_pan_scan,OMX_S64 timestamp)1343 void h264_stream_parser::fill_pan_scan_data(OMX_QCOM_PANSCAN *dest_pan_scan, OMX_S64 timestamp)
1344 {
1345 #ifdef PANSCAN_HDLR
1346 h264_pan_scan *pan_scan_param = panscan_hdl->get_populated(timestamp);
1347 #else
1348 h264_pan_scan *pan_scan_param = &panscan_param;
1349 #endif
1350 if (pan_scan_param) {
1351 if (!(pan_scan_param->rect_id & NO_PAN_SCAN_BIT)) {
1352 PRINT_PANSCAN_PARAM(*pan_scan_param);
1353 dest_pan_scan->numWindows = pan_scan_param->cnt;
1354 for (unsigned int i = 0; i < dest_pan_scan->numWindows; i++) {
1355 dest_pan_scan->window[i].x = pan_scan_param->rect_left_offset[i];
1356 dest_pan_scan->window[i].y = pan_scan_param->rect_top_offset[i];
1357 dest_pan_scan->window[i].dx = pan_scan_param->rect_right_offset[i];
1358 dest_pan_scan->window[i].dy = pan_scan_param->rect_bottom_offset[i];
1359 }
1360 #ifndef PANSCAN_HDLR
1361 if (pan_scan_param->rect_repetition_period == 0)
1362 pan_scan_param->rect_id = NO_PAN_SCAN_BIT;
1363 else if (pan_scan_param->rect_repetition_period > 1)
1364 pan_scan_param->rect_repetition_period =
1365 (pan_scan_param->rect_repetition_period == 2)? 0 :
1366 (pan_scan_param->rect_repetition_period - 1);
1367 #endif
1368 } else
1369 pan_scan_param->rect_repetition_period = 0;
1370 }
1371 }
1372
process_ts_with_sei_vui(OMX_S64 timestamp)1373 OMX_S64 h264_stream_parser::process_ts_with_sei_vui(OMX_S64 timestamp)
1374 {
1375 bool clock_ts_flag = false;
1376 OMX_S64 clock_ts = timestamp;
1377 OMX_U32 deltaTfiDivisor = 2;
1378 if (vui_param.timing_info_present_flag) {
1379 if (vui_param.pic_struct_present_flag) {
1380 if (sei_pic_timing.clock_ts_flag) {
1381 clock_ts = ((sei_pic_timing.hours_value * 60 + sei_pic_timing.minutes_value) * 60 + sei_pic_timing.seconds_value) * 1e6 +
1382 (sei_pic_timing.n_frames * (vui_param.num_units_in_tick * (1 + sei_pic_timing.nuit_field_based_flag)) + sei_pic_timing.time_offset) *
1383 1e6 / vui_param.time_scale;
1384 ALOGV("-->CLOCK TIMESTAMP : %lld", clock_ts);
1385 clock_ts_flag = true;
1386 }
1387 if (vui_param.fixed_frame_rate_flag) {
1388 switch (sei_pic_timing.pic_struct) {
1389 case 1:
1390 case 2:
1391 deltaTfiDivisor = 1;
1392 break;
1393 case 0:
1394 case 3:
1395 case 4:
1396 deltaTfiDivisor = 2;
1397 break;
1398 case 5:
1399 case 6:
1400 deltaTfiDivisor = 3;
1401 break;
1402 case 7:
1403 deltaTfiDivisor = 4;
1404 break;
1405 case 8:
1406 deltaTfiDivisor = 6;
1407 break;
1408 default:
1409 ALOGE("process_ts_with_sei_vui: pic_struct invalid!");
1410 }
1411 }
1412 }
1413 if (!clock_ts_flag) {
1414 if (vui_param.fixed_frame_rate_flag)
1415 clock_ts = calculate_fixed_fps_ts(timestamp, deltaTfiDivisor);
1416 else if (sei_buf_period.is_valid)
1417 clock_ts = calculate_buf_period_ts(timestamp);
1418 }
1419 } else {
1420 ALOGV("NO TIMING information present in VUI!");
1421 }
1422 sei_pic_timing.is_valid = false; // SEI data is valid only for current frame
1423 return clock_ts;
1424 }
1425
1426 #ifdef PANSCAN_HDLR
1427
panscan_handler()1428 panscan_handler::panscan_handler() : panscan_data(NULL) {}
1429
~panscan_handler()1430 panscan_handler::~panscan_handler()
1431 {
1432 if (panscan_data) {
1433 free(panscan_data);
1434 panscan_data = NULL;
1435 }
1436 }
1437
initialize(int num_data)1438 bool panscan_handler::initialize(int num_data)
1439 {
1440 bool ret = false;
1441 if (!panscan_data) {
1442 panscan_data = (PANSCAN_NODE *) malloc (sizeof(PANSCAN_NODE) * num_data);
1443 if (panscan_data) {
1444 panscan_free.add_multiple(panscan_data, num_data);
1445 ret = true;
1446 }
1447 } else {
1448 ALOGE("ERROR: Old panscan memory must be freed to allocate new");
1449 }
1450 return ret;
1451 }
1452
get_free()1453 h264_pan_scan *panscan_handler::get_free()
1454 {
1455 h264_pan_scan *data = NULL;
1456 PANSCAN_NODE *panscan_node = panscan_used.watch_last();
1457 panscan_node = (!panscan_node || VALID_TS(panscan_node->start_ts))?
1458 panscan_free.remove_first() :
1459 panscan_used.remove_last();
1460 if (panscan_node) {
1461 panscan_node->start_ts = LLONG_MAX;
1462 panscan_node->end_ts = LLONG_MAX;
1463 panscan_node->pan_scan_param.rect_id = NO_PAN_SCAN_BIT;
1464 panscan_node->active = false;
1465 panscan_used.add_last(panscan_node);
1466 data = &panscan_node->pan_scan_param;
1467 }
1468 return data;
1469 }
1470
get_populated(OMX_S64 frame_ts)1471 h264_pan_scan *panscan_handler::get_populated(OMX_S64 frame_ts)
1472 {
1473 h264_pan_scan *data = NULL;
1474 PANSCAN_NODE *panscan_node = panscan_used.watch_first();
1475 while (panscan_node && !data) {
1476 if (VALID_TS(panscan_node->start_ts)) {
1477 if (panscan_node->active && frame_ts < panscan_node->start_ts)
1478 panscan_node->start_ts = frame_ts;
1479 if (frame_ts >= panscan_node->start_ts)
1480 if (frame_ts < panscan_node->end_ts) {
1481 data = &panscan_node->pan_scan_param;
1482 panscan_node->active = true;
1483 } else {
1484 panscan_free.add_last(panscan_used.remove_first());
1485 panscan_node = panscan_used.watch_first();
1486 }
1487 else
1488 // Finish search if current timestamp has not reached
1489 // start timestamp of first panscan data.
1490 panscan_node = NULL;
1491 } else {
1492 // Only one panscan data is stored for clips
1493 // with invalid timestamps in every frame
1494 data = &panscan_node->pan_scan_param;
1495 panscan_node->active = true;
1496 }
1497 }
1498 if (data) {
1499 if (data->rect_repetition_period == 0)
1500 panscan_free.add_last(panscan_used.remove_first());
1501 else if (data->rect_repetition_period > 1)
1502 data->rect_repetition_period -= 2;
1503 }
1504 PRINT_PANSCAN_DATA(panscan_node);
1505 return data;
1506 }
1507
update_last(OMX_S64 frame_ts)1508 void panscan_handler::update_last(OMX_S64 frame_ts)
1509 {
1510 PANSCAN_NODE *panscan_node = panscan_used.watch_last();
1511 if (panscan_node && !VALID_TS(panscan_node->start_ts)) {
1512 panscan_node->start_ts = frame_ts;
1513 PRINT_PANSCAN_DATA(panscan_node);
1514 if (panscan_node->prev) {
1515 if (frame_ts < panscan_node->prev->end_ts)
1516 panscan_node->prev->end_ts = frame_ts;
1517 else if (!VALID_TS(frame_ts))
1518 panscan_node->prev->pan_scan_param.rect_repetition_period = 0;
1519 PRINT_PANSCAN_DATA(panscan_node->prev);
1520 }
1521 }
1522 }
1523
1524 template <class NODE_STRUCT>
add_multiple(NODE_STRUCT * data_arr,int data_num)1525 void omx_dl_list<NODE_STRUCT>::add_multiple(NODE_STRUCT *data_arr, int data_num)
1526 {
1527 for (int idx = 0; idx < data_num; idx++)
1528 add_last(&data_arr[idx]);
1529 }
1530
1531 template <class NODE_STRUCT>
remove_first()1532 NODE_STRUCT *omx_dl_list<NODE_STRUCT>::remove_first()
1533 {
1534 NODE_STRUCT *data = head;
1535 if (head) {
1536 if (head->next) {
1537 head = head->next;
1538 head->prev = NULL;
1539 } else
1540 head = tail = NULL;
1541 data->next = data->prev = NULL;
1542 }
1543 return data;
1544 }
1545
1546 template <class NODE_STRUCT>
remove_last()1547 NODE_STRUCT *omx_dl_list<NODE_STRUCT>::remove_last()
1548 {
1549 NODE_STRUCT *data = tail;
1550 if (tail) {
1551 if (tail->prev) {
1552 tail = tail->prev;
1553 tail->next = NULL;
1554 } else
1555 head = tail = NULL;
1556 data->next = data->prev = NULL;
1557 }
1558 return data;
1559 }
1560
1561 template <class NODE_STRUCT>
add_last(NODE_STRUCT * data_ptr)1562 void omx_dl_list<NODE_STRUCT>::add_last(NODE_STRUCT* data_ptr)
1563 {
1564 if (data_ptr) {
1565 data_ptr->next = NULL;
1566 data_ptr->prev = tail;
1567 if (tail) {
1568 tail->next = data_ptr;
1569 tail = data_ptr;
1570 } else
1571 head = tail = data_ptr;
1572 }
1573 }
1574
1575 template <class NODE_STRUCT>
watch_first()1576 NODE_STRUCT* omx_dl_list<NODE_STRUCT>::watch_first()
1577 {
1578 return head;
1579 }
1580
1581 template <class NODE_STRUCT>
watch_last()1582 NODE_STRUCT* omx_dl_list<NODE_STRUCT>::watch_last()
1583 {
1584 return tail;
1585 }
1586
1587 #endif
1588