• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
InitAudioEncoderAttr(const AudioEncodeConfig & config)122 int32_t AudioEncoder::InitAudioEncoderAttr(const AudioEncodeConfig &config)
123 {
124     if (!IsAudioCodecFormatSupported(config.audioFormat)) {
125         MEDIA_ERR_LOG("audioFormat:0x%x is not support", config.audioFormat);
126         return ERR_INVALID_PARAM;
127     }
128     if (!IsAudioSampleRateSupported(config.audioFormat, config.sampleRate)) {
129         MEDIA_ERR_LOG("audioFormat:%d is not support sampleRate:%d", config.audioFormat, config.sampleRate);
130         return ERR_INVALID_PARAM;
131     }
132     uint32_t paramIndex = 0;
133     domainKind_ = AUDIO_ENCODER;
134     encAttr_[paramIndex].key = KEY_CODEC_TYPE;
135     encAttr_[paramIndex].val = &domainKind_;
136     encAttr_[paramIndex].size = sizeof(CodecType);
137     paramIndex++;
138     codecMime_ = GetMimeFromAudioCodecFormat(config.audioFormat);
139     encAttr_[paramIndex].key = KEY_MIMETYPE;
140     encAttr_[paramIndex].val = &codecMime_;
141     encAttr_[paramIndex].size = sizeof(AvCodecMime);
142     paramIndex++;
143     profile_ = GetProfileFromAudioCodecFormat(config.audioFormat);
144     encAttr_[paramIndex].key = KEY_AUDIO_PROFILE;
145     encAttr_[paramIndex].val = &profile_;
146     encAttr_[paramIndex].size = sizeof(Profile);
147     paramIndex++;
148     sampleRate_ = config.sampleRate;
149     encAttr_[paramIndex].key = KEY_AUDIO_SAMPLE_RATE;
150     encAttr_[paramIndex].val = &sampleRate_;
151     encAttr_[paramIndex].size = sizeof(uint32_t);
152     paramIndex++;
153     bitRate_ = config.bitRate;
154     encAttr_[paramIndex].key = KEY_BITRATE;
155     encAttr_[paramIndex].val = &bitRate_;
156     encAttr_[paramIndex].size = sizeof(uint32_t);
157     paramIndex++;
158     soundMode_ = ConvertSoundMode(config.channelCount);
159     encAttr_[paramIndex].key = KEY_AUDIO_SOUND_MODE;
160     encAttr_[paramIndex].val = &soundMode_;
161     encAttr_[paramIndex].size = sizeof(AudioSoundMode);
162     paramIndex++;
163     ptNumPerFrm_ = AUDIO_POINT_NUM;
164     encAttr_[paramIndex].key = KEY_AUDIO_POINTS_PER_FRAME;
165     encAttr_[paramIndex].val = &ptNumPerFrm_;
166     encAttr_[paramIndex].size = sizeof(uint32_t);
167     paramIndex++;
168     bufSize_ = AUDIO_FRAME_NUM_IN_BUF;
169     encAttr_[paramIndex].key = KEY_BUFFERSIZE;
170     encAttr_[paramIndex].val = &bufSize_;
171     encAttr_[paramIndex].size = sizeof(uint32_t);
172     return SUCCESS;
173 }
174 
Initialize(const AudioEncodeConfig & config)175 int32_t AudioEncoder::Initialize(const AudioEncodeConfig &config)
176 {
177     int32_t ret = InitAudioEncoderAttr(config);
178     if (ret != SUCCESS) {
179         MEDIA_ERR_LOG("InitAudioEncoderAttr failed:%d", ret);
180         return ret;
181     }
182     ret = CodecCreateByType(domainKind_, codecMime_, &encHandle_);
183     if (ret != SUCCESS) {
184         MEDIA_ERR_LOG("CodecCreateByType failed:0x%x", ret);
185         return ret;
186     }
187     ret = CodecSetParameter(encHandle_, encAttr_, AUDIO_ENC_PARAM_NUM);
188     if (ret != SUCCESS) {
189         CodecDestroy(encHandle_);
190         MEDIA_ERR_LOG("CodecSetParameter failed:0x%x", ret);
191         return ret;
192     }
193     initialized_ = true;
194     return SUCCESS;
195 }
196 
BindSource(uint32_t deviceId)197 int32_t AudioEncoder::BindSource(uint32_t deviceId)
198 {
199     Param params[1];
200     (void)memset_s(params, sizeof(params), 0x00, sizeof(params));
201     params[0].key = KEY_DEVICE_ID;
202     params[0].val = reinterpret_cast<void *>(&deviceId);
203     params[0].size = sizeof(uint32_t);
204     int32_t ret = CodecSetParameter(encHandle_, params, sizeof(params) / sizeof(params[0]));
205     if (ret != SUCCESS) {
206         MEDIA_ERR_LOG("CodecSetDevice:0x%x", ret);
207         return ret;
208     }
209     return SUCCESS;
210 }
211 
GetMute(bool & muted)212 int32_t AudioEncoder::GetMute(bool &muted)
213 {
214     (void)muted;
215     return ERR_UNKNOWN;
216 }
217 
SetMute(bool muted)218 int32_t AudioEncoder::SetMute(bool muted)
219 {
220     (void)muted;
221     return ERR_UNKNOWN;
222 }
223 
Start()224 int32_t AudioEncoder::Start()
225 {
226     if (!initialized_) {
227         MEDIA_ERR_LOG("not initialized");
228         return ERR_ILLEGAL_STATE;
229     }
230     int32_t ret = CodecStart(encHandle_);
231     if (ret != SUCCESS) {
232         MEDIA_ERR_LOG("CodecStart failed:0x%x", ret);
233         return ret;
234     }
235     started_ = true;
236     return ret;
237 }
238 
ReadStream(AudioStream & stream,bool isBlockingRead)239 int32_t AudioEncoder::ReadStream(AudioStream &stream, bool isBlockingRead)
240 {
241     if (!started_) {
242         MEDIA_ERR_LOG("Codec not Started");
243         return ERR_INVALID_READ;
244     }
245     if (stream.buffer == nullptr || stream.bufferLen == 0) {
246         MEDIA_ERR_LOG("stream.buffer is nullptr");
247         return ERR_INVALID_READ;
248     }
249     uint32_t timeoutMs;
250     if (isBlockingRead) {
251         timeoutMs = AUDIO_READ_STREAM_TIME_OUT_MS;
252     } else {
253         timeoutMs = 0;
254     }
255     AudioBufferInfo outInfo;
256     int32_t ret = CodecDequeueOutput(encHandle_, timeoutMs, nullptr, (CodecBuffer *)&outInfo);
257     if (ret != SUCCESS && outInfo.info.buffer[0].buf == 0) {
258         MEDIA_ERR_LOG("CodecDequeueOutput failed:0x%x", ret);
259         return ERR_INVALID_READ;
260     }
261     int32_t readLen = 0;
262     errno_t retCopy = memcpy_s(stream.buffer, stream.bufferLen, (void *)outInfo.info.buffer[0].buf,
263                                outInfo.info.buffer[0].length);
264     if (retCopy != EOK) {
265         MEDIA_ERR_LOG("memcpy_s failed, timeStamp:%lld, retCopy:0x%x", outInfo.info.timeStamp, retCopy);
266         return ERR_INVALID_OPERATION;
267     } else {
268         readLen = outInfo.info.buffer[0].length;
269     }
270     stream.timeStamp = outInfo.info.timeStamp;
271     (void)CodecQueueOutput(encHandle_, (CodecBuffer *)&outInfo, timeoutMs, -1);
272     return readLen;
273 }
274 
Stop()275 int32_t AudioEncoder::Stop()
276 {
277     MEDIA_DEBUG_LOG("AudioEncoder::Stop");
278     if (!started_) {
279         MEDIA_ERR_LOG("Codec not Start");
280     }
281     return CodecStop(encHandle_);
282 }
283 
Release()284 int32_t AudioEncoder::Release()
285 {
286     MEDIA_DEBUG_LOG("AudioEncoder::Release");
287     if (!initialized_) {
288         MEDIA_ERR_LOG("Codec not initialized");
289     }
290     if (encHandle_ != nullptr) {
291         CodecDestroy(encHandle_);
292         encHandle_ = nullptr;
293     }
294     initialized_ = false;
295     return SUCCESS;
296 }
297 }  // namespace Audio
298 }  // namespace OHOS
299