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