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_adec_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, "ProcessorAdecImpl"};
22 constexpr uint32_t DEFAULT_BUFFER_SIZE = 100000;
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
61 namespace OHOS {
62 namespace Media {
ProcessorAdecImpl()63 ProcessorAdecImpl::ProcessorAdecImpl()
64 {
65 }
66
~ProcessorAdecImpl()67 ProcessorAdecImpl::~ProcessorAdecImpl()
68 {
69 }
70
ProcessMandatory(const Format & format)71 int32_t ProcessorAdecImpl::ProcessMandatory(const Format &format)
72 {
73 CHECK_AND_RETURN_RET(format.GetIntValue("channel_count", channels_) == true, MSERR_INVALID_VAL);
74 CHECK_AND_RETURN_RET(format.GetIntValue("sample_rate", sampleRate_) == true, MSERR_INVALID_VAL);
75 CHECK_AND_RETURN_RET(format.GetIntValue("audio_sample_format", audioSampleFormat_) == true, MSERR_INVALID_VAL);
76 MEDIA_LOGD("channels:%{public}d, sampleRate:%{public}d, pcm:%{public}d",
77 channels_, sampleRate_, audioSampleFormat_);
78
79 gstRawFormat_ = RawAudioFormatToGst(static_cast<AudioStandard::AudioSampleFormat>(audioSampleFormat_));
80 return MSERR_OK;
81 }
82
ProcessOptional(const Format & format)83 int32_t ProcessorAdecImpl::ProcessOptional(const Format &format)
84 {
85 (void)format;
86 return MSERR_OK;
87 }
88
GetInputPortConfig()89 std::shared_ptr<ProcessorConfig> ProcessorAdecImpl::GetInputPortConfig()
90 {
91 CHECK_AND_RETURN_RET(channels_ > 0 && sampleRate_ > 0 && channels_ <= MAX_CHANNELS, nullptr);
92
93 guint64 channelMask = 0;
94 if (!gst_audio_channel_positions_to_mask(CHANNEL_POSITION[channels_ - 1], channels_, FALSE, &channelMask)) {
95 MEDIA_LOGE("Invalid channel positions");
96 return nullptr;
97 }
98
99 GstCaps *caps = nullptr;
100 switch (codecName_) {
101 case CODEC_MIME_TYPE_AUDIO_VORBIS:
102 caps = gst_caps_new_simple("audio/x-vorbis",
103 "rate", G_TYPE_INT, sampleRate_, "channels", G_TYPE_INT, channels_, nullptr);
104 break;
105 case CODEC_MIME_TYPE_AUDIO_MPEG:
106 caps = gst_caps_new_simple("audio/mpeg",
107 "rate", G_TYPE_INT, sampleRate_, "channels", G_TYPE_INT, channels_,
108 "channel-mask", GST_TYPE_BITMASK, channelMask, "mpegversion", G_TYPE_INT, 1,
109 "layer", G_TYPE_INT, 3, nullptr);
110 break;
111 case CODEC_MIME_TYPE_AUDIO_AAC:
112 caps = gst_caps_new_simple("audio/mpeg",
113 "rate", G_TYPE_INT, sampleRate_, "channels", G_TYPE_INT, channels_,
114 "mpegversion", G_TYPE_INT, 4, "stream-format", G_TYPE_STRING, "adts",
115 "base-profile", G_TYPE_STRING, "lc", nullptr);
116 break;
117 case CODEC_MIME_TYPE_AUDIO_FLAC:
118 caps = gst_caps_new_simple("audio/x-flac",
119 "rate", G_TYPE_INT, sampleRate_, "channels", G_TYPE_INT, channels_,
120 "framed", G_TYPE_BOOLEAN, TRUE, nullptr);
121 break;
122 case CODEC_MIME_TYPE_AUDIO_OPUS:
123 caps = gst_caps_new_simple("audio/x-opus",
124 "rate", G_TYPE_INT, sampleRate_, "channels", G_TYPE_INT, channels_, nullptr);
125 break;
126 default:
127 break;
128 }
129 CHECK_AND_RETURN_RET_LOG(caps != nullptr, nullptr, "Unsupported format");
130
131 auto config = std::make_shared<ProcessorConfig>(caps, false);
132 config->needParser_ = (codecName_ == CODEC_MIME_TYPE_AUDIO_FLAC);
133 config->needCodecData_ = (codecName_ == CODEC_MIME_TYPE_AUDIO_VORBIS);
134 config->bufferSize_ = DEFAULT_BUFFER_SIZE;
135
136 return config;
137 }
138
GetOutputPortConfig()139 std::shared_ptr<ProcessorConfig> ProcessorAdecImpl::GetOutputPortConfig()
140 {
141 CHECK_AND_RETURN_RET(channels_ > 0 && sampleRate_ > 0 && channels_ <= MAX_CHANNELS, nullptr);
142
143 GstCaps *caps = gst_caps_new_simple("audio/x-raw",
144 "rate", G_TYPE_INT, sampleRate_,
145 "channels", G_TYPE_INT, channels_,
146 "format", G_TYPE_STRING, gstRawFormat_.c_str(),
147 "layout", G_TYPE_STRING, "interleaved", nullptr);
148 CHECK_AND_RETURN_RET_LOG(caps != nullptr, nullptr, "No memory");
149
150 auto config = std::make_shared<ProcessorConfig>(caps, false);
151 config->bufferSize_ = DEFAULT_BUFFER_SIZE;
152
153 return config;
154 }
155 } // namespace Media
156 } // namespace OHOS
157