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