• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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