1/*-------------------------------------------------------------------------- 2Copyright (c) 2010-2012, Code Aurora Forum. 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 Code Aurora 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#include "mp4_utils.h" 29#include "omx_vdec.h" 30# include <stdio.h> 31#ifdef _ANDROID_ 32 extern "C"{ 33 #include<utils/Log.h> 34 } 35#endif//_ANDROID_ 36 37#undef DEBUG_PRINT_LOW 38#undef DEBUG_PRINT_HIGH 39#undef DEBUG_PRINT_ERROR 40 41#define DEBUG_PRINT_LOW ALOGV 42#define DEBUG_PRINT_HIGH ALOGV 43#define DEBUG_PRINT_ERROR ALOGE 44 45MP4_Utils::MP4_Utils() 46{ 47 m_SrcWidth = 0; 48 m_SrcHeight = 0; 49 vop_time_resolution = 0; 50 vop_time_found = false; 51 52} 53MP4_Utils::~MP4_Utils() 54{ 55} 56 57uint32 MP4_Utils::read_bit_field(posInfoType * posPtr, uint32 size) { 58 uint8 *bits = &posPtr->bytePtr[0]; 59 uint32 bitBuf = 60 (bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | bits[3]; 61 62 uint32 value = (bitBuf >> (32 - posPtr->bitPos - size)) & MASK(size); 63 64 /* Update the offset in preparation for next field */ 65 posPtr->bitPos += size; 66 67 while (posPtr->bitPos >= 8) { 68 posPtr->bitPos -= 8; 69 posPtr->bytePtr++; 70 } 71 return value; 72} 73static uint8 *find_code 74 (uint8 * bytePtr, uint32 size, uint32 codeMask, uint32 referenceCode) { 75 uint32 code = 0xFFFFFFFF; 76 for (uint32 i = 0; i < size; i++) { 77 code <<= 8; 78 code |= *bytePtr++; 79 80 if ((code & codeMask) == referenceCode) { 81 return bytePtr; 82 } 83 } 84 85 DEBUG_PRINT_LOW("Unable to find code 0x%x\n", referenceCode); 86 return NULL; 87} 88bool MP4_Utils::parseHeader(mp4StreamType * psBits) { 89 uint32 profile_and_level_indication = 0; 90 uint8 VerID = 1; /* default value */ 91 long hxw = 0; 92 93 m_posInfo.bitPos = 0; 94 m_posInfo.bytePtr = psBits->data; 95 m_dataBeginPtr = psBits->data; 96 97 m_posInfo.bytePtr = find_code(m_posInfo.bytePtr,4, 98 MASK(32),VOP_START_CODE); 99 if(m_posInfo.bytePtr) { 100 return false; 101 } 102 103 m_posInfo.bitPos = 0; 104 m_posInfo.bytePtr = psBits->data; 105 m_dataBeginPtr = psBits->data; 106 m_posInfo.bytePtr = find_code(m_posInfo.bytePtr,4, 107 MASK(32),GOV_START_CODE); 108 if(m_posInfo.bytePtr) { 109 return false; 110 } 111 112 m_posInfo.bitPos = 0; 113 m_posInfo.bytePtr = psBits->data; 114 m_dataBeginPtr = psBits->data; 115 /* parsing Visual Object Seqence(VOS) header */ 116 m_posInfo.bytePtr = find_code(m_posInfo.bytePtr, 117 psBits->numBytes, 118 MASK(32), 119 VISUAL_OBJECT_SEQUENCE_START_CODE); 120 if ( m_posInfo.bytePtr == NULL ){ 121 m_posInfo.bitPos = 0; 122 m_posInfo.bytePtr = psBits->data; 123 } 124 else { 125 uint32 profile_and_level_indication = read_bit_field (&m_posInfo, 8); 126 } 127 /* parsing Visual Object(VO) header*/ 128 /* note: for now, we skip over the user_data */ 129 m_posInfo.bytePtr = find_code(m_posInfo.bytePtr,psBits->numBytes, 130 MASK(32),VISUAL_OBJECT_START_CODE); 131 if(m_posInfo.bytePtr == NULL) { 132 m_posInfo.bitPos = 0; 133 m_posInfo.bytePtr = psBits->data; 134 } 135 else { 136 uint32 is_visual_object_identifier = read_bit_field (&m_posInfo, 1); 137 if ( is_visual_object_identifier ) { 138 /* visual_object_verid*/ 139 read_bit_field (&m_posInfo, 4); 140 /* visual_object_priority*/ 141 read_bit_field (&m_posInfo, 3); 142 } 143 144 /* visual_object_type*/ 145 uint32 visual_object_type = read_bit_field (&m_posInfo, 4); 146 if ( visual_object_type != VISUAL_OBJECT_TYPE_VIDEO_ID ) { 147 return false; 148 } 149 /* skipping video_signal_type params*/ 150 /*parsing Video Object header*/ 151 m_posInfo.bytePtr = find_code(m_posInfo.bytePtr,psBits->numBytes, 152 VIDEO_OBJECT_START_CODE_MASK,VIDEO_OBJECT_START_CODE); 153 if ( m_posInfo.bytePtr == NULL ) { 154 return false; 155 } 156 } 157 158 /* parsing Video Object Layer(VOL) header */ 159 m_posInfo.bitPos = 0; 160 m_posInfo.bytePtr = find_code(m_posInfo.bytePtr, 161 psBits->numBytes, 162 VIDEO_OBJECT_LAYER_START_CODE_MASK, 163 VIDEO_OBJECT_LAYER_START_CODE); 164 if ( m_posInfo.bytePtr == NULL ) { 165 m_posInfo.bitPos = 0; 166 m_posInfo.bytePtr = psBits->data; 167 } 168 169 // 1 -> random accessible VOL 170 read_bit_field(&m_posInfo, 1); 171 172 uint32 video_object_type_indication = read_bit_field (&m_posInfo, 8); 173 if ( (video_object_type_indication != SIMPLE_OBJECT_TYPE) && 174 (video_object_type_indication != SIMPLE_SCALABLE_OBJECT_TYPE) && 175 (video_object_type_indication != CORE_OBJECT_TYPE) && 176 (video_object_type_indication != ADVANCED_SIMPLE) && 177 (video_object_type_indication != RESERVED_OBJECT_TYPE) && 178 (video_object_type_indication != MAIN_OBJECT_TYPE)) { 179 return false; 180 } 181 /* is_object_layer_identifier*/ 182 uint32 is_object_layer_identifier = read_bit_field (&m_posInfo, 1); 183 if (is_object_layer_identifier) { 184 uint32 video_object_layer_verid = read_bit_field (&m_posInfo, 4); 185 uint32 video_object_layer_priority = read_bit_field (&m_posInfo, 3); 186 VerID = (unsigned char)video_object_layer_verid; 187 } 188 189 /* aspect_ratio_info*/ 190 uint32 aspect_ratio_info = read_bit_field (&m_posInfo, 4); 191 if ( aspect_ratio_info == EXTENDED_PAR ) { 192 /* par_width*/ 193 read_bit_field (&m_posInfo, 8); 194 /* par_height*/ 195 read_bit_field (&m_posInfo, 8); 196 } 197 /* vol_control_parameters */ 198 uint32 vol_control_parameters = read_bit_field (&m_posInfo, 1); 199 if ( vol_control_parameters ) { 200 /* chroma_format*/ 201 uint32 chroma_format = read_bit_field (&m_posInfo, 2); 202 if ( chroma_format != 1 ) { 203 return false; 204 } 205 /* low_delay*/ 206 uint32 low_delay = read_bit_field (&m_posInfo, 1); 207 /* vbv_parameters (annex D)*/ 208 uint32 vbv_parameters = read_bit_field (&m_posInfo, 1); 209 if ( vbv_parameters ) { 210 /* first_half_bitrate*/ 211 uint32 first_half_bitrate = read_bit_field (&m_posInfo, 15); 212 uint32 marker_bit = read_bit_field (&m_posInfo, 1); 213 if ( marker_bit != 1) { 214 return false; 215 } 216 /* latter_half_bitrate*/ 217 uint32 latter_half_bitrate = read_bit_field (&m_posInfo, 15); 218 marker_bit = read_bit_field (&m_posInfo, 1); 219 if ( marker_bit != 1) { 220 return false; 221 } 222 uint32 VBVPeakBitRate = (first_half_bitrate << 15) + latter_half_bitrate; 223 /* first_half_vbv_buffer_size*/ 224 uint32 first_half_vbv_buffer_size = read_bit_field (&m_posInfo, 15); 225 marker_bit = read_bit_field (&m_posInfo, 1); 226 if ( marker_bit != 1) { 227 return false; 228 } 229 /* latter_half_vbv_buffer_size*/ 230 uint32 latter_half_vbv_buffer_size = read_bit_field (&m_posInfo, 3); 231 uint32 VBVBufferSize = (first_half_vbv_buffer_size << 3) + latter_half_vbv_buffer_size; 232 /* first_half_vbv_occupancy*/ 233 uint32 first_half_vbv_occupancy = read_bit_field (&m_posInfo, 11); 234 marker_bit = read_bit_field (&m_posInfo, 1); 235 if ( marker_bit != 1) { 236 return false; 237 } 238 /* latter_half_vbv_occupancy*/ 239 uint32 latter_half_vbv_occupancy = read_bit_field (&m_posInfo, 15); 240 marker_bit = read_bit_field (&m_posInfo, 1); 241 if ( marker_bit != 1) { 242 return false; 243 } 244 }/* vbv_parameters*/ 245 }/*vol_control_parameters*/ 246 247 /* video_object_layer_shape*/ 248 uint32 video_object_layer_shape = read_bit_field (&m_posInfo, 2); 249 uint8 VOLShape = (unsigned char)video_object_layer_shape; 250 if ( VOLShape != MPEG4_SHAPE_RECTANGULAR ) { 251 return false; 252 } 253 /* marker_bit*/ 254 uint32 marker_bit = read_bit_field (&m_posInfo, 1); 255 if ( marker_bit != 1 ) { 256 return false; 257 } 258 /* vop_time_increment_resolution*/ 259 uint32 vop_time_increment_resolution = read_bit_field (&m_posInfo, 16); 260 vop_time_resolution = vop_time_increment_resolution; 261 vop_time_found = true; 262 return true; 263} 264 265bool MP4_Utils::is_notcodec_vop(unsigned char *pbuffer, unsigned int len) 266{ 267 unsigned int index = 4,vop_bits=0; 268 unsigned int temp = vop_time_resolution - 1; 269 unsigned char vop_type=0,modulo_bit=0,not_coded=0; 270 if (!vop_time_found || !pbuffer || len < 5) { 271 return false; 272 } 273 if((pbuffer[0] == 0) && (pbuffer[1] == 0) && (pbuffer[2] == 1) && (pbuffer[3] == 0xB6)){ 274 while(temp) { 275 vop_bits++; 276 temp >>= 1; 277 } 278 vop_type = (pbuffer[index] & 0xc0) >> 6; 279 unsigned bits_parsed = 2; 280 do { 281 modulo_bit = pbuffer[index] & (1 << (7-bits_parsed)); 282 bits_parsed++; 283 index += bits_parsed/8; 284 bits_parsed = bits_parsed %8; 285 if(index >= len) { 286 return false; 287 } 288 }while(modulo_bit); 289 bits_parsed++; //skip marker bit 290 bits_parsed += vop_bits + 1;//Vop bit & Marker bits 291 index += bits_parsed/8; 292 if(index >= len) { 293 return false; 294 } 295 bits_parsed = bits_parsed % 8; 296 not_coded = pbuffer[index] & (1 << (7 - bits_parsed)); 297 if(!not_coded){ 298 return true; 299 } 300 } 301 return false; 302} 303 304void mp4_fill_aspect_ratio_info(struct vdec_aspectratioinfo *aspect_ratio_info, 305 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info) 306{ 307 switch(aspect_ratio_info->aspect_ratio) { 308 case 1 : 309 frame_info->aspectRatio.aspectRatioX = 1; 310 frame_info->aspectRatio.aspectRatioY = 1; 311 break; 312 313 case 2 : 314 frame_info->aspectRatio.aspectRatioX = 12; 315 frame_info->aspectRatio.aspectRatioY = 11; 316 break; 317 318 case 3 : 319 frame_info->aspectRatio.aspectRatioX = 10; 320 frame_info->aspectRatio.aspectRatioY = 11; 321 break; 322 323 case 4 : 324 frame_info->aspectRatio.aspectRatioX = 16; 325 frame_info->aspectRatio.aspectRatioY = 11; 326 break; 327 328 case 5 : 329 frame_info->aspectRatio.aspectRatioX = 40; 330 frame_info->aspectRatio.aspectRatioY = 33; 331 break; 332 333 case 15: 334 frame_info->aspectRatio.aspectRatioX = 335 aspect_ratio_info->par_width; 336 frame_info->aspectRatio.aspectRatioY = 337 aspect_ratio_info->par_height; 338 break; 339 340 default: 341 ALOGE(" Incorrect aspect_ratio = %d", 342 aspect_ratio_info->aspect_ratio); 343 } 344} 345