1 /*--------------------------------------------------------------------------
2 Copyright (c) 2013, 2018, 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 "qc_omx_msg.h"
51 #include <string.h>
52 #include <stdlib.h>
53 #ifdef _ANDROID_
54 #include <cutils/properties.h>
55 #endif
56
57
58 /* =======================================================================
59
60 DEFINITIONS AND DECLARATIONS FOR MODULE
61
62 This section contains definitions for constants, macros, types, variables
63 and other items needed by this module.
64
65 ========================================================================== */
66
HEVC_Utils()67 HEVC_Utils::HEVC_Utils()
68 {
69 initialize_frame_checking_environment();
70 }
71
~HEVC_Utils()72 HEVC_Utils::~HEVC_Utils()
73 {
74 }
75
76 /***********************************************************************/
77 /*
78 FUNCTION:
79 HEVC_Utils::initialize_frame_checking_environment
80
81 DESCRIPTION:
82 Extract RBSP data from a NAL
83
84 INPUT/OUTPUT PARAMETERS:
85 None
86
87 RETURN VALUE:
88 boolean
89
90 SIDE EFFECTS:
91 None.
92 */
93 /***********************************************************************/
initialize_frame_checking_environment()94 void HEVC_Utils::initialize_frame_checking_environment()
95 {
96 m_forceToStichNextNAL = false;
97 m_au_data = false;
98 nalu_type = NAL_UNIT_INVALID;
99 }
100
101 /*===========================================================================
102 FUNCTION:
103 HEVC_Utils::iSNewFrame
104
105 DESCRIPTION:
106 Returns true if NAL parsing successfull otherwise false.
107
108 INPUT/OUTPUT PARAMETERS:
109 <In>
110 buffer : buffer containing start code or nal length + NAL units
111 buffer_length : the length of the NAL buffer
112 start_code : If true, start code is detected,
113 otherwise size nal length is detected
114 size_of_nal_length_field: size of nal length field
115 <out>
116 isNewFrame: true if the NAL belongs to a differenet frame
117 false if the NAL belongs to a current frame
118
119 RETURN VALUE:
120 boolean true, if nal parsing is successful
121 false, if the nal parsing has errors
122
123 SIDE EFFECTS:
124 None.
125 ===========================================================================*/
isNewFrame(OMX_BUFFERHEADERTYPE * p_buf_hdr,OMX_IN OMX_U32 size_of_nal_length_field,OMX_OUT OMX_BOOL & isNewFrame)126 bool HEVC_Utils::isNewFrame(OMX_BUFFERHEADERTYPE *p_buf_hdr,
127 OMX_IN OMX_U32 size_of_nal_length_field,
128 OMX_OUT OMX_BOOL &isNewFrame)
129 {
130 OMX_IN OMX_U8 *buffer = p_buf_hdr->pBuffer;
131 OMX_IN OMX_U32 buffer_length = p_buf_hdr->nFilledLen;
132 byte bFirstSliceInPic = 0;
133
134 byte coef1=1, coef2=0, coef3=0;
135 uint32 pos = 0;
136 uint32 nal_len = buffer_length;
137 uint32 sizeofNalLengthField = 0;
138 uint32 zero_count;
139 boolean start_code = (size_of_nal_length_field==0)?true:false;
140
141 if (start_code) {
142 // Search start_code_prefix_one_3bytes (0x000001)
143 coef2 = buffer[pos++];
144 coef3 = buffer[pos++];
145
146 do {
147 if (pos >= buffer_length) {
148 DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__);
149 return false;
150 }
151
152 coef1 = coef2;
153 coef2 = coef3;
154 coef3 = buffer[pos++];
155 } while (coef1 || coef2 || coef3 != 1);
156 } else if (size_of_nal_length_field) {
157 /* This is the case to play multiple NAL units inside each access unit*/
158 /* Extract the NAL length depending on sizeOfNALength field */
159 sizeofNalLengthField = size_of_nal_length_field;
160 nal_len = 0;
161
162 while (size_of_nal_length_field--) {
163 nal_len |= buffer[pos++]<<(size_of_nal_length_field<<3);
164 }
165
166 if (nal_len >= buffer_length) {
167 DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__);
168 return false;
169 }
170 }
171
172 if (nal_len > buffer_length) {
173 DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__);
174 return false;
175 }
176
177 if (pos + 2 > (nal_len + sizeofNalLengthField)) {
178 DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__);
179 return false;
180 }
181
182 nalu_type = (buffer[pos] & 0x7E)>>1 ; //=== nal_unit_type
183
184 DEBUG_PRINT("@#@# Pos = %x NalType = %x buflen = %u", pos-1, nalu_type, (unsigned int) buffer_length);
185
186 isNewFrame = OMX_FALSE;
187
188 if (nalu_type == NAL_UNIT_VPS ||
189 nalu_type == NAL_UNIT_SPS ||
190 nalu_type == NAL_UNIT_PPS ||
191 nalu_type == NAL_UNIT_SEI) {
192 DEBUG_PRINT("Non-AU boundary with NAL type %d", nalu_type);
193
194 if (m_au_data) {
195 isNewFrame = OMX_TRUE;
196 m_au_data = false;
197 }
198
199 m_forceToStichNextNAL = true;
200 } else if (nalu_type <= NAL_UNIT_RESERVED_23) {
201 DEBUG_PRINT("AU Boundary with NAL type %d ", nalu_type);
202
203 if (!m_forceToStichNextNAL) {
204 bFirstSliceInPic = ((buffer[pos+2] & 0x80)>>7);
205
206 if (bFirstSliceInPic) { //=== first_ctb_in_slice is only 1'b1 coded tree block
207 DEBUG_PRINT("Found a New Frame due to 1st coded tree block");
208 isNewFrame = OMX_TRUE;
209 }
210 }
211
212 m_au_data = true;
213 m_forceToStichNextNAL = false;
214 }
215
216 DEBUG_PRINT("get_HEVC_nal_type - newFrame value %d",isNewFrame);
217 return true;
218 }
219
220