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