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, ¶m); 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, ¶m); 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, ¶m); 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, ¶m); 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, ¶m); 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, ¶m); 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, ¶m); 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, ¶m); 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, ¶m); 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, ¶m); 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, ¶m); 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, ¶m); 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, ¶m); 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, ¶m); 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, ¶m); 264 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 265 } 266