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
MP4_Utils()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 }
~MP4_Utils()46 MP4_Utils::~MP4_Utils()
47 {
48 }
49
read_bit_field(posInfoType * posPtr,uint32 size)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 }
find_code(uint8 * bytePtr,uint32 size,uint32 codeMask,uint32 referenceCode)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 }
parseHeader(mp4StreamType * psBits)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
is_notcodec_vop(unsigned char * pbuffer,unsigned int len)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