1 /*--------------------------------------------------------------------------
2 Copyright (c) 2010-2012, Code Aurora Forum. 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 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
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 <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
MP4_Utils()45 MP4_Utils::MP4_Utils()
46 {
47 m_SrcWidth = 0;
48 m_SrcHeight = 0;
49 vop_time_resolution = 0;
50 vop_time_found = false;
51
52 }
~MP4_Utils()53 MP4_Utils::~MP4_Utils()
54 {
55 }
56
read_bit_field(posInfoType * posPtr,uint32 size)57 uint32 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 }
find_code(uint8 * bytePtr,uint32 size,uint32 codeMask,uint32 referenceCode)73 static 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 }
parseHeader(mp4StreamType * psBits)88 bool 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
is_notcodec_vop(unsigned char * pbuffer,unsigned int len)265 bool 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
mp4_fill_aspect_ratio_info(struct vdec_aspectratioinfo * aspect_ratio_info,OMX_QCOM_EXTRADATA_FRAMEINFO * frame_info)304 void 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