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 "audio_ffmpeg_flac_decoder_plugin.h"
17 #include "avcodec_errors.h"
18 #include "media_description.h"
19 #include "avcodec_trace.h"
20 #include "avcodec_log.h"
21 #include "avcodec_mime_type.h"
22
23 namespace {
24 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_AUDIO, "AvCodec-AudioFFMpegFlacDecoderPlugin"};
25 constexpr int32_t MAX_BYTES_PER_SAMPLE = 4;
26 constexpr int32_t SAMPLES = 9216;
27 constexpr int32_t MIN_CHANNELS = 1;
28 constexpr int32_t MAX_CHANNELS = 8;
29 static const int32_t FLAC_DECODER_SAMPLE_RATE_TABLE[] = {
30 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000, 192000,
31 };
32 } // namespace
33
34 namespace OHOS {
35 namespace MediaAVCodec {
36 constexpr std::string_view AUDIO_CODEC_NAME = "flac";
AudioFFMpegFlacDecoderPlugin()37 AudioFFMpegFlacDecoderPlugin::AudioFFMpegFlacDecoderPlugin() : basePlugin(std::make_unique<AudioFfmpegDecoderPlugin>())
38 {
39 channels = 0;
40 }
41
~AudioFFMpegFlacDecoderPlugin()42 AudioFFMpegFlacDecoderPlugin::~AudioFFMpegFlacDecoderPlugin()
43 {
44 if (basePlugin != nullptr) {
45 basePlugin->Release();
46 basePlugin.reset();
47 }
48 }
49
CheckSampleRate(int32_t sampleRate)50 static bool CheckSampleRate(int32_t sampleRate)
51 {
52 for (auto i : FLAC_DECODER_SAMPLE_RATE_TABLE) {
53 if (i == sampleRate) {
54 return true;
55 }
56 }
57 return false;
58 }
59
CheckFormat(const Format & format)60 int32_t AudioFFMpegFlacDecoderPlugin::CheckFormat(const Format &format)
61 {
62 int32_t channelCount;
63 int32_t sampleRate;
64 format.GetIntValue(MediaDescriptionKey::MD_KEY_CHANNEL_COUNT, channelCount);
65 format.GetIntValue(MediaDescriptionKey::MD_KEY_SAMPLE_RATE, sampleRate);
66 if (!CheckSampleRate(sampleRate)) {
67 AVCODEC_LOGE("init failed, because sampleRate=%{public}d not in table.", sampleRate);
68 return AVCodecServiceErrCode::AVCS_ERR_MISMATCH_SAMPLE_RATE;
69 } else if (channelCount < MIN_CHANNELS || channelCount > MAX_CHANNELS) {
70 AVCODEC_LOGE("init failed, because channelCount=%{public}d not support.", channelCount);
71 return AVCodecServiceErrCode::AVCS_ERR_CONFIGURE_MISMATCH_CHANNEL_COUNT;
72 }
73 channels = channelCount;
74 return AVCodecServiceErrCode::AVCS_ERR_OK;
75 }
76
Init(const Format & format)77 int32_t AudioFFMpegFlacDecoderPlugin::Init(const Format &format)
78 {
79 int32_t ret = basePlugin->AllocateContext("flac");
80 if (ret != AVCodecServiceErrCode::AVCS_ERR_OK) {
81 AVCODEC_LOGE("init failed, because AllocateContext failed. ret=%{public}d", ret);
82 return ret;
83 }
84
85 ret = CheckFormat(format);
86 if (ret != AVCodecServiceErrCode::AVCS_ERR_OK) {
87 AVCODEC_LOGE("init failed, because CheckFormat failed. ret=%{public}d", ret);
88 return ret;
89 }
90
91 ret = basePlugin->InitContext(format);
92 if (ret != AVCodecServiceErrCode::AVCS_ERR_OK) {
93 AVCODEC_LOGE("init failed, because InitContext failed. ret=%{public}d", ret);
94 return ret;
95 }
96
97 ret = basePlugin->OpenContext();
98 if (ret != AVCodecServiceErrCode::AVCS_ERR_OK) {
99 AVCODEC_LOGE("init failed, because OpenContext failed. ret=%{public}d", ret);
100 return ret;
101 }
102
103 return AVCodecServiceErrCode::AVCS_ERR_OK;
104 }
105
ProcessSendData(const std::shared_ptr<AudioBufferInfo> & inputBuffer)106 int32_t AudioFFMpegFlacDecoderPlugin::ProcessSendData(const std::shared_ptr<AudioBufferInfo> &inputBuffer)
107 {
108 return basePlugin->ProcessSendData(inputBuffer);
109 }
110
ProcessRecieveData(std::shared_ptr<AudioBufferInfo> & outBuffer)111 int32_t AudioFFMpegFlacDecoderPlugin::ProcessRecieveData(std::shared_ptr<AudioBufferInfo> &outBuffer)
112 {
113 return basePlugin->ProcessRecieveData(outBuffer);
114 }
115
Reset()116 int32_t AudioFFMpegFlacDecoderPlugin::Reset()
117 {
118 return basePlugin->Reset();
119 }
120
Release()121 int32_t AudioFFMpegFlacDecoderPlugin::Release()
122 {
123 return basePlugin->Release();
124 }
125
Flush()126 int32_t AudioFFMpegFlacDecoderPlugin::Flush()
127 {
128 return basePlugin->Flush();
129 }
130
GetInputBufferSize() const131 int32_t AudioFFMpegFlacDecoderPlugin::GetInputBufferSize() const
132 {
133 int32_t inputBufferSize = SAMPLES * channels * MAX_BYTES_PER_SAMPLE;
134 int32_t maxSize = basePlugin->GetMaxInputSize();
135 if (maxSize < 0 || maxSize > inputBufferSize) {
136 maxSize = inputBufferSize;
137 }
138 return maxSize;
139 }
140
GetOutputBufferSize() const141 int32_t AudioFFMpegFlacDecoderPlugin::GetOutputBufferSize() const
142 {
143 int32_t outputBufferSize = SAMPLES * channels * MAX_BYTES_PER_SAMPLE;
144 return outputBufferSize;
145 }
146
GetFormat() const147 Format AudioFFMpegFlacDecoderPlugin::GetFormat() const noexcept
148 {
149 auto format = basePlugin->GetFormat();
150 format.PutStringValue(MediaDescriptionKey::MD_KEY_CODEC_MIME, AVCodecMimeType::MEDIA_MIMETYPE_AUDIO_FLAC);
151 return format;
152 }
153
GetCodecType() const154 std::string_view AudioFFMpegFlacDecoderPlugin::GetCodecType() const noexcept
155 {
156 return AUDIO_CODEC_NAME;
157 }
158 } // namespace MediaAVCodec
159 } // namespace OHOS