1/*--------------------------------------------------------------------------
2Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
3
4Redistribution and use in source and binary forms, with or without
5modification, 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
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26ADVISED 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
45MP4_Utils::MP4_Utils()
46{
47   m_SrcWidth = 0;
48   m_SrcHeight = 0;
49   vop_time_resolution = 0;
50   vop_time_found = false;
51
52}
53MP4_Utils::~MP4_Utils()
54{
55}
56
57uint32 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}
73static 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}
88bool 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
265bool 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
304void 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