• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-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 #include "meta/meta.h"
17 #include <functional>
18 #include "common/log.h"
19 
20 /**
21  * Steps of Adding New Tag
22  *
23  * 1. In meta_key.h, Add a Tag.
24  * 2. In meta.h, Register Tag key Value mapping.
25  *    Example: DEFINE_INSERT_GET_FUNC(tagCharSeq == Tag::TAGNAME, TAGTYPE, ValueType::VALUETYPE)
26  * 3. In meta.cpp, Register default value to g_metadataDefaultValueMap ({Tag::TAGNAME, defaultTAGTYPE}).
27  * 4. In order to support Enum/Bool Value Getter Setter from AVFormat,
28  *    In meta.cpp, Register Tag key getter setter function mapping.
29  *    Example: DEFINE_METADATA_SETTER_GETTER_FUNC(SrcTAGNAME, int32_t/int64_t)
30  *    For Int32/Int64 Type, update g_metadataGetterSetterMap/g_metadataGetterSetterInt64Map.
31  *    For Bool Type, update g_metadataBoolVector.
32  * 5. Update meta_func_unit_test.cpp to add the testcase of new added Tag Type.
33  *
34  * Theory:
35  * App --> AVFormat(ndk) --> Meta --> Parcel(ipc) --> Meta
36  * AVFormat only support: int, int64(Long), float, double, string, buffer
37  * Parcel only support: bool, int8, int16, int32, int64, uint8, uint16, uint32, uint64, float, double, pointer, buffer
38  * Meta (based on any) support : all types in theory.
39  *
40  * Attention: Use AVFormat with Meta, with or without ipc, be care of the difference of supported types.
41  * Currently, The ToParcel/FromParcel function(In Any.h) supports single value convert to/from parcel.
42  * you can use meta's helper functions to handle the key and the correct value type:
43  *    GetDefaultAnyValue: get the specified key's default value, It can get the value type.
44  *    SetMetaData/GetMetaData: AVFormat use them to set/get enum/bool/int values,
45  *    It can convert the integer to/from enum/bool automatically.
46  **/
47 namespace OHOS {
48 namespace Media {
49 using namespace Plugins;
50 
51 #define DEFINE_METADATA_SETTER_GETTER_FUNC(EnumTypeName, ExtTypeName)                       \
52 static bool Set##EnumTypeName(Meta& meta, const TagType& tag, ExtTypeName& value)           \
53 {                                                                                           \
54     if (__is_enum(EnumTypeName)) {                                                          \
55         meta.SetData(tag, EnumTypeName(value));                                             \
56     } else {                                                                                \
57         meta.SetData(tag, value);                                                           \
58     }                                                                                       \
59     return true;                                                                            \
60 }                                                                                           \
61                                                                                             \
62 static bool Get##EnumTypeName(const Meta& meta, const TagType& tag, ExtTypeName& value)     \
63 {                                                                                           \
64     EnumTypeName tmpValue;                                                                  \
65     if (meta.GetData(tag, tmpValue)) {                                                      \
66         value = static_cast<ExtTypeName>(tmpValue);                                         \
67         return true;                                                                        \
68     }                                                                                       \
69     return false;                                                                           \
70 }
71 
72 DEFINE_METADATA_SETTER_GETTER_FUNC(SrcInputType, int32_t)
73 DEFINE_METADATA_SETTER_GETTER_FUNC(AudioSampleFormat, int32_t)
74 DEFINE_METADATA_SETTER_GETTER_FUNC(VideoPixelFormat, int32_t)
75 DEFINE_METADATA_SETTER_GETTER_FUNC(MediaType, int32_t)
76 DEFINE_METADATA_SETTER_GETTER_FUNC(VideoH264Profile, int32_t)
77 DEFINE_METADATA_SETTER_GETTER_FUNC(VideoRotation, int32_t)
78 DEFINE_METADATA_SETTER_GETTER_FUNC(ColorPrimary, int32_t)
79 DEFINE_METADATA_SETTER_GETTER_FUNC(TransferCharacteristic, int32_t)
80 DEFINE_METADATA_SETTER_GETTER_FUNC(MatrixCoefficient, int32_t)
81 DEFINE_METADATA_SETTER_GETTER_FUNC(HEVCProfile, int32_t)
82 DEFINE_METADATA_SETTER_GETTER_FUNC(HEVCLevel, int32_t)
83 DEFINE_METADATA_SETTER_GETTER_FUNC(ChromaLocation, int32_t)
84 DEFINE_METADATA_SETTER_GETTER_FUNC(FileType, int32_t)
85 DEFINE_METADATA_SETTER_GETTER_FUNC(VideoEncodeBitrateMode, int32_t)
86 
87 DEFINE_METADATA_SETTER_GETTER_FUNC(AudioChannelLayout, int64_t)
88 
89 #define  DEFINE_METADATA_SETTER_GETTER(tag, EnumType) {tag, std::make_pair(Set##EnumType, Get##EnumType)}
90 
91 using  MetaSetterFunction = std::function<bool(Meta&, const TagType&, int32_t&)>;
92 using  MetaGetterFunction = std::function<bool(const Meta&, const TagType&, int32_t&)>;
93 
94 static std::map<TagType, std::pair<MetaSetterFunction, MetaGetterFunction>> g_metadataGetterSetterMap = {
95     DEFINE_METADATA_SETTER_GETTER(Tag::SRC_INPUT_TYPE, SrcInputType),
96     DEFINE_METADATA_SETTER_GETTER(Tag::AUDIO_SAMPLE_FORMAT, AudioSampleFormat),
97     DEFINE_METADATA_SETTER_GETTER(Tag::VIDEO_PIXEL_FORMAT, VideoPixelFormat),
98     DEFINE_METADATA_SETTER_GETTER(Tag::MEDIA_TYPE, MediaType),
99     DEFINE_METADATA_SETTER_GETTER(Tag::VIDEO_H264_PROFILE, VideoH264Profile),
100     DEFINE_METADATA_SETTER_GETTER(Tag::VIDEO_ROTATION, VideoRotation),
101     DEFINE_METADATA_SETTER_GETTER(Tag::VIDEO_COLOR_PRIMARIES, ColorPrimary),
102     DEFINE_METADATA_SETTER_GETTER(Tag::VIDEO_COLOR_TRC, TransferCharacteristic),
103     DEFINE_METADATA_SETTER_GETTER(Tag::VIDEO_COLOR_MATRIX_COEFF, MatrixCoefficient),
104     DEFINE_METADATA_SETTER_GETTER(Tag::VIDEO_H265_PROFILE, HEVCProfile),
105     DEFINE_METADATA_SETTER_GETTER(Tag::VIDEO_H265_LEVEL, HEVCLevel),
106     DEFINE_METADATA_SETTER_GETTER(Tag::VIDEO_CHROMA_LOCATION, ChromaLocation),
107     DEFINE_METADATA_SETTER_GETTER(Tag::MEDIA_FILE_TYPE, FileType),
108     DEFINE_METADATA_SETTER_GETTER(Tag::VIDEO_ENCODE_BITRATE_MODE, VideoEncodeBitrateMode)
109 };
110 
111 using  MetaSetterInt64Function = std::function<bool(Meta&, const TagType&, int64_t&)>;
112 using  MetaGetterInt64Function = std::function<bool(const Meta&, const TagType&, int64_t&)>;
113 static std::map<TagType, std::pair<MetaSetterInt64Function, MetaGetterInt64Function>> g_metadataGetterSetterInt64Map = {
114         DEFINE_METADATA_SETTER_GETTER(Tag::AUDIO_CHANNEL_LAYOUT, AudioChannelLayout),
115         DEFINE_METADATA_SETTER_GETTER(Tag::AUDIO_OUTPUT_CHANNEL_LAYOUT, AudioChannelLayout)
116 };
117 
118 static std::vector<TagType> g_metadataBoolVector = {
119     Tag::VIDEO_COLOR_RANGE,
120     Tag::VIDEO_FRAME_RATE_ADAPTIVE_MODE,
121     Tag::VIDEO_REQUEST_I_FRAME,
122     Tag::VIDEO_IS_HDR_VIVID,
123     Tag::MEDIA_HAS_VIDEO,
124     Tag::MEDIA_HAS_AUDIO,
125     Tag::MEDIA_END_OF_STREAM
126 };
127 
SetMetaData(Meta & meta,const TagType & tag,int32_t value)128 bool SetMetaData(Meta& meta, const TagType& tag, int32_t value)
129 {
130     auto iter = g_metadataGetterSetterMap.find(tag);
131     if (iter == g_metadataGetterSetterMap.end()) {
132         if (std::find(g_metadataBoolVector.begin(), g_metadataBoolVector.end(), tag) != g_metadataBoolVector.end()) {
133             meta.SetData(tag, value != 0 ? true : false);
134             return true;
135         }
136         meta.SetData(tag, value);
137         return true;
138     }
139     return iter->second.first(meta, tag, value);
140 }
141 
GetMetaData(const Meta & meta,const TagType & tag,int32_t & value)142 bool GetMetaData(const Meta& meta, const TagType& tag, int32_t& value)
143 {
144     auto iter = g_metadataGetterSetterMap.find(tag);
145     if (iter == g_metadataGetterSetterMap.end()) {
146         if (std::find(g_metadataBoolVector.begin(), g_metadataBoolVector.end(), tag) != g_metadataBoolVector.end()) {
147             bool valueBool = false;
148             FALSE_RETURN_V(meta.GetData(tag, valueBool), false);
149             value = valueBool ? 1 : 0;
150             return true;
151         }
152         return meta.GetData(tag, value);
153     }
154     return iter->second.second(meta, tag, value);
155 }
156 
SetMetaData(Meta & meta,const TagType & tag,int64_t value)157 bool SetMetaData(Meta& meta, const TagType& tag, int64_t value)
158 {
159     auto iter = g_metadataGetterSetterInt64Map.find(tag);
160     if (iter == g_metadataGetterSetterInt64Map.end()) {
161         meta.SetData(tag, value);
162         return true;
163     }
164     return iter->second.first(meta, tag, value);
165 }
166 
GetMetaData(const Meta & meta,const TagType & tag,int64_t & value)167 bool GetMetaData(const Meta& meta, const TagType& tag, int64_t& value)
168 {
169     auto iter = g_metadataGetterSetterInt64Map.find(tag);
170     if (iter == g_metadataGetterSetterInt64Map.end()) {
171         return meta.GetData(tag, value);
172     }
173     return iter->second.second(meta, tag, value);
174 }
175 
176 static Any defaultString = std::string();
177 static Any defaultUInt8 = (uint8_t)0;
178 static Any defaultInt32 = (int32_t)0;
179 static Any defaultInt64 = (int64_t)0;
180 static Any defaultUInt64 = (uint64_t)0;
181 static Any defaultFloat = 0.0f;
182 static Any defaultDouble = (double)0.0;
183 static Any defaultBool = (bool) false;
184 static Any defaultSrcInputType = SrcInputType::UNKNOWN;
185 static Any defaultAudioSampleFormat = AudioSampleFormat::INVALID_WIDTH;
186 static Any defaultVideoPixelFormat = VideoPixelFormat::UNKNOWN;
187 static Any defaultMediaType = MediaType::UNKNOWN;
188 static Any defaultVideoH264Profile = VideoH264Profile::UNKNOWN;
189 static Any defaultVideoRotation = VideoRotation::VIDEO_ROTATION_0;
190 static Any defaultColorPrimary = ColorPrimary::BT2020;
191 static Any defaultTransferCharacteristic = TransferCharacteristic::BT1361;
192 static Any defaultMatrixCoefficient = MatrixCoefficient::BT2020_CL;
193 static Any defaultHEVCProfile = HEVCProfile::HEVC_PROFILE_UNKNOW;
194 static Any defaultHEVCLevel = HEVCLevel::HEVC_LEVEL_UNKNOW;
195 static Any defaultChromaLocation = ChromaLocation::BOTTOM;
196 static Any defaultFileType = FileType::UNKNOW;
197 static Any defaultVideoEncodeBitrateMode = VideoEncodeBitrateMode::CBR;
198 
199 static Any defaultAudioChannelLayout = AudioChannelLayout::UNKNOWN;
200 static Any defaultAudioAacProfile = AudioAacProfile::ELD;
201 static Any defaultAudioAacStreamFormat = AudioAacStreamFormat::ADIF;
202 static Any defaultVectorUInt8 = std::vector<uint8_t>();
203 static Any defaultVectorVideoBitStreamFormat = std::vector<VideoBitStreamFormat>();
204 static std::map<TagType, const Any &> g_metadataDefaultValueMap = {
205     {Tag::SRC_INPUT_TYPE, defaultSrcInputType},
206     {Tag::AUDIO_SAMPLE_FORMAT, defaultAudioSampleFormat},
207     {Tag::VIDEO_PIXEL_FORMAT, defaultVideoPixelFormat},
208     {Tag::MEDIA_TYPE, defaultMediaType},
209     {Tag::VIDEO_H264_PROFILE, defaultVideoH264Profile},
210     {Tag::VIDEO_ROTATION, defaultVideoRotation},
211     {Tag::VIDEO_COLOR_PRIMARIES, defaultColorPrimary},
212     {Tag::VIDEO_COLOR_TRC, defaultTransferCharacteristic},
213     {Tag::VIDEO_COLOR_MATRIX_COEFF, defaultMatrixCoefficient},
214     {Tag::VIDEO_H265_PROFILE, defaultHEVCProfile},
215     {Tag::VIDEO_H265_LEVEL, defaultHEVCLevel},
216     {Tag::VIDEO_CHROMA_LOCATION, defaultChromaLocation},
217     {Tag::MEDIA_FILE_TYPE, defaultFileType},
218     {Tag::VIDEO_ENCODE_BITRATE_MODE, defaultVideoEncodeBitrateMode},
219 
220     // Int32
221     {Tag::APP_UID, defaultInt32},
222     {Tag::APP_PID, defaultInt32},
223     {Tag::APP_TOKEN_ID, defaultInt32},
224     {Tag::REQUIRED_IN_BUFFER_CNT, defaultInt32},
225     {Tag::REQUIRED_IN_BUFFER_SIZE, defaultInt32},
226     {Tag::REQUIRED_OUT_BUFFER_CNT, defaultInt32},
227     {Tag::REQUIRED_OUT_BUFFER_SIZE, defaultInt32},
228     {Tag::BUFFERING_SIZE, defaultInt32},
229     {Tag::WATERLINE_HIGH, defaultInt32},
230     {Tag::WATERLINE_LOW, defaultInt32},
231     {Tag::AUDIO_CHANNEL_COUNT, defaultInt32},
232     {Tag::AUDIO_SAMPLE_RATE, defaultInt32},
233     {Tag::AUDIO_SAMPLE_PER_FRAME, defaultInt32},
234     {Tag::AUDIO_OUTPUT_CHANNELS, defaultInt32},
235     {Tag::AUDIO_MPEG_VERSION, defaultInt32},
236     {Tag::AUDIO_MPEG_LAYER, defaultInt32},
237     {Tag::AUDIO_AAC_LEVEL, defaultInt32},
238     {Tag::AUDIO_OBJECT_NUMBER, defaultInt32},
239     {Tag::AUDIO_MAX_INPUT_SIZE, defaultInt32},
240     {Tag::AUDIO_MAX_OUTPUT_SIZE, defaultInt32},
241     {Tag::VIDEO_WIDTH, defaultInt32},
242     {Tag::VIDEO_HEIGHT, defaultInt32},
243     {Tag::VIDEO_DELAY, defaultInt32},
244     {Tag::VIDEO_MAX_SURFACE_NUM, defaultInt32},
245     {Tag::VIDEO_H264_LEVEL, defaultInt32},
246     {Tag::MEDIA_TRACK_COUNT, defaultInt32},
247     {Tag::AUDIO_AAC_IS_ADTS, defaultInt32},
248     {Tag::AUDIO_COMPRESSION_LEVEL, defaultInt32},
249     {Tag::AUDIO_BITS_PER_CODED_SAMPLE, defaultInt32},
250     {Tag::REGULAR_TRACK_ID, defaultInt32},
251     {Tag::VIDEO_SCALE_TYPE, defaultInt32},
252     {Tag::VIDEO_I_FRAME_INTERVAL, defaultInt32},
253     {Tag::MEDIA_PROFILE, defaultInt32},
254     {Tag::VIDEO_ENCODE_QUALITY, defaultInt32},
255     {Tag::AUDIO_AAC_SBR, defaultInt32},
256     {Tag::AUDIO_FLAC_COMPLIANCE_LEVEL, defaultInt32},
257     {Tag::MEDIA_LEVEL, defaultInt32},
258     {Tag::VIDEO_STRIDE, defaultInt32},
259     {Tag::VIDEO_DISPLAY_WIDTH, defaultInt32},
260     {Tag::VIDEO_DISPLAY_HEIGHT, defaultInt32},
261     // String
262     {Tag::MIME_TYPE, defaultString},
263     {Tag::MEDIA_FILE_URI, defaultString},
264     {Tag::MEDIA_TITLE, defaultString},
265     {Tag::MEDIA_ARTIST, defaultString},
266     {Tag::MEDIA_LYRICIST, defaultString},
267     {Tag::MEDIA_ALBUM, defaultString},
268     {Tag::MEDIA_ALBUM_ARTIST, defaultString},
269     {Tag::MEDIA_DATE, defaultString},
270     {Tag::MEDIA_COMMENT, defaultString},
271     {Tag::MEDIA_GENRE, defaultString},
272     {Tag::MEDIA_COPYRIGHT, defaultString},
273     {Tag::MEDIA_LANGUAGE, defaultString},
274     {Tag::MEDIA_DESCRIPTION, defaultString},
275     {Tag::USER_TIME_SYNC_RESULT, defaultString},
276     {Tag::USER_AV_SYNC_GROUP_INFO, defaultString},
277     {Tag::USER_SHARED_MEMORY_FD, defaultString},
278     {Tag::MEDIA_AUTHOR, defaultString},
279     {Tag::MEDIA_COMPOSER, defaultString},
280     {Tag::MEDIA_LYRICS, defaultString},
281     {Tag::MEDIA_CODEC_NAME, defaultString},
282     {Tag::PROCESS_NAME, defaultString},
283     {Tag::MEDIA_CREATION_TIME, defaultString},
284     // Float
285     {Tag::MEDIA_LATITUDE, defaultFloat},
286     {Tag::MEDIA_LONGITUDE, defaultFloat},
287     // Double
288     {Tag::VIDEO_CAPTURE_RATE, defaultDouble},
289     {Tag::VIDEO_FRAME_RATE, defaultDouble},
290     // Bool
291     {Tag::VIDEO_COLOR_RANGE, defaultBool},
292     {Tag::VIDEO_REQUEST_I_FRAME, defaultBool},
293     {Tag::VIDEO_IS_HDR_VIVID, defaultBool},
294     {Tag::MEDIA_HAS_VIDEO, defaultBool},
295     {Tag::MEDIA_HAS_AUDIO, defaultBool},
296     {Tag::MEDIA_END_OF_STREAM, defaultBool},
297     {Tag::VIDEO_FRAME_RATE_ADAPTIVE_MODE, defaultBool},
298     // Int64
299     {Tag::MEDIA_FILE_SIZE, defaultUInt64},
300     {Tag::MEDIA_POSITION, defaultUInt64},
301     {Tag::APP_FULL_TOKEN_ID, defaultInt64},
302     {Tag::MEDIA_DURATION, defaultInt64},
303     {Tag::MEDIA_BITRATE, defaultInt64},
304     {Tag::MEDIA_START_TIME, defaultInt64},
305     {Tag::USER_FRAME_PTS, defaultInt64},
306     {Tag::USER_PUSH_DATA_TIME, defaultInt64},
307     {Tag::MEDIA_TIME_STAMP, defaultInt64},
308     // AudioChannelLayout UINT64_T
309     {Tag::AUDIO_CHANNEL_LAYOUT, defaultAudioChannelLayout},
310     {Tag::AUDIO_OUTPUT_CHANNEL_LAYOUT, defaultAudioChannelLayout},
311     // AudioAacProfile UInt8
312     {Tag::AUDIO_AAC_PROFILE, defaultAudioAacProfile},
313     // AudioAacStreamFormat UInt8
314     {Tag::AUDIO_AAC_STREAM_FORMAT, defaultAudioAacStreamFormat},
315     // vector<uint8_t>
316     {Tag::MEDIA_CODEC_CONFIG, defaultVectorUInt8},
317     {Tag::AUDIO_VIVID_METADATA, defaultVectorUInt8},
318     {Tag::MEDIA_COVER, defaultVectorUInt8},
319     {Tag::AUDIO_VORBIS_IDENTIFICATION_HEADER, defaultVectorUInt8},
320     {Tag::AUDIO_VORBIS_SETUP_HEADER, defaultVectorUInt8},
321     // vector<Plugins::VideoBitStreamFormat>
322     {Tag::VIDEO_BIT_STREAM_FORMAT, defaultVectorVideoBitStreamFormat},
323     // vector<uint8_t>
324     {Tag::DRM_CENC_INFO, defaultVectorUInt8}
325 };
326 
GetDefaultAnyValue(const TagType & tag)327 Any GetDefaultAnyValue(const TagType& tag)
328 {
329     auto iter = g_metadataDefaultValueMap.find(tag);
330     if (iter == g_metadataDefaultValueMap.end()) {
331         return defaultString; //Default String type
332     }
333     return iter->second;
334 }
335 
ToParcel(MessageParcel & parcel) const336 bool Meta::ToParcel(MessageParcel &parcel) const
337 {
338     MessageParcel metaParcel;
339     int32_t metaSize = 0;
340     bool ret = true;
341     for (auto it = begin(); it != end(); ++it) {
342         ++metaSize;
343         ret &= metaParcel.WriteString(it->first);
344         ret &= it->second.ToParcel(metaParcel);
345         if (!ret) {
346             MEDIA_LOG_E("fail to Marshalling Key: " PUBLIC_LOG_S, it->first.c_str());
347             return false;
348         }
349     }
350     if (ret) {
351         ret &= parcel.WriteInt32(metaSize);
352         if (metaSize != 0) {
353             ret &= parcel.Append(metaParcel);
354         }
355     }
356     return ret;
357 }
358 
FromParcel(MessageParcel & parcel)359 bool Meta::FromParcel(MessageParcel &parcel)
360 {
361     map_.clear();
362     int32_t size = parcel.ReadInt32();
363     if (size < 0 || static_cast<size_t>(size) > parcel.GetRawDataCapacity()) {
364         MEDIA_LOG_E("fail to Unmarshalling size: %{public}d", size);
365         return false;
366     }
367 
368     for (int32_t index = 0; index < size; index++) {
369         std::string key = parcel.ReadString();
370         Any value = GetDefaultAnyValue(key); //Init Default Value
371         if (value.FromParcel(parcel)) {
372             map_[key] = value;
373         } else {
374             MEDIA_LOG_E("fail to Unmarshalling Key: %{public}s", key.c_str());
375             return false;
376         }
377     }
378     return true;
379 }
380 }
381 } // namespace OHOS