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