| /* |
| * Copyright (C) 2011 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #include "utils/Log.h" |
| #include "M4OSA_Types.h" |
| #include "M4OSA_Debug.h" |
| |
| #include "M4VD_EXTERNAL_Interface.h" |
| #include "M4VD_Tools.h" |
| #include "M4_VideoEditingCommon.h" |
| #include "OMX_Video.h" |
| /** |
| ************************************************************************ |
| * @file M4VD_EXTERNAL_BitstreamParser.c |
| * @brief |
| * @note This file implements external Bitstream parser |
| ************************************************************************ |
| */ |
| |
| typedef struct { |
| M4OSA_UInt8 code; |
| M4OSA_Int32 profile; |
| M4OSA_Int32 level; |
| } codeProfileLevel; |
| |
| static codeProfileLevel mpeg4ProfileLevelTable[] = { |
| {0x01, OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level1}, |
| {0x02, OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level2}, |
| {0x03, OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level3}, |
| {0x04, OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level4a}, |
| {0x05, OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level5}, |
| {0x08, OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0}, |
| {0x11, OMX_VIDEO_MPEG4ProfileSimpleScalable,OMX_VIDEO_MPEG4Level1}, |
| {0x12, OMX_VIDEO_MPEG4ProfileSimpleScalable,OMX_VIDEO_MPEG4Level2}, |
| {0x21, OMX_VIDEO_MPEG4ProfileCore, OMX_VIDEO_MPEG4Level1}, |
| {0x22, OMX_VIDEO_MPEG4ProfileCore, OMX_VIDEO_MPEG4Level2}, |
| {0x32, OMX_VIDEO_MPEG4ProfileMain, OMX_VIDEO_MPEG4Level2}, |
| {0x33, OMX_VIDEO_MPEG4ProfileMain, OMX_VIDEO_MPEG4Level3}, |
| {0x34, OMX_VIDEO_MPEG4ProfileMain, OMX_VIDEO_MPEG4Level4}, |
| {0x42, OMX_VIDEO_MPEG4ProfileNbit, OMX_VIDEO_MPEG4Level2}, |
| {0x51, OMX_VIDEO_MPEG4ProfileScalableTexture, OMX_VIDEO_MPEG4Level1}, |
| {0x61, OMX_VIDEO_MPEG4ProfileSimpleFace, OMX_VIDEO_MPEG4Level1}, |
| {0x62, OMX_VIDEO_MPEG4ProfileSimpleFace, OMX_VIDEO_MPEG4Level2}, |
| {0x71, OMX_VIDEO_MPEG4ProfileBasicAnimated, OMX_VIDEO_MPEG4Level1}, |
| {0x72, OMX_VIDEO_MPEG4ProfileBasicAnimated, OMX_VIDEO_MPEG4Level2}, |
| {0x81, OMX_VIDEO_MPEG4ProfileHybrid, OMX_VIDEO_MPEG4Level1}, |
| {0x82, OMX_VIDEO_MPEG4ProfileHybrid, OMX_VIDEO_MPEG4Level2}, |
| {0x91, OMX_VIDEO_MPEG4ProfileAdvancedRealTime, OMX_VIDEO_MPEG4Level1}, |
| {0x92, OMX_VIDEO_MPEG4ProfileAdvancedRealTime, OMX_VIDEO_MPEG4Level2}, |
| {0x93, OMX_VIDEO_MPEG4ProfileAdvancedRealTime, OMX_VIDEO_MPEG4Level3}, |
| {0x94, OMX_VIDEO_MPEG4ProfileAdvancedRealTime, OMX_VIDEO_MPEG4Level4}, |
| {0xa1, OMX_VIDEO_MPEG4ProfileCoreScalable, OMX_VIDEO_MPEG4Level1}, |
| {0xa2, OMX_VIDEO_MPEG4ProfileCoreScalable, OMX_VIDEO_MPEG4Level2}, |
| {0xa3, OMX_VIDEO_MPEG4ProfileCoreScalable, OMX_VIDEO_MPEG4Level3}, |
| {0xb1, OMX_VIDEO_MPEG4ProfileAdvancedCoding, OMX_VIDEO_MPEG4Level1}, |
| {0xb2, OMX_VIDEO_MPEG4ProfileAdvancedCoding, OMX_VIDEO_MPEG4Level2}, |
| {0xb3, OMX_VIDEO_MPEG4ProfileAdvancedCoding, OMX_VIDEO_MPEG4Level3}, |
| {0xb4, OMX_VIDEO_MPEG4ProfileAdvancedCoding, OMX_VIDEO_MPEG4Level4}, |
| {0xc1, OMX_VIDEO_MPEG4ProfileAdvancedCore, OMX_VIDEO_MPEG4Level1}, |
| {0xc2, OMX_VIDEO_MPEG4ProfileAdvancedCore, OMX_VIDEO_MPEG4Level2}, |
| {0xd1, OMX_VIDEO_MPEG4ProfileAdvancedScalable, OMX_VIDEO_MPEG4Level1}, |
| {0xd2, OMX_VIDEO_MPEG4ProfileAdvancedScalable, OMX_VIDEO_MPEG4Level2}, |
| {0xd3, OMX_VIDEO_MPEG4ProfileAdvancedScalable, OMX_VIDEO_MPEG4Level3}, |
| {0xf0, OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level0}, |
| {0xf1, OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level1}, |
| {0xf2, OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level2}, |
| {0xf3, OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level3}, |
| {0xf4, OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level4}, |
| {0xf5, OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level5} |
| }; |
| |
| M4OSA_UInt32 M4VD_EXTERNAL_GetBitsFromMemory(M4VS_Bitstream_ctxt* parsingCtxt, |
| M4OSA_UInt32 nb_bits) |
| { |
| return(M4VD_Tools_GetBitsFromMemory(parsingCtxt,nb_bits)); |
| } |
| |
| M4OSA_ERR M4VD_EXTERNAL_WriteBitsToMemory(M4OSA_UInt32 bitsToWrite, |
| M4OSA_MemAddr32 dest_bits, |
| M4OSA_UInt8 offset, M4OSA_UInt8 nb_bits) |
| { |
| return (M4VD_Tools_WriteBitsToMemory( bitsToWrite,dest_bits, |
| offset, nb_bits)); |
| } |
| |
| M4OSA_ERR M4DECODER_EXTERNAL_ParseVideoDSI(M4OSA_UInt8* pVol, M4OSA_Int32 aVolSize, |
| M4DECODER_MPEG4_DecoderConfigInfo* pDci, |
| M4DECODER_VideoSize* pVideoSize) |
| { |
| M4VS_Bitstream_ctxt parsingCtxt; |
| M4OSA_UInt32 code, j; |
| M4OSA_MemAddr8 start; |
| M4OSA_UInt8 i; |
| M4OSA_UInt32 time_incr_length; |
| M4OSA_UInt8 vol_verid=0, b_hierarchy_type; |
| |
| /* Parsing variables */ |
| M4OSA_UInt8 video_object_layer_shape = 0; |
| M4OSA_UInt8 sprite_enable = 0; |
| M4OSA_UInt8 reduced_resolution_vop_enable = 0; |
| M4OSA_UInt8 scalability = 0; |
| M4OSA_UInt8 enhancement_type = 0; |
| M4OSA_UInt8 complexity_estimation_disable = 0; |
| M4OSA_UInt8 interlaced = 0; |
| M4OSA_UInt8 sprite_warping_points = 0; |
| M4OSA_UInt8 sprite_brightness_change = 0; |
| M4OSA_UInt8 quant_precision = 0; |
| |
| /* Fill the structure with default parameters */ |
| pVideoSize->m_uiWidth = 0; |
| pVideoSize->m_uiHeight = 0; |
| |
| pDci->uiTimeScale = 0; |
| pDci->uiProfile = 0; |
| pDci->uiUseOfResynchMarker = 0; |
| pDci->bDataPartition = M4OSA_FALSE; |
| pDci->bUseOfRVLC = M4OSA_FALSE; |
| |
| /* Reset the bitstream context */ |
| parsingCtxt.stream_byte = 0; |
| parsingCtxt.stream_index = 8; |
| parsingCtxt.in = (M4OSA_Int8 *)pVol; |
| |
| start = (M4OSA_Int8 *)pVol; |
| |
| /* Start parsing */ |
| while (parsingCtxt.in - start < aVolSize) |
| { |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8); |
| if (code == 0) |
| { |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8); |
| if (code == 0) |
| { |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8); |
| if (code == 1) |
| { |
| /* start code found */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8); |
| |
| /* ----- 0x20..0x2F : video_object_layer_start_code ----- */ |
| |
| if ((code > 0x1F) && (code < 0x30)) |
| { |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1);/* random accessible vol */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 8);/* video object type indication */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1);/* is object layer identifier */ |
| if (code == 1) |
| { |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 4); /* video object layer verid */ |
| vol_verid = (M4OSA_UInt8)code; |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 3); /* video object layer priority */ |
| } |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 4);/* aspect ratio */ |
| if (code == 15) |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 16); /* par_width and par_height (8+8) */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1);/* vol control parameters */ |
| if (code == 1) |
| { |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 3);/* chroma format + low delay (3+1) */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1);/* vbv parameters */ |
| if (code == 1) |
| { |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 32);/* first and latter half bitrate + 2 marker bits |
| (15 + 1 + 15 + 1) */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 31);/* first and latter half vbv buffer size + first |
| half vbv occupancy + marker bits (15+1+3+11+1)*/ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 16);/* first half vbv occupancy + marker bits (15+1)*/ |
| } |
| } |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 2); /* video object layer shape */ |
| /* Need to save it for vop parsing */ |
| video_object_layer_shape = (M4OSA_UInt8)code; |
| |
| if (code != 0) return 0; /* only rectangular case supported */ |
| |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1); /* Marker bit */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 16); /* VOP time increment resolution */ |
| pDci->uiTimeScale = code; |
| |
| /* Computes time increment length */ |
| j = code - 1; |
| for (i = 0; (i < 32) && (j != 0); j >>=1) |
| { |
| i++; |
| } |
| time_incr_length = (i == 0) ? 1 : i; |
| |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1);/* Marker bit */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1);/* Fixed VOP rate */ |
| if (code == 1) |
| { |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| time_incr_length);/* Fixed VOP time increment */ |
| } |
| |
| if(video_object_layer_shape != 1) /* 1 = Binary */ |
| { |
| if(video_object_layer_shape == 0) /* 0 = rectangular */ |
| { |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1);/* Marker bit */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 13);/* Width */ |
| pVideoSize->m_uiWidth = code; |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1);/* Marker bit */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 13);/* Height */ |
| pVideoSize->m_uiHeight = code; |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1);/* Marker bit */ |
| } |
| } |
| |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1);/* interlaced */ |
| interlaced = (M4OSA_UInt8)code; |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1);/* OBMC disable */ |
| |
| if(vol_verid == 1) |
| { |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1);/* sprite enable */ |
| sprite_enable = (M4OSA_UInt8)code; |
| } |
| else |
| { |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 2);/* sprite enable */ |
| sprite_enable = (M4OSA_UInt8)code; |
| } |
| if ((sprite_enable == 1) || (sprite_enable == 2)) |
| /* Sprite static = 1 and Sprite GMC = 2 */ |
| { |
| if (sprite_enable != 2) |
| { |
| |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 13);/* sprite width */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1);/* Marker bit */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 13);/* sprite height */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1);/* Marker bit */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 13);/* sprite l coordinate */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1);/* Marker bit */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 13);/* sprite top coordinate */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1);/* Marker bit */ |
| } |
| |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 6);/* sprite warping points */ |
| sprite_warping_points = (M4OSA_UInt8)code; |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 2);/* sprite warping accuracy */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1);/* sprite brightness change */ |
| sprite_brightness_change = (M4OSA_UInt8)code; |
| if (sprite_enable != 2) |
| { |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1);/* low latency sprite enable */ |
| } |
| } |
| if ((vol_verid != 1) && (video_object_layer_shape != 0)) |
| { |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1);/* sadct disable */ |
| } |
| |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1); /* not 8 bits */ |
| if (code) |
| { |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 4);/* quant precision */ |
| quant_precision = (M4OSA_UInt8)code; |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 4);/* bits per pixel */ |
| } |
| |
| /* greyscale not supported */ |
| if(video_object_layer_shape == 3) |
| { |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 3); /* nogray quant update + composition method + |
| linear composition */ |
| } |
| |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1);/* quant type */ |
| if (code) |
| { |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1);/* load intra quant mat */ |
| if (code) |
| { |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8);/* */ |
| i = 1; |
| while (i < 64) |
| { |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8); |
| if (code == 0) |
| break; |
| i++; |
| } |
| } |
| |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1);/* load non intra quant mat */ |
| if (code) |
| { |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8);/* */ |
| i = 1; |
| while (i < 64) |
| { |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8); |
| if (code == 0) |
| break; |
| i++; |
| } |
| } |
| } |
| |
| if (vol_verid != 1) |
| { |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1);/* quarter sample */ |
| } |
| |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1);/* complexity estimation disable */ |
| complexity_estimation_disable = (M4OSA_UInt8)code; |
| if (!code) |
| { |
| //return M4ERR_NOT_IMPLEMENTED; |
| } |
| |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1);/* resync marker disable */ |
| pDci->uiUseOfResynchMarker = (code) ? 0 : 1; |
| |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, |
| 1);/* data partitionned */ |
| pDci->bDataPartition = (code) ? M4OSA_TRUE : M4OSA_FALSE; |
| if (code) |
| { |
| /* reversible VLC */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1); |
| pDci->bUseOfRVLC = (code) ? M4OSA_TRUE : M4OSA_FALSE; |
| } |
| |
| if (vol_verid != 1) |
| { |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1);/* newpred */ |
| if (code) |
| { |
| //return M4ERR_PARAMETER; |
| } |
| /* reduced resolution vop enable */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1); |
| reduced_resolution_vop_enable = (M4OSA_UInt8)code; |
| } |
| |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1);/* scalability */ |
| scalability = (M4OSA_UInt8)code; |
| if (code) |
| { |
| /* hierarchy type */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1); |
| b_hierarchy_type = (M4OSA_UInt8)code; |
| /* ref layer id */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 4); |
| /* ref sampling direct */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1); |
| /* hor sampling factor N */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 5); |
| /* hor sampling factor M */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 5); |
| /* vert sampling factor N */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 5); |
| /* vert sampling factor M */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 5); |
| /* enhancement type */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1); |
| enhancement_type = (M4OSA_UInt8)code; |
| if ((!b_hierarchy_type) && (video_object_layer_shape == 1)) |
| { |
| /* use ref shape */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1); |
| /* use ref texture */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1); |
| /* shape hor sampling factor N */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 5); |
| /* shape hor sampling factor M */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 5); |
| /* shape vert sampling factor N */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 5); |
| /* shape vert sampling factor M */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 5); |
| } |
| } |
| break; |
| } |
| |
| /* ----- 0xB0 : visual_object_sequence_start_code ----- */ |
| |
| else if(code == 0xB0) |
| { |
| /* profile_and_level_indication */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8); |
| pDci->uiProfile = (M4OSA_UInt8)code; |
| } |
| |
| /* ----- 0xB5 : visual_object_start_code ----- */ |
| |
| else if(code == 0xB5) |
| { |
| /* is object layer identifier */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1); |
| if (code == 1) |
| { |
| /* visual object verid */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 4); |
| vol_verid = (M4OSA_UInt8)code; |
| /* visual object layer priority */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 3); |
| } |
| else |
| { |
| /* Realign on byte */ |
| code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 7); |
| vol_verid = 1; |
| } |
| } |
| |
| /* ----- end ----- */ |
| } |
| else |
| { |
| if ((code >> 2) == 0x20) |
| { |
| /* H263 ...-> wrong*/ |
| break; |
| } |
| } |
| } |
| } |
| } |
| |
| return M4NO_ERROR; |
| } |
| |
| M4OSA_ERR getAVCProfileAndLevel(M4OSA_UInt8* pDSI, M4OSA_Int32 DSISize, |
| M4OSA_Int32 *pProfile, M4OSA_Int32 *pLevel) { |
| |
| M4OSA_UInt16 index = 28; /* the 29th byte is SPS start */ |
| M4OSA_Bool constraintSet3; |
| |
| if ((pProfile == M4OSA_NULL) || (pLevel == M4OSA_NULL)) { |
| return M4ERR_PARAMETER; |
| } |
| |
| if ((DSISize <= index) || (pDSI == M4OSA_NULL)) { |
| LOGE("getAVCProfileAndLevel: DSI is invalid"); |
| *pProfile = M4VIDEOEDITING_VIDEO_UNKNOWN_PROFILE; |
| *pLevel = M4VIDEOEDITING_VIDEO_UNKNOWN_LEVEL; |
| return M4ERR_PARAMETER; |
| } |
| |
| constraintSet3 = (pDSI[index+2] & 0x10); |
| LOGV("getAVCProfileAndLevel profile_byte %d, level_byte: %d constrain3flag", |
| pDSI[index+1], pDSI[index+3], constraintSet3); |
| |
| switch (pDSI[index+1]) { |
| case 66: |
| *pProfile = OMX_VIDEO_AVCProfileBaseline; |
| break; |
| case 77: |
| *pProfile = OMX_VIDEO_AVCProfileMain; |
| break; |
| case 88: |
| *pProfile = OMX_VIDEO_AVCProfileExtended; |
| break; |
| case 100: |
| *pProfile = OMX_VIDEO_AVCProfileHigh; |
| break; |
| case 110: |
| *pProfile = OMX_VIDEO_AVCProfileHigh10; |
| break; |
| case 122: |
| *pProfile = OMX_VIDEO_AVCProfileHigh422; |
| break; |
| case 244: |
| *pProfile = OMX_VIDEO_AVCProfileHigh444; |
| break; |
| default: |
| *pProfile = M4VIDEOEDITING_VIDEO_UNKNOWN_PROFILE; |
| } |
| |
| switch (pDSI[index+3]) { |
| case 10: |
| *pLevel = OMX_VIDEO_AVCLevel1; |
| break; |
| case 11: |
| if (constraintSet3) |
| *pLevel = OMX_VIDEO_AVCLevel1b; |
| else |
| *pLevel = OMX_VIDEO_AVCLevel11; |
| break; |
| case 12: |
| *pLevel = OMX_VIDEO_AVCLevel12; |
| break; |
| case 13: |
| *pLevel = OMX_VIDEO_AVCLevel13; |
| break; |
| case 20: |
| *pLevel = OMX_VIDEO_AVCLevel2; |
| break; |
| case 21: |
| *pLevel = OMX_VIDEO_AVCLevel21; |
| break; |
| case 22: |
| *pLevel = OMX_VIDEO_AVCLevel22; |
| break; |
| case 30: |
| *pLevel = OMX_VIDEO_AVCLevel3; |
| break; |
| case 31: |
| *pLevel = OMX_VIDEO_AVCLevel31; |
| break; |
| case 32: |
| *pLevel = OMX_VIDEO_AVCLevel32; |
| break; |
| case 40: |
| *pLevel = OMX_VIDEO_AVCLevel4; |
| break; |
| case 41: |
| *pLevel = OMX_VIDEO_AVCLevel41; |
| break; |
| case 42: |
| *pLevel = OMX_VIDEO_AVCLevel42; |
| break; |
| case 50: |
| *pLevel = OMX_VIDEO_AVCLevel5; |
| break; |
| case 51: |
| *pLevel = OMX_VIDEO_AVCLevel51; |
| break; |
| default: |
| *pLevel = M4VIDEOEDITING_VIDEO_UNKNOWN_LEVEL; |
| } |
| LOGV("getAVCProfileAndLevel profile %ld level %ld", *pProfile, *pLevel); |
| return M4NO_ERROR; |
| } |
| |
| M4OSA_ERR getH263ProfileAndLevel(M4OSA_UInt8* pDSI, M4OSA_Int32 DSISize, |
| M4OSA_Int32 *pProfile, M4OSA_Int32 *pLevel) { |
| |
| M4OSA_UInt16 index = 7; /* the 5th and 6th bytes contain the level and profile */ |
| |
| if ((pProfile == M4OSA_NULL) || (pLevel == M4OSA_NULL)) { |
| LOGE("getH263ProfileAndLevel invalid pointer for pProfile"); |
| return M4ERR_PARAMETER; |
| } |
| |
| if ((DSISize < index) || (pDSI == M4OSA_NULL)) { |
| LOGE("getH263ProfileAndLevel: DSI is invalid"); |
| *pProfile = M4VIDEOEDITING_VIDEO_UNKNOWN_PROFILE; |
| *pLevel = M4VIDEOEDITING_VIDEO_UNKNOWN_LEVEL; |
| return M4ERR_PARAMETER; |
| } |
| LOGV("getH263ProfileAndLevel profile_byte %d, level_byte", |
| pDSI[6], pDSI[5]); |
| /* get the H263 level */ |
| switch (pDSI[5]) { |
| case 10: |
| *pLevel = OMX_VIDEO_H263Level10; |
| break; |
| case 20: |
| *pLevel = OMX_VIDEO_H263Level20; |
| break; |
| case 30: |
| *pLevel = OMX_VIDEO_H263Level30; |
| break; |
| case 40: |
| *pLevel = OMX_VIDEO_H263Level40; |
| break; |
| case 45: |
| *pLevel = OMX_VIDEO_H263Level45; |
| break; |
| case 50: |
| *pLevel = OMX_VIDEO_H263Level50; |
| break; |
| case 60: |
| *pLevel = OMX_VIDEO_H263Level60; |
| break; |
| case 70: |
| *pLevel = OMX_VIDEO_H263Level70; |
| break; |
| default: |
| *pLevel = M4VIDEOEDITING_VIDEO_UNKNOWN_LEVEL; |
| } |
| |
| /* get H263 profile */ |
| switch (pDSI[6]) { |
| case 0: |
| *pProfile = OMX_VIDEO_H263ProfileBaseline; |
| break; |
| case 1: |
| *pProfile = OMX_VIDEO_H263ProfileH320Coding; |
| break; |
| case 2: |
| *pProfile = OMX_VIDEO_H263ProfileBackwardCompatible; |
| break; |
| case 3: |
| *pProfile = OMX_VIDEO_H263ProfileISWV2; |
| break; |
| case 4: |
| *pProfile = OMX_VIDEO_H263ProfileISWV3; |
| break; |
| case 5: |
| *pProfile = OMX_VIDEO_H263ProfileHighCompression; |
| break; |
| case 6: |
| *pProfile = OMX_VIDEO_H263ProfileInternet; |
| break; |
| case 7: |
| *pProfile = OMX_VIDEO_H263ProfileInterlace; |
| break; |
| case 8: |
| *pProfile = OMX_VIDEO_H263ProfileHighLatency; |
| break; |
| default: |
| *pProfile = M4VIDEOEDITING_VIDEO_UNKNOWN_PROFILE; |
| } |
| LOGV("getH263ProfileAndLevel profile %ld level %ld", *pProfile, *pLevel); |
| return M4NO_ERROR; |
| } |
| |
| M4OSA_ERR getMPEG4ProfileAndLevel(M4OSA_UInt8 profileAndLevel, |
| M4OSA_Int32 *pProfile, M4OSA_Int32 *pLevel) { |
| |
| M4OSA_UInt32 i = 0; |
| M4OSA_UInt32 length = 0; |
| if ((pProfile == M4OSA_NULL) || (pLevel == M4OSA_NULL)) { |
| return M4ERR_PARAMETER; |
| } |
| LOGV("getMPEG4ProfileAndLevel profileAndLevel %d", profileAndLevel); |
| length = sizeof(mpeg4ProfileLevelTable) /sizeof(mpeg4ProfileLevelTable[0]); |
| *pProfile = M4VIDEOEDITING_VIDEO_UNKNOWN_PROFILE; |
| *pLevel = M4VIDEOEDITING_VIDEO_UNKNOWN_LEVEL; |
| for (i = 0; i < length; i++) { |
| if (mpeg4ProfileLevelTable[i].code == profileAndLevel) { |
| *pProfile = mpeg4ProfileLevelTable[i].profile; |
| *pLevel = mpeg4ProfileLevelTable[i].level; |
| break; |
| } |
| } |
| LOGV("getMPEG4ProfileAndLevel profile %ld level %ld", *pProfile, *pLevel); |
| return M4NO_ERROR; |
| } |