1 /*
2 * Copyright (c) 2024 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_mp3_encoder_plugin.h"
17 #include "avcodec_audio_common.h"
18 #include "avcodec_codec_name.h"
19 #include "avcodec_log.h"
20 #include "avcodec_mime_type.h"
21 #include "lame.h"
22 #include "plugin/codec_plugin.h"
23 #include "plugin/plugin_definition.h"
24
25 namespace {
26 using namespace OHOS::Media;
27 using namespace OHOS::Media::Plugins;
28 using namespace Mp3;
29 using namespace std;
30
31 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_AUDIO, "AvCodec-AudioMp3EncoderPlugin"};
32 constexpr int32_t ONE_CHANNEL = 1;
33 constexpr int32_t TWO_CHANNELS = 2;
34 constexpr int32_t SUPPORT_SAMPLE_RATE = 9;
35 constexpr int32_t SUPPORT_BIT_RATE = 16;
36 constexpr int32_t ONE_THOUSAND_BITRATE = 1000; // 1khz
37 constexpr int32_t SAMPLE_RATE_16000 = 16000;
38 constexpr int32_t SAMPLE_RATE_32000 = 32000;
39 constexpr int32_t BIT_RATE_32000 = 32000;
40 constexpr int32_t BIT_RATE_64000 = 64000;
41 constexpr int32_t BIT_RATE_160000 = 160000;
42
43 constexpr int32_t OUTPUT_BUFFER_SIZE_DEFAULT = 4096;
44 constexpr int32_t LAME_BUFFER_SIZE_DEFAULT = 8640; // 1152*1.25+7200=8640
45 constexpr int32_t LAME_INPUT_BUFFER_SIZE_ONE_CHAN = 2304; // 1152*2=2304
46 constexpr int32_t LAME_INPUT_BUFFER_SIZE_TWO_CHAN = 4608; // 1152*2*2=4608
47 constexpr int32_t INPUT_BUFFER_SIZE_DEFAULT = 5120; // 1152*2*2=4608
48
49 constexpr int32_t BUFFER_FLAG_EOS = 0x00000001;
50
51 constexpr int32_t BIT_RATE_PICK[SUPPORT_BIT_RATE] = {8000, 16000, 32000, 40000, 48000, 56000,
52 64000, 80000, 96000, 112000, 128000, 160000,
53 192000, 224000, 256000, 320000};
54 constexpr int32_t SAMPLE_RATE_PICK[SUPPORT_SAMPLE_RATE] = {8000, 11025, 12000, 16000, 22050,
55 24000, 32000, 44100, 48000};
56 constexpr int32_t DEFAULT_COMPRESSION_LEVEL = 5;
57
RegisterAudioEncoderPlugins(const std::shared_ptr<Register> & reg)58 Status RegisterAudioEncoderPlugins(const std::shared_ptr<Register>& reg)
59 {
60 CodecPluginDef definition;
61 definition.name = std::string(OHOS::MediaAVCodec::AVCodecCodecName::AUDIO_ENCODER_MP3_NAME);
62 definition.pluginType = PluginType::AUDIO_ENCODER;
63 definition.rank = 100; // 100
64 definition.SetCreator([](const std::string& name) -> std::shared_ptr<CodecPlugin> {
65 return std::make_shared<AudioMp3EncoderPlugin>(name);
66 });
67
68 Capability cap;
69
70 cap.SetMime(MimeType::AUDIO_MPEG);
71 cap.AppendFixedKey<CodecMode>(Tag::MEDIA_CODEC_MODE, CodecMode::SOFTWARE);
72
73 definition.AddInCaps(cap);
74 // do not delete the codec in the deleter
75 if (reg->AddPlugin(definition) != Status::OK) {
76 AVCODEC_LOGE("AudioMp3EncoderPlugin Register Failure");
77 return Status::ERROR_UNKNOWN;
78 }
79
80 return Status::OK;
81 }
82
UnRegisterAudioEncoderPlugin()83 void UnRegisterAudioEncoderPlugin() {}
84
85 PLUGIN_DEFINITION(Mp3AudioEncoder, LicenseType::APACHE_V2, RegisterAudioEncoderPlugins, UnRegisterAudioEncoderPlugin);
86 } // namespace
87
88 namespace OHOS {
89 namespace Media {
90 namespace Plugins {
91 namespace Mp3 {
92
93 struct AudioMp3EncoderPlugin::LameInfo {
94 lame_global_flags* gfp;
95 };
96
AudioMp3EncoderPlugin(const std::string & name)97 AudioMp3EncoderPlugin::AudioMp3EncoderPlugin(const std::string& name)
98 : CodecPlugin(std::move(name)),
99 audioSampleFormat_(AudioSampleFormat::SAMPLE_S16LE),
100 lameInitFlag(0),
101 channels_(ONE_CHANNEL),
102 bitrate_(0),
103 pts_(0),
104 sampleRate_(SUPPORT_SAMPLE_RATE),
105 maxInputSize_(INPUT_BUFFER_SIZE_DEFAULT),
106 maxOutputSize_(OUTPUT_BUFFER_SIZE_DEFAULT),
107 outputSize_(0)
108 {
109 std::lock_guard<std::mutex> lock(avMutex_);
110 lameMp3Buffer = std::make_unique<unsigned char []>(LAME_BUFFER_SIZE_DEFAULT);
111 lameInfo = std::make_unique<LameInfo>();
112 }
113
~AudioMp3EncoderPlugin()114 AudioMp3EncoderPlugin::~AudioMp3EncoderPlugin() {}
115
CheckFormat()116 bool AudioMp3EncoderPlugin::CheckFormat()
117 {
118 if (channels_ != ONE_CHANNEL && channels_ != TWO_CHANNELS) {
119 AVCODEC_LOGE("AudioMp3EncoderPlugin channels not supported");
120 return false;
121 }
122 for (int32_t i = 0; i < SUPPORT_BIT_RATE; i++) {
123 if (bitrate_ == BIT_RATE_PICK[i]) {
124 break;
125 } else if (i == SUPPORT_BIT_RATE - 1) {
126 AVCODEC_LOGE("AudioMp3EncoderPlugin bitRate not supported");
127 return false;
128 }
129 }
130 for (int32_t i = 0; i < SUPPORT_SAMPLE_RATE; i++) {
131 if (sampleRate_ == SAMPLE_RATE_PICK[i]) {
132 break;
133 } else if (i == SUPPORT_SAMPLE_RATE - 1) {
134 AVCODEC_LOGE("AudioMp3EncoderPlugin sampleRate not supported");
135 return false;
136 }
137 }
138 if (audioSampleFormat_ != AudioSampleFormat::SAMPLE_S16LE) {
139 AVCODEC_LOGE("AudioMp3EncoderPlugin sampleFmt not supported");
140 return false;
141 }
142 if (sampleRate_ < SAMPLE_RATE_16000 && bitrate_ > BIT_RATE_64000) {
143 AVCODEC_LOGE("sample<16k,bitrate must <=64k");
144 return false;
145 } else if (sampleRate_ < SAMPLE_RATE_32000 && bitrate_ > BIT_RATE_160000) {
146 AVCODEC_LOGE("sample<32k,bitrate must <=160k");
147 return false;
148 } else if (sampleRate_ >= SAMPLE_RATE_32000 && bitrate_ < BIT_RATE_32000) {
149 AVCODEC_LOGE("sample>=32k,bitrate must >=32k");
150 return false;
151 }
152 return true;
153 }
154
Init()155 Status AudioMp3EncoderPlugin::Init()
156 {
157 std::lock_guard<std::mutex> lock(avMutex_);
158 if (lameInfo == nullptr) {
159 AVCODEC_LOGE("AudioMp3EncoderPlugin lameInfo allocation failed");
160 return Status::ERROR_UNKNOWN;
161 }
162 lameInfo->gfp = lame_init();
163 lameInitFlag = 0;
164 if (lameInfo->gfp == nullptr) {
165 AVCODEC_LOGE("AudioMp3EncoderPlugin LAME initialization error");
166 return Status::ERROR_UNKNOWN;
167 }
168 if (lameMp3Buffer == nullptr) {
169 AVCODEC_LOGE("AudioMp3EncoderPlugin lameMp3Buffer allocation failed");
170 return Status::ERROR_UNKNOWN;
171 }
172 return Status::OK;
173 }
174
Start()175 Status AudioMp3EncoderPlugin::Start()
176 {
177 if (!CheckFormat()) {
178 AVCODEC_LOGE("Format check failed.");
179 return Status::ERROR_INVALID_PARAMETER;
180 }
181 return Status::OK;
182 }
183
QueueInputBuffer(const std::shared_ptr<AVBuffer> & inputBuffer)184 Status AudioMp3EncoderPlugin::QueueInputBuffer(const std::shared_ptr<AVBuffer>& inputBuffer)
185 {
186 auto memory = inputBuffer->memory_;
187 auto inputSize = memory->GetSize();
188 CHECK_AND_RETURN_RET_LOG(inputSize >= 0, Status::ERROR_UNKNOWN,
189 "SendBuffer buffer is less than zero. size: %{public}d", inputSize);
190 if (inputSize == 0 && !(inputBuffer->flag_ & BUFFER_FLAG_EOS)) {
191 AVCODEC_LOGE("size is 0, but eos flag is not 1");
192 return Status::ERROR_INVALID_DATA;
193 }
194 if ((channels_ == ONE_CHANNEL && inputSize > LAME_INPUT_BUFFER_SIZE_ONE_CHAN) ||
195 (channels_ == TWO_CHANNELS && inputSize > LAME_INPUT_BUFFER_SIZE_TWO_CHAN)) {
196 AVCODEC_LOGE("SendBuffer size > max InputBufferSize(1 channel: 2304bytes; 2 channels: 4608bytes)\
197 size: %{public}d", inputSize);
198 return Status::ERROR_UNKNOWN;
199 }
200 if (inputSize > memory->GetCapacity()) {
201 AVCODEC_LOGE("send input buffer is > allocate size. size : %{public}d, allocate size : %{public}d",
202 inputSize, memory->GetCapacity());
203 return Status::ERROR_UNKNOWN;
204 }
205 std::lock_guard<std::mutex> lock(avMutex_);
206 int32_t sampleNumTmp = -1; // -1:initialize invalid value
207 sampleNumTmp = channels_ == ONE_CHANNEL ? inputSize / sizeof(int16_t) : inputSize / sizeof(int16_t) / 2; // 2ch
208 unsigned char* lamePcmBuffer = memory->GetAddr();
209 int outputSize = 0;
210
211 const int sampleNum = static_cast<const int>(sampleNumTmp);
212 const short* inputPcmBuffer = reinterpret_cast<const short*>(lamePcmBuffer);
213 if (sampleNumTmp > 0) {
214 if (channels_ == 1) { // 1:mono
215 outputSize = lame_encode_buffer(lameInfo->gfp, inputPcmBuffer, inputPcmBuffer, sampleNum,
216 lameMp3Buffer.get(), LAME_BUFFER_SIZE_DEFAULT);
217 } else {
218 outputSize = lame_encode_buffer_interleaved(lameInfo->gfp, reinterpret_cast<short*>(lamePcmBuffer),
219 sampleNumTmp, lameMp3Buffer.get(), LAME_BUFFER_SIZE_DEFAULT);
220 }
221 } else if (sampleNumTmp == 0) {
222 outputSize = lame_encode_flush(lameInfo->gfp, lameMp3Buffer.get(), LAME_BUFFER_SIZE_DEFAULT);
223 }
224
225 if (outputSize < 0) {
226 AVCODEC_LOGE("AudioMp3EncoderPlugin lame encode error.");
227 return Status::ERROR_UNKNOWN;
228 }
229 outputSize_ = outputSize;
230 pts_ = inputBuffer->pts_;
231 dataCallback_->OnInputBufferDone(inputBuffer);
232
233 return Status::OK;
234 }
235
QueueOutputBuffer(std::shared_ptr<AVBuffer> & outputBuffer)236 Status AudioMp3EncoderPlugin::QueueOutputBuffer(std::shared_ptr<AVBuffer>& outputBuffer)
237 {
238 if (!outputBuffer) {
239 AVCODEC_LOGE("AudioMp3EncoderPlugin Queue out buffer is null.");
240 return Status::ERROR_INVALID_PARAMETER;
241 }
242 {
243 std::lock_guard<std::mutex> lock(avMutex_);
244 auto memory = outputBuffer->memory_;
245
246 if (outputSize_ == 0) {
247 AVCODEC_LOGD("AudioMp3EncoderPlugin lame outputSize of this frame is 0.");
248 return Status::ERROR_NOT_ENOUGH_DATA;
249 }
250
251 memory->Write(const_cast<const uint8_t*>(lameMp3Buffer.get()), outputSize_, 0);
252 memory->SetSize(outputSize_);
253 outputBuffer->pts_ = pts_;
254 dataCallback_->OnOutputBufferDone(outputBuffer);
255 }
256
257 return Status::OK;
258 }
259
Reset()260 Status AudioMp3EncoderPlugin::Reset()
261 {
262 AVCODEC_LOGD("Reset begins");
263 auto ret = Release();
264 if (ret != Status::OK) {
265 AVCODEC_LOGE("AudioMp3EncoderPlugin Reset Release error.");
266 return ret;
267 }
268 ret = Init();
269 if (ret != Status::OK) {
270 AVCODEC_LOGE("AudioMp3EncoderPlugin Reset Init error.");
271 return ret;
272 }
273
274 return Status::OK;
275 }
276
Release()277 Status AudioMp3EncoderPlugin::Release()
278 {
279 std::lock_guard<std::mutex> lock(avMutex_);
280 if (lameInfo != nullptr && lameInfo->gfp != nullptr) {
281 if (lameInitFlag == 0) {
282 if (lame_init_params(lameInfo->gfp) < 0) {
283 AVCODEC_LOGE("AudioMp3EncoderPlugin Release LAME parameter initialization error");
284 return Status::ERROR_UNKNOWN;
285 }
286 lameInitFlag = 1;
287 }
288 int ret = lame_encode_flush(lameInfo->gfp, lameMp3Buffer.get(), LAME_BUFFER_SIZE_DEFAULT);
289 if (ret < 0) {
290 AVCODEC_LOGE("AudioMp3EncoderPlugin Release lame_encode_flush error.");
291 return Status::ERROR_UNKNOWN;
292 }
293 (void)lame_close(lameInfo->gfp);
294
295 lameInfo->gfp = nullptr;
296 lameInitFlag = 0;
297 }
298 return Status::OK;
299 }
300
Flush()301 Status AudioMp3EncoderPlugin::Flush()
302 {
303 return Status::OK;
304 }
305
SetParameter(const std::shared_ptr<Meta> & parameter)306 Status AudioMp3EncoderPlugin::SetParameter(const std::shared_ptr<Meta>& parameter)
307 {
308 std::lock_guard<std::mutex> lock(avMutex_);
309 if (!parameter->Get<Tag::AUDIO_CHANNEL_COUNT>(channels_)) {
310 AVCODEC_LOGE("AudioMp3EncoderPlugin SetParameter error. no AUDIO_CHANNEL_COUNT");
311 return Status::ERROR_INVALID_PARAMETER;
312 }
313 if (!parameter->Get<Tag::AUDIO_SAMPLE_RATE>(sampleRate_)) {
314 AVCODEC_LOGE("AudioMp3EncoderPlugin SetParameter error. no AUDIO_SAMPLE_RATE");
315 return Status::ERROR_INVALID_PARAMETER;
316 }
317 if (!parameter->Get<Tag::AUDIO_SAMPLE_FORMAT>(audioSampleFormat_)) {
318 AVCODEC_LOGE("AudioMp3EncoderPlugin SetParameter error. no AUDIO_SAMPLE_FORMAT");
319 return Status::ERROR_INVALID_PARAMETER;
320 }
321 if (!parameter->Get<Tag::MEDIA_BITRATE>(bitrate_)) {
322 AVCODEC_LOGE("AudioMp3EncoderPlugin SetParameter error. no MEDIA_BITRATE of mp3 encoder CBR");
323 return Status::ERROR_INVALID_PARAMETER;
324 }
325 if (parameter->Find(Tag::AUDIO_MAX_INPUT_SIZE) != parameter->end()) {
326 parameter->Get<Tag::AUDIO_MAX_INPUT_SIZE>(maxInputSize_);
327 AVCODEC_LOGD("AudioMp3EncoderPlugin SetParameter maxInputSize_: %{public}d", maxInputSize_);
328 }
329 if (!CheckFormat()) {
330 AVCODEC_LOGE("AudioMp3EncoderPlugin SetParameter error. CheckFormat fail");
331 return Status::ERROR_INVALID_PARAMETER;
332 }
333 audioParameter_ = *parameter;
334 lame_set_in_samplerate(lameInfo->gfp, sampleRate_);
335 lame_set_out_samplerate(lameInfo->gfp, sampleRate_);
336 lame_set_num_channels(lameInfo->gfp, channels_);
337 lame_set_quality(lameInfo->gfp, DEFAULT_COMPRESSION_LEVEL);
338 if (channels_ == 1) {
339 lame_set_mode(lameInfo->gfp, MPEG_mode_e::MONO);
340 }
341 lame_set_brate(lameInfo->gfp, bitrate_ / ONE_THOUSAND_BITRATE);
342 if (lame_init_params(lameInfo->gfp) < 0) {
343 AVCODEC_LOGE("AudioMp3EncoderPlugin LAME parameter initialization error");
344 return Status::ERROR_UNKNOWN;
345 }
346 int32_t frameSize = lame_get_framesize(lameInfo->gfp);
347 audioParameter_.Set<Tag::AUDIO_SAMPLE_PER_FRAME>(frameSize);
348 lameInitFlag = 1;
349 return Status::OK;
350 }
351
GetParameter(std::shared_ptr<Meta> & parameter)352 Status AudioMp3EncoderPlugin::GetParameter(std::shared_ptr<Meta>& parameter)
353 {
354 std::lock_guard<std::mutex> lock(avMutex_);
355 if (maxInputSize_ <= 0 || maxInputSize_ > INPUT_BUFFER_SIZE_DEFAULT) {
356 maxInputSize_ = INPUT_BUFFER_SIZE_DEFAULT;
357 }
358 maxOutputSize_ = OUTPUT_BUFFER_SIZE_DEFAULT;
359 AVCODEC_LOGD("AudioMp3EncoderPlugin GetParameter maxInputSize_: %{public}d", maxInputSize_);
360 audioParameter_.Set<Tag::AUDIO_SAMPLE_FORMAT>(AudioSampleFormat::SAMPLE_S16LE);
361 audioParameter_.Set<Tag::AUDIO_MAX_INPUT_SIZE>(maxInputSize_);
362 audioParameter_.Set<Tag::AUDIO_MAX_OUTPUT_SIZE>(maxOutputSize_);
363 audioParameter_.Set<Tag::MEDIA_BITRATE>(bitrate_);
364 *parameter = audioParameter_;
365 return Status::OK;
366 }
367
Prepare()368 Status AudioMp3EncoderPlugin::Prepare()
369 {
370 return Status::OK;
371 }
372
Stop()373 Status AudioMp3EncoderPlugin::Stop()
374 {
375 std::lock_guard<std::mutex> lock(avMutex_);
376 if (!lameInfo || !lameMp3Buffer) {
377 AVCODEC_LOGE("AudioMp3EncoderPlugin Stop lameInfo or lameMp3Buffer is nullptr");
378 return Status::ERROR_NULL_POINTER;
379 }
380 int result = lame_encode_flush(lameInfo->gfp, lameMp3Buffer.get(), LAME_BUFFER_SIZE_DEFAULT);
381 if (result < 0) {
382 AVCODEC_LOGE("AudioMp3EncoderPlugin Stop lame_encode_flush error.");
383 return Status::ERROR_UNKNOWN;
384 }
385 return Status::OK;
386 }
387
GetInputBuffers(std::vector<std::shared_ptr<AVBuffer>> & inputBuffers)388 Status AudioMp3EncoderPlugin::GetInputBuffers(std::vector<std::shared_ptr<AVBuffer>>& inputBuffers)
389 {
390 return Status::OK;
391 }
392
GetOutputBuffers(std::vector<std::shared_ptr<AVBuffer>> & outputBuffers)393 Status AudioMp3EncoderPlugin::GetOutputBuffers(std::vector<std::shared_ptr<AVBuffer>>& outputBuffers)
394 {
395 return Status::OK;
396 }
397
398 } // namespace Mp3
399 } // namespace Plugins
400 } // namespace Media
401 } // namespace OHOS