• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef AVMETA_ELEM_META_COLLECTOR_H
17 #define AVMETA_ELEM_META_COLLECTOR_H
18 
19 #include <functional>
20 #include <unordered_map>
21 #include <string>
22 #include <string_view>
23 #include <vector>
24 #include <mutex>
25 #include <memory>
26 #include <gst/gst.h>
27 #include "avsharedmemory.h"
28 #include "format.h"
29 #include "nocopyable.h"
30 
31 namespace OHOS {
32 namespace Media {
33 struct Metadata {
34     Metadata() = default;
35     ~Metadata() = default;
36 
SetMetaMetadata37     void SetMeta(int32_t key, const std::string &value)
38     {
39         tbl_[key] = value;
40     }
41 
TryGetMetaMetadata42     bool TryGetMeta(int32_t key, std::string &value) const
43     {
44         auto it = tbl_.find(key);
45         if (it == tbl_.end()) {
46             return false;
47         }
48         value = it->second;
49         return true;
50     }
51 
HasMetaMetadata52     bool HasMeta(int32_t key) const
53     {
54         return tbl_.count(key) != 0;
55     }
56 
GetMetaMetadata57     std::string GetMeta(int32_t key) const
58     {
59         if (tbl_.count(key) != 0) {
60             return tbl_.at(key);
61         }
62         return "";
63     }
64 
65     std::unordered_map<int32_t, std::string> tbl_;
66 };
67 
68 /**
69  * @brief populate the default meta if the key does not exist.
70  */
71 void PopulateMeta(Metadata &meta);
72 
73 // indicate this number is not track's number, just represent the whole file.
74 inline constexpr int32_t AVMETA_TRACK_NUMBER_FILE = -1;
75 
76 /* param: trackId, metadata */
77 using MetaResCb = std::function<void(const Metadata &)>;
78 
79 enum class AVMetaSourceType : uint8_t {
80     TYPEFIND,
81     DEMUXER,
82     PARSER,
83 };
84 
85 class AVMetaElemMetaCollector : public NoCopyable {
86 public:
87     AVMetaElemMetaCollector(AVMetaSourceType type, const MetaResCb &resCb);
88     virtual ~AVMetaElemMetaCollector();
89 
90     static std::unique_ptr<AVMetaElemMetaCollector> Create(AVMetaSourceType type, const MetaResCb &resCb);
91 
92     virtual void AddMetaSource(GstElement &elem) = 0;
93     bool IsMetaCollected();
GetType()94     AVMetaSourceType GetType() const
95     {
96         return type_;
97     }
98     std::shared_ptr<AVSharedMemory> FetchArtPicture();
99     void Stop();
100 
101 protected:
102     bool AddProbeToPadList(GList &list);
103     bool AddProbeToPad(GstPad &pad);
104     bool ConnectSignal(GstElement &elem, std::string_view signal, GCallback callback);
105     void ReportMeta(const Metadata &uploadMeta);
106 
107     static GstPadProbeReturn ProbeCallback(GstPad *pad, GstPadProbeInfo *info, gpointer usrdata);
108     void OnEventProbe(GstPad &pad, GstEvent &event);
109     void QueryDuration(GstPad &pad);
110 
111     struct TrackInfo;
112     void ParseTagList(const GstTagList &tagList, TrackInfo &trackInfo);
113     void ParseCaps(const GstCaps &caps, TrackInfo &trackInfo);
114     bool EnsureTrackValid(TrackInfo &trackInfo);
115     void ConvertToAVMeta(const Format &innerMeta, Metadata &avmeta) const;
116     std::shared_ptr<AVSharedMemory> DoFetchArtPicture(const Format &innerMeta);
117 
118     AVMetaSourceType type_;
119     MetaResCb resCb_;
120     std::unordered_map<GstPad *, gulong> padProbes_;
121     std::unordered_map<GstElement *, gulong> signalIds_;
122     std::unordered_map<GstPad *, TrackInfo> trackInfos_;
123     Metadata fileUploadMeta_;
124     Format fileInnerMeta_;
125     int64_t duration_ = 0;
126     bool globalTagCatched_ = false;
127     bool stopCollecting_ = false;
128     uint32_t trackcount_ = 0;
129     std::mutex mutex_;
130 };
131 
132 /**
133  * Detail Element Meta Collector Implementation Begin.
134  */
135 class TypeFindMetaCollector : public AVMetaElemMetaCollector {
136 public:
137     using AVMetaElemMetaCollector::AVMetaElemMetaCollector;
138     ~TypeFindMetaCollector() = default;
139 
140     void AddMetaSource(GstElement &elem) override;
141 
142 private:
143     static void HaveTypeCallback(GstElement *elem, guint probability, GstCaps *caps, gpointer userData);
144     void OnHaveType(const GstElement &elem, const GstCaps &caps);
145 };
146 
147 class DemuxerMetaCollector : public AVMetaElemMetaCollector {
148 public:
149     using AVMetaElemMetaCollector::AVMetaElemMetaCollector;
150     ~DemuxerMetaCollector() = default;
151 
152     void AddMetaSource(GstElement &elem) override;
153 
154 private:
155     static void PadAddedCallback(GstElement *elem, GstPad *pad, gpointer userData);
156     void OnPadAdded(GstElement &src, GstPad &pad);
157 };
158 
159 class ParserMetaCollector : public AVMetaElemMetaCollector {
160 public:
161     using AVMetaElemMetaCollector::AVMetaElemMetaCollector;
162     ~ParserMetaCollector() = default;
163 
164     void AddMetaSource(GstElement &elem) override;
165 };
166 } // namespace Media
167 } // namespace OHOS
168 #endif // AVMETA_ELEM_META_COLLECTOR_H
169