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