1 /*--------------------------------------------------------------------------
2 Copyright (c) 2013, The Linux Foundation. All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
6 * Redistributions of source code must retain the above copyright
7 notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above copyright
9 notice, this list of conditions and the following disclaimer in the
10 documentation and/or other materials provided with the distribution.
11 * Neither the name of 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
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 --------------------------------------------------------------------------*/
28
29 /*========================================================================
30
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
66 This section contains definitions for constants, macros, types, variables
67 and other items needed by this module.
68
69 ========================================================================== */
70
HEVC_Utils()71 HEVC_Utils::HEVC_Utils()
72 {
73 initialize_frame_checking_environment();
74 }
75
~HEVC_Utils()76 HEVC_Utils::~HEVC_Utils()
77 {
78 }
79
80 /***********************************************************************/
81 /*
82 FUNCTION:
83 HEVC_Utils::initialize_frame_checking_environment
84
85 DESCRIPTION:
86 Extract RBSP data from a NAL
87
88 INPUT/OUTPUT PARAMETERS:
89 None
90
91 RETURN VALUE:
92 boolean
93
94 SIDE EFFECTS:
95 None.
96 */
97 /***********************************************************************/
initialize_frame_checking_environment()98 void 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 /*===========================================================================
106 FUNCTION:
107 HEVC_Utils::iSNewFrame
108
109 DESCRIPTION:
110 Returns true if NAL parsing successfull otherwise false.
111
112 INPUT/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
123 RETURN VALUE:
124 boolean true, if nal parsing is successful
125 false, if the nal parsing has errors
126
127 SIDE EFFECTS:
128 None.
129 ===========================================================================*/
isNewFrame(OMX_BUFFERHEADERTYPE * p_buf_hdr,OMX_IN OMX_U32 size_of_nal_length_field,OMX_OUT OMX_BOOL & isNewFrame)130 bool 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
150 do {
151 if (pos >= buffer_length) {
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 } else if (size_of_nal_length_field) {
161 /* This is the case to play multiple NAL units inside each access unit*/
162 /* Extract the NAL length depending on sizeOfNALength field */
163 sizeofNalLengthField = size_of_nal_length_field;
164 nal_len = 0;
165
166 while (size_of_nal_length_field--) {
167 nal_len |= buffer[pos++]<<(size_of_nal_length_field<<3);
168 }
169
170 if (nal_len >= buffer_length) {
171 DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__);
172 return false;
173 }
174 }
175
176 if (nal_len > buffer_length) {
177 DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__);
178 return false;
179 }
180
181 if (pos + 2 > (nal_len + sizeofNalLengthField)) {
182 DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__);
183 return false;
184 }
185
186 nalu_type = (buffer[pos] & 0x7E)>>1 ; //=== nal_unit_type
187
188 DEBUG_PRINT_LOW("\n@#@# Pos = %x NalType = %x buflen = %d", pos-1, nalu_type, buffer_length);
189
190 isNewFrame = OMX_FALSE;
191
192 if (nalu_type == NAL_UNIT_VPS ||
193 nalu_type == NAL_UNIT_SPS ||
194 nalu_type == NAL_UNIT_PPS ||
195 nalu_type == NAL_UNIT_SEI) {
196 DEBUG_PRINT_LOW("\n Non-AU boundary with NAL type %d", nalu_type);
197
198 if (m_au_data) {
199 isNewFrame = OMX_TRUE;
200 m_au_data = false;
201 }
202
203 m_forceToStichNextNAL = true;
204 } else if (nalu_type <= NAL_UNIT_RESERVED_23) {
205 DEBUG_PRINT_LOW("\n AU Boundary with NAL type %d ",nal_unit.nalu_type);
206
207 if (!m_forceToStichNextNAL) {
208 bFirstSliceInPic = ((buffer[pos+2] & 0x80)>>7);
209
210 if (bFirstSliceInPic) { //=== first_ctb_in_slice is only 1'b1 coded tree block
211 DEBUG_PRINT_LOW("Found a New Frame due to 1st coded tree block");
212 isNewFrame = OMX_TRUE;
213 }
214 }
215
216 m_au_data = true;
217 m_forceToStichNextNAL = false;
218 }
219
220 DEBUG_PRINT_LOW("get_HEVC_nal_type - newFrame value %d\n",isNewFrame);
221 return true;
222 }
223
224