1 /*
2 * Copyright (C) 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 "processor_aenc_impl.h"
17 #include "media_errors.h"
18 #include "media_log.h"
19
20 namespace {
21 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "ProcessorAencImpl"};
22 constexpr uint32_t DEFAULT_BUFFER_SIZE = 50000;
23 constexpr int32_t MAX_CHANNELS = 6;
24 static const GstAudioChannelPosition CHANNEL_POSITION[6][6] = {
25 {
26 GST_AUDIO_CHANNEL_POSITION_MONO
27 },
28 {
29 GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
30 GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT
31 },
32 {
33 GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
34 GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
35 GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT
36 },
37 {
38 GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
39 GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
40 GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
41 GST_AUDIO_CHANNEL_POSITION_REAR_CENTER
42 },
43 {
44 GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
45 GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
46 GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
47 GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
48 GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT
49 },
50 {
51 GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
52 GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
53 GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
54 GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
55 GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
56 GST_AUDIO_CHANNEL_POSITION_LFE1
57 },
58 };
59
60 enum MPEG4SamplingFrequencies : int32_t {
61 MPEG4_SAMPLING_FREQUENCY_0 = 0,
62 MPEG4_SAMPLING_FREQUENCY_1,
63 MPEG4_SAMPLING_FREQUENCY_2,
64 MPEG4_SAMPLING_FREQUENCY_3,
65 MPEG4_SAMPLING_FREQUENCY_4,
66 MPEG4_SAMPLING_FREQUENCY_5,
67 MPEG4_SAMPLING_FREQUENCY_6,
68 MPEG4_SAMPLING_FREQUENCY_7,
69 MPEG4_SAMPLING_FREQUENCY_8,
70 MPEG4_SAMPLING_FREQUENCY_9,
71 MPEG4_SAMPLING_FREQUENCY_10,
72 MPEG4_SAMPLING_FREQUENCY_11,
73 MPEG4_SAMPLING_FREQUENCY_12,
74 MPEG4_SAMPLING_FREQUENCY_13,
75 };
76
77 constexpr size_t SAMPLING_ROW_COUNT = 14;
78 static const int32_t MPEG4_SAMPLING_FREQUENCIES[SAMPLING_ROW_COUNT][2] = {
79 { 96000, MPEG4_SAMPLING_FREQUENCY_0 },
80 { 88200, MPEG4_SAMPLING_FREQUENCY_1 },
81 { 64000, MPEG4_SAMPLING_FREQUENCY_2 },
82 { 48000, MPEG4_SAMPLING_FREQUENCY_3 },
83 { 44100, MPEG4_SAMPLING_FREQUENCY_4 },
84 { 32000, MPEG4_SAMPLING_FREQUENCY_5 },
85 { 24000, MPEG4_SAMPLING_FREQUENCY_6 },
86 { 22050, MPEG4_SAMPLING_FREQUENCY_7 },
87 { 16000, MPEG4_SAMPLING_FREQUENCY_8 },
88 { 12000, MPEG4_SAMPLING_FREQUENCY_9 },
89 { 11025, MPEG4_SAMPLING_FREQUENCY_10 },
90 { 8000, MPEG4_SAMPLING_FREQUENCY_11 },
91 { 7350, MPEG4_SAMPLING_FREQUENCY_12 },
92 { -1, MPEG4_SAMPLING_FREQUENCY_13 },
93 };
94 }
95
96 namespace OHOS {
97 namespace Media {
ProcessorAencImpl()98 ProcessorAencImpl::ProcessorAencImpl()
99 {
100 }
101
~ProcessorAencImpl()102 ProcessorAencImpl::~ProcessorAencImpl()
103 {
104 }
105
ProcessMandatory(const Format & format)106 int32_t ProcessorAencImpl::ProcessMandatory(const Format &format)
107 {
108 CHECK_AND_RETURN_RET(format.GetIntValue("channel_count", channels_) == true, MSERR_INVALID_VAL);
109 CHECK_AND_RETURN_RET(format.GetIntValue("sample_rate", sampleRate_) == true, MSERR_INVALID_VAL);
110 CHECK_AND_RETURN_RET(format.GetIntValue("audio_sample_format", audioSampleFormat_) == true, MSERR_INVALID_VAL);
111 MEDIA_LOGD("channels:%{public}d, sampleRate:%{public}d, pcm:%{public}d",
112 channels_, sampleRate_, audioSampleFormat_);
113
114 gstRawFormat_ = RawAudioFormatToGst(static_cast<AudioStandard::AudioSampleFormat>(audioSampleFormat_));
115
116 return MSERR_OK;
117 }
118
ProcessOptional(const Format & format)119 int32_t ProcessorAencImpl::ProcessOptional(const Format &format)
120 {
121 if (format.GetValueType(std::string_view("profile")) == FORMAT_TYPE_INT32) {
122 (void)format.GetIntValue("profile", profile_);
123 }
124
125 return MSERR_OK;
126 }
127
GetInputPortConfig()128 std::shared_ptr<ProcessorConfig> ProcessorAencImpl::GetInputPortConfig()
129 {
130 CHECK_AND_RETURN_RET(channels_ > 0 && sampleRate_ > 0 && channels_ <= MAX_CHANNELS, nullptr);
131
132 guint64 channelMask = 0;
133 if (!gst_audio_channel_positions_to_mask(CHANNEL_POSITION[channels_ - 1], channels_, FALSE, &channelMask)) {
134 MEDIA_LOGE("Invalid channel positions");
135 return nullptr;
136 }
137
138 GstCaps *caps = gst_caps_new_simple("audio/x-raw",
139 "rate", G_TYPE_INT, sampleRate_,
140 "channels", G_TYPE_INT, channels_,
141 "format", G_TYPE_STRING, gstRawFormat_.c_str(),
142 "channel-mask", GST_TYPE_BITMASK, channelMask,
143 "layout", G_TYPE_STRING, "interleaved", nullptr);
144 CHECK_AND_RETURN_RET(caps != nullptr, nullptr);
145
146 auto config = std::make_shared<ProcessorConfig>(caps, true);
147 config->bufferSize_ = DEFAULT_BUFFER_SIZE;
148
149 return config;
150 }
151
GetOutputPortConfig()152 std::shared_ptr<ProcessorConfig> ProcessorAencImpl::GetOutputPortConfig()
153 {
154 CHECK_AND_RETURN_RET(channels_ > 0 && sampleRate_ > 0 && channels_ <= MAX_CHANNELS, nullptr);
155
156 GstCaps *caps = nullptr;
157 switch (codecName_) {
158 case CODEC_MIME_TYPE_AUDIO_AAC:
159 caps = gst_caps_new_simple("audio/mpeg",
160 "rate", G_TYPE_INT, sampleRate_,
161 "channels", G_TYPE_INT, channels_,
162 "mpegversion", G_TYPE_INT, 4,
163 "stream-format", G_TYPE_STRING, "raw",
164 "base-profile", G_TYPE_STRING, "lc", nullptr);
165 break;
166 case CODEC_MIME_TYPE_AUDIO_OPUS:
167 caps = gst_caps_new_simple("audio/x-opus",
168 "rate", G_TYPE_INT, sampleRate_, "channels", G_TYPE_INT, channels_, nullptr);
169 break;
170 default:
171 break;
172 }
173 CHECK_AND_RETURN_RET_LOG(caps != nullptr, nullptr, "Unsupported format");
174
175 auto config = std::make_shared<ProcessorConfig>(caps, true);
176 config->bufferSize_ = DEFAULT_BUFFER_SIZE;
177 if (codecName_ == CODEC_MIME_TYPE_AUDIO_AAC) {
178 config->needFilter_ = true;
179 config->filterMode_ = BUFFER_FILTER_MODE_ADD_ADTS;
180 config->adtsHead_.channelConfig = static_cast<uint32_t>(channels_);
181 config->adtsHead_.objectType = 2; // AAC_LC
182 for (size_t i = 0; i < SAMPLING_ROW_COUNT; i++) {
183 if (sampleRate_ >= MPEG4_SAMPLING_FREQUENCIES[i][0]) {
184 config->adtsHead_.samplingIndex = MPEG4_SAMPLING_FREQUENCIES[i][1];
185 break;
186 }
187 }
188 }
189
190 return config;
191 }
192 } // namespace Media
193 } // namespace OHOS
194