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 #ifndef HISTREAMER_FFMPEG_DEMUXER_PLUGIN_H
17 #define HISTREAMER_FFMPEG_DEMUXER_PLUGIN_H
18 
19 #include <memory>
20 #include <string>
21 #include <vector>
22 #include "foundation/osal/thread/mutex.h"
23 #include "plugin/interface/demuxer_plugin.h"
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 #include "libavformat/avformat.h"
29 #include "libavcodec/avcodec.h"
30 #include "libavcodec/bsf.h"
31 #ifdef __cplusplus
32 }
33 #endif
34 
35 namespace OHOS {
36 namespace Media {
37 namespace Plugin {
38 namespace Ffmpeg {
39 class FFmpegDemuxerPlugin : public DemuxerPlugin {
40 public:
41     explicit FFmpegDemuxerPlugin(std::string name);
42     ~FFmpegDemuxerPlugin() override;
43 
44     Status Init() override;
45     Status Deinit() override;
46     Status Prepare() override;
47     Status Reset() override;
48     Status GetParameter(Tag tag, ValueType& value) override;
49     Status SetParameter(Tag tag, const ValueType& value) override;
50     std::shared_ptr<Allocator> GetAllocator() override;
51     Status SetCallback(Callback* cb) override;
52 
53     Status SetDataSource(const std::shared_ptr<DataSource>& source) override;
54     Status GetMediaInfo(MediaInfo& mediaInfo) override;
55     size_t GetTrackCount() override;
56     Status SelectTrack(int32_t trackId) override;
57     Status UnselectTrack(int32_t trackId) override;
58     Status GetSelectedTracks(std::vector<int32_t>& trackIds) override;
59     Status ReadFrame(Buffer& info, int32_t timeOutMs) override;
60     Status SeekTo(int32_t trackId, int64_t seekTime, SeekMode mode, int64_t& realSeekTime) override;
61 
62 private:
63     class DemuxerPluginAllocator : public Allocator {
64     public:
65         DemuxerPluginAllocator() = default;
66         ~DemuxerPluginAllocator() override = default;
67         void* Alloc(size_t size) override;
68         void Free(void* ptr) override; // NOLINT: void*
69     };
70 
71     struct IOContext {
72         std::shared_ptr<DataSource> dataSource {nullptr};
73         int64_t offset {0};
74         bool eos {false};
75     };
76 
77     void InitAVFormatContext();
78 
79     static std::shared_ptr<AVCodecContext> InitCodecContext(const AVStream& avStream);
80 
81     AVIOContext* AllocAVIOContext(int flags);
82 
83     bool IsSelectedTrack(int32_t trackId);
84 
85     void SaveFileInfoToMetaInfo(Meta &meta);
86 
87     bool ParseMediaData();
88 
89     bool ConvertAVPacketToFrameInfo(const AVStream& avStream, AVPacket& pkt, Buffer& frameInfo);
90 
91     static int AVReadPacket(void* opaque, uint8_t* buf, int bufSize); // NOLINT: void*
92 
93     static int AVWritePacket(void* opaque, uint8_t* buf, int bufSize); // NOLINT: void*
94 
95     static int64_t AVSeek(void* opaque, int64_t offset, int whence); // NOLINT: void*
96 
97     void InitConvertContext(const AVStream& avStream);
98 
99     void ConvertAvcOrHevcToAnnexb(AVPacket& pkt);
100 
101     VideoBitStreamFormat vdBitStreamFormat_ {VideoBitStreamFormat::UNKNOWN};
102     std::shared_ptr<AVBSFContext> avbsfContext_ {nullptr};
103     double playbackSpeed_ {1.0};
104     Seekable seekable_ = Seekable::UNSEEKABLE;
105     IOContext ioContext_;
106     Callback* callback_ {};
107     std::shared_ptr<AVInputFormat> pluginImpl_;
108     std::shared_ptr<AVFormatContext> formatContext_;
109     std::shared_ptr<Allocator> allocator_;
110     std::unique_ptr<MediaInfo> mediaInfo_;
111     std::vector<int32_t> selectedTrackIds_;
112     OSAL::Mutex mutex_ {};
113 };
114 } // namespace Ffmpeg
115 } // namespace Plugin
116 } // namespace Media
117 } // namespace OHOS
118 
119 #endif // HISTREAMER_FFMPEG_DEMUXER_PLUGIN_H
120