hevc_utils.cpp revision 6eec4d1ea65df853450a6e158718981cba900bf6
1/*--------------------------------------------------------------------------
2Copyright (c) 2013, The Linux Foundation. All rights reserved.
3
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions are met:
6    * Redistributions of source code must retain the above copyright
7      notice, this list of conditions and the following disclaimer.
8    * Redistributions in binary form must reproduce the above copyright
9      notice, this list of conditions and the following disclaimer in the
10      documentation and/or other materials provided with the distribution.
11    * Neither the name of The Linux Foundation nor
12      the names of its contributors may be used to endorse or promote
13      products derived from this software without specific prior written
14      permission.
15
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27--------------------------------------------------------------------------*/
28
29/*========================================================================
30
31                      O p e n M M
32         V i d e o   U t i l i t i e s
33
34*//** @file VideoUtils.cpp
35  This module contains utilities and helper routines.
36
37@par EXTERNALIZED FUNCTIONS
38
39@par INITIALIZATION AND SEQUENCING REQUIREMENTS
40  (none)
41
42*//*====================================================================== */
43
44/* =======================================================================
45
46                     INCLUDE FILES FOR MODULE
47
48========================================================================== */
49#include "hevc_utils.h"
50#include <string.h>
51#include <stdlib.h>
52#include <limits.h>
53#include <sys/time.h>
54#ifdef _ANDROID_
55#include <cutils/properties.h>
56#endif
57
58#define DEBUG_PRINT_LOW ALOGV
59#define DEBUG_PRINT_ERROR ALOGE
60
61
62/* =======================================================================
63
64                DEFINITIONS AND DECLARATIONS FOR MODULE
65
66This section contains definitions for constants, macros, types, variables
67and other items needed by this module.
68
69========================================================================== */
70
71HEVC_Utils::HEVC_Utils()
72{
73	initialize_frame_checking_environment();
74}
75
76HEVC_Utils::~HEVC_Utils()
77{
78}
79
80/***********************************************************************/
81/*
82FUNCTION:
83  HEVC_Utils::initialize_frame_checking_environment
84
85DESCRIPTION:
86  Extract RBSP data from a NAL
87
88INPUT/OUTPUT PARAMETERS:
89  None
90
91RETURN VALUE:
92  boolean
93
94SIDE EFFECTS:
95  None.
96*/
97/***********************************************************************/
98void HEVC_Utils::initialize_frame_checking_environment()
99{
100	m_forceToStichNextNAL = false;
101	m_au_data = false;
102	nalu_type = NAL_UNIT_INVALID;
103}
104
105/*===========================================================================
106FUNCTION:
107  HEVC_Utils::iSNewFrame
108
109DESCRIPTION:
110  Returns true if NAL parsing successfull otherwise false.
111
112INPUT/OUTPUT PARAMETERS:
113  <In>
114    buffer : buffer containing start code or nal length + NAL units
115    buffer_length : the length of the NAL buffer
116    start_code : If true, start code is detected,
117                 otherwise size nal length is detected
118    size_of_nal_length_field: size of nal length field
119  <out>
120    isNewFrame: true if the NAL belongs to a differenet frame
121                false if the NAL belongs to a current frame
122
123RETURN VALUE:
124  boolean  true, if nal parsing is successful
125           false, if the nal parsing has errors
126
127SIDE EFFECTS:
128  None.
129===========================================================================*/
130bool HEVC_Utils::isNewFrame(OMX_BUFFERHEADERTYPE *p_buf_hdr,
131                            OMX_IN OMX_U32 size_of_nal_length_field,
132                            OMX_OUT OMX_BOOL &isNewFrame)
133{
134	OMX_IN OMX_U8 *buffer = p_buf_hdr->pBuffer;
135	OMX_IN OMX_U32 buffer_length = p_buf_hdr->nFilledLen;
136	byte bFirstSliceInPic = 0;
137
138	byte coef1=1, coef2=0, coef3=0;
139	uint32 pos = 0;
140	uint32 nal_len = buffer_length;
141	uint32 sizeofNalLengthField = 0;
142	uint32 zero_count;
143	boolean start_code = (size_of_nal_length_field==0)?true:false;
144
145	if(start_code) {
146	  // Search start_code_prefix_one_3bytes (0x000001)
147	  coef2 = buffer[pos++];
148	  coef3 = buffer[pos++];
149	  do {
150		if(pos >= buffer_length)
151		{
152		  DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__);
153		  return false;
154		}
155
156		coef1 = coef2;
157		coef2 = coef3;
158		coef3 = buffer[pos++];
159	  } while(coef1 || coef2 || coef3 != 1);
160	}
161	else if (size_of_nal_length_field)
162	{
163	  /* This is the case to play multiple NAL units inside each access unit*/
164	  /* Extract the NAL length depending on sizeOfNALength field */
165	  sizeofNalLengthField = size_of_nal_length_field;
166	  nal_len = 0;
167	  while(size_of_nal_length_field--)
168	  {
169		nal_len |= buffer[pos++]<<(size_of_nal_length_field<<3);
170	  }
171	  if (nal_len >= buffer_length)
172	  {
173		DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__);
174		return false;
175	  }
176	}
177
178	if (nal_len > buffer_length)
179	{
180	  DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__);
181	  return false;
182	}
183
184	if(pos + 2 > (nal_len + sizeofNalLengthField))
185	{
186	  DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__);
187	  return false;
188	}
189
190	nalu_type = (buffer[pos] & 0x7E)>>1 ;	  //=== nal_unit_type
191
192	DEBUG_PRINT_LOW("\n@#@# Pos = %x NalType = %x buflen = %d", pos-1, nalu_type, buffer_length);
193
194	isNewFrame =  OMX_FALSE;
195
196	if (nalu_type == NAL_UNIT_VPS ||
197		nalu_type == NAL_UNIT_SPS ||
198		nalu_type == NAL_UNIT_PPS ||
199		nalu_type == NAL_UNIT_SEI)
200	{
201	  	DEBUG_PRINT_LOW("\n Non-AU boundary with NAL type %d", nalu_type);
202		if(m_au_data)
203		{
204			isNewFrame = OMX_TRUE;
205			m_au_data = false;
206		}
207
208		m_forceToStichNextNAL = true;
209	}
210	else if (nalu_type <= NAL_UNIT_RESERVED_23)
211	{
212		DEBUG_PRINT_LOW("\n AU Boundary with NAL type %d ",nal_unit.nalu_type);
213		if (!m_forceToStichNextNAL)
214		{
215			bFirstSliceInPic = ((buffer[pos+2] & 0x80)>>7);
216			if (bFirstSliceInPic)	//=== first_ctb_in_slice is only 1'b1  coded tree block
217			{
218				DEBUG_PRINT_LOW("Found a New Frame due to 1st coded tree block");
219				isNewFrame = OMX_TRUE;
220			}
221		}
222		m_au_data = true;
223		m_forceToStichNextNAL = false;
224	}
225	DEBUG_PRINT_LOW("get_HEVC_nal_type - newFrame value %d\n",isNewFrame);
226	return true;
227}
228
229