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