1 /*
2 * Copyright (c) 2021-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 #define HST_LOG_TAG "AACDemuxerPlugin"
17
18 #include "aac_demuxer_plugin.h"
19 #include <algorithm>
20 #include <cstdio>
21 #include <cstring>
22 #include <new>
23 #include <securec.h>
24 #include "foundation/log.h"
25 #include "osal/thread/scoped_lock.h"
26 #include "plugin/common/plugin_buffer.h"
27 #include "constants.h"
28 #include "osal/utils/util.h"
29
30 namespace OHOS {
31 namespace Media {
32 namespace Plugin {
33 namespace AacDemuxer {
34 namespace {
35 constexpr uint32_t PROBE_READ_LENGTH = 2;
36 constexpr uint32_t GET_INFO_READ_LEN = 7;
37 constexpr uint32_t MEDIA_IO_SIZE = 2048;
38 constexpr uint32_t MAX_RANK = 100;
39 uint32_t usedDataSize_ = 0;
40 int samplingRateMap[] = {96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350};
41 int IsAACPattern(const uint8_t *data);
42 int Sniff(const std::string& name, std::shared_ptr<DataSource> dataSource);
43 Status RegisterPlugin(const std::shared_ptr<Register>& reg);
44 }
45
AACDemuxerPlugin(std::string name)46 AACDemuxerPlugin::AACDemuxerPlugin(std::string name)
47 : DemuxerPlugin(std::move(name)),
48 ioContext_(),
49 fileSize_(0),
50 isSeekable_(false),
51 inIoBuffer_(nullptr),
52 inIoBufferSize_(MEDIA_IO_SIZE),
53 ioDataRemainSize_(0)
54 {
55 FALSE_LOG(memset_s(&aacDemuxerRst_, sizeof(aacDemuxerRst_), 0x00, sizeof(AACDemuxerRst)) == 0);
56 MEDIA_LOG_I("AACDemuxerPlugin, plugin name: " PUBLIC_LOG_S, pluginName_.c_str());
57 }
58
~AACDemuxerPlugin()59 AACDemuxerPlugin::~AACDemuxerPlugin()
60 {
61 MEDIA_LOG_I("~AACDemuxerPlugin");
62 }
63
SetDataSource(const std::shared_ptr<DataSource> & source)64 Status AACDemuxerPlugin::SetDataSource(const std::shared_ptr<DataSource>& source)
65 {
66 ioContext_.dataSource = source;
67 if (ioContext_.dataSource != nullptr) {
68 ioContext_.dataSource->GetSize(fileSize_);
69 }
70 MEDIA_LOG_I("fileSize_ " PUBLIC_LOG_ZU, fileSize_);
71 isSeekable_ = fileSize_ > 0 ? true : false;
72 return Status::OK;
73 }
74
DoReadFromSource(uint32_t readSize)75 Status AACDemuxerPlugin::DoReadFromSource(uint32_t readSize)
76 {
77 if (readSize == 0) {
78 return Status::OK;
79 }
80 auto buffer = std::make_shared<Buffer>();
81 auto bufData = buffer->AllocMemory(nullptr, readSize);
82 int retryTimes = 0;
83 MEDIA_LOG_D("readSize " PUBLIC_LOG_U32 " inIoBufferSize_ " PUBLIC_LOG_D32 "ioDataRemainSize_ "
84 PUBLIC_LOG_U32, readSize, inIoBufferSize_, ioDataRemainSize_);
85 do {
86 if (isSeekable_) {
87 auto result = ioContext_.dataSource->ReadAt(ioContext_.offset, buffer, static_cast<size_t>(readSize));
88 MEDIA_LOG_D("ioContext_.offset " PUBLIC_LOG_U32, static_cast<uint32_t>(ioContext_.offset));
89 if (result != Status::OK) {
90 MEDIA_LOG_W("read data from source warning " PUBLIC_LOG_D32, static_cast<int>(result));
91 return result;
92 }
93 } else {
94 auto result = ioContext_.dataSource->ReadAt(0, buffer, static_cast<size_t>(readSize));
95 if (result != Status::OK) {
96 MEDIA_LOG_W("read data from source warning " PUBLIC_LOG_D32, static_cast<int>(result));
97 return result;
98 }
99 }
100
101 MEDIA_LOG_D("bufData->GetSize() " PUBLIC_LOG_ZU, bufData->GetSize());
102 if (bufData->GetSize() > 0) {
103 if (readSize >= bufData->GetSize()) {
104 (void)memcpy_s(inIoBuffer_ + ioDataRemainSize_, readSize,
105 const_cast<uint8_t *>(bufData->GetReadOnlyData()), bufData->GetSize());
106 } else {
107 MEDIA_LOG_E("Error: readSize < bufData->GetSize()");
108 return Status::ERROR_UNKNOWN;
109 }
110 if (isSeekable_) {
111 ioContext_.offset += bufData->GetSize();
112 }
113 ioDataRemainSize_ += bufData->GetSize();
114 }
115 if (bufData->GetSize() == 0 && ioDataRemainSize_ == 0 && retryTimes < 200) { // 200
116 OSAL::SleepFor(30); // 30
117 retryTimes++;
118 continue;
119 }
120 if (retryTimes >= 200) { // 200
121 MEDIA_LOG_E("Warning: not end of file, but do not have enough data");
122 return Status::ERROR_NOT_ENOUGH_DATA;
123 }
124 break;
125 } while (true);
126 return Status::OK;
127 }
128
GetDataFromSource()129 Status AACDemuxerPlugin::GetDataFromSource()
130 {
131 uint32_t ioNeedReadSize = inIoBufferSize_ - ioDataRemainSize_;
132 MEDIA_LOG_D("ioDataRemainSize_ " PUBLIC_LOG_U32, " ioNeedReadSize " PUBLIC_LOG_U32, ioDataRemainSize_,
133 ioNeedReadSize);
134 if (ioDataRemainSize_) {
135 // 将剩余数据移动到buffer的起始位置
136 auto ret = memmove_s(inIoBuffer_,
137 ioDataRemainSize_,
138 inIoBuffer_ + usedDataSize_,
139 ioDataRemainSize_);
140 if (ret != 0) {
141 MEDIA_LOG_E("copy buffer error(" PUBLIC_LOG_D32, ret);
142 return Status::ERROR_UNKNOWN;
143 }
144 ret = memset_s(inIoBuffer_ + ioDataRemainSize_, ioNeedReadSize, 0x00, ioNeedReadSize);
145 if (ret != 0) {
146 MEDIA_LOG_E("memset_s buffer error(" PUBLIC_LOG_D32, ret);
147 return Status::ERROR_UNKNOWN;
148 }
149 }
150 if (isSeekable_) {
151 if (ioContext_.offset >= fileSize_ && ioDataRemainSize_ == 0) {
152 ioContext_.eos = true;
153 ioContext_.offset = 0;
154 return Status::END_OF_STREAM;
155 }
156 if (ioContext_.offset + ioNeedReadSize > fileSize_) {
157 ioNeedReadSize = fileSize_ - ioContext_.offset; // 在读取文件即将结束时,剩余数据不足,更新读取长度
158 }
159 }
160
161 return DoReadFromSource(ioNeedReadSize);
162 }
163
GetMediaInfo(MediaInfo & mediaInfo)164 Status AACDemuxerPlugin::GetMediaInfo(MediaInfo& mediaInfo)
165 {
166 Status retStatus = GetDataFromSource();
167 if (retStatus != Status::OK) {
168 return retStatus;
169 }
170 int ret = AudioDemuxerAACPrepare(inIoBuffer_, ioDataRemainSize_, &aacDemuxerRst_);
171 if (ret == 0) {
172 mediaInfo.tracks.resize(1);
173 if (aacDemuxerRst_.frameChannels == 1) {
174 mediaInfo.tracks[0].Insert<Tag::AUDIO_CHANNEL_LAYOUT>(AudioChannelLayout::MONO);
175 } else {
176 mediaInfo.tracks[0].Insert<Tag::AUDIO_CHANNEL_LAYOUT>(AudioChannelLayout::STEREO);
177 }
178 mediaInfo.tracks[0].Insert<Tag::MEDIA_TYPE>(MediaType::AUDIO);
179 mediaInfo.tracks[0].Insert<Tag::AUDIO_SAMPLE_RATE>(aacDemuxerRst_.frameSampleRate);
180 mediaInfo.tracks[0].Insert<Tag::MEDIA_BITRATE>(aacDemuxerRst_.frameBitrateKbps);
181 mediaInfo.tracks[0].Insert<Tag::AUDIO_CHANNELS>(aacDemuxerRst_.frameChannels);
182 mediaInfo.tracks[0].Insert<Tag::TRACK_ID>(0);
183 mediaInfo.tracks[0].Insert<Tag::MIME>(MEDIA_MIME_AUDIO_AAC);
184 mediaInfo.tracks[0].Insert<Tag::AUDIO_MPEG_VERSION>(aacDemuxerRst_.mpegVersion);
185 mediaInfo.tracks[0].Insert<Tag::AUDIO_SAMPLE_FORMAT>(AudioSampleFormat::S16);
186 mediaInfo.tracks[0].Insert<Tag::AUDIO_SAMPLE_PER_FRAME>(1024); // 1024
187 mediaInfo.tracks[0].Insert<Tag::AUDIO_AAC_PROFILE>(AudioAacProfile::LC);
188 mediaInfo.tracks[0].Insert<Tag::AUDIO_AAC_STREAM_FORMAT>(AudioAacStreamFormat::MP4ADTS);
189 return Status::OK;
190 } else {
191 return Status::ERROR_UNSUPPORTED_FORMAT;
192 }
193 }
194
ReadFrame(Buffer & outBuffer,int32_t timeOutMs)195 Status AACDemuxerPlugin::ReadFrame(Buffer& outBuffer, int32_t timeOutMs)
196 {
197 int status = -1;
198 std::shared_ptr<Memory> aacFrameData;
199 Status retStatus = GetDataFromSource();
200 if (retStatus != Status::OK) {
201 return retStatus;
202 }
203 status = AudioDemuxerAACProcess(inIoBuffer_, ioDataRemainSize_, &aacDemuxerRst_);
204
205 if (outBuffer.IsEmpty()) {
206 aacFrameData = outBuffer.AllocMemory(nullptr, aacDemuxerRst_.frameLength);
207 } else {
208 aacFrameData = outBuffer.GetMemory();
209 }
210 switch (status) {
211 case 0:
212 aacFrameData->Write(aacDemuxerRst_.frameBuffer, aacDemuxerRst_.frameLength);
213 if (aacDemuxerRst_.frameBuffer) {
214 free(aacDemuxerRst_.frameBuffer);
215 aacDemuxerRst_.frameBuffer = nullptr;
216 }
217 usedDataSize_ = aacDemuxerRst_.usedInputLength;
218 ioDataRemainSize_ -= aacDemuxerRst_.usedInputLength;
219 break;
220 case -1:
221 default:
222 if (aacDemuxerRst_.frameBuffer) {
223 free(aacDemuxerRst_.frameBuffer);
224 aacDemuxerRst_.frameBuffer = nullptr;
225 }
226 return Status::ERROR_UNKNOWN;
227 }
228
229 return Status::OK;
230 }
231
SeekTo(int32_t trackId,int64_t hstTime,SeekMode mode)232 Status AACDemuxerPlugin::SeekTo(int32_t trackId, int64_t hstTime, SeekMode mode)
233 {
234 return Status::OK;
235 }
236
Init()237 Status AACDemuxerPlugin::Init()
238 {
239 inIoBuffer_ = static_cast<uint8_t *>(malloc(inIoBufferSize_));
240 if (inIoBuffer_ == nullptr) {
241 MEDIA_LOG_E("inIoBuffer_ malloc failed");
242 return Status::ERROR_NO_MEMORY;
243 }
244 (void)memset_s(inIoBuffer_, inIoBufferSize_, 0x00, inIoBufferSize_);
245 return Status::OK;
246 }
Deinit()247 Status AACDemuxerPlugin::Deinit()
248 {
249 if (inIoBuffer_) {
250 free(inIoBuffer_);
251 inIoBuffer_ = nullptr;
252 }
253 return Status::OK;
254 }
255
Prepare()256 Status AACDemuxerPlugin::Prepare()
257 {
258 return Status::OK;
259 }
260
Reset()261 Status AACDemuxerPlugin::Reset()
262 {
263 ioContext_.eos = false;
264 ioContext_.dataSource.reset();
265 ioContext_.offset = 0;
266 ioContext_.dataSource.reset();
267 ioDataRemainSize_ = 0;
268 (void)memset_s(inIoBuffer_, inIoBufferSize_, 0x00, inIoBufferSize_);
269 return Status::OK;
270 }
271
Start()272 Status AACDemuxerPlugin::Start()
273 {
274 return Status::OK;
275 }
276
Stop()277 Status AACDemuxerPlugin::Stop()
278 {
279 return Status::OK;
280 }
281
GetParameter(Tag tag,ValueType & value)282 Status AACDemuxerPlugin::GetParameter(Tag tag, ValueType &value)
283 {
284 return Status::ERROR_UNIMPLEMENTED;
285 }
286
SetParameter(Tag tag,const ValueType & value)287 Status AACDemuxerPlugin::SetParameter(Tag tag, const ValueType &value)
288 {
289 return Status::ERROR_UNIMPLEMENTED;
290 }
291
GetAllocator()292 std::shared_ptr<Allocator> AACDemuxerPlugin::GetAllocator()
293 {
294 return nullptr;
295 }
296
SetCallback(Callback * cb)297 Status AACDemuxerPlugin::SetCallback(Callback* cb)
298 {
299 return Status::OK;
300 }
301
GetTrackCount()302 size_t AACDemuxerPlugin::GetTrackCount()
303 {
304 return 0;
305 }
306
SelectTrack(int32_t trackId)307 Status AACDemuxerPlugin::SelectTrack(int32_t trackId)
308 {
309 return Status::OK;
310 }
311
UnselectTrack(int32_t trackId)312 Status AACDemuxerPlugin::UnselectTrack(int32_t trackId)
313 {
314 return Status::OK;
315 }
316
GetSelectedTracks(std::vector<int32_t> & trackIds)317 Status AACDemuxerPlugin::GetSelectedTracks(std::vector<int32_t>& trackIds)
318 {
319 return Status::OK;
320 }
321
GetFrameLength(const uint8_t * data)322 int AACDemuxerPlugin::GetFrameLength(const uint8_t *data)
323 {
324 return ((data[3] & 0x03) << 11) | (data[4] << 3) | ((data[5] & 0xE0) >> 5); // 根据协议计算帧长
325 }
326
AudioDemuxerAACOpen(AudioDemuxerUserArg * userArg)327 int AACDemuxerPlugin::AudioDemuxerAACOpen(AudioDemuxerUserArg *userArg)
328 {
329 return 0;
330 }
331
AudioDemuxerAACClose()332 int AACDemuxerPlugin::AudioDemuxerAACClose()
333 {
334 return 0;
335 }
336
AudioDemuxerAACPrepare(const uint8_t * buf,uint32_t len,AACDemuxerRst * rst)337 int AACDemuxerPlugin::AudioDemuxerAACPrepare(const uint8_t *buf, uint32_t len, AACDemuxerRst *rst)
338 {
339 if (IsAACPattern(buf)) {
340 int mpegVersionIndex = ((buf[1] & 0x0F) >> 3); // 根据协议计算 mpegVersionIndex
341 int mpegVersion = -1;
342 if (mpegVersionIndex == 0) {
343 mpegVersion = 4; // 4
344 } else if (mpegVersionIndex == 1) {
345 mpegVersion = 2; // 2
346 } else {
347 return -1;
348 }
349
350 int sampleIndex = ((buf[2] & 0x3C) >> 2); // 根据协议计算 sampleIndex
351 int channelCount = ((buf[2] & 0x01) << 2) | ((buf[3] & 0xC0) >> 6); // 根据协议计算 channelCount
352
353 int sample = samplingRateMap[sampleIndex];
354
355 rst->frameChannels = channelCount;
356 rst->frameSampleRate = sample;
357 rst->mpegVersion = mpegVersion;
358 MEDIA_LOG_D("channel " PUBLIC_LOG_U8 " sample " PUBLIC_LOG_U32, rst->frameChannels, rst->frameSampleRate);
359 return 0;
360 } else {
361 MEDIA_LOG_D("Err:IsAACPattern");
362 return -1;
363 }
364 }
365
AudioDemuxerAACProcess(const uint8_t * buffer,uint32_t bufferLen,AACDemuxerRst * rst)366 int AACDemuxerPlugin::AudioDemuxerAACProcess(const uint8_t *buffer, uint32_t bufferLen, AACDemuxerRst *rst)
367 {
368 if (rst == nullptr || buffer == nullptr) {
369 return -1;
370 }
371 rst->frameLength = 0;
372 rst->frameBuffer = nullptr;
373 rst->usedInputLength = 0;
374
375 do {
376 if (IsAACPattern(buffer) == 0) {
377 MEDIA_LOG_D("Err: IsAACPattern");
378 break;
379 }
380
381 auto length = static_cast<unsigned int>(GetFrameLength(buffer));
382 if (length + 2 > bufferLen) { // 2
383 rst->usedInputLength = bufferLen;
384 return 0;
385 }
386
387 if (length == 0) {
388 MEDIA_LOG_D("length = 0 error");
389 return -1;
390 }
391
392 if (IsAACPattern(buffer + length)) {
393 rst->frameBuffer = static_cast<uint8_t *>(malloc(length));
394 if (rst->frameBuffer) {
395 FALSE_LOG(memcpy_s(rst->frameBuffer, length, buffer, length) == 0);
396 rst->frameLength = length;
397 rst->usedInputLength = length;
398 } else {
399 MEDIA_LOG_E("malloc error, length " PUBLIC_LOG_U32, length);
400 }
401 } else {
402 MEDIA_LOG_D("can't find next aac, length " PUBLIC_LOG_U32 " is error", length);
403 break;
404 }
405
406 return 0;
407 } while (0);
408
409 rst->usedInputLength = 1;
410 return 0;
411 }
412
AudioDemuxerAACFreeFrame(uint8_t * frame)413 int AACDemuxerPlugin::AudioDemuxerAACFreeFrame(uint8_t *frame)
414 {
415 if (frame) {
416 free(frame);
417 }
418 return 0;
419 }
420
421 namespace {
IsAACPattern(const uint8_t * data)422 int IsAACPattern(const uint8_t *data)
423 {
424 return data[0] == 0xff && (data[1] & 0xf0) == 0xf0 && (data[1] & 0x06) == 0x00; // 根据协议判断是否为AAC帧
425 }
426
Sniff(const std::string & name,std::shared_ptr<DataSource> dataSource)427 int Sniff(const std::string& name, std::shared_ptr<DataSource> dataSource)
428 {
429 auto buffer = std::make_shared<Buffer>();
430 auto bufData = buffer->AllocMemory(nullptr, PROBE_READ_LENGTH);
431 auto result = dataSource->ReadAt(0, buffer, static_cast<size_t>(PROBE_READ_LENGTH));
432 if (result != Status::OK) {
433 return 0;
434 }
435 auto inputDataPtr = const_cast<uint8_t *>(bufData->GetReadOnlyData());
436 if (IsAACPattern(inputDataPtr) == 0) {
437 MEDIA_LOG_W("Not AAC format");
438 return 0;
439 }
440 return MAX_RANK;
441 }
442
RegisterPlugin(const std::shared_ptr<Register> & reg)443 Status RegisterPlugin(const std::shared_ptr<Register>& reg)
444 {
445 MEDIA_LOG_I("RegisterPlugin called.");
446 if (!reg) {
447 MEDIA_LOG_E("RegisterPlugin failed due to nullptr pointer for reg.");
448 return Status::ERROR_INVALID_PARAMETER;
449 }
450
451 std::string pluginName = "AACDemuxerPlugin";
452 DemuxerPluginDef regInfo;
453 regInfo.name = pluginName;
454 regInfo.description = "adapter for aac demuxer plugin";
455 regInfo.rank = MAX_RANK;
456 regInfo.creator = [](const std::string &name) -> std::shared_ptr<DemuxerPlugin> {
457 return std::make_shared<AACDemuxerPlugin>(name);
458 };
459 regInfo.sniffer = Sniff;
460 auto rtv = reg->AddPlugin(regInfo);
461 if (rtv != Status::OK) {
462 MEDIA_LOG_I("RegisterPlugin AddPlugin failed with return " PUBLIC_LOG_D32, static_cast<int>(rtv));
463 }
464 return Status::OK;
465 }
466 }
467
__anon4ef59f530402null468 PLUGIN_DEFINITION(AACDemuxer, LicenseType::APACHE_V2, RegisterPlugin, [] {});
469 } // namespace AacDemuxer
470 } // namespace Plugin
471 } // namespace Media
472 } // namespace OHOS