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