1 /*
2  * Copyright (C) 2023 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_DATA_COLLECTOR_H
17 #define AVMETA_DATA_COLLECTOR_H
18 
19 #include <condition_variable>
20 #include <mutex>
21 #include <nocopyable.h>
22 #include <set>
23 #include <unordered_map>
24 
25 #include "media_demuxer.h"
26 #include "meta/meta.h"
27 #include "meta/meta_key.h"
28 
29 namespace OHOS {
30 namespace Media {
31 struct Metadata {
32     Metadata() = default;
33     ~Metadata() = default;
34 
SetMetaMetadata35     void SetMeta(int32_t key, const std::string &value)
36     {
37         tbl_[key] = value;
38     }
39 
TryGetMetaMetadata40     bool TryGetMeta(int32_t key, std::string &value) const
41     {
42         auto it = tbl_.find(key);
43         if (it == tbl_.end()) {
44             return false;
45         }
46         value = it->second;
47         return true;
48     }
49 
HasMetaMetadata50     bool HasMeta(int32_t key) const
51     {
52         return tbl_.count(key) != 0;
53     }
54 
GetMetaMetadata55     std::string GetMeta(int32_t key) const
56     {
57         if (tbl_.count(key) != 0) {
58             return tbl_.at(key);
59         }
60         return "";
61     }
62 
63     std::unordered_map<int32_t, std::string> tbl_;
64 };
65 
66 class AVMetaDataCollector : public NoCopyable {
67 public:
68     explicit AVMetaDataCollector(std::shared_ptr<MediaDemuxer> &mediaDemuxer);
69     ~AVMetaDataCollector();
70 
71     std::unordered_map<int32_t, std::string> ExtractMetadata();
72     std::shared_ptr<Meta> GetAVMetadata();
73     std::string ExtractMetadata(int32_t key);
74     std::shared_ptr<AVSharedMemory> GetArtPicture();
75     int32_t GetTimeByFrameIndex(uint32_t index, uint64_t &timeUs);
76     int32_t GetFrameIndexByTime(uint64_t timeUs, uint32_t &index);
77     void Reset();
78     void Destroy();
79 
80 private:
81     std::shared_ptr<MediaDemuxer> mediaDemuxer_;
82     std::unordered_map<int32_t, std::string> collectedMeta_ = {};
83     std::shared_ptr<AVSharedMemory> collectedArtPicture_;
84     std::shared_ptr<Meta> customInfo_;
85     std::shared_ptr<Meta> collectedAVMetaData_;
86     uint32_t videoTrackId_ = 0;
87     std::atomic<bool> hasVideo_ = false;
88 
89     std::unordered_map<int32_t, std::string> GetMetadata(
90         const std::shared_ptr<Meta> &globalInfo, const std::vector<std::shared_ptr<Meta>> &trackInfos);
91     void ConvertToAVMeta(const std::shared_ptr<Meta> &innerMeta, Metadata &avmeta) const;
92     void FormatAVMeta(Metadata &avmeta, int32_t imageTrackCount, const std::shared_ptr<Meta> &globalInfo);
93     void FormatMimeType(Metadata &avmeta, const std::shared_ptr<Meta> &globalInfo);
94     void FormatDateTime(Metadata &avmeta, const std::shared_ptr<Meta> &globalInfo);
95     void SetEmptyStringIfNoData(Metadata &avmeta, int32_t avKey) const;
96     bool SetStringByValueType(const std::shared_ptr<Meta> &innerMeta,
97         Metadata &avmeta, int32_t avKey, std::string innerKey) const;
98     Status GetVideoTrackId(uint32_t &trackId);
99 };
100 }  // namespace Media
101 }  // namespace OHOS
102 #endif  // AVMETA_DATA_COLLECTOR_H