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