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