Home | History | Annotate | Download | only in video
      1 /*
      2  * Copyright (C) 2017 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 
     17 #define LOG_TAG "media_omx_hidl_video_test_common"
     18 #ifdef __LP64__
     19 #define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
     20 #endif
     21 
     22 #include <android-base/logging.h>
     23 
     24 #include <android/hardware/media/omx/1.0/IOmx.h>
     25 #include <android/hardware/media/omx/1.0/IOmxNode.h>
     26 #include <android/hardware/media/omx/1.0/IOmxObserver.h>
     27 #include <android/hardware/media/omx/1.0/types.h>
     28 #include <android/hidl/allocator/1.0/IAllocator.h>
     29 #include <android/hidl/memory/1.0/IMapper.h>
     30 #include <android/hidl/memory/1.0/IMemory.h>
     31 
     32 using ::android::hardware::media::omx::V1_0::IOmx;
     33 using ::android::hardware::media::omx::V1_0::IOmxObserver;
     34 using ::android::hardware::media::omx::V1_0::IOmxNode;
     35 using ::android::hardware::media::omx::V1_0::Message;
     36 using ::android::hardware::media::omx::V1_0::CodecBuffer;
     37 using ::android::hardware::media::omx::V1_0::PortMode;
     38 using ::android::hidl::allocator::V1_0::IAllocator;
     39 using ::android::hidl::memory::V1_0::IMemory;
     40 using ::android::hidl::memory::V1_0::IMapper;
     41 using ::android::hardware::Return;
     42 using ::android::hardware::Void;
     43 using ::android::hardware::hidl_vec;
     44 using ::android::hardware::hidl_string;
     45 using ::android::sp;
     46 
     47 #include <VtsHalHidlTargetTestBase.h>
     48 #include <hidlmemory/mapping.h>
     49 #include <media/hardware/HardwareAPI.h>
     50 #include <media_hidl_test_common.h>
     51 #include <media_video_hidl_test_common.h>
     52 #include <memory>
     53 
     54 void enumerateProfileAndLevel(sp<IOmxNode> omxNode, OMX_U32 portIndex,
     55                               std::vector<int32_t>* arrProfile,
     56                               std::vector<int32_t>* arrLevel) {
     57     android::hardware::media::omx::V1_0::Status status;
     58     OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
     59     param.nProfileIndex = 0;
     60     arrProfile->clear();
     61     arrLevel->clear();
     62     while (1) {
     63         status =
     64             getPortParam(omxNode, OMX_IndexParamVideoProfileLevelQuerySupported,
     65                          portIndex, &param);
     66         if (status != ::android::hardware::media::omx::V1_0::Status::OK) break;
     67         arrProfile->push_back(static_cast<int32_t>(param.eProfile));
     68         arrLevel->push_back(static_cast<int32_t>(param.eLevel));
     69         param.nProfileIndex++;
     70         if (param.nProfileIndex == 512) {
     71             // enumerated way too many, highly unusual for this to happen.
     72             EXPECT_LE(param.nProfileIndex, 512U)
     73                 << "Expecting OMX_ErrorNoMore but not received";
     74             break;
     75         }
     76     }
     77 }
     78 
     79 void setupRAWPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_U32 nFrameWidth,
     80                   OMX_U32 nFrameHeight, OMX_U32 nBitrate, OMX_U32 xFramerate,
     81                   OMX_COLOR_FORMATTYPE eColorFormat) {
     82     android::hardware::media::omx::V1_0::Status status;
     83 
     84     OMX_PARAM_PORTDEFINITIONTYPE portDef;
     85     status = getPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
     86                           &portDef);
     87     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
     88     portDef.format.video.nFrameWidth = nFrameWidth;
     89     portDef.format.video.nFrameHeight = nFrameHeight;
     90     portDef.format.video.nStride = (((nFrameWidth + 15) >> 4) << 4);
     91     portDef.format.video.nSliceHeight = (((nFrameHeight + 15) >> 4) << 4);
     92     portDef.format.video.nBitrate = nBitrate;
     93     portDef.format.video.xFramerate = xFramerate;
     94     portDef.format.video.bFlagErrorConcealment = OMX_TRUE;
     95     portDef.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
     96     portDef.format.video.eColorFormat = eColorFormat;
     97     status = setPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
     98                           &portDef);
     99     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    100 }
    101 
    102 void setupAVCPort(sp<IOmxNode> omxNode, OMX_U32 portIndex,
    103                   OMX_VIDEO_AVCPROFILETYPE eProfile,
    104                   OMX_VIDEO_AVCLEVELTYPE eLevel, OMX_U32 xFramerate) {
    105     android::hardware::media::omx::V1_0::Status status;
    106     OMX_VIDEO_PARAM_AVCTYPE param;
    107     (void)xFramerate;  // necessary for intra frame spacing
    108 
    109     status = getPortParam(omxNode, OMX_IndexParamVideoAvc, portIndex, &param);
    110     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    111     param.nSliceHeaderSpacing = 0;
    112     param.nPFrames = 300;
    113     param.nBFrames = 0;
    114     param.bUseHadamard = OMX_TRUE;
    115     param.nRefFrames = 1;
    116     param.eProfile = eProfile;
    117     param.eLevel = eLevel;
    118     param.nAllowedPictureTypes =
    119         OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
    120     param.bFrameMBsOnly = OMX_TRUE;
    121     param.bEntropyCodingCABAC = OMX_FALSE;
    122     param.bWeightedPPrediction = OMX_FALSE;
    123     param.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
    124     status = setPortParam(omxNode, OMX_IndexParamVideoAvc, portIndex, &param);
    125     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    126 }
    127 
    128 void setupHEVCPort(sp<IOmxNode> omxNode, OMX_U32 portIndex,
    129                    OMX_VIDEO_HEVCPROFILETYPE eProfile,
    130                    OMX_VIDEO_HEVCLEVELTYPE eLevel) {
    131     android::hardware::media::omx::V1_0::Status status;
    132     OMX_VIDEO_PARAM_HEVCTYPE param;
    133 
    134     status = getPortParam(omxNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc,
    135                           portIndex, &param);
    136     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    137     (void)eProfile;
    138     (void)eLevel;
    139     // SPECIAL CASE; OMX.qcom.video.encoder.hevc does not support the level it
    140     // enumerated in the list. Lets skip this for now
    141     // param.eProfile = eProfile;
    142     // param.eLevel = eLevel;
    143     param.nKeyFrameInterval = 300;
    144     status = setPortParam(omxNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc,
    145                           portIndex, &param);
    146     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    147 }
    148 
    149 void setupMPEG4Port(sp<IOmxNode> omxNode, OMX_U32 portIndex,
    150                     OMX_VIDEO_MPEG4PROFILETYPE eProfile,
    151                     OMX_VIDEO_MPEG4LEVELTYPE eLevel, OMX_U32 xFramerate) {
    152     android::hardware::media::omx::V1_0::Status status;
    153     OMX_VIDEO_PARAM_MPEG4TYPE param;
    154     (void)xFramerate;  // necessary for intra frame spacing
    155 
    156     status = getPortParam(omxNode, OMX_IndexParamVideoMpeg4, portIndex, &param);
    157     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    158 
    159     param.nSliceHeaderSpacing = 0;
    160     param.bSVH = OMX_FALSE;
    161     param.bGov = OMX_FALSE;
    162     param.nPFrames = 300;
    163     param.nBFrames = 0;
    164     param.nIDCVLCThreshold = 0;
    165     param.bACPred = OMX_TRUE;
    166     param.nMaxPacketSize = 256;
    167     param.eProfile = eProfile;
    168     param.eLevel = eLevel;
    169     param.nAllowedPictureTypes =
    170         OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
    171     param.nHeaderExtension = 0;
    172     param.bReversibleVLC = OMX_FALSE;
    173     status = setPortParam(omxNode, OMX_IndexParamVideoMpeg4, portIndex, &param);
    174     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    175 }
    176 
    177 void setupH263Port(sp<IOmxNode> omxNode, OMX_U32 portIndex,
    178                    OMX_VIDEO_H263PROFILETYPE eProfile,
    179                    OMX_VIDEO_H263LEVELTYPE eLevel, OMX_U32 xFramerate) {
    180     android::hardware::media::omx::V1_0::Status status;
    181     OMX_VIDEO_PARAM_H263TYPE param;
    182     (void)xFramerate;  // necessary for intra frame spacing
    183 
    184     status = getPortParam(omxNode, OMX_IndexParamVideoH263, portIndex, &param);
    185     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    186 
    187     param.nPFrames = 300;
    188     param.nBFrames = 0;
    189     param.eProfile = eProfile;
    190     param.eLevel = eLevel;
    191     param.nAllowedPictureTypes =
    192         OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
    193     param.bPLUSPTYPEAllowed = OMX_FALSE;
    194     param.bForceRoundingTypeToZero = OMX_FALSE;
    195     param.nPictureHeaderRepetition = 0;
    196     param.nGOBHeaderInterval = 0;
    197     status = setPortParam(omxNode, OMX_IndexParamVideoH263, portIndex, &param);
    198     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    199 }
    200 
    201 void setupVPXPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_U32 xFramerate) {
    202     android::hardware::media::omx::V1_0::Status status;
    203     OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE param;
    204     (void)xFramerate;  // necessary for intra frame spacing
    205 
    206     status = getPortParam(omxNode,
    207                           (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
    208                           portIndex, &param);
    209     // EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    210     // SPECIAL CASE; OMX.qcom.video.encoder.vp8 does not support this index
    211     // type. Dont flag error for now
    212     if (status != ::android::hardware::media::omx::V1_0::Status::OK) return;
    213 
    214     param.nKeyFrameInterval = 300;
    215     param.eTemporalPattern = OMX_VIDEO_VPXTemporalLayerPatternNone;
    216     param.nMinQuantizer = 2;
    217     param.nMaxQuantizer = 63;
    218     status = setPortParam(omxNode,
    219                           (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
    220                           portIndex, &param);
    221     // EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    222     // SPECIAL CASE; OMX.qcom.video.encoder.vp8 does not support this index
    223     // type. Dont flag error for now
    224     if (status != ::android::hardware::media::omx::V1_0::Status::OK) return;
    225 }
    226 
    227 void setupVP8Port(sp<IOmxNode> omxNode, OMX_U32 portIndex,
    228                   OMX_VIDEO_VP8PROFILETYPE eProfile,
    229                   OMX_VIDEO_VP8LEVELTYPE eLevel) {
    230     android::hardware::media::omx::V1_0::Status status;
    231     OMX_VIDEO_PARAM_VP8TYPE param;
    232 
    233     status = getPortParam(omxNode, (OMX_INDEXTYPE)OMX_IndexParamVideoVp8,
    234                           portIndex, &param);
    235     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    236 
    237     param.eProfile = eProfile;
    238     param.eLevel = eLevel;
    239     param.bErrorResilientMode = OMX_TRUE;
    240     param.nDCTPartitions = 1;
    241     status = setPortParam(omxNode, (OMX_INDEXTYPE)OMX_IndexParamVideoVp8,
    242                           portIndex, &param);
    243     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    244 }
    245 
    246 void setupVP9Port(sp<IOmxNode> omxNode, OMX_U32 portIndex,
    247                   OMX_VIDEO_VP9PROFILETYPE eProfile,
    248                   OMX_VIDEO_VP9LEVELTYPE eLevel) {
    249     android::hardware::media::omx::V1_0::Status status;
    250     OMX_VIDEO_PARAM_VP9TYPE param;
    251 
    252     status = getPortParam(omxNode, (OMX_INDEXTYPE)OMX_IndexParamVideoVp9,
    253                           portIndex, &param);
    254     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    255 
    256     param.eProfile = eProfile;
    257     param.eLevel = eLevel;
    258     param.bErrorResilientMode = OMX_TRUE;
    259     param.nTileRows = 1;
    260     param.nTileColumns = 1;
    261     param.bEnableFrameParallelDecoding = OMX_TRUE;
    262     status = setPortParam(omxNode, (OMX_INDEXTYPE)OMX_IndexParamVideoVp9,
    263                           portIndex, &param);
    264     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    265 }
    266