1 /*
2 * Copyright (c) 2020-2021 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 "audio_encoder.h"
17 #include "media_log.h"
18 #include "securec.h"
19
20 namespace OHOS {
21 namespace Audio {
22 using namespace OHOS::Media;
23
24 constexpr uint32_t AUDIO_READ_STREAM_TIME_OUT_MS = 1000; /* 1S */
25
26 constexpr uint32_t AUDIO_CHANNEL_MONO = 1;
27 constexpr uint32_t AUDIO_CHANNEL_STEREO = 2;
28
AudioEncoder()29 AudioEncoder::AudioEncoder()
30 :initialized_(false),
31 encHandle_(nullptr),
32 started_(false)
33 {
34 for (int i = 0; i < AUDIO_ENC_PARAM_NUM; i++) {
35 encAttr_[i] = {};
36 }
37 CodecInit();
38 MEDIA_INFO_LOG("AudioEncoder ctor");
39 }
40
~AudioEncoder()41 AudioEncoder::~AudioEncoder()
42 {
43 if (initialized_) {
44 Release();
45 }
46 MEDIA_INFO_LOG("AudioEncoder dtor");
47 }
48
IsAudioCodecFormatSupported(AudioCodecFormat format)49 static bool IsAudioCodecFormatSupported(AudioCodecFormat format)
50 {
51 if ((format < AAC_LC) || (format > G726)) {
52 MEDIA_ERR_LOG("Invalid format:%d", format);
53 return false;
54 }
55 return true;
56 }
57
IsAudioSampleRateSupported(AudioCodecFormat format,uint32_t sampleRate)58 static bool IsAudioSampleRateSupported(AudioCodecFormat format, uint32_t sampleRate)
59 {
60 if (format == G711A || format == G711U || format == G726) {
61 if (sampleRate != 8000) { // 8000 G711/G726 only support 8kHz
62 MEDIA_ERR_LOG("Invalid sampleRate:%d, G711/G726 only support 8kHz", sampleRate);
63 return false;
64 }
65 }
66 return true;
67 }
68
GetMimeFromAudioCodecFormat(AudioCodecFormat format)69 static AvCodecMime GetMimeFromAudioCodecFormat(AudioCodecFormat format)
70 {
71 switch (format) {
72 case AAC_LC:
73 case AAC_HE_V1:
74 case AAC_HE_V2:
75 case AAC_LD:
76 case AAC_ELD:
77 return MEDIA_MIMETYPE_AUDIO_AAC;
78 case G711A:
79 return MEDIA_MIMETYPE_AUDIO_G711A;
80 case G711U:
81 return MEDIA_MIMETYPE_AUDIO_G711U;
82 case G726:
83 return MEDIA_MIMETYPE_AUDIO_G726;
84 default:
85 MEDIA_ERR_LOG("Invalid format:0x%x", format);
86 return MEDIA_MIMETYPE_INVALID;
87 }
88 }
89
GetProfileFromAudioCodecFormat(AudioCodecFormat format)90 static Profile GetProfileFromAudioCodecFormat(AudioCodecFormat format)
91 {
92 switch (format) {
93 case AAC_LC:
94 return AAC_LC_PROFILE;
95 case AAC_HE_V1:
96 return AAC_HE_V1_PROFILE;
97 case AAC_HE_V2:
98 return AAC_HE_V2_PROFILE;
99 case AAC_LD:
100 return AAC_LD_PROFILE;
101 case AAC_ELD:
102 return AAC_ELD_PROFILE;
103 default:
104 MEDIA_ERR_LOG("Invalid format: 0x%x", format);
105 return AAC_LC_PROFILE;
106 }
107 }
108
ConvertSoundMode(uint32_t channelCount)109 static AudioSoundMode ConvertSoundMode(uint32_t channelCount)
110 {
111 switch (channelCount) {
112 case AUDIO_CHANNEL_MONO:
113 return AUD_SOUND_MODE_MONO;
114 case AUDIO_CHANNEL_STEREO:
115 return AUD_SOUND_MODE_STEREO;
116 default:
117 MEDIA_ERR_LOG("Invalid soundMode:%u", channelCount);
118 return AUD_SOUND_MODE_MONO;
119 }
120 }
121
setEncAttrValue(const AudioEncodeConfig & config)122 void AudioEncoder::setEncAttrValue(const AudioEncodeConfig &config)
123 {
124 uint32_t paramIndex = 0;
125 domainKind_ = AUDIO_ENCODER;
126 encAttr_[paramIndex].key = KEY_CODEC_TYPE;
127 encAttr_[paramIndex].val = &domainKind_;
128 encAttr_[paramIndex].size = sizeof(CodecType);
129 paramIndex++;
130 codecMime_ = GetMimeFromAudioCodecFormat(config.audioFormat);
131 encAttr_[paramIndex].key = KEY_MIMETYPE;
132 encAttr_[paramIndex].val = &codecMime_;
133 encAttr_[paramIndex].size = sizeof(AvCodecMime);
134 paramIndex++;
135 profile_ = GetProfileFromAudioCodecFormat(config.audioFormat);
136 encAttr_[paramIndex].key = KEY_AUDIO_PROFILE;
137 encAttr_[paramIndex].val = &profile_;
138 encAttr_[paramIndex].size = sizeof(Profile);
139 paramIndex++;
140 sampleRate_ = config.sampleRate;
141 encAttr_[paramIndex].key = KEY_AUDIO_SAMPLE_RATE;
142 encAttr_[paramIndex].val = &sampleRate_;
143 encAttr_[paramIndex].size = sizeof(uint32_t);
144 paramIndex++;
145 bitRate_ = config.bitRate;
146 encAttr_[paramIndex].key = KEY_BITRATE;
147 encAttr_[paramIndex].val = &bitRate_;
148 encAttr_[paramIndex].size = sizeof(uint32_t);
149 paramIndex++;
150 soundMode_ = ConvertSoundMode(config.channelCount);
151 encAttr_[paramIndex].key = KEY_AUDIO_SOUND_MODE;
152 encAttr_[paramIndex].val = &soundMode_;
153 encAttr_[paramIndex].size = sizeof(AudioSoundMode);
154 paramIndex++;
155 ptNumPerFrm_ = AUDIO_POINT_NUM;
156 encAttr_[paramIndex].key = KEY_AUDIO_POINTS_PER_FRAME;
157 encAttr_[paramIndex].val = &ptNumPerFrm_;
158 encAttr_[paramIndex].size = sizeof(uint32_t);
159 paramIndex++;
160 bufSize_ = AUDIO_FRAME_NUM_IN_BUF;
161 encAttr_[paramIndex].key = KEY_BUFFERSIZE;
162 encAttr_[paramIndex].val = &bufSize_;
163 encAttr_[paramIndex].size = sizeof(uint32_t);
164 }
165
InitAudioEncoderAttr(const AudioEncodeConfig & config)166 int32_t AudioEncoder::InitAudioEncoderAttr(const AudioEncodeConfig &config)
167 {
168 if (!IsAudioCodecFormatSupported(config.audioFormat)) {
169 MEDIA_ERR_LOG("audioFormat:0x%x is not support", config.audioFormat);
170 return ERR_INVALID_PARAM;
171 }
172 if (!IsAudioSampleRateSupported(config.audioFormat, config.sampleRate)) {
173 MEDIA_ERR_LOG("audioFormat:%d is not support sampleRate:%d", config.audioFormat, config.sampleRate);
174 return ERR_INVALID_PARAM;
175 }
176 setEncAttrValue(config);
177
178 return SUCCESS;
179 }
180
Initialize(const AudioEncodeConfig & config)181 int32_t AudioEncoder::Initialize(const AudioEncodeConfig &config)
182 {
183 int32_t ret = InitAudioEncoderAttr(config);
184 if (ret != SUCCESS) {
185 MEDIA_ERR_LOG("InitAudioEncoderAttr failed:%d", ret);
186 return ret;
187 }
188 ret = CodecCreateByType(domainKind_, codecMime_, &encHandle_);
189 if (ret != SUCCESS) {
190 MEDIA_ERR_LOG("CodecCreateByType failed:0x%x", ret);
191 return ret;
192 }
193 ret = CodecSetParameter(encHandle_, encAttr_, AUDIO_ENC_PARAM_NUM);
194 if (ret != SUCCESS) {
195 CodecDestroy(encHandle_);
196 MEDIA_ERR_LOG("CodecSetParameter failed:0x%x", ret);
197 return ret;
198 }
199 initialized_ = true;
200 return SUCCESS;
201 }
202
BindSource(uint32_t deviceId)203 int32_t AudioEncoder::BindSource(uint32_t deviceId)
204 {
205 Param params[1];
206 (void)memset_s(params, sizeof(params), 0x00, sizeof(params));
207 params[0].key = KEY_DEVICE_ID;
208 params[0].val = reinterpret_cast<void *>(&deviceId);
209 params[0].size = sizeof(uint32_t);
210 int32_t ret = CodecSetParameter(encHandle_, params, sizeof(params) / sizeof(params[0]));
211 if (ret != SUCCESS) {
212 MEDIA_ERR_LOG("CodecSetDevice:0x%x", ret);
213 return ret;
214 }
215 return SUCCESS;
216 }
217
GetMute(bool & muted)218 int32_t AudioEncoder::GetMute(bool &muted)
219 {
220 (void)muted;
221 return ERR_UNKNOWN;
222 }
223
SetMute(bool muted)224 int32_t AudioEncoder::SetMute(bool muted)
225 {
226 (void)muted;
227 return ERR_UNKNOWN;
228 }
229
Start()230 int32_t AudioEncoder::Start()
231 {
232 if (!initialized_) {
233 MEDIA_ERR_LOG("not initialized");
234 return ERR_ILLEGAL_STATE;
235 }
236 int32_t ret = CodecStart(encHandle_);
237 if (ret != SUCCESS) {
238 MEDIA_ERR_LOG("CodecStart failed:0x%x", ret);
239 return ret;
240 }
241 started_ = true;
242 return ret;
243 }
244
ReadStream(AudioStream & stream,bool isBlockingRead)245 int32_t AudioEncoder::ReadStream(AudioStream &stream, bool isBlockingRead)
246 {
247 if (!started_) {
248 MEDIA_ERR_LOG("Codec not Started");
249 return ERR_INVALID_READ;
250 }
251 if (stream.buffer == nullptr || stream.bufferLen == 0) {
252 MEDIA_ERR_LOG("stream.buffer is nullptr");
253 return ERR_INVALID_READ;
254 }
255 uint32_t timeoutMs;
256 if (isBlockingRead) {
257 timeoutMs = AUDIO_READ_STREAM_TIME_OUT_MS;
258 } else {
259 timeoutMs = 0;
260 }
261 AudioBufferInfo outInfo;
262 int32_t ret = CodecDequeueOutput(encHandle_, timeoutMs, nullptr, (CodecBuffer *)&outInfo);
263 if (ret != SUCCESS && outInfo.info.buffer[0].buf == 0) {
264 MEDIA_ERR_LOG("CodecDequeueOutput failed:0x%x", ret);
265 return ERR_INVALID_READ;
266 }
267 int32_t readLen = 0;
268 errno_t retCopy = memcpy_s(stream.buffer, stream.bufferLen, (void *)outInfo.info.buffer[0].buf,
269 outInfo.info.buffer[0].length);
270 if (retCopy != EOK) {
271 MEDIA_ERR_LOG("memcpy_s failed, timeStamp:%lld, retCopy:0x%x", outInfo.info.timeStamp, retCopy);
272 return ERR_INVALID_OPERATION;
273 } else {
274 readLen = outInfo.info.buffer[0].length;
275 }
276 stream.timeStamp = outInfo.info.timeStamp;
277 (void)CodecQueueOutput(encHandle_, (CodecBuffer *)&outInfo, timeoutMs, -1);
278 return readLen;
279 }
280
Stop()281 int32_t AudioEncoder::Stop()
282 {
283 MEDIA_DEBUG_LOG("AudioEncoder::Stop");
284 if (!started_) {
285 MEDIA_ERR_LOG("Codec not Start");
286 }
287 return CodecStop(encHandle_);
288 }
289
Release()290 int32_t AudioEncoder::Release()
291 {
292 MEDIA_DEBUG_LOG("AudioEncoder::Release");
293 if (!initialized_) {
294 MEDIA_ERR_LOG("Codec not initialized");
295 }
296 if (encHandle_ != nullptr) {
297 CodecDestroy(encHandle_);
298 encHandle_ = nullptr;
299 }
300 initialized_ = false;
301 return SUCCESS;
302 }
303 } // namespace Audio
304 } // namespace OHOS
305