1e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly/*--------------------------------------------------------------------------
2826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan MalchevCopyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
3e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
4e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyRedistribution and use in source and binary forms, with or without
5e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pellymodification, are permitted provided that the following conditions are met:
6e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    * Redistributions of source code must retain the above copyright
7e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly      notice, this list of conditions and the following disclaimer.
8e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    * Redistributions in binary form must reproduce the above copyright
9e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly      notice, this list of conditions and the following disclaimer in the
10e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly      documentation and/or other materials provided with the distribution.
11e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    * Neither the name of Code Aurora nor
12e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly      the names of its contributors may be used to endorse or promote
13e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly      products derived from this software without specific prior written
14e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly      permission.
15e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
16e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyIMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyNON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyCONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyEXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyPROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyOR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyWHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyOTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly--------------------------------------------------------------------------*/
28e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly/*========================================================================
29e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
30e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly                      O p e n M M
31e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly         V i d e o   U t i l i t i e s
32e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
33e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly*//** @file VideoUtils.cpp
34e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  This module contains utilities and helper routines.
35e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
36e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly@par EXTERNALIZED FUNCTIONS
37e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
38e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly@par INITIALIZATION AND SEQUENCING REQUIREMENTS
39e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  (none)
40e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
41e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly*//*====================================================================== */
42e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
43e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly/* =======================================================================
44e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
45e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly                     INCLUDE FILES FOR MODULE
46e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
47e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly========================================================================== */
48e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly#include "h264_utils.h"
4940f34d83af63a67dfa16c98767e582c4a2b2fdecHaynes Mathew George#include "extra_data_handler.h"
50e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly#include <string.h>
51e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly#include <stdlib.h>
52826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#include <limits.h>
53826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#include <sys/time.h>
54826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#ifdef _ANDROID_
55826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#include <cutils/properties.h>
5640f34d83af63a67dfa16c98767e582c4a2b2fdecHaynes Mathew George    extern "C"{
5740f34d83af63a67dfa16c98767e582c4a2b2fdecHaynes Mathew George        #include<utils/Log.h>
5840f34d83af63a67dfa16c98767e582c4a2b2fdecHaynes Mathew George    }
5940f34d83af63a67dfa16c98767e582c4a2b2fdecHaynes Mathew George
60826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#endif
61e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
62e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly/* =======================================================================
63e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
64e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly                DEFINITIONS AND DECLARATIONS FOR MODULE
65e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
66e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyThis section contains definitions for constants, macros, types, variables
67e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pellyand other items needed by this module.
68e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
69e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly========================================================================== */
70e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
71e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly#define SIZE_NAL_FIELD_MAX  4
72e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly#define BASELINE_PROFILE 66
73e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly#define MAIN_PROFILE     77
74e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly#define HIGH_PROFILE     100
75e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
76e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly#define MAX_SUPPORTED_LEVEL 32
77e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
78e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyRbspParser::RbspParser (const uint8 *_begin, const uint8 *_end)
79e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly: begin (_begin), end(_end), pos (- 1), bit (0),
80e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pellycursor (0xFFFFFF), advanceNeeded (true)
81e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly{
82e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly}
83e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
84e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly// Destructor
85e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly/*lint -e{1540}  Pointer member neither freed nor zeroed by destructor
86e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly * No problem
87e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly */
88e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyRbspParser::~RbspParser () {}
89e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
90e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly// Return next RBSP byte as a word
91e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pellyuint32 RbspParser::next ()
92e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly{
93e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    if (advanceNeeded) advance ();
94e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    //return static_cast<uint32> (*pos);
95e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    return static_cast<uint32> (begin[pos]);
96e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly}
97e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
98e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly// Advance RBSP decoder to next byte
99e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pellyvoid RbspParser::advance ()
100e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly{
101e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    ++pos;
102e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    //if (pos >= stop)
103e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    if (begin + pos == end)
104e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    {
105e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        /*lint -e{730}  Boolean argument to function
106e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly         * I don't see a problem here
107e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly         */
108e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        //throw false;
109826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        ALOGV("H264Parser-->NEED TO THROW THE EXCEPTION...\n");
110e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    }
111e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    cursor <<= 8;
112e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    //cursor |= static_cast<uint32> (*pos);
113e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    cursor |= static_cast<uint32> (begin[pos]);
114e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    if ((cursor & 0xFFFFFF) == 0x000003)
115e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    {
116e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        advance ();
117e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    }
118e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    advanceNeeded = false;
119e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly}
120e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
121e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly// Decode unsigned integer
122e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pellyuint32 RbspParser::u (uint32 n)
123e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly{
124e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    uint32 i, s, x = 0;
125e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    for (i = 0; i < n; i += s)
126e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    {
127e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        s = static_cast<uint32>STD_MIN(static_cast<int>(8 - bit),
128e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly            static_cast<int>(n - i));
129e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        x <<= s;
130e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
131e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        x |= ((next () >> ((8 - static_cast<uint32>(bit)) - s)) &
132e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly            ((1 << s) - 1));
133e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
134e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        bit = (bit + s) % 8;
135e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        if (!bit)
136e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        {
137e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly            advanceNeeded = true;
138e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        }
139e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    }
140e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    return x;
141e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly}
142e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
143e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly// Decode unsigned integer Exp-Golomb-coded syntax element
144e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pellyuint32 RbspParser::ue ()
145e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly{
146e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    int leadingZeroBits = -1;
147e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    for (uint32 b = 0; !b; ++leadingZeroBits)
148e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    {
149e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        b = u (1);
150e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    }
151e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    return ((1 << leadingZeroBits) - 1) +
152e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        u (static_cast<uint32>(leadingZeroBits));
153e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly}
154e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
155e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly// Decode signed integer Exp-Golomb-coded syntax element
156e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pellyint32 RbspParser::se ()
157e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly{
158e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    const uint32 x = ue ();
159e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    if (!x) return 0;
160e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    else if (x & 1) return static_cast<int32> ((x >> 1) + 1);
161e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    else return - static_cast<int32> (x >> 1);
162e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly}
163e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
164e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pellyvoid H264_Utils::allocate_rbsp_buffer(uint32 inputBufferSize)
165e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly{
166e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    m_rbspBytes = (byte *) calloc(1,inputBufferSize);
167e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    m_prv_nalu.nal_ref_idc = 0;
168e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    m_prv_nalu.nalu_type = NALU_TYPE_UNSPECIFIED;
169e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly}
170e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
171e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyH264_Utils::H264_Utils(): m_height(0),
172e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly                          m_width(0),
173e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly                          m_rbspBytes(NULL),
174e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly                          m_au_data (false)
175e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly{
176e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    initialize_frame_checking_environment();
177e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly}
178e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
179e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyH264_Utils::~H264_Utils()
180e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly{
181e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly/*  if(m_pbits)
182e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  {
183e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    delete(m_pbits);
184e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    m_pbits = NULL;
185e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  }
186e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly*/
187e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  if (m_rbspBytes)
188e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  {
189e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    free(m_rbspBytes);
190e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    m_rbspBytes = NULL;
191e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  }
192e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly}
193e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
194e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly/***********************************************************************/
195e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly/*
196e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyFUNCTION:
197e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  H264_Utils::initialize_frame_checking_environment
198e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
199e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyDESCRIPTION:
200e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  Extract RBSP data from a NAL
201e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
202e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyINPUT/OUTPUT PARAMETERS:
203e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  None
204e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
205e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyRETURN VALUE:
206e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  boolean
207e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
208e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellySIDE EFFECTS:
209e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  None.
210e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly*/
211e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly/***********************************************************************/
212e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pellyvoid H264_Utils::initialize_frame_checking_environment()
213e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly{
214e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  m_forceToStichNextNAL = false;
215e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  m_au_data = false;
216e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  m_prv_nalu.nal_ref_idc = 0;
217e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  m_prv_nalu.nalu_type = NALU_TYPE_UNSPECIFIED;
218e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly}
219e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
220e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly/***********************************************************************/
221e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly/*
222e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyFUNCTION:
223e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  H264_Utils::extract_rbsp
224e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
225e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyDESCRIPTION:
226e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  Extract RBSP data from a NAL
227e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
228e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyINPUT/OUTPUT PARAMETERS:
229e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  <In>
230e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    buffer : buffer containing start code or nal length + NAL units
231e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    buffer_length : the length of the NAL buffer
232e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    start_code : If true, start code is detected,
233e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly                 otherwise size nal length is detected
234e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    size_of_nal_length_field: size of nal length field
235e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
236e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  <Out>
237e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    rbsp_bistream : extracted RBSP bistream
238e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    rbsp_length : the length of the RBSP bitstream
239e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    nal_unit : decoded NAL header information
240e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
241e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyRETURN VALUE:
242e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  boolean
243e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
244e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellySIDE EFFECTS:
245e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  None.
246e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly*/
247e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly/***********************************************************************/
248e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
249e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pellyboolean H264_Utils::extract_rbsp(OMX_IN   OMX_U8  *buffer,
250e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly                                 OMX_IN   OMX_U32 buffer_length,
251e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly                                 OMX_IN   OMX_U32 size_of_nal_length_field,
252e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly                                 OMX_OUT  OMX_U8  *rbsp_bistream,
253e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly                                 OMX_OUT  OMX_U32 *rbsp_length,
254e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly                                 OMX_OUT  NALU    *nal_unit)
255e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly{
256e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  byte coef1, coef2, coef3;
257e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  uint32 pos = 0;
258e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  uint32 nal_len = buffer_length;
259e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  uint32 sizeofNalLengthField = 0;
260e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  uint32 zero_count;
261e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  boolean eRet = true;
262e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  boolean start_code = (size_of_nal_length_field==0)?true:false;
263e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
264e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  if(start_code) {
265e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    // Search start_code_prefix_one_3bytes (0x000001)
266e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    coef2 = buffer[pos++];
267e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    coef3 = buffer[pos++];
268e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    do {
269e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly      if(pos >= buffer_length)
270e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly      {
271826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        ALOGE("ERROR: In %s() - line %d", __func__, __LINE__);
272e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        return false;
273e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly      }
274e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
275e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly      coef1 = coef2;
276e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly      coef2 = coef3;
277e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly      coef3 = buffer[pos++];
278e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    } while(coef1 || coef2 || coef3 != 1);
279e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  }
280e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  else if (size_of_nal_length_field)
281e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  {
282e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    /* This is the case to play multiple NAL units inside each access unit*/
283e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    /* Extract the NAL length depending on sizeOfNALength field */
284e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    sizeofNalLengthField = size_of_nal_length_field;
285e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    nal_len = 0;
286e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    while(size_of_nal_length_field--)
287e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    {
288e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly      nal_len |= buffer[pos++]<<(size_of_nal_length_field<<3);
289e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    }
290e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    if (nal_len >= buffer_length)
291e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    {
292826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      ALOGE("ERROR: In %s() - line %d", __func__, __LINE__);
293e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly      return false;
294e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    }
295e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  }
296e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
297e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  if (nal_len > buffer_length)
298e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  {
299826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGE("ERROR: In %s() - line %d", __func__, __LINE__);
300e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    return false;
301e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  }
302e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  if(pos + 1 > (nal_len + sizeofNalLengthField))
303e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  {
304826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGE("ERROR: In %s() - line %d", __func__, __LINE__);
305e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    return false;
306e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  }
307e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  if (nal_unit->forbidden_zero_bit = (buffer[pos] & 0x80))
308e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  {
309826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGE("ERROR: In %s() - line %d", __func__, __LINE__);
310e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  }
311e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  nal_unit->nal_ref_idc   = (buffer[pos] & 0x60) >> 5;
312e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  nal_unit->nalu_type = buffer[pos++] & 0x1f;
313826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("\n@#@# Pos = %x NalType = %x buflen = %d",
314826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      pos-1, nal_unit->nalu_type, buffer_length);
315e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  *rbsp_length = 0;
316e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
317e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
318e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  if( nal_unit->nalu_type == NALU_TYPE_EOSEQ ||
319e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly      nal_unit->nalu_type == NALU_TYPE_EOSTREAM)
320e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    return (nal_len + sizeofNalLengthField);
321e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
322e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  zero_count = 0;
323e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  while (pos < (nal_len+sizeofNalLengthField))    //similar to for in p-42
324e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly   {
325e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    if( zero_count == 2 ) {
326e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly      if( buffer[pos] == 0x03 ) {
327e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        pos ++;
328e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        zero_count = 0;
329e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        continue;
330e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly      }
331e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly      if( buffer[pos] <= 0x01 ) {
332e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        if( start_code ) {
333e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly          *rbsp_length -= 2;
334e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly          pos -= 2;
335e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly          return pos;
336e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        }
337e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly      }
338e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly      zero_count = 0;
339e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    }
340e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    zero_count ++;
341e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    if( buffer[pos] != 0 )
342e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly      zero_count = 0;
343e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
344e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    rbsp_bistream[(*rbsp_length)++] = buffer[pos++];
345e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  }
346e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
347e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  return eRet;
348e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly}
349e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
350e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly/*===========================================================================
351e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyFUNCTION:
352e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  H264_Utils::iSNewFrame
353e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
354e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyDESCRIPTION:
355e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  Returns true if NAL parsing successfull otherwise false.
356e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
357e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyINPUT/OUTPUT PARAMETERS:
358e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  <In>
359e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    buffer : buffer containing start code or nal length + NAL units
360e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    buffer_length : the length of the NAL buffer
361e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    start_code : If true, start code is detected,
362e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly                 otherwise size nal length is detected
363e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    size_of_nal_length_field: size of nal length field
364e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  <out>
365e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    isNewFrame: true if the NAL belongs to a differenet frame
366e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly                false if the NAL belongs to a current frame
367e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
368e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellyRETURN VALUE:
369e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  boolean  true, if nal parsing is successful
370e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly           false, if the nal parsing has errors
371e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
372e7273837b521d16f87dd5fb6eea3750a51ea92daNick PellySIDE EFFECTS:
373e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly  None.
374e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly===========================================================================*/
375826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevbool H264_Utils::isNewFrame(OMX_BUFFERHEADERTYPE *p_buf_hdr,
376e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly                            OMX_IN OMX_U32 size_of_nal_length_field,
377e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly                            OMX_OUT OMX_BOOL &isNewFrame)
378e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly{
379e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    NALU nal_unit;
380e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    uint16 first_mb_in_slice = 0;
38140f34d83af63a67dfa16c98767e582c4a2b2fdecHaynes Mathew George    OMX_IN OMX_U32 numBytesInRBSP = 0;
382826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    OMX_IN OMX_U8 *buffer = p_buf_hdr->pBuffer;
383826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    OMX_IN OMX_U32 buffer_length = p_buf_hdr->nFilledLen;
384e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    bool eRet = true;
385e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
386826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("isNewFrame: buffer %p buffer_length %d "
387826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        "size_of_nal_length_field %d\n", buffer, buffer_length,
388826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        size_of_nal_length_field);
389e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
390e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    if ( false == extract_rbsp(buffer, buffer_length, size_of_nal_length_field,
391e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly                               m_rbspBytes, &numBytesInRBSP, &nal_unit) )
392e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    {
393826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        ALOGE("ERROR: In %s() - extract_rbsp() failed", __func__);
394e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        isNewFrame = OMX_FALSE;
395e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        eRet = false;
396e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    }
397e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    else
398e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    {
399826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      nalu_type = nal_unit.nalu_type;
400e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly      switch (nal_unit.nalu_type)
401e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly      {
402e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        case NALU_TYPE_IDR:
403e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        case NALU_TYPE_NON_IDR:
404e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        {
405826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          ALOGV("\n AU Boundary with NAL type %d ",nal_unit.nalu_type);
406e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly          if (m_forceToStichNextNAL)
407e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly          {
408e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly            isNewFrame = OMX_FALSE;
409e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly          }
410e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly          else
411e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly          {
412e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly            RbspParser rbsp_parser(m_rbspBytes, (m_rbspBytes+numBytesInRBSP));
413e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly            first_mb_in_slice = rbsp_parser.ue();
414e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
415e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly            if((!first_mb_in_slice) || /*(slice.prv_frame_num != slice.frame_num ) ||*/
416e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly               ( (m_prv_nalu.nal_ref_idc != nal_unit.nal_ref_idc) && ( nal_unit.nal_ref_idc * m_prv_nalu.nal_ref_idc == 0 ) ) ||
417e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly               /*( ((m_prv_nalu.nalu_type == NALU_TYPE_IDR) && (nal_unit.nalu_type == NALU_TYPE_IDR)) && (slice.idr_pic_id != slice.prv_idr_pic_id) ) || */
418e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly               ( (m_prv_nalu.nalu_type != nal_unit.nalu_type ) && ((m_prv_nalu.nalu_type == NALU_TYPE_IDR) || (nal_unit.nalu_type == NALU_TYPE_IDR)) ) )
419e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly            {
420826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev              //ALOGV("Found a New Frame due to NALU_TYPE_IDR/NALU_TYPE_NON_IDR");
421e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly              isNewFrame = OMX_TRUE;
422e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly            }
423e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly            else
424e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly            {
425e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly              isNewFrame = OMX_FALSE;
426e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly            }
427e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly          }
428e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly          m_au_data = true;
429e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly          m_forceToStichNextNAL = false;
430e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly          break;
431e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        }
432e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        case NALU_TYPE_SPS:
433e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        case NALU_TYPE_PPS:
434e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        case NALU_TYPE_SEI:
435e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        {
436826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          ALOGV("\n Non-AU boundary with NAL type %d", nal_unit.nalu_type);
437e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly          if(m_au_data)
438e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly          {
439e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly            isNewFrame = OMX_TRUE;
440e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly            m_au_data = false;
441e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly          }
442e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly          else
443e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly          {
444e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly            isNewFrame =  OMX_FALSE;
445e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly          }
446e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly
447e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly          m_forceToStichNextNAL = true;
448e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly          break;
449e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        }
450e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        case NALU_TYPE_ACCESS_DELIM:
451826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        case NALU_TYPE_UNSPECIFIED:
452826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        case NALU_TYPE_EOSEQ:
453826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        case NALU_TYPE_EOSTREAM:
454e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        default:
455e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        {
456e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly          isNewFrame =  OMX_FALSE;
457e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly          // Do not update m_forceToStichNextNAL
458e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly          break;
459e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly        }
460e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly      } // end of switch
461e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    } // end of if
462e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    m_prv_nalu = nal_unit;
463826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("get_h264_nal_type - newFrame value %d\n",isNewFrame);
464e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly    return eRet;
465e7273837b521d16f87dd5fb6eea3750a51ea92daNick Pelly}
466826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
467826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid perf_metrics::start()
468826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
469826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (!active)
470826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
471826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    start_time = get_act_time();
472826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    active = true;
473826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
474826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
475826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
476826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid perf_metrics::stop()
477826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
478826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_U64 stop_time = get_act_time();
479826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (active)
480826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
481826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    proc_time += (stop_time - start_time);
482826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    active = false;
483826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
484826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
485826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
486826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid perf_metrics::end(OMX_U32 units_cntr)
487826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
488826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  stop();
489826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("--> Processing time : [%.2f] Sec", (float)proc_time / 1e6);
490826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (units_cntr)
491826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
492826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("--> Avrg proc time  : [%.2f] mSec", proc_time / (float)(units_cntr * 1e3));
493826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
494826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
495826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
496826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid perf_metrics::reset()
497826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
498826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  start_time = 0;
499826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  proc_time = 0;
500826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  active = false;
501826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
502826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
503826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan MalchevOMX_U64 perf_metrics::get_act_time()
504826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
505826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  struct timeval act_time = {0, 0};
506826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  gettimeofday(&act_time, NULL);
507826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  return (act_time.tv_usec + act_time.tv_sec * 1e6);
508826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
509826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
510826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan MalchevOMX_U64 perf_metrics::processing_time_us()
511826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
512826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  return proc_time;
513826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
514826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
515826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevh264_stream_parser::h264_stream_parser()
516826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
517826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  reset();
518826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#ifdef PANSCAN_HDLR
519826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  panscan_hdl = new panscan_handler();
520826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (!panscan_hdl)
521826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
522826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGE("ERROR: Panscan hdl was not allocated!");
523826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
524826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  else if (!panscan_hdl->initialize(10))
525826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
526826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGE("ERROR: Allocating memory for panscan!");
527826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    delete panscan_hdl;
528826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    panscan_hdl = NULL;
529826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
530826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#else
531826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  memset(&panscan_param, 0, sizeof(panscan_param));
532826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  panscan_param.rect_id = NO_PAN_SCAN_BIT;
533826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#endif
534826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
535826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
536826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevh264_stream_parser::~h264_stream_parser()
537826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
538826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#ifdef PANSCAN_HDLR
539826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (panscan_hdl)
540826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
541826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    delete panscan_hdl;
542826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    panscan_hdl = NULL;
543826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
544826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#endif
545826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
546826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
547826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid h264_stream_parser::reset()
548826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
549826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  curr_32_bit = 0;
550826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  bits_read = 0;
551826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  zero_cntr = 0;
552826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  emulation_code_skip_cntr = 0;
553826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  emulation_sc_enabled = true;
554826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  bitstream = NULL;
555826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  bitstream_bytes = 0;
556826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  memset(&vui_param, 0, sizeof(vui_param));
557826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  vui_param.fixed_fps_prev_ts = LLONG_MAX;
558826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  memset(&sei_buf_period, 0, sizeof(sei_buf_period));
559826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  memset(&sei_pic_timing, 0, sizeof(sei_pic_timing));
560826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  memset(&frame_packing_arrangement,0,sizeof(frame_packing_arrangement));
561826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  frame_packing_arrangement.cancel_flag = 1;
562826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  mbaff_flag = 0;
563826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
564826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
565826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid h264_stream_parser::init_bitstream(OMX_U8* data, OMX_U32 size)
566826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
567826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  bitstream = data;
568826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  bitstream_bytes = size;
569826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  curr_32_bit = 0;
570826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  bits_read = 0;
571826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  zero_cntr = 0;
572826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  emulation_code_skip_cntr = 0;
573826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
574826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
575826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid h264_stream_parser::parse_vui(bool vui_in_extradata)
576826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
577826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_U32 value = 0;
578826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("parse_vui: IN");
579826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (vui_in_extradata)
580826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    while (!extract_bits(1) && more_bits()); // Discard VUI enable flag
581826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (!more_bits())
582826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    return;
583826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
584826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  vui_param.aspect_ratio_info_present_flag = extract_bits(1); //aspect_ratio_info_present_flag
585826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (vui_param.aspect_ratio_info_present_flag)
586826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
587826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      ALOGV("Aspect Ratio Info present!");
588826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_info();
589826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
590826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
591826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (extract_bits(1)) //overscan_info_present_flag
592826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    extract_bits(1); //overscan_appropriate_flag
593826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (extract_bits(1)) //video_signal_type_present_flag
594826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
595826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    extract_bits(3); //video_format
596826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    extract_bits(1); //video_full_range_flag
597826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    if (extract_bits(1)) //colour_description_present_flag
598826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
599826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      extract_bits(8); //colour_primaries
600826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      extract_bits(8); //transfer_characteristics
601826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      extract_bits(8); //matrix_coefficients
602826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
603826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
604826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (extract_bits(1)) //chroma_location_info_present_flag
605826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
606826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    uev(); //chroma_sample_loc_type_top_field
607826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    uev(); //chroma_sample_loc_type_bottom_field
608826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
609826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  vui_param.timing_info_present_flag = extract_bits(1);
610826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (vui_param.timing_info_present_flag)
611826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
612826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    vui_param.num_units_in_tick = extract_bits(32);
613826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    vui_param.time_scale = extract_bits(32);
614826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    vui_param.fixed_frame_rate_flag = extract_bits(1);
615826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("Timing info present in VUI!");
616826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("  num units in tick  : %u", vui_param.num_units_in_tick);
617826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("  time scale         : %u", vui_param.time_scale);
618826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("  fixed frame rate   : %u", vui_param.fixed_frame_rate_flag);
619826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
620826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  vui_param.nal_hrd_parameters_present_flag = extract_bits(1);
621826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (vui_param.nal_hrd_parameters_present_flag)
622826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
623826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("nal hrd params present!");
624826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    hrd_parameters(&vui_param.nal_hrd_parameters);
625826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
626826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  vui_param.vcl_hrd_parameters_present_flag = extract_bits(1);
627826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (vui_param.vcl_hrd_parameters_present_flag)
628826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
629826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("vcl hrd params present!");
630826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    hrd_parameters(&vui_param.vcl_hrd_parameters);
631826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
632826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (vui_param.nal_hrd_parameters_present_flag ||
633826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      vui_param.vcl_hrd_parameters_present_flag)
634826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    vui_param.low_delay_hrd_flag = extract_bits(1);
635826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  vui_param.pic_struct_present_flag = extract_bits(1);
636826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("pic_struct_present_flag : %u", vui_param.pic_struct_present_flag);
637826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (extract_bits(1)) //bitstream_restriction_flag
638826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
639826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    extract_bits(1); //motion_vectors_over_pic_boundaries_flag
640826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    uev(); //max_bytes_per_pic_denom
641826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    uev(); //max_bits_per_mb_denom
642826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    uev(); //log2_max_mv_length_vertical
643826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    uev(); //log2_max_mv_length_horizontal
644826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    uev(); //num_reorder_frames
645826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    uev(); //max_dec_frame_buffering
646826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
647826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("parse_vui: OUT");
648826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
649826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
650826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid h264_stream_parser::aspect_ratio_info()
651826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
652826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("aspect_ratio_info: IN");
653826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_U32  aspect_ratio_idc = 0;
654826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_U32  aspect_ratio_x = 0;
655826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_U32  aspect_ratio_y = 0;
656826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  aspect_ratio_idc = extract_bits(8); //aspect_ratio_idc
657826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  switch (aspect_ratio_idc)
658826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
659826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    case 1:
660826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_x = 1;
661826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_y = 1;
662826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      break;
663826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    case 2:
664826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_x = 12;
665826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_y = 11;
666826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      break;
667826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    case 3:
668826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_x = 10;
669826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_y = 11;
670826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      break;
671826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    case 4:
672826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_x = 16;
673826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_y = 11;
674826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      break;
675826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    case 5:
676826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_x = 40;
677826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_y = 33;
678826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      break;
679826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    case 6:
680826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_x = 24;
681826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_y = 11;
682826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      break;
683826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    case 7:
684826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_x = 20;
685826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_y = 11;
686826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      break;
687826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    case 8:
688826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_x = 32;
689826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_y = 11;
690826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      break;
691826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    case 9:
692826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_x = 80;
693826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_y = 33;
694826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      break;
695826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    case 10:
696826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_x = 18;
697826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_y = 11;
698826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      break;
699826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    case 11:
700826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_x = 15;
701826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_y = 11;
702826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      break;
703826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    case 12:
704826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_x = 64;
705826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_y = 33;
706826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      break;
707826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    case 13:
708826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_x = 160;
709826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_y = 99;
710826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      break;
711826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    case 14:
712826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_x = 4;
713826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_y = 3;
714826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      break;
715826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    case 15:
716826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_x = 3;
717826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_y = 2;
718826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      break;
719826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    case 16:
720826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_x = 2;
721826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_y = 1;
722826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      break;
723826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    case 255:
724826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_x = extract_bits(16); //sar_width
725826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      aspect_ratio_y = extract_bits(16); //sar_height
726826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      break;
727826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    default:
728826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      ALOGV("-->aspect_ratio_idc: Reserved Value ");
729826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      break;
730826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
731826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("-->aspect_ratio_idc        : %u", aspect_ratio_idc);
732826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("-->aspect_ratio_x          : %u", aspect_ratio_x);
733826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("-->aspect_ratio_y          : %u", aspect_ratio_y);
734826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  vui_param.aspect_ratio_info.aspect_ratio_idc = aspect_ratio_idc;
735826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  vui_param.aspect_ratio_info.aspect_ratio_x = aspect_ratio_x;
736826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  vui_param.aspect_ratio_info.aspect_ratio_y = aspect_ratio_y;
737826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("aspect_ratio_info: OUT");
738826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
739826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
740826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid h264_stream_parser::hrd_parameters(h264_hrd_param *hrd_param)
741826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
742826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  int idx;
743826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("hrd_parameters: IN");
744826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  hrd_param->cpb_cnt = uev() + 1;
745826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  hrd_param->bit_rate_scale = extract_bits(4);
746826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  hrd_param->cpb_size_scale = extract_bits(4);
747826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("-->cpb_cnt        : %u", hrd_param->cpb_cnt);
748826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("-->bit_rate_scale : %u", hrd_param->bit_rate_scale);
749826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("-->cpb_size_scale : %u", hrd_param->cpb_size_scale);
750826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (hrd_param->cpb_cnt > MAX_CPB_COUNT)
751826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
752826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("ERROR: Invalid hrd_param->cpb_cnt [%u]!", hrd_param->cpb_cnt);
753826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    return;
754826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
755826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  for (idx = 0; idx < hrd_param->cpb_cnt && more_bits(); idx++)
756826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
757826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    hrd_param->bit_rate_value[idx] = uev() + 1;
758826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    hrd_param->cpb_size_value[idx] = uev() + 1;
759826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    hrd_param->cbr_flag[idx] = extract_bits(1);
760826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("-->bit_rate_value [%d] : %u", idx, hrd_param->bit_rate_value[idx]);
761826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("-->cpb_size_value [%d] : %u", idx, hrd_param->cpb_size_value[idx]);
762826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("-->cbr_flag       [%d] : %u", idx, hrd_param->cbr_flag[idx]);
763826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
764826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  hrd_param->initial_cpb_removal_delay_length = extract_bits(5) + 1;
765826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  hrd_param->cpb_removal_delay_length = extract_bits(5) + 1;
766826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  hrd_param->dpb_output_delay_length = extract_bits(5) + 1;
767826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  hrd_param->time_offset_length = extract_bits(5);
768826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("-->initial_cpb_removal_delay_length : %u", hrd_param->initial_cpb_removal_delay_length);
769826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("-->cpb_removal_delay_length         : %u", hrd_param->cpb_removal_delay_length);
770826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("-->dpb_output_delay_length          : %u", hrd_param->dpb_output_delay_length);
771826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("-->time_offset_length               : %u", hrd_param->time_offset_length);
772826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("hrd_parameters: OUT");
773826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
774826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
775826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid h264_stream_parser::parse_sei()
776826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
777826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_U32 value = 0, processed_bytes = 0;
778826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_U8 *sei_msg_start = bitstream;
779826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_U32 sei_unit_size = bitstream_bytes;
780826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("@@parse_sei: IN sei_unit_size(%u)", sei_unit_size);
781826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  while ((processed_bytes + 2) < sei_unit_size && more_bits())
782826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
783826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    init_bitstream(sei_msg_start + processed_bytes, sei_unit_size - processed_bytes);
784826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("-->NALU_TYPE_SEI");
785826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    OMX_U32 payload_type = 0, payload_size = 0, aux = 0;
786826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    do {
787826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      value = extract_bits(8);
788826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      payload_type += value;
789826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      processed_bytes++;
790826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    } while (value == 0xFF);
791826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("-->payload_type   : %u", payload_type);
792826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    do {
793826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      value = extract_bits(8);
794826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      payload_size += value;
795826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      processed_bytes++;
796826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    } while (value == 0xFF);
797826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("-->payload_size   : %u", payload_size);
798826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    if (payload_size > 0)
799826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
800826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      switch (payload_type)
801826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      {
802826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        case BUFFERING_PERIOD:
803826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          sei_buffering_period();
804826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        break;
805826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        case PIC_TIMING:
806826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          sei_picture_timing();
807826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        break;
808826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        case PAN_SCAN_RECT:
809826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          sei_pan_scan();
810826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        break;
811826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        case SEI_PAYLOAD_FRAME_PACKING_ARRANGEMENT:
812826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          parse_frame_pack();
813826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        break;
814826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        default:
815826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          ALOGV("-->SEI payload type [%u] not implemented! size[%u]", payload_type, payload_size);
816826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      }
817826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
818826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    processed_bytes += (payload_size + emulation_code_skip_cntr);
819826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("-->SEI processed_bytes[%u]", processed_bytes);
820826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
821826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("@@parse_sei: OUT");
822826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
823826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
824826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid h264_stream_parser::sei_buffering_period()
825826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
826826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  int idx;
827826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_U32 value = 0;
828826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  h264_hrd_param *hrd_param = NULL;
829826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("@@sei_buffering_period: IN");
830826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  value = uev(); // seq_parameter_set_id
831826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("-->seq_parameter_set_id : %u", value);
832826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (value > 31)
833826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
834826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("ERROR: Invalid seq_parameter_set_id [%u]!", value);
835826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    return;
836826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
837826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  sei_buf_period.is_valid = false;
838826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (vui_param.nal_hrd_parameters_present_flag)
839826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
840826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    hrd_param = &vui_param.nal_hrd_parameters;
841826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    if (hrd_param->cpb_cnt > MAX_CPB_COUNT)
842826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
843826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      ALOGV("ERROR: Invalid hrd_param->cpb_cnt [%u]!", hrd_param->cpb_cnt);
844826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      return;
845826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
846826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    for (idx = 0; idx < hrd_param->cpb_cnt ; idx++)
847826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
848826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      sei_buf_period.is_valid = true;
849826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      sei_buf_period.initial_cpb_removal_delay[idx] = extract_bits(hrd_param->initial_cpb_removal_delay_length);
850826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      sei_buf_period.initial_cpb_removal_delay_offset[idx] = extract_bits(hrd_param->initial_cpb_removal_delay_length);
851826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      ALOGV("-->initial_cpb_removal_delay        : %u", sei_buf_period.initial_cpb_removal_delay[idx]);
852826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      ALOGV("-->initial_cpb_removal_delay_offset : %u", sei_buf_period.initial_cpb_removal_delay_offset[idx]);
853826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
854826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
855826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (vui_param.vcl_hrd_parameters_present_flag)
856826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
857826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    hrd_param = &vui_param.vcl_hrd_parameters;
858826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    if (hrd_param->cpb_cnt > MAX_CPB_COUNT)
859826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
860826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      ALOGV("ERROR: Invalid hrd_param->cpb_cnt [%u]!", hrd_param->cpb_cnt);
861826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      return;
862826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
863826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    for (idx = 0; idx < hrd_param->cpb_cnt ; idx++)
864826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
865826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      sei_buf_period.is_valid = true;
866826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      sei_buf_period.initial_cpb_removal_delay[idx] = extract_bits(hrd_param->initial_cpb_removal_delay_length);
867826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      sei_buf_period.initial_cpb_removal_delay_offset[idx] = extract_bits(hrd_param->initial_cpb_removal_delay_length);
868826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      ALOGV("-->initial_cpb_removal_delay        : %u", sei_buf_period.initial_cpb_removal_delay[idx]);
869826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      ALOGV("-->initial_cpb_removal_delay_offset : %u", sei_buf_period.initial_cpb_removal_delay_offset[idx]);
870826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
871826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
872826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  sei_buf_period.au_cntr = 0;
873826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("@@sei_buffering_period: OUT");
874826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
875826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
876826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid h264_stream_parser::sei_picture_timing()
877826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
878826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("@@sei_picture_timing: IN");
879826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_U32 time_offset_len = 0, cpb_removal_len = 24, dpb_output_len  = 24;
880826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_U8 cbr_flag = 0;
881826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  sei_pic_timing.is_valid = true;
882826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (vui_param.nal_hrd_parameters_present_flag)
883826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
884826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    cpb_removal_len = vui_param.nal_hrd_parameters.cpb_removal_delay_length;
885826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    dpb_output_len = vui_param.nal_hrd_parameters.dpb_output_delay_length;
886826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    time_offset_len = vui_param.nal_hrd_parameters.time_offset_length;
887826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    cbr_flag = vui_param.nal_hrd_parameters.cbr_flag[0];
888826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
889826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  else if (vui_param.vcl_hrd_parameters_present_flag)
890826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
891826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    cpb_removal_len = vui_param.vcl_hrd_parameters.cpb_removal_delay_length;
892826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    dpb_output_len = vui_param.vcl_hrd_parameters.dpb_output_delay_length;
893826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    time_offset_len = vui_param.vcl_hrd_parameters.time_offset_length;
894826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    cbr_flag = vui_param.vcl_hrd_parameters.cbr_flag[0];
895826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
896826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  sei_pic_timing.cpb_removal_delay = extract_bits(cpb_removal_len);
897826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  sei_pic_timing.dpb_output_delay = extract_bits(dpb_output_len);
898826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("-->cpb_removal_len : %u", cpb_removal_len);
899826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("-->dpb_output_len  : %u", dpb_output_len);
900826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("-->cpb_removal_delay : %u", sei_pic_timing.cpb_removal_delay);
901826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("-->dpb_output_delay  : %u", sei_pic_timing.dpb_output_delay);
902826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (vui_param.pic_struct_present_flag)
903826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
904826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    sei_pic_timing.pic_struct = extract_bits(4);
905826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    sei_pic_timing.num_clock_ts = 0;
906826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    switch (sei_pic_timing.pic_struct)
907826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
908826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      case 0: case 1: case 2: sei_pic_timing.num_clock_ts = 1; break;
909826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      case 3: case 4: case 7: sei_pic_timing.num_clock_ts = 2; break;
910826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      case 5: case 6: case 8: sei_pic_timing.num_clock_ts = 3; break;
911826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      default:
912826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        ALOGE("sei_picture_timing: pic_struct invalid!");
913826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
914826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("-->num_clock_ts      : %u", sei_pic_timing.num_clock_ts);
915826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    for (int i = 0; i < sei_pic_timing.num_clock_ts && more_bits(); i++)
916826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
917826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      sei_pic_timing.clock_ts_flag = extract_bits(1);
918826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      if(sei_pic_timing.clock_ts_flag)
919826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      {
920826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        ALOGV("-->clock_timestamp present!");
921826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        sei_pic_timing.ct_type = extract_bits(2);
922826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        sei_pic_timing.nuit_field_based_flag = extract_bits(1);
923826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        sei_pic_timing.counting_type = extract_bits(5);
924826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        sei_pic_timing.full_timestamp_flag = extract_bits(1);
925826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        sei_pic_timing.discontinuity_flag = extract_bits(1);
926826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        sei_pic_timing.cnt_dropped_flag = extract_bits(1);
927826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        sei_pic_timing.n_frames = extract_bits(8);
928826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        ALOGV("-->f_timestamp_flg   : %u", sei_pic_timing.full_timestamp_flag);
929826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        ALOGV("-->n_frames          : %u", sei_pic_timing.n_frames);
930826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        sei_pic_timing.seconds_value = 0;
931826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        sei_pic_timing.minutes_value = 0;
932826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        sei_pic_timing.hours_value = 0;
933826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        if (sei_pic_timing.full_timestamp_flag)
934826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        {
935826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          sei_pic_timing.seconds_value = extract_bits(6);
936826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          sei_pic_timing.minutes_value = extract_bits(6);
937826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          sei_pic_timing.hours_value = extract_bits(5);
938826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        }
939826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        else if (extract_bits(1))
940826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        {
941826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          ALOGV("-->seconds_flag enabled!");
942826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          sei_pic_timing.seconds_value = extract_bits(6);
943826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          if (extract_bits(1))
944826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          {
945826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev            ALOGV("-->minutes_flag enabled!");
946826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev            sei_pic_timing.minutes_value = extract_bits(6);
947826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev            if (extract_bits(1))
948826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev            {
949826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev              ALOGV("-->hours_flag enabled!");
950826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev              sei_pic_timing.hours_value = extract_bits(5);
951826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev            }
952826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          }
953826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        }
954826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        sei_pic_timing.time_offset = 0;
955826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        if (time_offset_len > 0)
956826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          sei_pic_timing.time_offset = iv(time_offset_len);
957826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        ALOGV("-->seconds_value     : %u", sei_pic_timing.seconds_value);
958826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        ALOGV("-->minutes_value     : %u", sei_pic_timing.minutes_value);
959826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        ALOGV("-->hours_value       : %u", sei_pic_timing.hours_value);
960826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        ALOGV("-->time_offset       : %d", sei_pic_timing.time_offset);
961826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      }
962826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
963826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
964826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("@@sei_picture_timing: OUT");
965826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
966826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
967826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid h264_stream_parser::sei_pan_scan()
968826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
969826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#ifdef _ANDROID_
970826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  char property_value[PROPERTY_VALUE_MAX] = {0};
971826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_S32 enable_panscan_log = 0;
972826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  property_get("vidc.dec.debug.panframedata", property_value, "0");
973826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  enable_panscan_log = atoi(property_value);
974826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#endif
975826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#ifdef PANSCAN_HDLR
976826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  h264_pan_scan *pan_scan_param = panscan_hdl->get_free();
977826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#else
978826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  h264_pan_scan *pan_scan_param = &panscan_param;
979826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#endif
980826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
981826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (!pan_scan_param)
982826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
983826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGE("sei_pan_scan: ERROR: Invalid pointer!");
984826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    return;
985826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
986826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
987826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  pan_scan_param->rect_id = uev();
988826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (pan_scan_param->rect_id > 0xFF)
989826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
990826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGE("sei_pan_scan: ERROR: Invalid rect_id[%u]!", pan_scan_param->rect_id);
991826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    pan_scan_param->rect_id = NO_PAN_SCAN_BIT;
992826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    return;
993826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
994826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
995826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  pan_scan_param->rect_cancel_flag = extract_bits(1);
996826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
997826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (pan_scan_param->rect_cancel_flag)
998826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    pan_scan_param->rect_id = NO_PAN_SCAN_BIT;
999826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  else
1000826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1001826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    pan_scan_param->cnt = uev() + 1;
1002826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    if (pan_scan_param->cnt > MAX_PAN_SCAN_RECT)
1003826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
1004826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      ALOGE("sei_pan_scan: ERROR: Invalid num of rect [%u]!", pan_scan_param->cnt);
1005826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      pan_scan_param->rect_id = NO_PAN_SCAN_BIT;
1006826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      return;
1007826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
1008826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1009826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    for (int i = 0; i < pan_scan_param->cnt; i++)
1010826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
1011826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      pan_scan_param->rect_left_offset[i] = sev();
1012826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      pan_scan_param->rect_right_offset[i] = sev();
1013826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      pan_scan_param->rect_top_offset[i] = sev();
1014826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      pan_scan_param->rect_bottom_offset[i] = sev();
1015826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1016826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
1017826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    pan_scan_param->rect_repetition_period = uev();
1018826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#ifdef PANSCAN_HDLR
1019826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    if (pan_scan_param->rect_repetition_period > 1)
1020826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      // Repetition period is decreased by 2 each time panscan data is used
1021826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      pan_scan_param->rect_repetition_period *= 2;
1022826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#endif
1023826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#ifdef _ANDROID_
1024826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev     if (enable_panscan_log)
1025826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev     {
1026826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev       print_pan_data(pan_scan_param);
1027826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev     }
1028826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#endif
1029826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1030826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1031826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1032826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid h264_stream_parser::print_pan_data(h264_pan_scan *pan_scan_param)
1033826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1034826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("@@print_pan_data: IN");
1035826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1036826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("-->rect_id            : %u", pan_scan_param->rect_id);
1037826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("-->rect_cancel_flag   : %u", pan_scan_param->rect_cancel_flag);
1038826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1039826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("-->cnt                : %u", pan_scan_param->cnt);
1040826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1041826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  for (int i = 0; i < pan_scan_param->cnt; i++)
1042826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1043826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("-->rect_left_offset   : %d", pan_scan_param->rect_left_offset[i]);
1044826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("-->rect_right_offset  : %d", pan_scan_param->rect_right_offset[i]);
1045826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("-->rect_top_offset    : %d", pan_scan_param->rect_top_offset[i]);
1046826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("-->rect_bottom_offset : %d", pan_scan_param->rect_bottom_offset[i]);
1047826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1048826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("-->repetition_period  : %u", pan_scan_param->rect_repetition_period);
1049826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1050826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("@@print_pan_data: OUT");
1051826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1052826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1053826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid h264_stream_parser::parse_sps()
1054826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1055826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_U32 value = 0, scaling_matrix_limit;
1056826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("@@parse_sps: IN");
1057826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  value = extract_bits(8); //profile_idc
1058826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  extract_bits(8); //constraint flags and reserved bits
1059826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  extract_bits(8); //level_idc
1060826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  uev(); //sps id
1061826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (value == 100 || value == 110 || value == 122 || value == 244 ||
1062826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      value ==  44 || value ==  83 || value ==  86 || value == 118)
1063826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1064826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    if (uev() == 3) //chroma_format_idc
1065826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
1066826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      extract_bits(1); //separate_colour_plane_flag
1067826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      scaling_matrix_limit = 12;
1068826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
1069826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    else
1070826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      scaling_matrix_limit = 12;
1071826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    uev(); //bit_depth_luma_minus8
1072826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    uev(); //bit_depth_chroma_minus8
1073826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    extract_bits(1); //qpprime_y_zero_transform_bypass_flag
1074826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    if (extract_bits(1)) //seq_scaling_matrix_present_flag
1075826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      for (int i = 0; i < scaling_matrix_limit && more_bits(); i++)
1076826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      {
1077826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        if (extract_bits(1)) ////seq_scaling_list_present_flag[ i ]
1078826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          if (i < 6)
1079826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev            scaling_list(16);
1080826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          else
1081826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev            scaling_list(64);
1082826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      }
1083826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1084826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  uev(); //log2_max_frame_num_minus4
1085826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  value = uev(); //pic_order_cnt_type
1086826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (value == 0)
1087826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    uev(); //log2_max_pic_order_cnt_lsb_minus4
1088826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  else if (value == 1)
1089826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1090826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    extract_bits(1); //delta_pic_order_always_zero_flag
1091826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    sev(); //offset_for_non_ref_pic
1092826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    sev(); //offset_for_top_to_bottom_field
1093826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    value = uev(); // num_ref_frames_in_pic_order_cnt_cycle
1094826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    for (int i = 0; i < value; i++)
1095826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      sev(); //offset_for_ref_frame[ i ]
1096826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1097826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  uev(); //max_num_ref_frames
1098826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  extract_bits(1); //gaps_in_frame_num_value_allowed_flag
1099826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  value = uev(); //pic_width_in_mbs_minus1
1100826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  value = uev(); //pic_height_in_map_units_minus1
1101826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (!extract_bits(1)) //frame_mbs_only_flag
1102826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    mbaff_flag = extract_bits(1); //mb_adaptive_frame_field_flag
1103826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  extract_bits(1); //direct_8x8_inference_flag
1104826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (extract_bits(1)) //frame_cropping_flag
1105826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1106826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    uev(); //frame_crop_left_offset
1107826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    uev(); //frame_crop_right_offset
1108826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    uev(); //frame_crop_top_offset
1109826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    uev(); //frame_crop_bottom_offset
1110826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1111826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (extract_bits(1)) //vui_parameters_present_flag
1112826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    parse_vui(false);
1113826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("@@parse_sps: OUT");
1114826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1115826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1116826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid h264_stream_parser::scaling_list(OMX_U32 size_of_scaling_list)
1117826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1118826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_S32 last_scale = 8, next_scale = 8, delta_scale;
1119826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  for (int j = 0; j < size_of_scaling_list; j++)
1120826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1121826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    if (next_scale != 0)
1122826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
1123826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      delta_scale = sev();
1124826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      next_scale = (last_scale + delta_scale + 256) % 256;
1125826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
1126826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    last_scale = (next_scale == 0)? last_scale : next_scale;
1127826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1128826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1129826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1130826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan MalchevOMX_U32 h264_stream_parser::extract_bits(OMX_U32 n)
1131826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1132826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_U32 value = 0;
1133826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (n > 32)
1134826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1135826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGE("ERROR: extract_bits limit to 32 bits!");
1136826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    return value;
1137826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1138826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  value = curr_32_bit >> (32 - n);
1139826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (bits_read < n)
1140826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1141826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    n -= bits_read;
1142826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    read_word();
1143826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    value |= (curr_32_bit >> (32 - n));
1144826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    if (bits_read < n)
1145826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
1146826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      ALOGV("ERROR: extract_bits underflow!");
1147826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      value >>= (n - bits_read);
1148826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      n = bits_read;
1149826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
1150826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1151826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  bits_read -= n;
1152826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  curr_32_bit <<= n;
1153826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  return value;
1154826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1155826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1156826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid h264_stream_parser::read_word()
1157826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1158826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  curr_32_bit = 0;
1159826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  bits_read = 0;
1160826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  while (bitstream_bytes && bits_read < 32)
1161826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1162826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    if (*bitstream == EMULATION_PREVENTION_THREE_BYTE &&
1163826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        zero_cntr >= 2 && emulation_sc_enabled)
1164826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
1165826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      ALOGV("EMULATION_PREVENTION_THREE_BYTE: Skip 0x03 byte aligned!");
1166826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      emulation_code_skip_cntr++;
1167826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
1168826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    else
1169826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
1170826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      curr_32_bit <<= 8;
1171826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      curr_32_bit |= *bitstream;
1172826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      bits_read += 8;
1173826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
1174826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    if (*bitstream == 0)
1175826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      zero_cntr++;
1176826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    else
1177826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      zero_cntr = 0;
1178826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    bitstream++;
1179826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    bitstream_bytes--;
1180826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1181826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  curr_32_bit <<= (32 - bits_read);
1182826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1183826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1184826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan MalchevOMX_U32 h264_stream_parser::uev()
1185826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1186826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_U32 lead_zero_bits = 0, code_num = 0;
1187826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  while(!extract_bits(1) && more_bits())
1188826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    lead_zero_bits++;
1189826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  code_num = lead_zero_bits == 0 ? 0 :
1190826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    (1 << lead_zero_bits) - 1 + extract_bits(lead_zero_bits);
1191826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  return code_num;
1192826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1193826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1194826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevbool h264_stream_parser::more_bits()
1195826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1196826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  return (bitstream_bytes > 0 || bits_read > 0);
1197826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1198826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1199826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan MalchevOMX_S32 h264_stream_parser::sev()
1200826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1201826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_U32 code_num = uev();
1202826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_S32 ret;
1203826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ret = (code_num + 1) >> 1;
1204826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  return ((code_num & 1) ? ret : -ret);
1205826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1206826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1207826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan MalchevOMX_S32 h264_stream_parser::iv(OMX_U32 n_bits)
1208826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1209826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_U32 code_num = extract_bits(n_bits);
1210826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_S32 ret = (code_num >> (n_bits - 1))? (-1)*(~(code_num & ~(0x1 << (n_bits - 1))) + 1) : code_num;
1211826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  return ret;
1212826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1213826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1214826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan MalchevOMX_U32 h264_stream_parser::get_nal_unit_type(OMX_U32 *nal_unit_type)
1215826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1216826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_U32 value = 0, consumed_bytes = 3;
1217826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  *nal_unit_type = NALU_TYPE_UNSPECIFIED;
1218826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("-->get_nal_unit_type: IN");
1219826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  value = extract_bits(24);
1220826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  while (value != 0x00000001 && more_bits())
1221826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1222826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    value <<= 8;
1223826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    value |= extract_bits(8);
1224826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    consumed_bytes++;
1225826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1226826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (value != 0x00000001)
1227826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1228826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGE("ERROR in get_nal_unit_type: Start code not found!");
1229826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1230826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  else
1231826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1232826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    if (extract_bits(1)) // forbidden_zero_bit
1233826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
1234826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      ALOGE("WARNING: forbidden_zero_bit should be zero!");
1235826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
1236826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    value = extract_bits(2);
1237826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("-->nal_ref_idc    : %x", value);
1238826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    *nal_unit_type = extract_bits(5);
1239826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("-->nal_unit_type  : %x", *nal_unit_type);
1240826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    consumed_bytes++;
1241826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    if (consumed_bytes > 5)
1242826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
1243826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      ALOGE("-->WARNING: Startcode was found after the first 4 bytes!");
1244826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
1245826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1246826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("-->get_nal_unit_type: OUT");
1247826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  return consumed_bytes;
1248826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1249826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1250826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan MalchevOMX_S64 h264_stream_parser::calculate_buf_period_ts(OMX_S64 timestamp)
1251826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1252826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_S64 clock_ts = timestamp;
1253826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("calculate_ts(): IN");
1254826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (sei_buf_period.au_cntr == 0)
1255826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    clock_ts = sei_buf_period.reference_ts = timestamp;
1256826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  else if (sei_pic_timing.is_valid && VALID_TS(sei_buf_period.reference_ts))
1257826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1258826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    clock_ts = sei_buf_period.reference_ts + sei_pic_timing.cpb_removal_delay *
1259826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev               1e6 * vui_param.num_units_in_tick / vui_param.time_scale;
1260826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1261826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  sei_buf_period.au_cntr++;
1262826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("calculate_ts(): OUT");
1263826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  return clock_ts;
1264826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1265826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1266826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan MalchevOMX_S64 h264_stream_parser::calculate_fixed_fps_ts(OMX_S64 timestamp, OMX_U32 DeltaTfiDivisor)
1267826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1268826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (VALID_TS(timestamp))
1269826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    vui_param.fixed_fps_prev_ts = timestamp;
1270826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  else if (VALID_TS(vui_param.fixed_fps_prev_ts))
1271826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    vui_param.fixed_fps_prev_ts += DeltaTfiDivisor * 1e6 *
1272826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev                                   vui_param.num_units_in_tick / vui_param.time_scale;
1273826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  return vui_param.fixed_fps_prev_ts;
1274826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1275826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1276826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid h264_stream_parser::parse_frame_pack()
1277826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1278826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#ifdef _ANDROID_
1279826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  char property_value[PROPERTY_VALUE_MAX] = {0};
1280826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_S32 enable_framepack_log = 0;
1281826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1282826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  property_get("vidc.dec.debug.panframedata", property_value, "0");
1283826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  enable_framepack_log = atoi(property_value);
1284826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#endif
1285826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("\n%s:%d parse_frame_pack", __func__, __LINE__);
1286826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1287826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  frame_packing_arrangement.id = uev();
1288826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1289826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  frame_packing_arrangement.cancel_flag = extract_bits(1);
1290826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if(!frame_packing_arrangement.cancel_flag) {
1291826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev     frame_packing_arrangement.type = extract_bits(7);
1292826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev     frame_packing_arrangement.quincunx_sampling_flag = extract_bits(1);
1293826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev     frame_packing_arrangement.content_interpretation_type = extract_bits(6);
1294826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev     frame_packing_arrangement.spatial_flipping_flag = extract_bits(1);
1295826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev     frame_packing_arrangement.frame0_flipped_flag = extract_bits(1);
1296826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev     frame_packing_arrangement.field_views_flag = extract_bits(1);
1297826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev     frame_packing_arrangement.current_frame_is_frame0_flag = extract_bits(1);
1298826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev     frame_packing_arrangement.frame0_self_contained_flag = extract_bits(1);
1299826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev     frame_packing_arrangement.frame1_self_contained_flag = extract_bits(1);
1300826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1301826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev     if(!frame_packing_arrangement.quincunx_sampling_flag &&
1302826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        frame_packing_arrangement.type != 5) {
1303826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        frame_packing_arrangement.frame0_grid_position_x = extract_bits(4);
1304826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        frame_packing_arrangement.frame0_grid_position_y = extract_bits(4);
1305826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        frame_packing_arrangement.frame1_grid_position_x = extract_bits(4);
1306826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        frame_packing_arrangement.frame1_grid_position_y = extract_bits(4);
1307826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev     }
1308826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev     frame_packing_arrangement.reserved_byte = extract_bits(8);
1309826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev     frame_packing_arrangement.repetition_period = uev();
1310826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev   }
1311826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev   frame_packing_arrangement.extension_flag = extract_bits(1);
1312826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1313826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#ifdef _ANDROID_
1314826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev   if (enable_framepack_log)
1315826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev   {
1316826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev     print_frame_pack();
1317826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev   }
1318826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#endif
1319826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1320826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1321826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid h264_stream_parser::print_frame_pack()
1322826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1323826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("\n ## frame_packing_arrangement.id = %u", frame_packing_arrangement.id);
1324826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("\n ## frame_packing_arrangement.cancel_flag = %u",
1325826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev                       frame_packing_arrangement.cancel_flag);
1326826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if(!frame_packing_arrangement.cancel_flag)
1327826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1328826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("\n ## frame_packing_arrangement.type = %u",
1329826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev                         frame_packing_arrangement.type);
1330826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("\n ## frame_packing_arrangement.quincunx_sampling_flag = %u",
1331826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev                         frame_packing_arrangement.quincunx_sampling_flag);
1332826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("\n ## frame_packing_arrangement.content_interpretation_type = %u",
1333826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev                         frame_packing_arrangement.content_interpretation_type);
1334826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("\n ## frame_packing_arrangement.spatial_flipping_flag = %u",
1335826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev                         frame_packing_arrangement.spatial_flipping_flag);
1336826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("\n ## frame_packing_arrangement.frame0_flipped_flag = %u",
1337826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev                         frame_packing_arrangement.frame0_flipped_flag);
1338826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("\n ## frame_packing_arrangement.field_views_flag = %u",
1339826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev                         frame_packing_arrangement.field_views_flag);
1340826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("\n ## frame_packing_arrangement.current_frame_is_frame0_flag = %u",
1341826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev                         frame_packing_arrangement.current_frame_is_frame0_flag);
1342826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("\n ## frame_packing_arrangement.frame0_self_contained_flag = %u",
1343826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev                         frame_packing_arrangement.frame0_self_contained_flag);
1344826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("\n ## frame_packing_arrangement.frame1_self_contained_flag = %u",
1345826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev                         frame_packing_arrangement.frame1_self_contained_flag);
1346826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("\n ## frame_packing_arrangement.reserved_byte = %u",
1347826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev                         frame_packing_arrangement.reserved_byte);
1348826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("\n ## frame_packing_arrangement.repetition_period = %u",
1349826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev                         frame_packing_arrangement.repetition_period);
1350826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("\n ## frame_packing_arrangement.extension_flag = %u",
1351826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev                         frame_packing_arrangement.extension_flag);
1352826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1353826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1354826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev/* API'S EXPOSED TO OMX COMPONENT */
1355826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1356826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid h264_stream_parser::get_frame_pack_data(
1357826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_QCOM_FRAME_PACK_ARRANGEMENT *frame_pack)
1358826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1359826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev   ALOGV("\n%s:%d get frame data", __func__, __LINE__);
1360826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev   memcpy(&frame_pack->id,&frame_packing_arrangement.id,
1361826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev   FRAME_PACK_SIZE*sizeof(OMX_U32));
1362826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev   return;
1363826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1364826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1365826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1366826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevbool h264_stream_parser::is_mbaff()
1367826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1368826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev   ALOGV("\n%s:%d MBAFF flag=%d", __func__, __LINE__,mbaff_flag);
1369826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev   return mbaff_flag;
1370826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1371826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1372826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid h264_stream_parser::get_frame_rate(OMX_U32 *frame_rate)
1373826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1374826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (vui_param.num_units_in_tick != 0)
1375826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    *frame_rate = vui_param.time_scale / (2 * vui_param.num_units_in_tick);
1376826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1377826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1378826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid h264_stream_parser::parse_nal(OMX_U8* data_ptr, OMX_U32 data_len, OMX_U32 nal_type, bool enable_emu_sc)
1379826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1380826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_U32 nal_unit_type = NALU_TYPE_UNSPECIFIED, cons_bytes = 0;
1381826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("parse_nal(): IN nal_type(%lu)", nal_type);
1382826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (!data_len)
1383826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    return;
1384826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  init_bitstream(data_ptr, data_len);
1385826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  emulation_sc_enabled = enable_emu_sc;
1386826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (nal_type != NALU_TYPE_VUI)
1387826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1388826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    cons_bytes = get_nal_unit_type(&nal_unit_type);
1389826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    if (nal_type != nal_unit_type && nal_type != NALU_TYPE_UNSPECIFIED)
1390826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
1391826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      ALOGV("Unexpected nal_type(%x) expected(%x)", nal_unit_type, nal_type);
1392826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      return;
1393826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
1394826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1395826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  switch (nal_type)
1396826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1397826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    case NALU_TYPE_SPS:
1398826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      if (more_bits())
1399826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        parse_sps();
1400826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#ifdef PANSCAN_HDLR
1401826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      panscan_hdl->get_free();
1402826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#endif
1403826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    break;
1404826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    case NALU_TYPE_SEI:
1405826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      init_bitstream(data_ptr + cons_bytes, data_len - cons_bytes);
1406826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      parse_sei();
1407826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    break;
1408826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    case NALU_TYPE_VUI:
1409826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      parse_vui(true);
1410826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    break;
1411826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    default:
1412826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      ALOGV("nal_unit_type received : %lu", nal_type);
1413826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1414826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  ALOGV("parse_nal(): OUT");
1415826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1416826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1417826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#ifdef PANSCAN_HDLR
1418826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid h264_stream_parser::update_panscan_data(OMX_S64 timestamp)
1419826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1420826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  panscan_hdl->update_last(timestamp);
1421826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1422826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#endif
1423826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1424826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid h264_stream_parser::fill_aspect_ratio_info(OMX_QCOM_ASPECT_RATIO *dest_aspect_ratio)
1425826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1426826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if(dest_aspect_ratio && vui_param.aspect_ratio_info_present_flag)
1427826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1428826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    dest_aspect_ratio->aspectRatioX = vui_param.aspect_ratio_info.aspect_ratio_x;
1429826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    dest_aspect_ratio->aspectRatioY = vui_param.aspect_ratio_info.aspect_ratio_y;
1430826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1431826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1432826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1433826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid h264_stream_parser::fill_pan_scan_data(OMX_QCOM_PANSCAN *dest_pan_scan, OMX_S64 timestamp)
1434826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1435826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#ifdef PANSCAN_HDLR
1436826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  h264_pan_scan *pan_scan_param = panscan_hdl->get_populated(timestamp);
1437826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#else
1438826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  h264_pan_scan *pan_scan_param = &panscan_param;
1439826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#endif
1440826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (pan_scan_param)
1441826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    if (!(pan_scan_param->rect_id & NO_PAN_SCAN_BIT))
1442826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
1443826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      PRINT_PANSCAN_PARAM(*pan_scan_param);
1444826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      dest_pan_scan->numWindows = pan_scan_param->cnt;
1445826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      for (int i = 0; i < dest_pan_scan->numWindows; i++)
1446826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      {
1447826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        dest_pan_scan->window[i].x = pan_scan_param->rect_left_offset[i];
1448826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        dest_pan_scan->window[i].y = pan_scan_param->rect_top_offset[i];
1449826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        dest_pan_scan->window[i].dx = pan_scan_param->rect_right_offset[i];
1450826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        dest_pan_scan->window[i].dy = pan_scan_param->rect_bottom_offset[i];
1451826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      }
1452826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#ifndef PANSCAN_HDLR
1453826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      if (pan_scan_param->rect_repetition_period == 0)
1454826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        pan_scan_param->rect_id = NO_PAN_SCAN_BIT;
1455826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      else if (pan_scan_param->rect_repetition_period > 1)
1456826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        pan_scan_param->rect_repetition_period =
1457826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        (pan_scan_param->rect_repetition_period == 2)? 0 :
1458826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        (pan_scan_param->rect_repetition_period - 1);
1459826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#endif
1460826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
1461826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    else
1462826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      pan_scan_param->rect_repetition_period = 0;
1463826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1464826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1465826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan MalchevOMX_S64 h264_stream_parser::process_ts_with_sei_vui(OMX_S64 timestamp)
1466826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1467826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  bool clock_ts_flag = false;
1468826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_S64 clock_ts = timestamp;
1469826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  OMX_U32 deltaTfiDivisor = 2;
1470826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (vui_param.timing_info_present_flag)
1471826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1472826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    if (vui_param.pic_struct_present_flag)
1473826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
1474826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      if(sei_pic_timing.clock_ts_flag)
1475826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      {
1476826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        clock_ts = ((sei_pic_timing.hours_value * 60 + sei_pic_timing.minutes_value) * 60 + sei_pic_timing.seconds_value) * 1e6 +
1477826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev                    (sei_pic_timing.n_frames * (vui_param.num_units_in_tick * (1 + sei_pic_timing.nuit_field_based_flag)) + sei_pic_timing.time_offset) *
1478826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev                    1e6 / vui_param.time_scale;
1479826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        ALOGV("-->CLOCK TIMESTAMP   : %lld", clock_ts);
1480826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        clock_ts_flag = true;
1481826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      }
1482826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      if (vui_param.fixed_frame_rate_flag)
1483826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      {
1484826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        switch (sei_pic_timing.pic_struct)
1485826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        {
1486826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          case 1: case 2:         deltaTfiDivisor = 1; break;
1487826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          case 0: case 3: case 4: deltaTfiDivisor = 2; break;
1488826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          case 5: case 6:         deltaTfiDivisor = 3; break;
1489826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          case 7:                 deltaTfiDivisor = 4; break;
1490826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          case 8:                 deltaTfiDivisor = 6; break;
1491826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          default:
1492826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev            ALOGE("process_ts_with_sei_vui: pic_struct invalid!");
1493826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        }
1494826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      }
1495826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
1496826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    if (!clock_ts_flag)
1497826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
1498826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      if (vui_param.fixed_frame_rate_flag)
1499826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        clock_ts = calculate_fixed_fps_ts(timestamp, deltaTfiDivisor);
1500826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      else if (sei_buf_period.is_valid)
1501826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        clock_ts = calculate_buf_period_ts(timestamp);
1502826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
1503826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1504826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  else
1505826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1506826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGV("NO TIMING information present in VUI!");
1507826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1508826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  sei_pic_timing.is_valid = false; // SEI data is valid only for current frame
1509826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  return clock_ts;
1510826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1511826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1512826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#ifdef PANSCAN_HDLR
1513826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1514826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevpanscan_handler::panscan_handler() : panscan_data(NULL) {}
1515826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1516826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevpanscan_handler::~panscan_handler()
1517826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1518826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (panscan_data)
1519826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1520826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    free(panscan_data);
1521826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    panscan_data = NULL;
1522826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1523826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1524826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1525826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevbool panscan_handler::initialize(int num_data)
1526826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1527826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  bool ret = false;
1528826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (!panscan_data)
1529826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1530826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    panscan_data = (PANSCAN_NODE *) malloc (sizeof(PANSCAN_NODE) * num_data);
1531826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    if (panscan_data)
1532826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
1533826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      panscan_free.add_multiple(panscan_data, num_data);
1534826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      ret = true;
1535826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
1536826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1537826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  else
1538826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1539826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    ALOGE("ERROR: Old panscan memory must be freed to allocate new");
1540826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1541826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  return ret;
1542826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1543826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1544826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevh264_pan_scan *panscan_handler::get_free()
1545826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1546826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  h264_pan_scan *data = NULL;
1547826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  PANSCAN_NODE *panscan_node = panscan_used.watch_last();
1548826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  panscan_node = (!panscan_node || VALID_TS(panscan_node->start_ts))?
1549826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev                 panscan_free.remove_first() :
1550826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev                 panscan_used.remove_last();
1551826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (panscan_node)
1552826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1553826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    panscan_node->start_ts = LLONG_MAX;
1554826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    panscan_node->end_ts = LLONG_MAX;
1555826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    panscan_node->pan_scan_param.rect_id = NO_PAN_SCAN_BIT;
1556826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    panscan_node->active = false;
1557826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    panscan_used.add_last(panscan_node);
1558826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    data = &panscan_node->pan_scan_param;
1559826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1560826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  return data;
1561826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1562826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1563826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevh264_pan_scan *panscan_handler::get_populated(OMX_S64 frame_ts)
1564826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1565826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  h264_pan_scan *data = NULL;
1566826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  PANSCAN_NODE *panscan_node = panscan_used.watch_first();
1567826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  while (panscan_node && !data)
1568826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1569826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    if (VALID_TS(panscan_node->start_ts))
1570826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
1571826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      if (panscan_node->active && frame_ts < panscan_node->start_ts)
1572826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        panscan_node->start_ts = frame_ts;
1573826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      if (frame_ts >= panscan_node->start_ts)
1574826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        if (frame_ts < panscan_node->end_ts)
1575826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        {
1576826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          data = &panscan_node->pan_scan_param;
1577826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          panscan_node->active = true;
1578826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        }
1579826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        else
1580826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        {
1581826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          panscan_free.add_last(panscan_used.remove_first());
1582826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev          panscan_node = panscan_used.watch_first();
1583826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        }
1584826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      else
1585826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        // Finish search if current timestamp has not reached
1586826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        // start timestamp of first panscan data.
1587826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        panscan_node = NULL;
1588826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
1589826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    else
1590826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
1591826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      // Only one panscan data is stored for clips
1592826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      // with invalid timestamps in every frame
1593826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      data = &panscan_node->pan_scan_param;
1594826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      panscan_node->active = true;
1595826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
1596826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1597826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (data)
1598826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    if (data->rect_repetition_period == 0)
1599826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      panscan_free.add_last(panscan_used.remove_first());
1600826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    else if (data->rect_repetition_period > 1)
1601826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      data->rect_repetition_period -= 2;
1602826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  PRINT_PANSCAN_DATA(panscan_node);
1603826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  return data;
1604826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1605826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1606826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid panscan_handler::update_last(OMX_S64 frame_ts)
1607826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1608826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  PANSCAN_NODE *panscan_node = panscan_used.watch_last();
1609826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (panscan_node && !VALID_TS(panscan_node->start_ts))
1610826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1611826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    panscan_node->start_ts = frame_ts;
1612826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    PRINT_PANSCAN_DATA(panscan_node);
1613826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    if (panscan_node->prev)
1614826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
1615826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      if (frame_ts < panscan_node->prev->end_ts)
1616826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        panscan_node->prev->end_ts = frame_ts;
1617826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      else if (!VALID_TS(frame_ts))
1618826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev        panscan_node->prev->pan_scan_param.rect_repetition_period = 0;
1619826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      PRINT_PANSCAN_DATA(panscan_node->prev);
1620826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
1621826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1622826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1623826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1624826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevtemplate <class NODE_STRUCT>
1625826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid omx_dl_list<NODE_STRUCT>::add_multiple(NODE_STRUCT *data_arr, int data_num)
1626826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1627826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  for (int idx = 0; idx < data_num; idx++)
1628826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    add_last(&data_arr[idx]);
1629826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1630826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1631826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevtemplate <class NODE_STRUCT>
1632826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan MalchevNODE_STRUCT *omx_dl_list<NODE_STRUCT>::remove_first()
1633826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1634826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  NODE_STRUCT *data = head;
1635826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (head)
1636826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1637826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    if (head->next)
1638826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
1639826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      head = head->next;
1640826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      head->prev = NULL;
1641826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
1642826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    else
1643826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      head = tail = NULL;
1644826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    data->next = data->prev = NULL;
1645826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1646826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  return data;
1647826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1648826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1649826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevtemplate <class NODE_STRUCT>
1650826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan MalchevNODE_STRUCT *omx_dl_list<NODE_STRUCT>::remove_last()
1651826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1652826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  NODE_STRUCT *data = tail;
1653826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (tail)
1654826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1655826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    if (tail->prev)
1656826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
1657826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      tail = tail->prev;
1658826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      tail->next = NULL;
1659826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
1660826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    else
1661826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      head = tail = NULL;
1662826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    data->next = data->prev = NULL;
1663826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1664826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  return data;
1665826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1666826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1667826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevtemplate <class NODE_STRUCT>
1668826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevvoid omx_dl_list<NODE_STRUCT>::add_last(NODE_STRUCT* data_ptr)
1669826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1670826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  if (data_ptr)
1671826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  {
1672826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    data_ptr->next = NULL;
1673826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    data_ptr->prev = tail;
1674826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    if (tail)
1675826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    {
1676826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      tail->next = data_ptr;
1677826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      tail = data_ptr;
1678826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    }
1679826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev    else
1680826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev      head = tail = data_ptr;
1681826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  }
1682826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1683826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1684826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevtemplate <class NODE_STRUCT>
1685826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan MalchevNODE_STRUCT* omx_dl_list<NODE_STRUCT>::watch_first()
1686826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1687826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  return head;
1688826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1689826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1690826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchevtemplate <class NODE_STRUCT>
1691826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan MalchevNODE_STRUCT* omx_dl_list<NODE_STRUCT>::watch_last()
1692826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev{
1693826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev  return tail;
1694826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev}
1695826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev
1696826ececcbea342f7a0b92ec61847f1c95d384e05Iliyan Malchev#endif
1697