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