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 "sample_helper.h"
17 #include <iostream>
18 #include <unordered_map>
19 #include <unistd.h>
20 #include "sample_base.h"
21 #include "av_codec_sample_log.h"
22 #include "av_codec_sample_error.h"
23 #include "syspara/parameters.h"
24 
25 namespace {
26 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_TEST, "SampleHelper"};
27 constexpr std::string_view DEVICE_SAMPLE_RUN_TIMES_SYS_PARAM_KEY = "OHOS.Media.AVCodecSample.DeviceSampleRunTimes";
28 constexpr int32_t MAX_PAUSE_TIME = 60;
29 
30 const std::unordered_map<OHOS::MediaAVCodec::Sample::CodecType, std::string> CODEC_TYPE_TO_STRING = {
31     {OHOS::MediaAVCodec::Sample::CodecType::VIDEO_HW_DECODER, "Hardware Decoder"},
32     {OHOS::MediaAVCodec::Sample::CodecType::VIDEO_SW_DECODER, "Software Decoder"},
33     {OHOS::MediaAVCodec::Sample::CodecType::VIDEO_HW_ENCODER, "Hardware Encoder"},
34     {OHOS::MediaAVCodec::Sample::CodecType::VIDEO_SW_ENCODER, "Software Encoder"},
35 };
36 
37 const std::unordered_map<OHOS::MediaAVCodec::Sample::CodecRunMode, std::string> RUN_MODE_TO_STRING = {
38     {OHOS::MediaAVCodec::Sample::CodecRunMode::API10_SURFACE, "Surface API10"},
39     {OHOS::MediaAVCodec::Sample::CodecRunMode::API10_BUFFER,  "Buffer API10"},
40     {OHOS::MediaAVCodec::Sample::CodecRunMode::API11_BUFFER,  "Buffer API11"},
41     {OHOS::MediaAVCodec::Sample::CodecRunMode::API11_SURFACE, "Surface API11"},
42 };
43 
44 const std::unordered_map<bool, std::string> BOOL_TO_STRING = {
45     {false, "false"},
46     {true,  "true"}
47 };
48 
49 const std::unordered_map<OH_AVPixelFormat, std::string> PIXEL_FORMAT_TO_STRING = {
50     {AV_PIXEL_FORMAT_YUVI420,           "YUVI420"},
51     {AV_PIXEL_FORMAT_NV12,              "NV12"},
52     {AV_PIXEL_FORMAT_NV21,              "NV21"},
53     {AV_PIXEL_FORMAT_SURFACE_FORMAT,    "SURFACE_FORMAT"},
54     {AV_PIXEL_FORMAT_RGBA,              "RGBA"},
55 };
56 
Pause(int32_t sleepTime)57 inline void Pause(int32_t sleepTime)
58 {
59     CHECK_AND_RETURN(sleepTime > 0);
60 
61     if (sleepTime > MAX_PAUSE_TIME) {
62         std::cout << "Press enter to continue...";
63         std::cin.get();
64         std::cin.clear();
65     } else {
66         std::cout << "Pause " << sleepTime << " seconds and continue..." << std::endl;
67         sleep(sleepTime);
68     }
69 }
70 }
71 
72 namespace OHOS {
73 namespace MediaAVCodec {
74 namespace Sample {
ToString(OH_AVPixelFormat pixelFormat)75 std::string ToString(OH_AVPixelFormat pixelFormat)
76 {
77     std::string ret;
78     auto iter = PIXEL_FORMAT_TO_STRING.find(pixelFormat);
79     if (iter != PIXEL_FORMAT_TO_STRING.end()) {
80         ret = PIXEL_FORMAT_TO_STRING.at(pixelFormat);
81     }
82     return ret;
83 }
84 
RunSample(const SampleInfo & info)85 int32_t RunSample(const SampleInfo &info)
86 {
87     std::shared_ptr<SampleBase> sample = SampleFactory::CreateSample(info);
88 
89     Pause(info.pauseBeforeRunSample);
90 
91     int32_t ret = sample->Create(info);
92     CHECK_AND_RETURN_RET_LOG(ret == AVCODEC_SAMPLE_ERR_OK, AVCODEC_SAMPLE_ERR_ERROR, "Create failed");
93     ret = sample->Start();
94     CHECK_AND_RETURN_RET_LOG(ret == AVCODEC_SAMPLE_ERR_OK, AVCODEC_SAMPLE_ERR_ERROR, "Start failed");
95     ret = sample->WaitForSampleDone();
96     CHECK_AND_RETURN_RET_LOG(ret == AVCODEC_SAMPLE_ERR_OK, AVCODEC_SAMPLE_ERR_ERROR, "Wait for done failed");
97     return AVCODEC_SAMPLE_ERR_OK;
98 }
99 
PrintSampleInfo(const SampleInfo & info)100 void PrintSampleInfo(const SampleInfo &info)
101 {
102     int32_t deviceSampleRunTimes = system::GetIntParameter(DEVICE_SAMPLE_RUN_TIMES_SYS_PARAM_KEY.data(), 0);
103     deviceSampleRunTimes++;
104     (void)system::SetParameter(DEVICE_SAMPLE_RUN_TIMES_SYS_PARAM_KEY.data(), std::to_string(deviceSampleRunTimes));
105 
106     PrintProgress(info.sampleRepeatTimes, 0);
107 
108     AVCODEC_LOGI("This device has run %{public}d times.", deviceSampleRunTimes);
109     AVCODEC_LOGI("====== Video sample config ======");
110     AVCODEC_LOGI("codec type: %{public}s, codec run mode: %{public}s, max frames: %{public}u",
111         CODEC_TYPE_TO_STRING.at(info.codecType).c_str(), RUN_MODE_TO_STRING.at(info.codecRunMode).c_str(),
112         info.maxFrames);
113     AVCODEC_LOGI("input file: %{public}s", info.inputFilePath.c_str());
114     AVCODEC_LOGI("mime: %{public}s, %{public}d*%{public}d, %{public}.1ffps, %{public}.2fMbps, pixel format: %{public}s",
115         info.codecMime.c_str(), info.videoWidth, info.videoHeight, info.frameRate,
116         static_cast<double>(info.bitrate) / 1024 / 1024, // 1024: precision
117         OHOS::MediaAVCodec::Sample::ToString(static_cast<OH_AVPixelFormat>(info.pixelFormat)).c_str());
118     AVCODEC_LOGI("interval: %{public}dms, dump output: %{public}s",
119         info.frameInterval, BOOL_TO_STRING.at(info.needDumpOutput).c_str());
120     AVCODEC_LOGI("====== Video sample config ======");
121 }
122 
PrintProgress(int32_t times,int32_t frames)123 void PrintProgress(int32_t times, int32_t frames)
124 {
125     std::cout << "\r\033[K" << "Repeat times left: " << times << ", frames: " << frames  << " " << std::flush;
126 }
127 } // Sample
128 } // MediaAVCodec
129 } // OHOS