1 /*
2  * Copyright (c) 2022-2022 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_PLUGIN_TAG_VALUE_MAP_H
17 #define HISTREAMER_PLUGIN_TAG_VALUE_MAP_H
18 
19 #include "plugin/common/plugin_audio_tags.h"
20 #include "plugin/common/plugin_source_tags.h"
21 #include "plugin/common/plugin_tags.h"
22 #include "plugin/common/plugin_types.h"
23 #include "plugin/common/plugin_video_tags.h"
24 #if !defined(OHOS_LITE) && defined(VIDEO_SUPPORT)
25 #include "plugin/common/surface_allocator.h"
26 #endif
27 
28 namespace OHOS {
29 namespace Media {
30 namespace Plugin {
31 #define DEFINE_INSERT_GET_FUNC(condition, ValueType)             \
32         template<Tag tag>                                        \
33         inline typename std::enable_if<(condition), bool>::type  \
34         Set(ValueType value)                                     \
35         {                                                        \
36             auto iter = map_.find(tag);                          \
37             if (iter != map_.end()) {                            \
38                 map_.erase(iter++);                              \
39             }                                                    \
40             map_.insert(std::make_pair(tag, value));             \
41             return true;                                         \
42         }                                                        \
43         template<Tag tag>                                        \
44         inline typename std::enable_if<(condition), bool>::type  \
45         Get(ValueType& value) const                              \
46         {                                                        \
47             if (map_.count(tag) == 0) {                          \
48                 return false;                                    \
49             }                                                    \
50             return AnyCast<ValueType>(&map_.at(tag), value);     \
51         }
52 
53 
54 using MapIt = std::map<Tag, Any>::const_iterator;
55 class Meta {
56 public:
57 #if !defined(OHOS_LITE) && defined(VIDEO_SUPPORT)
58     DEFINE_INSERT_GET_FUNC(tag == Tag::BUFFER_ALLOCATOR or tag == Tag::VIDEO_SURFACE,
59                            std::shared_ptr<SurfaceAllocator>);
60 #endif
61     DEFINE_INSERT_GET_FUNC(tag == Tag::SRC_INPUT_TYPE, SrcInputType);
62     DEFINE_INSERT_GET_FUNC(tag == Tag::MEDIA_CODEC_CONFIG, std::vector<uint8_t>);
63     DEFINE_INSERT_GET_FUNC(
64         tag == Tag::AUDIO_CHANNEL_LAYOUT or
65         tag == Tag::AUDIO_OUTPUT_CHANNEL_LAYOUT, AudioChannelLayout);
66     DEFINE_INSERT_GET_FUNC(tag == Tag::AUDIO_SAMPLE_FORMAT, AudioSampleFormat);
67     DEFINE_INSERT_GET_FUNC(tag == Tag::AUDIO_AAC_PROFILE, AudioAacProfile);
68     DEFINE_INSERT_GET_FUNC(tag == Tag::AUDIO_AAC_STREAM_FORMAT, AudioAacStreamFormat);
69     DEFINE_INSERT_GET_FUNC(tag == Tag::VIDEO_PIXEL_FORMAT, VideoPixelFormat);
70     DEFINE_INSERT_GET_FUNC(tag == Tag::MEDIA_SEEKABLE, Seekable);
71     DEFINE_INSERT_GET_FUNC(tag == Tag::MEDIA_TYPE, MediaType);
72     DEFINE_INSERT_GET_FUNC(tag == Tag::VIDEO_BIT_STREAM_FORMAT, std::vector<VideoBitStreamFormat>);
73     DEFINE_INSERT_GET_FUNC(tag == Tag::VIDEO_H264_PROFILE, VideoH264Profile);
74     DEFINE_INSERT_GET_FUNC(
75         tag == Tag::TRACK_ID or
76         tag == Tag::REQUIRED_OUT_BUFFER_CNT or
77         tag == Tag::BUFFERING_SIZE or
78         tag == Tag::WATERLINE_HIGH or
79         tag == Tag::WATERLINE_LOW or
80         tag == Tag::AUDIO_CHANNELS or
81         tag == Tag::AUDIO_SAMPLE_RATE or
82         tag == Tag::AUDIO_SAMPLE_PER_FRAME or
83         tag == Tag::AUDIO_OUTPUT_CHANNELS or
84         tag == Tag::AUDIO_MPEG_VERSION or
85         tag == Tag::AUDIO_MPEG_LAYER or
86         tag == Tag::AUDIO_AAC_LEVEL or
87         tag == Tag::VIDEO_WIDTH or
88         tag == Tag::VIDEO_HEIGHT or
89         tag == Tag::VIDEO_FRAME_RATE or
90         tag == Tag::VIDEO_MAX_SURFACE_NUM or
91         tag == Tag::VIDEO_H264_LEVEL or
92         tag == Tag::BITS_PER_CODED_SAMPLE or
93         tag == Tag::USER_FRAME_NUMBER, uint32_t);
94     DEFINE_INSERT_GET_FUNC(
95         tag == Tag::MEDIA_DURATION or
96         tag == Tag::MEDIA_BITRATE or
97         tag == Tag::MEDIA_START_TIME or
98         tag == Tag::USER_FRAME_PTS or
99         tag == Tag::USER_PUSH_DATA_TIME or
100         tag == Tag::USER_PUSH_DATA_TIME or
101         tag == Tag::SUBTITLE_PTS or
102         tag == Tag::SUBTITLE_DURATION, int64_t);
103 
104     DEFINE_INSERT_GET_FUNC(
105         tag == Tag::MEDIA_FILE_SIZE or
106         tag == Tag::MEDIA_POSITION, uint64_t);
107     DEFINE_INSERT_GET_FUNC(
108         tag == Tag::VIDEO_CAPTURE_RATE, double);
109     DEFINE_INSERT_GET_FUNC(
110         tag == Tag::MIME or
111         tag == Tag::MEDIA_FILE_URI or
112         tag == Tag::MEDIA_TITLE or
113         tag == Tag::MEDIA_ARTIST or
114         tag == Tag::MEDIA_LYRICIST or
115         tag == Tag::MEDIA_ALBUM or
116         tag == Tag::MEDIA_ALBUM_ARTIST or
117         tag == Tag::MEDIA_DATE or
118         tag == Tag::MEDIA_COMMENT or
119         tag == Tag::MEDIA_GENRE or
120         tag == Tag::MEDIA_COPYRIGHT or
121         tag == Tag::MEDIA_LANGUAGE or
122         tag == Tag::MEDIA_DESCRIPTION or
123         tag == Tag::USER_TIME_SYNC_RESULT or
124         tag == Tag::USER_AV_SYNC_GROUP_INFO or
125         tag == Tag::USER_SHARED_MEMORY_FD or
126         tag == Tag::MEDIA_LYRICS or
127         tag == Tag::SUBTITLE_TEXT, std::string);
128     Meta& operator=(const Meta& other)
129     {
130         map_ = other.map_;
131         return *this;
132     }
133 
Meta()134     Meta() {
135     };
136 
Meta(const Meta & other)137     Meta(const Meta& other)
138     {
139         map_ = other.map_;
140     }
141 
142     ValueType& operator[](const Tag &tag)
143     {
144         return map_[tag];
145     }
146 
begin()147     MapIt begin() const // to support for (auto e : Meta), must use begin/end name
148     {
149         return map_.cbegin();
150     }
151 
end()152     MapIt end() const
153     {
154         return map_.cend();
155     }
156 
Clear()157     void Clear()
158     {
159         map_.clear();
160     }
161 
Find(Tag tag)162     MapIt Find(Tag tag) const
163     {
164         return map_.find(tag);
165     }
166 
Empty()167     bool Empty() const
168     {
169         return map_.empty();
170     }
171 
172     template <typename T>
SetData(Plugin::Tag id,const T & value)173     void SetData(Plugin::Tag id, const T& value)
174     {
175         map_[id] = value;
176     }
177 
178     template <typename T>
GetData(Plugin::Tag id,T & value)179     bool GetData(Plugin::Tag id, T& value) const
180     {
181         auto ite = map_.find(id);
182         if (ite == map_.end() || !Plugin::Any::IsSameTypeWith<T>(ite->second)) {
183             return false;
184         }
185         value = Plugin::AnyCast<T>(ite->second);
186         return true;
187     }
188 
GetData(Plugin::Tag id,Plugin::ValueType & value)189     bool GetData(Plugin::Tag id, Plugin::ValueType& value) const
190     {
191         auto ite = map_.find(id);
192         if (ite == map_.end()) {
193             return false;
194         }
195         value = ite->second;
196         return true;
197     }
198 
Remove(Plugin::Tag id)199     void Remove(Plugin::Tag id)
200     {
201         auto ite = map_.find(id);
202         if (ite != map_.end()) {
203             map_.erase(ite);
204         }
205     }
206 
GetKeys(std::vector<Tag> & keys)207     void GetKeys(std::vector<Tag>& keys) const
208     {
209         int cnt = 0;
210         keys.resize(map_.size());
211         for (const auto& tmp : map_) {
212             keys[cnt++] = tmp.first;
213         }
214     }
215 private:
216     std::map<Tag, Any> map_;
217 };
218 } // namespace Plugin
219 } // namespace Media
220 } // namespace OHOS
221 #endif // HISTREAMER_PLUGIN_TAG_VALUE_MAP_H
222