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