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