videoeditorengine/h263decoder/src/VedVolReader.cpp
changeset 0 951a5db380a0
equal deleted inserted replaced
-1:000000000000 0:951a5db380a0
       
     1 /*
       
     2 * Copyright (c) 2010 Ixonos Plc.
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - Initial contribution
       
    11 *
       
    12 * Contributors:
       
    13 * Ixonos Plc
       
    14 *
       
    15 * Description:  
       
    16 * MPEG-4 VOL header parsing.
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include "mpegcons.h"
       
    23 #include "VedVolReader.h"
       
    24 
       
    25 
       
    26 
       
    27 // MACROS
       
    28 #ifdef _DEBUG
       
    29 #include <e32svr.h>
       
    30 #define PRINT(x) RDebug::Print x;
       
    31 #else
       
    32 #define PRINT(x)
       
    33 #endif
       
    34 
       
    35 
       
    36 
       
    37 // CONSTANTS
       
    38 const TUint8 CVedVolReader::KMsbMask[] = {1, 3, 7, 15, 31, 63, 127, 255};
       
    39 const TUint8 CVedVolReader::KLsbMask[] = {255, 254, 252, 248, 240, 224, 192, 128, 0};
       
    40 
       
    41 const TInt CVedVolReader::KMaxUserDataLength = 512;
       
    42 
       
    43 
       
    44 
       
    45 // ================= MEMBER FUNCTIONS =======================
       
    46 
       
    47 // Two-phased constructor
       
    48 EXPORT_C CVedVolReader* CVedVolReader::NewL()
       
    49     {
       
    50     CVedVolReader* self = new (ELeave) CVedVolReader();
       
    51     CleanupStack::PushL(self);
       
    52     self->ConstructL();
       
    53     CleanupStack::Pop(self);
       
    54     return self;
       
    55     }
       
    56 
       
    57 
       
    58 // C++ default constructor
       
    59 CVedVolReader::CVedVolReader() : iBitstreamMode(EVedVideoBitstreamModeUnknown)
       
    60     {
       
    61     // Reset the header data to zeroes
       
    62     Mem::FillZ(&iHeader, sizeof(TVolHeader));
       
    63     }
       
    64 
       
    65 // Symbian OS default constructor can leave
       
    66 void CVedVolReader::ConstructL()
       
    67     {
       
    68     }
       
    69 
       
    70 // Destructor
       
    71 CVedVolReader::~CVedVolReader()
       
    72     {
       
    73     if (iHeader.iUserData != 0)
       
    74         {
       
    75         delete iHeader.iUserData;
       
    76         }
       
    77     }
       
    78     
       
    79 // ---------------------------------------------------------
       
    80 // CVedVolReader::ParseVolHeaderL
       
    81 // Parses given Video Object Layer header
       
    82 // ---------------------------------------------------------
       
    83 //
       
    84 EXPORT_C TInt CVedVolReader::ParseVolHeaderL(TDesC8& aData)
       
    85     {
       
    86     TInt useDefaultVBVParams = 0;
       
    87     TInt numBits;
       
    88     TUint32 bits;
       
    89     
       
    90     // Reset the header data
       
    91     if (iHeader.iUserData != 0)
       
    92         {
       
    93         delete iHeader.iUserData;
       
    94         iHeader.iUserData = 0;
       
    95         }
       
    96     Mem::FillZ(&iHeader, sizeof(TVolHeader));
       
    97     iBitstreamMode = EVedVideoBitstreamModeUnknown;
       
    98     iHeaderSize = 0;
       
    99     
       
   100     // Check that we have something to parse
       
   101     if (aData.Length() == 0)
       
   102         {
       
   103         User::Leave(KErrNotFound);
       
   104         }
       
   105     
       
   106     TSeqHeaderBuffer buffer(aData, 0, 7);   // Bit 7 is the first bit in a byte   
       
   107     
       
   108     // if H.263 PSC is present
       
   109     bits = ReadSeqHeaderBits(buffer, 22, EFalse);
       
   110     if (bits == 32)
       
   111         {
       
   112         // This is H.263 so there are no VOL headers
       
   113         iBitstreamMode = EVedVideoBitstreamModeH263;
       
   114         return KErrNone;
       
   115         }
       
   116 
       
   117     // if Visual Object Sequence Start Code is present 
       
   118     bits = ReadSeqHeaderBits(buffer, MP4_VOS_START_CODE_LENGTH, EFalse);
       
   119     if (bits == MP4_VOS_START_CODE)
       
   120         {
       
   121         // vos_start_code
       
   122         ReadSeqHeaderBits(buffer, MP4_VOS_START_CODE_LENGTH, ETrue);
       
   123 
       
   124         // profile_and_level_indication (8 bits) 
       
   125         bits = ReadSeqHeaderBits(buffer, 8, ETrue);      
       
   126         //   8: Simple Profile Level 0 (from ISO/IEC 14496-2:1999/FPDAM4 [N3670] October 2000)
       
   127         //   9: Simple Profile Level 0b
       
   128         //   1: Simple Profile Level 1
       
   129         //   2: Simple Profile Level 2
       
   130         //   3: Simple Profile Level 3
       
   131         //   4: Simple Profile Level 4a
       
   132         if (bits != 1 && bits != 2 && bits != 3 && bits != 4 && bits != 8 && bits != 9)
       
   133             {
       
   134             // Profile level id was not recognized so take a guess
       
   135             // This is changed later if resolution does not match
       
   136             bits = 9;
       
   137             }
       
   138             
       
   139         iHeader.iProfileLevelId = (TInt) bits;
       
   140             
       
   141         ReadUserDataL(buffer);
       
   142         }
       
   143 
       
   144     // if Visual Object Start Code is present 
       
   145     bits = ReadSeqHeaderBits(buffer, MP4_VO_START_CODE_LENGTH, EFalse);
       
   146     if (bits == MP4_VO_START_CODE)
       
   147         {
       
   148         // visual_object_start_code
       
   149         ReadSeqHeaderBits(buffer, MP4_VO_START_CODE_LENGTH, ETrue);
       
   150 
       
   151         // is_visual_object_identifier (1 bit)
       
   152         bits = ReadSeqHeaderBits(buffer, 1, ETrue);
       
   153         if (bits)
       
   154             {
       
   155             // visual_object_ver_id (4 bits)
       
   156             bits = ReadSeqHeaderBits(buffer, 4, ETrue);
       
   157             if (bits != 1 && bits != 2)
       
   158                 {
       
   159                 // this is not an MPEG-4 version 1 or 2 stream
       
   160                 PRINT((_L("CVedVolReader: ERROR - This is not an MPEG-4 version 1 or 2 stream")))
       
   161                 User::Leave(KErrNotSupported);
       
   162                 }
       
   163 
       
   164             // visual_object_priority (3 bits) 
       
   165             bits = ReadSeqHeaderBits(buffer, 3, ETrue);
       
   166             iHeader.iVoPriority = (TInt) bits;
       
   167             } 
       
   168         else
       
   169             {
       
   170             iHeader.iVoPriority = 0;
       
   171             }
       
   172 
       
   173         // visual_object_type (4 bits)
       
   174         bits = ReadSeqHeaderBits(buffer, 4, ETrue);
       
   175         if (bits != 1)
       
   176             {
       
   177             // this is not a video object
       
   178             PRINT((_L("CVedVolReader: ERROR - This is not a video object")))
       
   179             User::Leave(KErrNotSupported);
       
   180             }
       
   181 
       
   182         // is_video_signal_type (1 bit)
       
   183         bits = ReadSeqHeaderBits(buffer, 1, ETrue);
       
   184         if (bits)
       
   185             {
       
   186             /* Note: The following fields in the bitstream give information about the 
       
   187                video signal type before encoding. These parameters don't influence the 
       
   188                decoding algorithm, but the composition at the output of the video decoder.
       
   189                Until a way to utilize them is found, these fields are just dummyly read,
       
   190                but not interpreted.
       
   191                For interpretation see the MPEG-4 Visual standard page 66-70. */
       
   192 
       
   193             // video_format (3 bits)
       
   194             bits = ReadSeqHeaderBits(buffer, 3, ETrue);
       
   195             iHeader.iVideoFormat = (TInt) bits;
       
   196 
       
   197             // video_range (1 bit)
       
   198             bits = ReadSeqHeaderBits(buffer, 1, ETrue);
       
   199             iHeader.iVideoRange = (TInt) bits;
       
   200 
       
   201             // colour_description (1 bit)
       
   202             bits = ReadSeqHeaderBits(buffer, 1, ETrue);
       
   203             if (bits)
       
   204                 {          
       
   205                 // colour_primaries (8 bits)
       
   206                 bits = ReadSeqHeaderBits(buffer, 8, ETrue);
       
   207                 iHeader.iColourPrimaries = (TInt) bits;
       
   208 
       
   209                 // transfer_characteristics (8 bits)
       
   210                 bits = ReadSeqHeaderBits(buffer, 8, ETrue);
       
   211                 iHeader.iTransferCharacteristics = (TInt) bits;
       
   212 
       
   213                 // matrix_coefficients (8 bits)
       
   214                 bits = ReadSeqHeaderBits(buffer, 8, ETrue);
       
   215                 iHeader.iMatrixCoefficients = (TInt) bits;
       
   216                 }
       
   217             else
       
   218                 {
       
   219                 iHeader.iColourPrimaries = 1;         // default: ITU-R BT.709 
       
   220                 iHeader.iTransferCharacteristics = 1; // default: ITU-R BT.709 
       
   221                 iHeader.iMatrixCoefficients = 1;      // default: ITU-R BT.709 
       
   222                 }
       
   223             } 
       
   224         else
       
   225             {
       
   226             // default values
       
   227             iHeader.iVideoFormat = 5;             // Unspecified video format 
       
   228             iHeader.iVideoRange = 0;              // Y range 16-235 pixel values 
       
   229             iHeader.iColourPrimaries = 1;         // ITU-R BT.709 
       
   230             iHeader.iTransferCharacteristics = 1; // ITU-R BT.709 
       
   231             iHeader.iMatrixCoefficients = 1;      // ITU-R BT.709 
       
   232             }
       
   233 
       
   234         // check the next start code
       
   235         ReadSeqHeaderBits(buffer, 1, ETrue);
       
   236         if (buffer.iBitInOctet != 7)
       
   237             {
       
   238             numBits = buffer.iBitInOctet + 1;
       
   239 
       
   240             bits = ReadSeqHeaderBits(buffer, numBits, ETrue);
       
   241             if (bits != (TUint32) ((1 << numBits)-1))
       
   242                 {
       
   243                 // stuffing error in VO
       
   244                 PRINT((_L("CVedVolReader: ERROR - Stuffing error")))
       
   245                 User::Leave(KErrNotSupported);
       
   246                 }
       
   247             }
       
   248 
       
   249         ReadUserDataL(buffer);
       
   250         }
       
   251    
       
   252     // if Video Object Start Code is present
       
   253     bits = ReadSeqHeaderBits(buffer, MP4_VID_START_CODE_LENGTH, EFalse);
       
   254     if (bits == MP4_VID_START_CODE)
       
   255         {
       
   256         // video_object_start_code 
       
   257         ReadSeqHeaderBits(buffer, MP4_VID_START_CODE_LENGTH, ETrue);
       
   258 
       
   259         // video_object_id
       
   260         bits = ReadSeqHeaderBits(buffer, MP4_VID_ID_CODE_LENGTH, ETrue);
       
   261         iHeader.iVoId = (TInt) bits;
       
   262         }
       
   263         
       
   264     // Check if H.263 PSC follows the VO header, in which case this is MPEG-4 with short header
       
   265     bits = ReadSeqHeaderBits(buffer, 22, EFalse);
       
   266     if (bits == 32 || buffer.iData.Length() <= buffer.iGetIndex)
       
   267         {
       
   268         iBitstreamMode = EVedVideoBitstreamModeMPEG4ShortHeader;
       
   269         
       
   270         // Calculate the header size in bytes
       
   271         if (buffer.iBitInOctet == 7)
       
   272             {
       
   273             // The size is a multiple of 8 bits so the size is the number of bytes we've read so far
       
   274             iHeaderSize = buffer.iGetIndex;
       
   275             }
       
   276         else
       
   277             {
       
   278             // Round up to the next full byte
       
   279             iHeaderSize = buffer.iGetIndex + 1;
       
   280             }
       
   281         
       
   282         // We no longer support short header clips    
       
   283         User::Leave(KErrNotSupported);
       
   284         }
       
   285 
       
   286     // vol_start_code 
       
   287     bits = ReadSeqHeaderBits(buffer, MP4_VOL_START_CODE_LENGTH, ETrue);
       
   288     if(bits != MP4_VOL_START_CODE)
       
   289     {
       
   290         PRINT((_L("CVedVolReader: ERROR - Bitstream does not start with MP4_VOL_START_CODE")))
       
   291         User::Leave(KErrCorrupt);
       
   292     }
       
   293 
       
   294     // vol_id
       
   295     bits = ReadSeqHeaderBits(buffer, MP4_VOL_ID_CODE_LENGTH, ETrue);
       
   296     iHeader.iVolId = (TInt) bits;
       
   297 
       
   298     // random_accessible_vol (1 bit)
       
   299     bits = ReadSeqHeaderBits(buffer, 1, ETrue);
       
   300     iHeader.iRandomAccessibleVol = (TUint8) bits;
       
   301 
       
   302     // video_object_type_indication (8 bits)
       
   303     bits = ReadSeqHeaderBits(buffer, 8, ETrue);
       
   304     if (bits != 1)
       
   305         {
       
   306         // this is not a simple video object stream 
       
   307         PRINT((_L("CVedVolReader: ERROR - This is not a simple video object stream")))
       
   308         User::Leave(KErrNotSupported);
       
   309         }
       
   310 
       
   311     // is_object_layer_identifier (1 bit)
       
   312     bits = ReadSeqHeaderBits(buffer, 1, ETrue);
       
   313     if (bits)
       
   314         {
       
   315         // visual_object_ver_id (4 bits)
       
   316         bits = ReadSeqHeaderBits(buffer, 4, ETrue);
       
   317         if (bits != 1 && bits != 2)
       
   318             {
       
   319             // this is not an MPEG-4 version 1 or 2 stream
       
   320             PRINT((_L("CVedVolReader: ERROR - This is not an MPEG-4 version 1 or 2 stream")))
       
   321             User::Leave(KErrNotSupported);
       
   322             }
       
   323 
       
   324         // video_object_layer_priority (3 bits)
       
   325         bits = ReadSeqHeaderBits(buffer, 3, ETrue);
       
   326         iHeader.iVoPriority = (TInt) bits;
       
   327         } 
       
   328 
       
   329     // aspect_ratio_info: `0010`- 12:11 (625-type for 4:3 picture)
       
   330     bits = ReadSeqHeaderBits(buffer, 4, ETrue);
       
   331     iHeader.iPixelAspectRatio = (TInt) bits;
       
   332 
       
   333     // extended par 
       
   334     if (bits == 15)
       
   335         { 
       
   336         // par_width 
       
   337         bits = ReadSeqHeaderBits(buffer, 8, ETrue);
       
   338         // par_height 
       
   339         bits = ReadSeqHeaderBits(buffer, 8, ETrue);
       
   340         }
       
   341    
       
   342     // vol_control_parameters flag 
       
   343     bits = ReadSeqHeaderBits(buffer, 1, ETrue);
       
   344     if (bits)
       
   345         {
       
   346         // chroma_format (2 bits)
       
   347         bits = ReadSeqHeaderBits(buffer, 2, ETrue);
       
   348         if (bits != 1)
       
   349             {
       
   350             PRINT((_L("CVedVolReader: ERROR - Not supported chroma format")))
       
   351             User::Leave(KErrNotSupported);
       
   352             }
       
   353 
       
   354         // low_delay (1 bits)
       
   355         bits = ReadSeqHeaderBits(buffer, 1, ETrue);
       
   356 
       
   357         // vbv_parameters (1 bits)
       
   358         bits = ReadSeqHeaderBits(buffer, 1, ETrue);
       
   359         if (bits)
       
   360             {
       
   361             // first_half_bitrate (15 bits) 
       
   362             bits = ReadSeqHeaderBits(buffer, 15, ETrue);
       
   363             iHeader.iBitRate = (bits << 15);
       
   364           
       
   365             // marker_bit
       
   366             if (!ReadSeqHeaderBits(buffer, 1, ETrue))
       
   367                 {
       
   368                 User::Leave(KErrCorrupt);
       
   369                 }
       
   370            
       
   371             // latter_half_bitrate (15 bits)
       
   372             bits = ReadSeqHeaderBits(buffer, 15, ETrue);
       
   373             iHeader.iBitRate += bits;
       
   374             iHeader.iBitRate *= 400;
       
   375            
       
   376             // marker_bit
       
   377             if (!ReadSeqHeaderBits(buffer, 1, ETrue))
       
   378                 {
       
   379                 User::Leave(KErrCorrupt);
       
   380                 }
       
   381            
       
   382             // first_half_vbv_buffer_size (15 bits)
       
   383             bits = ReadSeqHeaderBits(buffer, 15, ETrue);
       
   384             iHeader.iVbvBufferSize = (bits << 3);
       
   385            
       
   386             // marker_bit
       
   387             if (!ReadSeqHeaderBits(buffer, 1, ETrue))
       
   388                 {
       
   389                 User::Leave(KErrCorrupt);
       
   390                 }
       
   391            
       
   392             // latter_half_vbv_buffer_size (3 bits)
       
   393             bits = ReadSeqHeaderBits(buffer, 3, ETrue);
       
   394             iHeader.iVbvBufferSize += bits;
       
   395             iHeader.iVbvBufferSize *= 16384;
       
   396            
       
   397             // first_half_vbv_occupancy (11 bits)
       
   398             bits = ReadSeqHeaderBits(buffer, 11, ETrue);
       
   399             iHeader.iVbvOccupancy = (bits << 15);
       
   400            
       
   401             // marker_bit
       
   402             if (!ReadSeqHeaderBits(buffer, 1, ETrue))
       
   403                 {
       
   404                 User::Leave(KErrCorrupt);
       
   405                 }
       
   406            
       
   407             // latter_half_vbv_occupancy (15 bits) 
       
   408             bits = ReadSeqHeaderBits(buffer, 15, ETrue);
       
   409             iHeader.iVbvOccupancy += bits;
       
   410             iHeader.iVbvOccupancy *= 64;
       
   411            
       
   412             // marker_bit
       
   413             if (!ReadSeqHeaderBits(buffer, 1, ETrue))
       
   414                 {
       
   415                 User::Leave(KErrCorrupt);
       
   416                 }
       
   417             }
       
   418         else
       
   419             {
       
   420             useDefaultVBVParams = 1;
       
   421             }
       
   422         }     
       
   423     else
       
   424         {
       
   425         useDefaultVBVParams = 1;
       
   426         }
       
   427 
       
   428     // vol_shape (2 bits) 
       
   429     bits = ReadSeqHeaderBits(buffer, 2, ETrue);
       
   430     // rectangular_shape = '00'
       
   431     if (bits != 0)
       
   432         {
       
   433         PRINT((_L("CVedVolReader: ERROR - Not rectangular shape is not supported")))
       
   434         User::Leave(KErrNotSupported);
       
   435         }
       
   436 
       
   437     // marker_bit
       
   438     if (!ReadSeqHeaderBits(buffer, 1, ETrue))
       
   439         {
       
   440         User::Leave(KErrCorrupt);
       
   441         }
       
   442     
       
   443     // time_increment_resolution 
       
   444     bits = ReadSeqHeaderBits(buffer, 16, ETrue);
       
   445     iHeader.iTimeIncrementResolution = (TInt) bits;
       
   446  
       
   447     // marker_bit
       
   448     if (!ReadSeqHeaderBits(buffer, 1, ETrue))
       
   449         {
       
   450         User::Leave(KErrCorrupt);
       
   451         }
       
   452     
       
   453     // fixed_vop_rate 
       
   454     bits = ReadSeqHeaderBits(buffer, 1, ETrue);
       
   455 
       
   456     // fixed_vop_time_increment (1-15 bits)
       
   457     if (bits)
       
   458         {
       
   459         for (numBits = 1; ((iHeader.iTimeIncrementResolution-1) >> numBits) != 0; numBits++) 
       
   460             {
       
   461             }
       
   462 
       
   463         bits = ReadSeqHeaderBits(buffer, numBits, ETrue);
       
   464         }
       
   465 
       
   466     // marker_bit
       
   467     if (!ReadSeqHeaderBits(buffer, 1, ETrue))
       
   468         {
       
   469         User::Leave(KErrCorrupt);
       
   470         }
       
   471     
       
   472     // vol_width (13 bits) 
       
   473     bits = ReadSeqHeaderBits(buffer, 13, ETrue);
       
   474     iHeader.iLumWidth = (TInt) bits;
       
   475 
       
   476     // marker_bit
       
   477     if (!ReadSeqHeaderBits(buffer, 1, ETrue))
       
   478         {
       
   479         User::Leave(KErrCorrupt);
       
   480         }
       
   481     
       
   482     // vol_height (13 bits) 
       
   483     bits = ReadSeqHeaderBits(buffer, 13, ETrue);
       
   484     iHeader.iLumHeight = (TInt) bits;
       
   485     
       
   486     // Accept only resolutions that are divisible by 16
       
   487     if ( ((iHeader.iLumWidth & 0x0000000f) != 0) ||
       
   488         ((iHeader.iLumHeight & 0x0000000f) != 0) )
       
   489         {
       
   490         PRINT((_L("CVedVolReader: ERROR - Unsupported resolution")))
       
   491         User::Leave(KErrNotSupported);
       
   492         }
       
   493         
       
   494     TInt macroBlocks = iHeader.iLumWidth * iHeader.iLumHeight / (16 * 16);
       
   495     
       
   496     // Check that we don't have too many macro blocks (ie resolution is not too big)
       
   497     if( macroBlocks > 1200 )
       
   498         {
       
   499         PRINT((_L("CVedVolReader: ERROR - Unsupported resolution")))
       
   500         User::Leave(KErrNotSupported);
       
   501         }
       
   502         
       
   503     // Check that profile level id matches with the number of macro blocks
       
   504     if( macroBlocks > 396 )
       
   505         {
       
   506         // Resolution is higher than CIF => level must be 4a
       
   507         if( iHeader.iProfileLevelId != 4 )
       
   508             {
       
   509             iHeader.iProfileLevelId = 4;
       
   510             useDefaultVBVParams = 1;
       
   511             }
       
   512         }
       
   513     else if( macroBlocks > 99 )
       
   514         {
       
   515         // Resolution is higher than QCIF => level must be atleast 2
       
   516         if( iHeader.iProfileLevelId < 2 || iHeader.iProfileLevelId > 4 )
       
   517             {
       
   518             iHeader.iProfileLevelId = 3;    // QVGA/CIF @ 30fps
       
   519             useDefaultVBVParams = 1;
       
   520             }
       
   521         }
       
   522     
       
   523     // Set default VBV params if not set already  
       
   524     if (useDefaultVBVParams)
       
   525         {
       
   526         switch (iHeader.iProfileLevelId)
       
   527             {
       
   528             case 1:
       
   529                 iHeader.iVbvBufferSize = 10;
       
   530                 iHeader.iBitRate = 64;
       
   531                 break;
       
   532             case 2:
       
   533                 iHeader.iVbvBufferSize = 20;
       
   534                 iHeader.iBitRate = 128;
       
   535                 break;
       
   536             case 4:
       
   537                 iHeader.iVbvBufferSize = 80;
       
   538                 iHeader.iBitRate = 4000;
       
   539                 break;
       
   540             case 8:
       
   541                 iHeader.iVbvBufferSize = 10;
       
   542                 iHeader.iBitRate = 64;
       
   543                 break;
       
   544             case 9:
       
   545                 iHeader.iVbvBufferSize = 20;
       
   546                 iHeader.iBitRate = 128;
       
   547                 break;
       
   548             default:
       
   549                 iHeader.iVbvBufferSize = 20;
       
   550                 iHeader.iBitRate = 384;
       
   551                 break;
       
   552             }
       
   553         
       
   554         iHeader.iVbvOccupancy = iHeader.iVbvBufferSize * 170;
       
   555        
       
   556         iHeader.iVbvOccupancy *= 64;
       
   557         iHeader.iVbvBufferSize *= 16384;
       
   558         iHeader.iBitRate *= 1024;
       
   559         }
       
   560     
       
   561     // marker_bit
       
   562     if (!ReadSeqHeaderBits(buffer, 1, ETrue))
       
   563         {
       
   564         User::Leave(KErrCorrupt);
       
   565         }
       
   566     
       
   567     // interlaced (1 bit)
       
   568     bits = ReadSeqHeaderBits(buffer, 1, ETrue);
       
   569     if (bits)
       
   570         {
       
   571         PRINT((_L("CVedVolReader: ERROR - Interlaced VOP not supported")))
       
   572         User::Leave(KErrNotSupported);
       
   573         }
       
   574 
       
   575     // OBMC_disable
       
   576     bits = ReadSeqHeaderBits(buffer, 1, ETrue);
       
   577     if (!bits)
       
   578         {
       
   579         PRINT((_L("CVedVolReader: ERROR - Overlapped motion compensation not supported")))
       
   580         User::Leave(KErrNotSupported);
       
   581         }
       
   582 
       
   583     // sprite_enable (1 bit) 
       
   584     bits = ReadSeqHeaderBits(buffer, 1, ETrue);
       
   585     if (bits)
       
   586         {
       
   587         PRINT((_L("CVedVolReader: ERROR - Sprites not supported")))
       
   588         User::Leave(KErrNotSupported);
       
   589         }
       
   590 
       
   591     // not_8_bit (1 bit) 
       
   592     bits = ReadSeqHeaderBits(buffer, 1, ETrue);
       
   593     if (bits)
       
   594         {
       
   595         PRINT((_L("CVedVolReader: ERROR - Not 8 bits/pixel not supported")))
       
   596         User::Leave(KErrNotSupported);
       
   597         }
       
   598 
       
   599     // quant_type (1 bit) 
       
   600     bits = ReadSeqHeaderBits(buffer, 1, ETrue);
       
   601     if (bits)
       
   602         {
       
   603         PRINT((_L("CVedVolReader: ERROR - H.263/MPEG-2 Quant Table switch not supported")))
       
   604         User::Leave(KErrNotSupported);
       
   605         }
       
   606 
       
   607     // complexity_estimation_disable (1 bit) 
       
   608     bits = ReadSeqHeaderBits(buffer, 1, ETrue);
       
   609     if (!bits)
       
   610         {
       
   611         PRINT((_L("CVedVolReader: ERROR - Complexity estimation header not supported")))
       
   612         User::Leave(KErrNotSupported);
       
   613         }
       
   614   
       
   615     // resync_marker_disable (1 bit)
       
   616     bits = ReadSeqHeaderBits(buffer, 1, ETrue);
       
   617     iHeader.iErrorResDisable = (TUint8) bits;
       
   618 
       
   619     // data_partitioned (1 bit) 
       
   620     bits = ReadSeqHeaderBits(buffer, 1, ETrue);
       
   621     iHeader.iDataPartitioned = (TUint8) bits;
       
   622 
       
   623     if (iHeader.iDataPartitioned)
       
   624         {
       
   625         // reversible_vlc (1 bit)
       
   626         bits = ReadSeqHeaderBits(buffer, 1, ETrue);
       
   627         iHeader.iReversibleVlc = (TUint8) bits;
       
   628         }
       
   629 
       
   630     // scalability (1 bit)
       
   631     bits = ReadSeqHeaderBits(buffer, 1, ETrue);
       
   632     if (bits)
       
   633         {
       
   634         PRINT((_L("CVedVolReader: ERROR - Scalability not supported")))
       
   635         User::Leave(KErrNotSupported);
       
   636         }
       
   637 
       
   638     // check the next start code
       
   639     ReadSeqHeaderBits(buffer, 1, ETrue);
       
   640     if (buffer.iBitInOctet != 7)
       
   641         {
       
   642         numBits = buffer.iBitInOctet + 1;
       
   643        
       
   644         bits = ReadSeqHeaderBits(buffer, numBits, ETrue);
       
   645         
       
   646         /* Removed temporarily
       
   647         if (bits != (TUint32) ((1 << numBits)-1))
       
   648             {
       
   649             // this is not a video object
       
   650             PRINT((_L("CVedVolReader: ERROR - Stuffing error")))
       
   651             User::Leave(KErrNotSupported);
       
   652             }*/
       
   653         }
       
   654 
       
   655     ReadUserDataL(buffer);
       
   656         
       
   657     // Calculate the header size in bytes
       
   658     if (buffer.iBitInOctet == 7)
       
   659         {
       
   660         // The size is a multiple of 8 bits so the size is the number of bytes we've read so far
       
   661         iHeaderSize = buffer.iGetIndex;
       
   662         }
       
   663     else
       
   664         {
       
   665         // Round up to the next full byte
       
   666         iHeaderSize = buffer.iGetIndex + 1;
       
   667         }
       
   668      
       
   669     // Determine the bitstream mode  
       
   670     iBitstreamMode = CheckBitstreamMode(iHeader.iErrorResDisable, iHeader.iDataPartitioned, iHeader.iReversibleVlc);
       
   671 
       
   672     // If no error in bit buffer functions
       
   673     return KErrNone;
       
   674     }
       
   675 
       
   676 // ---------------------------------------------------------
       
   677 // CVedVolReader::ReadSeqHeaderBits
       
   678 // Reads requested bits from given buffer
       
   679 // ---------------------------------------------------------
       
   680 //  
       
   681 TUint32 CVedVolReader::ReadSeqHeaderBits(TSeqHeaderBuffer& aBuffer, TInt aNumBits, TBool aFlush)
       
   682     {      
       
   683     TUint startIndex;       // the index of the first byte to read 
       
   684     TUint startMask;        // the mask for the first byte 
       
   685     TUint endIndex;         // the index of the last byte to read 
       
   686     TUint endMask;          // the mask for the last byte 
       
   687     TUint endShift;         // the number of shifts after masking the last byte 
       
   688     TUint endNumberOfBits;  // the number of bits in the last byte 
       
   689     TUint newBitIndex;      // bitIndex after getting the bits 
       
   690     TUint newGetIndex;      // getIndex after getting the bits 
       
   691     
       
   692     TUint32 returnValue = 0;
       
   693 
       
   694     startIndex = aBuffer.iGetIndex;
       
   695     startMask = KMsbMask[aBuffer.iBitInOctet];
       
   696 
       
   697     // Check that there are enough bits left
       
   698     if (startIndex * 8 + aNumBits > aBuffer.iData.Length() * 8)
       
   699         {
       
   700 	    return 0;
       
   701         }
       
   702 
       
   703     if (aBuffer.iBitInOctet + 1 >= aNumBits)
       
   704         {
       
   705         // The bits are within one byte. 
       
   706         endShift = aBuffer.iBitInOctet - aNumBits + 1;
       
   707         endMask = KLsbMask[endShift];
       
   708         returnValue = (aBuffer.iData[startIndex] & startMask & endMask) >> endShift;
       
   709         if (endShift > 0)
       
   710             {
       
   711             newBitIndex = aBuffer.iBitInOctet - aNumBits;
       
   712             newGetIndex = aBuffer.iGetIndex;
       
   713             }
       
   714         else
       
   715             {
       
   716             newBitIndex = 7;
       
   717             newGetIndex = aBuffer.iGetIndex + 1;
       
   718             }
       
   719         } 
       
   720     else
       
   721         {
       
   722         // The bits are in multiple bytes. 
       
   723         aNumBits -= aBuffer.iBitInOctet + 1;
       
   724         endNumberOfBits = aNumBits & 7;
       
   725 
       
   726         newBitIndex = 7 - endNumberOfBits;
       
   727         newGetIndex = aBuffer.iGetIndex + (aNumBits >> 3) + 1;
       
   728       
       
   729         // Calculate the return value. 
       
   730         endIndex = newGetIndex;
       
   731         endShift = 8 - (aNumBits & 7);
       
   732         endMask = KLsbMask[endShift];
       
   733       
       
   734         returnValue = aBuffer.iData[startIndex] & startMask;
       
   735         startIndex++;
       
   736       
       
   737         while (startIndex != endIndex)
       
   738             {
       
   739             returnValue <<= 8;
       
   740             returnValue += (TUint8) aBuffer.iData[startIndex];
       
   741             startIndex++;
       
   742             }
       
   743         
       
   744         if (endNumberOfBits != 0)
       
   745             {
       
   746             returnValue <<= endNumberOfBits;
       
   747             returnValue += (aBuffer.iData[startIndex] & endMask) >> endShift;
       
   748             }
       
   749         }
       
   750 
       
   751     if (aFlush)
       
   752         {
       
   753         // Update indexes. 
       
   754         aBuffer.iGetIndex = newGetIndex;
       
   755         aBuffer.iBitInOctet = newBitIndex;
       
   756         }
       
   757 
       
   758     return returnValue;
       
   759     }
       
   760 
       
   761 // ---------------------------------------------------------
       
   762 // CVedVolReader::ReadUserDataL
       
   763 // Reads user data from given buffer
       
   764 // ---------------------------------------------------------
       
   765 //    
       
   766 void CVedVolReader::ReadUserDataL(TSeqHeaderBuffer& aBuffer)
       
   767     {
       
   768     TUint32 bits;
       
   769     
       
   770     // Check if User data is available 
       
   771     bits = ReadSeqHeaderBits(aBuffer, 32, EFalse);
       
   772     if (bits == MP4_USER_DATA_START_CODE)
       
   773         {
       
   774         if (iHeader.iUserData == 0)
       
   775             {
       
   776             iHeader.iUserData = HBufC8::NewL(KMaxUserDataLength);
       
   777             }
       
   778             
       
   779         TInt i = iHeader.iUserData->Length();    
       
   780         do 
       
   781             {
       
   782             bits = ReadSeqHeaderBits(aBuffer, 8, ETrue);
       
   783             if (i++ < KMaxUserDataLength)
       
   784                 {
       
   785                 (iHeader.iUserData->Des()).Append(TChar(bits));
       
   786                 }
       
   787             }
       
   788         while (aBuffer.iData.Length() > aBuffer.iGetIndex &&
       
   789                ReadSeqHeaderBits(aBuffer, 24, EFalse) != 0x1);
       
   790         }
       
   791     }
       
   792      
       
   793 // ---------------------------------------------------------
       
   794 // CVedVolReader::CheckBitstreamMode
       
   795 // Checks what is the bit stream mode the video
       
   796 // ---------------------------------------------------------
       
   797 //
       
   798 TVedVideoBitstreamMode CVedVolReader::CheckBitstreamMode(TUint8 aErd, TUint8 aDp, TUint8 aRvlc)
       
   799     {
       
   800     TVedVideoBitstreamMode mode = EVedVideoBitstreamModeUnknown;
       
   801     int combination = ((!aErd) << 2) | (aDp << 1) | aRvlc;
       
   802                       
       
   803     switch (combination)
       
   804         {
       
   805         case 0:
       
   806             mode = EVedVideoBitstreamModeMPEG4Regular;
       
   807             break;
       
   808         case 2:
       
   809             mode = EVedVideoBitstreamModeMPEG4DP;
       
   810             break;
       
   811         case 3:
       
   812             mode = EVedVideoBitstreamModeMPEG4DP_RVLC;
       
   813             break;
       
   814         case 4:
       
   815             mode = EVedVideoBitstreamModeMPEG4Resyn;
       
   816             break;
       
   817         case 6:
       
   818             mode = EVedVideoBitstreamModeMPEG4Resyn_DP;
       
   819             break;
       
   820         case 7:
       
   821             mode = EVedVideoBitstreamModeMPEG4Resyn_DP_RVLC;
       
   822             break;
       
   823         default:
       
   824             break;
       
   825         }
       
   826         
       
   827     return mode;
       
   828     }
       
   829     
       
   830 // ---------------------------------------------------------
       
   831 // CVedVolReader::TimeIncrementResolution
       
   832 // Returns the time increment resolution that was read from the VOL header
       
   833 // ---------------------------------------------------------
       
   834 //     
       
   835 EXPORT_C TInt CVedVolReader::TimeIncrementResolution() const
       
   836     {
       
   837     return iHeader.iTimeIncrementResolution;
       
   838     }
       
   839        
       
   840 // ---------------------------------------------------------
       
   841 // CVedVolReader::Width
       
   842 // Returns the width of the video that was read from the VOL header
       
   843 // ---------------------------------------------------------
       
   844 // 
       
   845 EXPORT_C TInt CVedVolReader::Width() const
       
   846     {
       
   847     return iHeader.iLumWidth;
       
   848     }
       
   849       
       
   850 // ---------------------------------------------------------
       
   851 // CVedVolReader::Height
       
   852 // Returns the height of the video that was read from the VOL header
       
   853 // ---------------------------------------------------------
       
   854 // 
       
   855 EXPORT_C TInt CVedVolReader::Height() const
       
   856     {
       
   857     return iHeader.iLumHeight;
       
   858     }
       
   859     
       
   860 // ---------------------------------------------------------
       
   861 // CVedVolReader::ProfileLevelId
       
   862 // Returns the Level Id of the Simple Profile the Video Object conforms to
       
   863 // ---------------------------------------------------------
       
   864 // 
       
   865 EXPORT_C TInt CVedVolReader::ProfileLevelId() const
       
   866     {
       
   867     return iHeader.iProfileLevelId;
       
   868     }
       
   869     
       
   870 // ---------------------------------------------------------
       
   871 // CVedVolReader::BitstreamMode
       
   872 // Returns the bitstream mode of the video
       
   873 // ---------------------------------------------------------
       
   874 //  
       
   875 EXPORT_C TVedVideoBitstreamMode CVedVolReader::BitstreamMode() const
       
   876     {
       
   877     return iBitstreamMode;
       
   878     }
       
   879     
       
   880 // ---------------------------------------------------------
       
   881 // CVedVolReader::HeaderSize
       
   882 // Returns the bitstream mode of the video
       
   883 // ---------------------------------------------------------
       
   884 //  
       
   885 EXPORT_C TInt CVedVolReader::HeaderSize() const
       
   886     {
       
   887     return iHeaderSize;
       
   888     }
       
   889