1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include "utils/Log.h"
17#include "M4OSA_Types.h"
18#include "M4OSA_Debug.h"
19
20#include "M4VD_EXTERNAL_Interface.h"
21#include "M4VD_Tools.h"
22#include "M4_VideoEditingCommon.h"
23#include "OMX_Video.h"
24/**
25 ************************************************************************
26 * @file   M4VD_EXTERNAL_BitstreamParser.c
27 * @brief
28 * @note   This file implements external Bitstream parser
29 ************************************************************************
30 */
31
32typedef struct {
33    M4OSA_UInt8 code;
34    M4OSA_Int32 profile;
35    M4OSA_Int32 level;
36} codeProfileLevel;
37
38static codeProfileLevel mpeg4ProfileLevelTable[] = {
39    {0x01, OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level1},
40    {0x02, OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level2},
41    {0x03, OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level3},
42    {0x04, OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level4a},
43    {0x05, OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level5},
44    {0x08, OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0},
45    {0x11, OMX_VIDEO_MPEG4ProfileSimpleScalable,OMX_VIDEO_MPEG4Level1},
46    {0x12, OMX_VIDEO_MPEG4ProfileSimpleScalable,OMX_VIDEO_MPEG4Level2},
47    {0x21, OMX_VIDEO_MPEG4ProfileCore, OMX_VIDEO_MPEG4Level1},
48    {0x22, OMX_VIDEO_MPEG4ProfileCore, OMX_VIDEO_MPEG4Level2},
49    {0x32, OMX_VIDEO_MPEG4ProfileMain, OMX_VIDEO_MPEG4Level2},
50    {0x33, OMX_VIDEO_MPEG4ProfileMain, OMX_VIDEO_MPEG4Level3},
51    {0x34, OMX_VIDEO_MPEG4ProfileMain, OMX_VIDEO_MPEG4Level4},
52    {0x42, OMX_VIDEO_MPEG4ProfileNbit, OMX_VIDEO_MPEG4Level2},
53    {0x51, OMX_VIDEO_MPEG4ProfileScalableTexture, OMX_VIDEO_MPEG4Level1},
54    {0x61, OMX_VIDEO_MPEG4ProfileSimpleFace, OMX_VIDEO_MPEG4Level1},
55    {0x62, OMX_VIDEO_MPEG4ProfileSimpleFace, OMX_VIDEO_MPEG4Level2},
56    {0x71, OMX_VIDEO_MPEG4ProfileBasicAnimated, OMX_VIDEO_MPEG4Level1},
57    {0x72, OMX_VIDEO_MPEG4ProfileBasicAnimated, OMX_VIDEO_MPEG4Level2},
58    {0x81, OMX_VIDEO_MPEG4ProfileHybrid, OMX_VIDEO_MPEG4Level1},
59    {0x82, OMX_VIDEO_MPEG4ProfileHybrid, OMX_VIDEO_MPEG4Level2},
60    {0x91, OMX_VIDEO_MPEG4ProfileAdvancedRealTime, OMX_VIDEO_MPEG4Level1},
61    {0x92, OMX_VIDEO_MPEG4ProfileAdvancedRealTime, OMX_VIDEO_MPEG4Level2},
62    {0x93, OMX_VIDEO_MPEG4ProfileAdvancedRealTime, OMX_VIDEO_MPEG4Level3},
63    {0x94, OMX_VIDEO_MPEG4ProfileAdvancedRealTime, OMX_VIDEO_MPEG4Level4},
64    {0xa1, OMX_VIDEO_MPEG4ProfileCoreScalable, OMX_VIDEO_MPEG4Level1},
65    {0xa2, OMX_VIDEO_MPEG4ProfileCoreScalable, OMX_VIDEO_MPEG4Level2},
66    {0xa3, OMX_VIDEO_MPEG4ProfileCoreScalable, OMX_VIDEO_MPEG4Level3},
67    {0xb1, OMX_VIDEO_MPEG4ProfileAdvancedCoding, OMX_VIDEO_MPEG4Level1},
68    {0xb2, OMX_VIDEO_MPEG4ProfileAdvancedCoding, OMX_VIDEO_MPEG4Level2},
69    {0xb3, OMX_VIDEO_MPEG4ProfileAdvancedCoding, OMX_VIDEO_MPEG4Level3},
70    {0xb4, OMX_VIDEO_MPEG4ProfileAdvancedCoding, OMX_VIDEO_MPEG4Level4},
71    {0xc1, OMX_VIDEO_MPEG4ProfileAdvancedCore, OMX_VIDEO_MPEG4Level1},
72    {0xc2, OMX_VIDEO_MPEG4ProfileAdvancedCore, OMX_VIDEO_MPEG4Level2},
73    {0xd1, OMX_VIDEO_MPEG4ProfileAdvancedScalable, OMX_VIDEO_MPEG4Level1},
74    {0xd2, OMX_VIDEO_MPEG4ProfileAdvancedScalable, OMX_VIDEO_MPEG4Level2},
75    {0xd3, OMX_VIDEO_MPEG4ProfileAdvancedScalable, OMX_VIDEO_MPEG4Level3},
76    {0xf0, OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level0},
77    {0xf1, OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level1},
78    {0xf2, OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level2},
79    {0xf3, OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level3},
80    {0xf4, OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level4},
81    {0xf5, OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level5}
82};
83
84M4OSA_UInt32 M4VD_EXTERNAL_GetBitsFromMemory(M4VS_Bitstream_ctxt* parsingCtxt,
85     M4OSA_UInt32 nb_bits)
86{
87        return(M4VD_Tools_GetBitsFromMemory(parsingCtxt,nb_bits));
88}
89
90M4OSA_ERR M4VD_EXTERNAL_WriteBitsToMemory(M4OSA_UInt32 bitsToWrite,
91                                                 M4OSA_MemAddr32 dest_bits,
92                                                 M4OSA_UInt8 offset, M4OSA_UInt8 nb_bits)
93{
94        return (M4VD_Tools_WriteBitsToMemory( bitsToWrite,dest_bits,
95                                                offset,  nb_bits));
96}
97
98M4OSA_ERR M4DECODER_EXTERNAL_ParseVideoDSI(M4OSA_UInt8* pVol, M4OSA_Int32 aVolSize,
99                                             M4DECODER_MPEG4_DecoderConfigInfo* pDci,
100                                             M4DECODER_VideoSize* pVideoSize)
101{
102    M4VS_Bitstream_ctxt parsingCtxt;
103    M4OSA_UInt32 code, j;
104    M4OSA_MemAddr8 start;
105    M4OSA_UInt8 i;
106    M4OSA_UInt32 time_incr_length;
107    M4OSA_UInt8 vol_verid=0, b_hierarchy_type;
108
109    /* Parsing variables */
110    M4OSA_UInt8 video_object_layer_shape = 0;
111    M4OSA_UInt8 sprite_enable = 0;
112    M4OSA_UInt8 reduced_resolution_vop_enable = 0;
113    M4OSA_UInt8 scalability = 0;
114    M4OSA_UInt8 enhancement_type = 0;
115    M4OSA_UInt8 complexity_estimation_disable = 0;
116    M4OSA_UInt8 interlaced = 0;
117    M4OSA_UInt8 sprite_warping_points = 0;
118    M4OSA_UInt8 sprite_brightness_change = 0;
119    M4OSA_UInt8 quant_precision = 0;
120
121    /* Fill the structure with default parameters */
122    pVideoSize->m_uiWidth              = 0;
123    pVideoSize->m_uiHeight             = 0;
124
125    pDci->uiTimeScale          = 0;
126    pDci->uiProfile            = 0;
127    pDci->uiUseOfResynchMarker = 0;
128    pDci->bDataPartition       = M4OSA_FALSE;
129    pDci->bUseOfRVLC           = M4OSA_FALSE;
130
131    /* Reset the bitstream context */
132    parsingCtxt.stream_byte = 0;
133    parsingCtxt.stream_index = 8;
134    parsingCtxt.in = (M4OSA_Int8 *)pVol;
135
136    start = (M4OSA_Int8 *)pVol;
137
138    /* Start parsing */
139    while (parsingCtxt.in - start < aVolSize)
140    {
141        code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8);
142        if (code == 0)
143        {
144            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8);
145            if (code == 0)
146            {
147                code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8);
148                if (code == 1)
149                {
150                    /* start code found */
151                    code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8);
152
153                    /* ----- 0x20..0x2F : video_object_layer_start_code ----- */
154
155                    if ((code > 0x1F) && (code < 0x30))
156                    {
157                        code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
158                                 1);/* random accessible vol */
159                        code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
160                                 8);/* video object type indication */
161                        code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
162                                 1);/* is object layer identifier */
163                        if (code == 1)
164                        {
165                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
166                                     4); /* video object layer verid */
167                            vol_verid = (M4OSA_UInt8)code;
168                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
169                                     3); /* video object layer priority */
170                        }
171                        code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
172                                 4);/* aspect ratio */
173                        if (code == 15)
174                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
175                                     16); /* par_width and par_height (8+8) */
176                        code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
177                                 1);/* vol control parameters */
178                        if (code == 1)
179                        {
180                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
181                                     3);/* chroma format + low delay (3+1) */
182                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
183                                     1);/* vbv parameters */
184                            if (code == 1)
185                            {
186                                code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
187                                         32);/* first and latter half bitrate + 2 marker bits
188                                            (15 + 1 + 15 + 1) */
189                                code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
190                                         31);/* first and latter half vbv buffer size + first
191                                          half vbv occupancy + marker bits (15+1+3+11+1)*/
192                                code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
193                                         16);/* first half vbv occupancy + marker bits (15+1)*/
194                            }
195                        }
196                        code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
197                                 2); /* video object layer shape */
198                        /* Need to save it for vop parsing */
199                        video_object_layer_shape = (M4OSA_UInt8)code;
200
201                        if (code != 0) return 0; /* only rectangular case supported */
202
203                        code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
204                                 1); /* Marker bit */
205                        code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
206                                 16); /* VOP time increment resolution */
207                        pDci->uiTimeScale = code;
208
209                        /* Computes time increment length */
210                        j    = code - 1;
211                        for (i = 0; (i < 32) && (j != 0); j >>=1)
212                        {
213                            i++;
214                        }
215                        time_incr_length = (i == 0) ? 1 : i;
216
217                        code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
218                                 1);/* Marker bit */
219                        code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
220                                 1);/* Fixed VOP rate */
221                        if (code == 1)
222                        {
223                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
224                                     time_incr_length);/* Fixed VOP time increment */
225                        }
226
227                        if(video_object_layer_shape != 1) /* 1 = Binary */
228                        {
229                            if(video_object_layer_shape == 0) /* 0 = rectangular */
230                            {
231                                code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
232                                         1);/* Marker bit */
233                                code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
234                                         13);/* Width */
235                                pVideoSize->m_uiWidth = code;
236                                code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
237                                         1);/* Marker bit */
238                                code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
239                                         13);/* Height */
240                                pVideoSize->m_uiHeight = code;
241                                code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
242                                         1);/* Marker bit */
243                            }
244                        }
245
246                        code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
247                                 1);/* interlaced */
248                        interlaced = (M4OSA_UInt8)code;
249                        code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
250                                 1);/* OBMC disable */
251
252                        if(vol_verid == 1)
253                        {
254                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
255                                     1);/* sprite enable */
256                            sprite_enable = (M4OSA_UInt8)code;
257                        }
258                        else
259                        {
260                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
261                                     2);/* sprite enable */
262                            sprite_enable = (M4OSA_UInt8)code;
263                        }
264                        if ((sprite_enable == 1) || (sprite_enable == 2))
265                        /* Sprite static = 1 and Sprite GMC = 2 */
266                        {
267                            if (sprite_enable != 2)
268                            {
269
270                                code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
271                                         13);/* sprite width */
272                                code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
273                                         1);/* Marker bit */
274                                code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
275                                         13);/* sprite height */
276                                code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
277                                         1);/* Marker bit */
278                                code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
279                                         13);/* sprite l coordinate */
280                                code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
281                                         1);/* Marker bit */
282                                code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
283                                         13);/* sprite top coordinate */
284                                code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
285                                         1);/* Marker bit */
286                            }
287
288                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
289                                     6);/* sprite warping points */
290                            sprite_warping_points = (M4OSA_UInt8)code;
291                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
292                                     2);/* sprite warping accuracy */
293                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
294                                     1);/* sprite brightness change */
295                            sprite_brightness_change = (M4OSA_UInt8)code;
296                            if (sprite_enable != 2)
297                            {
298                                code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
299                                             1);/* low latency sprite enable */
300                            }
301                        }
302                        if ((vol_verid != 1) && (video_object_layer_shape != 0))
303                        {
304                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
305                                         1);/* sadct disable */
306                        }
307
308                        code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1); /* not 8 bits */
309                        if (code)
310                        {
311                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
312                                     4);/* quant precision */
313                            quant_precision = (M4OSA_UInt8)code;
314                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
315                                         4);/* bits per pixel */
316                        }
317
318                        /* greyscale not supported */
319                        if(video_object_layer_shape == 3)
320                        {
321                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
322                                     3); /* nogray quant update + composition method +
323                                            linear composition */
324                        }
325
326                        code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
327                                     1);/* quant type */
328                        if (code)
329                        {
330                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
331                                         1);/* load intra quant mat */
332                            if (code)
333                            {
334                                code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8);/* */
335                                 i    = 1;
336                                while (i < 64)
337                                {
338                                    code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8);
339                                    if (code == 0)
340                                        break;
341                                    i++;
342                                }
343                            }
344
345                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
346                                         1);/* load non intra quant mat */
347                            if (code)
348                            {
349                                code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8);/* */
350                                 i    = 1;
351                                while (i < 64)
352                                {
353                                    code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8);
354                                    if (code == 0)
355                                        break;
356                                    i++;
357                                }
358                            }
359                        }
360
361                        if (vol_verid != 1)
362                        {
363                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
364                                     1);/* quarter sample */
365                        }
366
367                        code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
368                                     1);/* complexity estimation disable */
369                        complexity_estimation_disable = (M4OSA_UInt8)code;
370                        if (!code)
371                        {
372                            //return M4ERR_NOT_IMPLEMENTED;
373                        }
374
375                        code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
376                                     1);/* resync marker disable */
377                        pDci->uiUseOfResynchMarker = (code) ? 0 : 1;
378
379                        code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt,
380                                     1);/* data partitionned */
381                        pDci->bDataPartition = (code) ? M4OSA_TRUE : M4OSA_FALSE;
382                        if (code)
383                        {
384                            /* reversible VLC */
385                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1);
386                            pDci->bUseOfRVLC = (code) ? M4OSA_TRUE : M4OSA_FALSE;
387                        }
388
389                        if (vol_verid != 1)
390                        {
391                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1);/* newpred */
392                            if (code)
393                            {
394                                //return M4ERR_PARAMETER;
395                            }
396                            /* reduced resolution vop enable */
397                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1);
398                            reduced_resolution_vop_enable = (M4OSA_UInt8)code;
399                        }
400
401                        code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1);/* scalability */
402                        scalability = (M4OSA_UInt8)code;
403                        if (code)
404                        {
405                            /* hierarchy type */
406                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1);
407                            b_hierarchy_type = (M4OSA_UInt8)code;
408                            /* ref layer id */
409                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 4);
410                            /* ref sampling direct */
411                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1);
412                            /* hor sampling factor N */
413                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 5);
414                            /* hor sampling factor M */
415                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 5);
416                            /* vert sampling factor N */
417                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 5);
418                            /* vert sampling factor M */
419                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 5);
420                            /* enhancement type */
421                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1);
422                            enhancement_type = (M4OSA_UInt8)code;
423                            if ((!b_hierarchy_type) && (video_object_layer_shape == 1))
424                            {
425                                /* use ref shape */
426                                code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1);
427                                /* use ref texture */
428                                code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1);
429                                /* shape hor sampling factor N */
430                                code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 5);
431                                /* shape hor sampling factor M */
432                                code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 5);
433                                /* shape vert sampling factor N */
434                                code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 5);
435                                /* shape vert sampling factor M */
436                                code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 5);
437                            }
438                        }
439                        break;
440                    }
441
442                    /* ----- 0xB0 : visual_object_sequence_start_code ----- */
443
444                    else if(code == 0xB0)
445                    {
446                        /* profile_and_level_indication */
447                        code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8);
448                        pDci->uiProfile = (M4OSA_UInt8)code;
449                    }
450
451                    /* ----- 0xB5 : visual_object_start_code ----- */
452
453                    else if(code == 0xB5)
454                    {
455                        /* is object layer identifier */
456                        code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1);
457                        if (code == 1)
458                        {
459                             /* visual object verid */
460                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 4);
461                            vol_verid = (M4OSA_UInt8)code;
462                             /* visual object layer priority */
463                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 3);
464                        }
465                        else
466                        {
467                             /* Realign on byte */
468                            code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 7);
469                            vol_verid = 1;
470                        }
471                    }
472
473                    /* ----- end ----- */
474                }
475                else
476                {
477                    if ((code >> 2) == 0x20)
478                    {
479                        /* H263 ...-> wrong*/
480                        break;
481                    }
482                }
483            }
484        }
485    }
486
487    return M4NO_ERROR;
488}
489
490M4OSA_ERR getAVCProfileAndLevel(M4OSA_UInt8* pDSI, M4OSA_Int32 DSISize,
491                      M4OSA_Int32 *pProfile, M4OSA_Int32 *pLevel) {
492
493    M4OSA_UInt16 index = 28; /* the 29th byte is SPS start */
494    M4OSA_Bool constraintSet3;
495
496    if ((pProfile == M4OSA_NULL) || (pLevel == M4OSA_NULL)) {
497        return M4ERR_PARAMETER;
498    }
499
500    if ((DSISize <= index) || (pDSI == M4OSA_NULL)) {
501        ALOGE("getAVCProfileAndLevel: DSI is invalid");
502        *pProfile = M4VIDEOEDITING_VIDEO_UNKNOWN_PROFILE;
503        *pLevel = M4VIDEOEDITING_VIDEO_UNKNOWN_LEVEL;
504        return M4ERR_PARAMETER;
505    }
506
507    constraintSet3 = (pDSI[index+2] & 0x10);
508    ALOGV("getAVCProfileAndLevel profile_byte %d, level_byte: %d constrain3flag",
509          pDSI[index+1], pDSI[index+3], constraintSet3);
510
511    switch (pDSI[index+1]) {
512        case 66:
513            *pProfile = OMX_VIDEO_AVCProfileBaseline;
514            break;
515        case 77:
516            *pProfile = OMX_VIDEO_AVCProfileMain;
517            break;
518        case 88:
519            *pProfile = OMX_VIDEO_AVCProfileExtended;
520            break;
521        case 100:
522            *pProfile = OMX_VIDEO_AVCProfileHigh;
523            break;
524        case 110:
525            *pProfile = OMX_VIDEO_AVCProfileHigh10;
526            break;
527        case 122:
528            *pProfile = OMX_VIDEO_AVCProfileHigh422;
529            break;
530        case 244:
531            *pProfile = OMX_VIDEO_AVCProfileHigh444;
532            break;
533        default:
534            *pProfile = M4VIDEOEDITING_VIDEO_UNKNOWN_PROFILE;
535    }
536
537    switch (pDSI[index+3]) {
538        case 10:
539            *pLevel = OMX_VIDEO_AVCLevel1;
540            break;
541        case 11:
542            if (constraintSet3)
543                *pLevel = OMX_VIDEO_AVCLevel1b;
544            else
545                *pLevel = OMX_VIDEO_AVCLevel11;
546            break;
547        case 12:
548            *pLevel = OMX_VIDEO_AVCLevel12;
549            break;
550        case 13:
551            *pLevel = OMX_VIDEO_AVCLevel13;
552            break;
553        case 20:
554            *pLevel = OMX_VIDEO_AVCLevel2;
555            break;
556        case 21:
557            *pLevel = OMX_VIDEO_AVCLevel21;
558            break;
559        case 22:
560            *pLevel = OMX_VIDEO_AVCLevel22;
561            break;
562        case 30:
563            *pLevel = OMX_VIDEO_AVCLevel3;
564            break;
565        case 31:
566            *pLevel = OMX_VIDEO_AVCLevel31;
567            break;
568        case 32:
569            *pLevel = OMX_VIDEO_AVCLevel32;
570            break;
571        case 40:
572            *pLevel = OMX_VIDEO_AVCLevel4;
573            break;
574        case 41:
575            *pLevel = OMX_VIDEO_AVCLevel41;
576            break;
577        case 42:
578            *pLevel = OMX_VIDEO_AVCLevel42;
579            break;
580        case 50:
581            *pLevel = OMX_VIDEO_AVCLevel5;
582            break;
583        case 51:
584            *pLevel = OMX_VIDEO_AVCLevel51;
585            break;
586        default:
587            *pLevel = M4VIDEOEDITING_VIDEO_UNKNOWN_LEVEL;
588    }
589    ALOGV("getAVCProfileAndLevel profile %ld level %ld", *pProfile, *pLevel);
590    return M4NO_ERROR;
591}
592
593M4OSA_ERR getH263ProfileAndLevel(M4OSA_UInt8* pDSI, M4OSA_Int32 DSISize,
594                      M4OSA_Int32 *pProfile, M4OSA_Int32 *pLevel) {
595
596    M4OSA_UInt16 index = 7; /* the 5th and 6th bytes contain the level and profile */
597
598    if ((pProfile == M4OSA_NULL) || (pLevel == M4OSA_NULL)) {
599        ALOGE("getH263ProfileAndLevel invalid pointer for pProfile");
600        return M4ERR_PARAMETER;
601    }
602
603    if ((DSISize < index) || (pDSI == M4OSA_NULL)) {
604        ALOGE("getH263ProfileAndLevel: DSI is invalid");
605        *pProfile = M4VIDEOEDITING_VIDEO_UNKNOWN_PROFILE;
606        *pLevel = M4VIDEOEDITING_VIDEO_UNKNOWN_LEVEL;
607        return M4ERR_PARAMETER;
608    }
609    ALOGV("getH263ProfileAndLevel profile_byte %d, level_byte",
610          pDSI[6], pDSI[5]);
611    /* get the H263 level */
612    switch (pDSI[5]) {
613        case 10:
614            *pLevel = OMX_VIDEO_H263Level10;
615            break;
616        case 20:
617            *pLevel = OMX_VIDEO_H263Level20;
618            break;
619        case 30:
620            *pLevel = OMX_VIDEO_H263Level30;
621            break;
622        case 40:
623            *pLevel = OMX_VIDEO_H263Level40;
624            break;
625        case 45:
626            *pLevel = OMX_VIDEO_H263Level45;
627            break;
628        case 50:
629            *pLevel = OMX_VIDEO_H263Level50;
630            break;
631        case 60:
632            *pLevel = OMX_VIDEO_H263Level60;
633            break;
634        case 70:
635            *pLevel = OMX_VIDEO_H263Level70;
636            break;
637        default:
638           *pLevel = M4VIDEOEDITING_VIDEO_UNKNOWN_LEVEL;
639    }
640
641    /* get H263 profile */
642    switch (pDSI[6]) {
643        case 0:
644            *pProfile = OMX_VIDEO_H263ProfileBaseline;
645            break;
646        case 1:
647            *pProfile = OMX_VIDEO_H263ProfileH320Coding;
648            break;
649        case 2:
650            *pProfile = OMX_VIDEO_H263ProfileBackwardCompatible;
651            break;
652        case 3:
653            *pProfile = OMX_VIDEO_H263ProfileISWV2;
654            break;
655        case 4:
656            *pProfile = OMX_VIDEO_H263ProfileISWV3;
657            break;
658        case 5:
659            *pProfile = OMX_VIDEO_H263ProfileHighCompression;
660            break;
661        case 6:
662            *pProfile = OMX_VIDEO_H263ProfileInternet;
663            break;
664        case 7:
665            *pProfile = OMX_VIDEO_H263ProfileInterlace;
666            break;
667        case 8:
668            *pProfile = OMX_VIDEO_H263ProfileHighLatency;
669            break;
670        default:
671           *pProfile = M4VIDEOEDITING_VIDEO_UNKNOWN_PROFILE;
672    }
673    ALOGV("getH263ProfileAndLevel profile %ld level %ld", *pProfile, *pLevel);
674    return M4NO_ERROR;
675}
676
677M4OSA_ERR getMPEG4ProfileAndLevel(M4OSA_UInt8 profileAndLevel,
678                      M4OSA_Int32 *pProfile, M4OSA_Int32 *pLevel) {
679
680    M4OSA_UInt32 i = 0;
681    M4OSA_UInt32 length = 0;
682    if ((pProfile == M4OSA_NULL) || (pLevel == M4OSA_NULL)) {
683        return M4ERR_PARAMETER;
684    }
685    ALOGV("getMPEG4ProfileAndLevel profileAndLevel %d", profileAndLevel);
686    length = sizeof(mpeg4ProfileLevelTable) /sizeof(mpeg4ProfileLevelTable[0]);
687    *pProfile = M4VIDEOEDITING_VIDEO_UNKNOWN_PROFILE;
688    *pLevel = M4VIDEOEDITING_VIDEO_UNKNOWN_LEVEL;
689    for (i = 0; i < length; i++) {
690        if (mpeg4ProfileLevelTable[i].code == profileAndLevel) {
691            *pProfile = mpeg4ProfileLevelTable[i].profile;
692            *pLevel = mpeg4ProfileLevelTable[i].level;
693            break;
694        }
695    }
696    ALOGV("getMPEG4ProfileAndLevel profile %ld level %ld", *pProfile, *pLevel);
697    return M4NO_ERROR;
698}
699