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