1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "command_parser.h"
17 #include <cinttypes>
18 #include <getopt.h>
19 #include <iostream>
20
21 namespace OHOS::MediaAVCodec {
22 using namespace std;
23
24 enum ShortOption {
25 OPT_UNKONWN = 0,
26 OPT_HELP,
27 OPT_INPUT = 'i',
28 OPT_WIDTH = 'w',
29 OPT_HEIGHT = 'h',
30 OPT_API_TYPE = UINT8_MAX + 1,
31 OPT_IS_ENCODER,
32 OPT_IS_BUFFER_MODE,
33 OPT_REPEAT_CNT,
34 OPT_MAX_READ_CNT,
35 OPT_PROTOCOL,
36 OPT_PIXEL_FMT,
37 OPT_FRAME_RATE,
38 OPT_TIME_OUT,
39 OPT_IS_HIGH_PERF_MODE,
40 // encoder only
41 OPT_MOCK_FRAME_CNT,
42 OPT_COLOR_RANGE,
43 OPT_COLOR_PRIMARY,
44 OPT_COLOR_TRANSFER,
45 OPT_COLOR_MATRIX,
46 OPT_I_FRAME_INTERVAL,
47 OPT_IDR_FRAME_NO,
48 OPT_PROFILE,
49 OPT_BITRATE_MODE,
50 OPT_BITRATE,
51 OPT_QUALITY,
52 // decoder only
53 OPT_RENDER,
54 OPT_DEC_THEN_ENC,
55 OPT_ROTATION,
56 OPT_FLUSH_CNT
57 };
58
59 static struct option g_longOptions[] = {
60 {"help", no_argument, nullptr, OPT_HELP},
61 {"in", required_argument, nullptr, OPT_INPUT},
62 {"width", required_argument, nullptr, OPT_WIDTH},
63 {"height", required_argument, nullptr, OPT_HEIGHT},
64 {"apiType", required_argument, nullptr, OPT_API_TYPE},
65 {"isEncoder", required_argument, nullptr, OPT_IS_ENCODER},
66 {"isBufferMode", required_argument, nullptr, OPT_IS_BUFFER_MODE},
67 {"repeatCnt", required_argument, nullptr, OPT_REPEAT_CNT},
68 {"maxReadFrameCnt", required_argument, nullptr, OPT_MAX_READ_CNT},
69 {"protocol", required_argument, nullptr, OPT_PROTOCOL},
70 {"pixelFmt", required_argument, nullptr, OPT_PIXEL_FMT},
71 {"frameRate", required_argument, nullptr, OPT_FRAME_RATE},
72 {"timeout", required_argument, nullptr, OPT_TIME_OUT},
73 {"isHighPerfMode", required_argument, nullptr, OPT_IS_HIGH_PERF_MODE},
74 // encoder only
75 {"mockFrameCnt", required_argument, nullptr, OPT_MOCK_FRAME_CNT},
76 {"colorRange", required_argument, nullptr, OPT_COLOR_RANGE},
77 {"colorPrimary", required_argument, nullptr, OPT_COLOR_PRIMARY},
78 {"colorTransfer", required_argument, nullptr, OPT_COLOR_TRANSFER},
79 {"colorMatrix", required_argument, nullptr, OPT_COLOR_MATRIX},
80 {"iFrameInterval", required_argument, nullptr, OPT_I_FRAME_INTERVAL},
81 {"idrFrameNo", required_argument, nullptr, OPT_IDR_FRAME_NO},
82 {"profile", required_argument, nullptr, OPT_PROFILE},
83 {"bitRateMode", required_argument, nullptr, OPT_BITRATE_MODE},
84 {"bitRate", required_argument, nullptr, OPT_BITRATE},
85 {"quality", required_argument, nullptr, OPT_QUALITY},
86 // decoder only
87 {"rotation", required_argument, nullptr, OPT_ROTATION},
88 {"render", required_argument, nullptr, OPT_RENDER},
89 {"decThenEnc", required_argument, nullptr, OPT_DEC_THEN_ENC},
90 {"flushCnt", required_argument, nullptr, OPT_FLUSH_CNT},
91 {nullptr, no_argument, nullptr, OPT_UNKONWN},
92 };
93
ShowUsage()94 void ShowUsage()
95 {
96 std::cout << "HCodec Test Options:" << std::endl;
97 std::cout << " --help help info." << std::endl;
98 std::cout << " -i, --in file name for input file." << std::endl;
99 std::cout << " -w, --width video width." << std::endl;
100 std::cout << " -h, --height video height." << std::endl;
101 std::cout << " --apiType 0: codecbase, 1: new capi, 2: old capi." << std::endl;
102 std::cout << " --isEncoder 1 is test encoder, 0 is test decoder" << std::endl;
103 std::cout << " --isBufferMode 0 is surface mode, 1 is buffer mode." << std::endl;
104 std::cout << " --repeatCnt repeat test, default is 1" << std::endl;
105 std::cout << " --maxReadFrameCnt read up to frame count from input file" << std::endl;
106 std::cout << " --protocol video protocol. 0 is H264, 1 is H265" << std::endl;
107 std::cout << " --pixelFmt video pixel fmt. 1 is I420, 2 is NV12, 3 is NV21, 5 is RGBA" << std::endl;
108 std::cout << " --frameRate video frame rate." << std::endl;
109 std::cout << " --timeout thread timeout(ms). -1 means wait forever" << std::endl;
110 std::cout << " --isHighPerfMode 0 is normal mode, 1 is high perf mode" << std::endl;
111 // encoder only
112 std::cout << " --mockFrameCnt when read up to maxReadFrameCnt, just send old frames" << std::endl;
113 std::cout << " --colorRange color range. 1 is full range, 0 is limited range." << std::endl;
114 std::cout << " --colorPrimary color primary. see H.273 standard." << std::endl;
115 std::cout << " --colorTransfer color transfer characteristic. see H.273 standard." << std::endl;
116 std::cout << " --colorMatrix color matrix coefficient. see H.273 standard." << std::endl;
117 std::cout << " --iFrameInterval <0 means only one I frame, =0 means all intra" << std::endl;
118 std::cout << " >0 means I frame interval in milliseconds" << std::endl;
119 std::cout << " --idrFrameNo which frame will be set to IDR frame." << std::endl;
120 std::cout << " --profile video profile, for 264: 0(baseline), 1(constrained baseline), " << std::endl;
121 std::cout << " 2(constrained high), 3(extended), 4(high), 8(main)" << std::endl;
122 std::cout << " for 265: 0(main), 1(main 10)" << std::endl;
123 std::cout << " --bitRateMode bit rate mode for encoder. 0(CBR), 1(VBR), 2(CQ)" << std::endl;
124 std::cout << " --bitRate target encode bit rate (bps)" << std::endl;
125 std::cout << " --quality target encode quality" << std::endl;
126 std::cout << " --render 0 means don't render, 1 means render to window" << std::endl;
127 std::cout << " --decThenEnc do surface encode after surface decode" << std::endl;
128 std::cout << " --rotation rotation angle after decode, eg. 0/90/180/270" << std::endl;
129 std::cout << " --flushCnt total flush count during decoding" << std::endl;
130 }
131
Parse(int argc,char * argv[])132 CommandOpt Parse(int argc, char *argv[])
133 {
134 CommandOpt opt;
135 int c;
136 while ((c = getopt_long(argc, argv, "i:w:h:", g_longOptions, nullptr)) != -1) {
137 switch (c) {
138 case OPT_HELP:
139 ShowUsage();
140 break;
141 case OPT_INPUT:
142 opt.inputFile = string(optarg);
143 break;
144 case OPT_WIDTH:
145 opt.dispW = stol(optarg);
146 break;
147 case OPT_HEIGHT:
148 opt.dispH = stol(optarg);
149 break;
150 case OPT_API_TYPE:
151 opt.apiType = static_cast<ApiType>(stol(optarg));
152 break;
153 case OPT_IS_ENCODER:
154 opt.isEncoder = stol(optarg);
155 break;
156 case OPT_IS_BUFFER_MODE:
157 opt.isBufferMode = stol(optarg);
158 break;
159 case OPT_REPEAT_CNT:
160 opt.repeatCnt = stol(optarg);
161 break;
162 case OPT_MAX_READ_CNT:
163 opt.maxReadFrameCnt = stol(optarg);
164 break;
165 case OPT_PROTOCOL:
166 opt.protocol = static_cast<CodeType>(stol(optarg));
167 break;
168 case OPT_PIXEL_FMT:
169 opt.pixFmt = static_cast<VideoPixelFormat>(stol(optarg));
170 break;
171 case OPT_FRAME_RATE:
172 opt.frameRate = stol(optarg);
173 break;
174 case OPT_TIME_OUT:
175 opt.timeout = stol(optarg);
176 break;
177 case OPT_IS_HIGH_PERF_MODE:
178 opt.isHighPerfMode = stol(optarg);
179 break;
180 case OPT_MOCK_FRAME_CNT:
181 opt.mockFrameCnt = stol(optarg);
182 break;
183 case OPT_COLOR_RANGE:
184 opt.rangeFlag = stol(optarg);
185 break;
186 case OPT_COLOR_PRIMARY:
187 opt.primary = static_cast<ColorPrimary>(stol(optarg));
188 break;
189 case OPT_COLOR_TRANSFER:
190 opt.transfer = static_cast<TransferCharacteristic>(stol(optarg));
191 break;
192 case OPT_COLOR_MATRIX:
193 opt.matrix = static_cast<MatrixCoefficient>(stol(optarg));
194 break;
195 case OPT_I_FRAME_INTERVAL:
196 opt.iFrameInterval = stol(optarg);
197 break;
198 case OPT_IDR_FRAME_NO:
199 opt.idrFrameNo = stol(optarg);
200 break;
201 case OPT_PROFILE:
202 opt.profile = stol(optarg);
203 break;
204 case OPT_BITRATE_MODE:
205 opt.rateMode = static_cast<VideoEncodeBitrateMode>(stol(optarg));
206 break;
207 case OPT_BITRATE:
208 opt.bitRate = stol(optarg);
209 break;
210 case OPT_QUALITY:
211 opt.quality = stol(optarg);
212 break;
213 case OPT_RENDER:
214 opt.render = stol(optarg);
215 break;
216 case OPT_DEC_THEN_ENC:
217 opt.decThenEnc = stol(optarg);
218 break;
219 case OPT_ROTATION:
220 opt.rotation = static_cast<VideoRotation>(stol(optarg));
221 break;
222 case OPT_FLUSH_CNT:
223 opt.flushCnt = stol(optarg);
224 break;
225 default:
226 break;
227 }
228 }
229 return opt;
230 }
231
Print() const232 void CommandOpt::Print() const
233 {
234 printf("-----------------------------\n");
235 printf("api type=%d, %s, %s mode, render = %d\n", apiType,
236 (isEncoder ? "encoder" : (decThenEnc ? "dec + enc" : "decoder")),
237 isBufferMode ? "buffer" : "surface", render);
238 printf("read inputFile %s up to %u frames\n", inputFile.c_str(), maxReadFrameCnt);
239 printf("%u x %u @ %u fps\n", dispW, dispH, frameRate);
240 printf("protocol = %s, pixFmt = %d\n", (protocol == H264) ? "264" : "265", pixFmt);
241 printf("repeat %u times, timeout = %d\n", repeatCnt, timeout);
242 printf("enableHighPerfMode : %s\n", isHighPerfMode ? "yes" : "no");
243
244 if (mockFrameCnt.has_value()) {
245 printf("mockFrameCnt %u\n", mockFrameCnt.value());
246 }
247 if (rangeFlag.has_value()) {
248 printf("rangeFlag %d\n", rangeFlag.value());
249 }
250 if (primary.has_value()) {
251 printf("primary %d\n", primary.value());
252 }
253 if (transfer.has_value()) {
254 printf("transfer %d\n", transfer.value());
255 }
256 if (matrix.has_value()) {
257 printf("matrix %d\n", matrix.value());
258 }
259 if (iFrameInterval.has_value()) {
260 printf("iFrameInterval %d\n", iFrameInterval.value());
261 }
262 if (idrFrameNo.has_value()) {
263 printf("idrFrameNo %u\n", idrFrameNo.value());
264 }
265 if (profile.has_value()) {
266 printf("profile %d\n", profile.value());
267 }
268 if (rateMode.has_value()) {
269 printf("rateMode %d\n", rateMode.value());
270 }
271 if (bitRate.has_value()) {
272 printf("bitRate %u\n", bitRate.value());
273 }
274 if (quality.has_value()) {
275 printf("quality %u\n", quality.value());
276 }
277 printf("rotation angle %u\n", rotation);
278 printf("flush cnt %d\n", flushCnt);
279 printf("-----------------------------\n");
280 }
281 }