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 #define HST_LOG_TAG "FfmpegFormatHelper"
17
18 #include <algorithm>
19 #include "ffmpeg_converter.h"
20 #include "meta/meta_key.h"
21 #include "meta/media_types.h"
22 #include "meta/mime_type.h"
23 #include "meta/video_types.h"
24 #include "meta/audio_types.h"
25 #include "common/log.h"
26 #include "ffmpeg_format_helper.h"
27
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 #include "libavutil/avutil.h"
32 #include "libavutil/mastering_display_metadata.h"
33 #ifdef __cplusplus
34 }
35 #endif
36
37 #define CUVA_VERSION_MAP (static_cast<uint16_t>(1))
38 #define TERMINAL_PROVIDE_CODE (static_cast<uint16_t>(4))
39 #define TERMINAL_PROVIDE_ORIENTED_CODE (static_cast<uint16_t>(5))
40
41 namespace OHOS {
42 namespace Media {
43 namespace Plugins {
44 namespace Ffmpeg {
45 namespace {
46 static std::map<AVMediaType, MediaType> g_convertFfmpegTrackType = {
47 {AVMEDIA_TYPE_VIDEO, MediaType::VIDEO},
48 {AVMEDIA_TYPE_AUDIO, MediaType::AUDIO},
49 };
50
51 static std::map<AVCodecID, std::string_view> g_codecIdToMime = {
52 {AV_CODEC_ID_MP1, MimeType::AUDIO_MPEG},
53 {AV_CODEC_ID_MP2, MimeType::AUDIO_MPEG},
54 {AV_CODEC_ID_MP3, MimeType::AUDIO_MPEG},
55 {AV_CODEC_ID_FLAC, MimeType::AUDIO_FLAC},
56 {AV_CODEC_ID_AAC, MimeType::AUDIO_AAC},
57 {AV_CODEC_ID_VORBIS, MimeType::AUDIO_VORBIS},
58 {AV_CODEC_ID_OPUS, MimeType::AUDIO_OPUS},
59 {AV_CODEC_ID_AMR_NB, MimeType::AUDIO_AMR_NB},
60 {AV_CODEC_ID_AMR_WB, MimeType::AUDIO_AMR_WB},
61 {AV_CODEC_ID_H264, MimeType::VIDEO_AVC},
62 {AV_CODEC_ID_MPEG4, MimeType::VIDEO_MPEG4},
63 {AV_CODEC_ID_MJPEG, MimeType::IMAGE_JPG},
64 {AV_CODEC_ID_PNG, MimeType::IMAGE_PNG},
65 {AV_CODEC_ID_BMP, MimeType::IMAGE_BMP},
66 {AV_CODEC_ID_H263, MimeType::VIDEO_H263},
67 {AV_CODEC_ID_MPEG2TS, MimeType::VIDEO_MPEG2},
68 {AV_CODEC_ID_MPEG2VIDEO, MimeType::VIDEO_MPEG2},
69 {AV_CODEC_ID_HEVC, MimeType::VIDEO_HEVC},
70 {AV_CODEC_ID_VP8, MimeType::VIDEO_VP8},
71 {AV_CODEC_ID_VP9, MimeType::VIDEO_VP9},
72 {AV_CODEC_ID_AVS3DA, MimeType::AUDIO_AVS3DA},
73 };
74
75 static std::map<std::string, FileType> g_convertFfmpegFileType = {
76 {"mpegts", FileType::MPEGTS},
77 {"matroska,webm", FileType::MKV},
78 {"amr", FileType::AMR},
79 {"aac", FileType::AAC},
80 {"mp3", FileType::MP3},
81 {"flac", FileType::FLAC},
82 {"ogg", FileType::OGG},
83 {"wav", FileType::WAV},
84 };
85
86 static std::map<TagType, std::string> g_formatToString = {
87 {Tag::MEDIA_TITLE, "title"},
88 {Tag::MEDIA_ARTIST, "artist"},
89 {Tag::MEDIA_ALBUM, "album"},
90 {Tag::MEDIA_ALBUM_ARTIST, "album_artist"},
91 {Tag::MEDIA_DATE, "date"},
92 {Tag::MEDIA_COMMENT, "comment"},
93 {Tag::MEDIA_GENRE, "genre"},
94 {Tag::MEDIA_COPYRIGHT, "copyright"},
95 {Tag::MEDIA_LANGUAGE, "language"},
96 {Tag::MEDIA_DESCRIPTION, "description"},
97 {Tag::MEDIA_LYRICS, "lyrics"},
98 {Tag::MEDIA_AUTHOR, "author"},
99 {Tag::MEDIA_COMPOSER, "composer"},
100 {Tag::MEDIA_CREATION_TIME, "creation_time"}
101 };
102
103 static std::vector<TagType> g_supportSourceFormat = {
104 Tag::MEDIA_TITLE,
105 Tag::MEDIA_ARTIST,
106 Tag::MEDIA_ALBUM,
107 Tag::MEDIA_ALBUM_ARTIST,
108 Tag::MEDIA_DATE,
109 Tag::MEDIA_COMMENT,
110 Tag::MEDIA_GENRE,
111 Tag::MEDIA_COPYRIGHT,
112 Tag::MEDIA_LANGUAGE,
113 Tag::MEDIA_DESCRIPTION,
114 Tag::MEDIA_LYRICS,
115 Tag::MEDIA_AUTHOR,
116 Tag::MEDIA_COMPOSER,
117 Tag::MEDIA_CREATION_TIME
118 };
119
SwitchCase(const std::string & str)120 std::string SwitchCase(const std::string& str)
121 {
122 std::string res;
123 for (char c : str) {
124 if (c == '_') {
125 res += c;
126 } else {
127 res += std::toupper(c);
128 }
129 }
130 MEDIA_LOG_W("Parse meta " PUBLIC_LOG_S " failed, try to parse " PUBLIC_LOG_S "", str.c_str(), res.c_str());
131 return res;
132 }
133
134 static std::vector<AVCodecID> g_imageCodecID = {
135 AV_CODEC_ID_MJPEG,
136 AV_CODEC_ID_PNG,
137 AV_CODEC_ID_PAM,
138 AV_CODEC_ID_BMP,
139 AV_CODEC_ID_JPEG2000,
140 AV_CODEC_ID_TARGA,
141 AV_CODEC_ID_TIFF,
142 AV_CODEC_ID_GIF,
143 AV_CODEC_ID_PCX,
144 AV_CODEC_ID_XWD,
145 AV_CODEC_ID_XBM,
146 AV_CODEC_ID_WEBP,
147 AV_CODEC_ID_APNG,
148 AV_CODEC_ID_XPM,
149 AV_CODEC_ID_SVG,
150 };
151
152 static std::map<std::string, VideoRotation> g_pFfRotationMap = {
153 {"0", VIDEO_ROTATION_0},
154 {"90", VIDEO_ROTATION_90},
155 {"180", VIDEO_ROTATION_180},
156 {"270", VIDEO_ROTATION_270},
157 };
158
IsPCMStream(AVCodecID codecID)159 bool IsPCMStream(AVCodecID codecID)
160 {
161 MEDIA_LOG_D("CodecID " PUBLIC_LOG_D32 "[" PUBLIC_LOG_S "].",
162 static_cast<int32_t>(codecID), avcodec_get_name(codecID));
163 return StartWith(avcodec_get_name(codecID), "pcm_");
164 }
165
GetFileTypeByName(const AVFormatContext & avFormatContext)166 FileType GetFileTypeByName(const AVFormatContext& avFormatContext)
167 {
168 const char *fileName = avFormatContext.iformat->name;
169 FileType fileType = FileType::UNKNOW;
170 FALSE_RETURN_V_MSG_E(avFormatContext.iformat != nullptr, fileType,
171 "Parser file type error due to iformat is nullptr.");
172 if (StartWith(fileName, "mov,mp4,m4a")) {
173 fileType = FileType::MP4;
174 const AVDictionaryEntry *type = av_dict_get(avFormatContext.metadata, "major_brand", NULL, 0);
175 if (type != nullptr && (StartWith(type->value, "m4a") || StartWith(type->value, "M4A"))) {
176 fileType = FileType::M4A;
177 }
178 } else {
179 if (g_convertFfmpegFileType.count(fileName) != 0) {
180 fileType = g_convertFfmpegFileType[fileName];
181 }
182 }
183 MEDIA_LOG_D("file name [" PUBLIC_LOG_S "] file type [" PUBLIC_LOG_D32 "].",
184 fileName, static_cast<int32_t>(fileType));
185 return fileType;
186 }
187 } // namespace
188
ParseMediaInfo(const AVFormatContext & avFormatContext,Meta & format)189 void FFmpegFormatHelper::ParseMediaInfo(const AVFormatContext& avFormatContext, Meta& format)
190 {
191 format.Set<Tag::MEDIA_TRACK_COUNT>(static_cast<int32_t>(avFormatContext.nb_streams));
192 bool hasVideo = false;
193 bool hasAudio = false;
194 for (uint32_t i = 0; i < avFormatContext.nb_streams; ++i) {
195 if (avFormatContext.streams[i] == nullptr) {
196 MEDIA_LOG_D("Track " PUBLIC_LOG_D32 " is nullptr.", i);
197 continue;
198 }
199 if (avFormatContext.streams[i]->codecpar == nullptr) {
200 MEDIA_LOG_D("CodecPar for track " PUBLIC_LOG_D32 " is nullptr.", i);
201 continue;
202 }
203 if (avFormatContext.streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
204 AVCodecID codecID = avFormatContext.streams[i]->codecpar->codec_id;
205 if (std::count(g_imageCodecID.begin(), g_imageCodecID.end(), codecID) <= 0) {
206 hasVideo = true;
207 }
208 } else if (avFormatContext.streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
209 hasAudio = true;
210 }
211 }
212 format.Set<Tag::MEDIA_HAS_VIDEO>(static_cast<int32_t>(hasVideo));
213 format.Set<Tag::MEDIA_HAS_AUDIO>(static_cast<int32_t>(hasAudio));
214 format.Set<Tag::MEDIA_FILE_TYPE>(GetFileTypeByName(avFormatContext));
215 int64_t duration = avFormatContext.duration;
216 if (duration == AV_NOPTS_VALUE) {
217 duration = 0;
218 const AVDictionaryEntry *metaDuration = av_dict_get(avFormatContext.metadata, "DURATION", NULL, 0);
219 int64_t us;
220 if (metaDuration != nullptr && (av_parse_time(&us, metaDuration->value, 1) == 0)) {
221 if (us > duration) {
222 duration = us;
223 }
224 }
225 }
226 if (duration <= 0) {
227 for (uint32_t i = 0; i < avFormatContext.nb_streams; ++i) {
228 auto streamDuration = avFormatContext.streams[i]->duration;
229 if (streamDuration > duration) {
230 duration = streamDuration;
231 }
232 }
233 } else {
234 format.Set<Tag::MEDIA_DURATION>(static_cast<int64_t>(duration));
235 }
236 for (TagType key: g_supportSourceFormat) {
237 ParseInfoFromMetadata(avFormatContext.metadata, key, format);
238 }
239 }
240
ParseTrackInfo(const AVStream & avStream,Meta & format)241 void FFmpegFormatHelper::ParseTrackInfo(const AVStream& avStream, Meta& format)
242 {
243 FALSE_RETURN_MSG(avStream.codecpar != nullptr, "Parse track info failed due to codec par is nullptr.");
244 ParseBaseTrackInfo(avStream, format);
245 if (avStream.codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
246 if ((avStream.disposition & AV_DISPOSITION_ATTACHED_PIC) ||
247 (std::count(g_imageCodecID.begin(), g_imageCodecID.end(), avStream.codecpar->codec_id) > 0)) {
248 ParseImageTrackInfo(avStream, format);
249 } else {
250 ParseAVTrackInfo(avStream, format);
251 ParseVideoTrackInfo(avStream, format);
252 }
253 } else if (avStream.codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
254 ParseAVTrackInfo(avStream, format);
255 ParseAudioTrackInfo(avStream, format);
256 }
257 }
258
ParseBaseTrackInfo(const AVStream & avStream,Meta & format)259 void FFmpegFormatHelper::ParseBaseTrackInfo(const AVStream& avStream, Meta &format)
260 {
261 if (g_codecIdToMime.count(avStream.codecpar->codec_id) != 0) {
262 format.Set<Tag::MIME_TYPE>(std::string(g_codecIdToMime[avStream.codecpar->codec_id]));
263 } else if (IsPCMStream(avStream.codecpar->codec_id)) {
264 format.Set<Tag::MIME_TYPE>(std::string(MimeType::AUDIO_RAW));
265 } else {
266 MEDIA_LOG_D("Parse mime type info failed: " PUBLIC_LOG_D32 ".",
267 static_cast<int32_t>(avStream.codecpar->codec_id));
268 }
269
270 AVMediaType mediaType = avStream.codecpar->codec_type;
271 if (g_convertFfmpegTrackType.count(mediaType) > 0) {
272 format.Set<Tag::MEDIA_TYPE>(g_convertFfmpegTrackType[mediaType]);
273 } else {
274 MEDIA_LOG_D("Parse track type info failed: " PUBLIC_LOG_D32 ".",
275 static_cast<int32_t>(avStream.codecpar->codec_type));
276 }
277 }
278
ParseAVTrackInfo(const AVStream & avStream,Meta & format)279 void FFmpegFormatHelper::ParseAVTrackInfo(const AVStream& avStream, Meta &format)
280 {
281 int64_t bitRate = static_cast<int64_t>(avStream.codecpar->bit_rate);
282 if (bitRate > 0) {
283 format.Set<Tag::MEDIA_BITRATE>(bitRate);
284 } else {
285 MEDIA_LOG_D("Parse bitrate info failed: ." PUBLIC_LOG_D64, bitRate);
286 }
287
288 if (avStream.codecpar->extradata_size > 0 && avStream.codecpar->extradata != nullptr) {
289 std::vector<uint8_t> extra(avStream.codecpar->extradata_size);
290 extra.assign(avStream.codecpar->extradata, avStream.codecpar->extradata + avStream.codecpar->extradata_size);
291 format.Set<Tag::MEDIA_CODEC_CONFIG>(extra);
292 } else {
293 MEDIA_LOG_D("Parse codec config info failed.");
294 }
295 }
296
ParseVideoTrackInfo(const AVStream & avStream,Meta & format)297 void FFmpegFormatHelper::ParseVideoTrackInfo(const AVStream& avStream, Meta &format)
298 {
299 format.Set<Tag::VIDEO_WIDTH>(static_cast<uint32_t>(avStream.codecpar->width));
300 format.Set<Tag::VIDEO_HEIGHT>(static_cast<uint32_t>(avStream.codecpar->height));
301 format.Set<Tag::VIDEO_DELAY>(static_cast<uint32_t>(avStream.codecpar->video_delay));
302
303 double frameRate = 0;
304 if (avStream.avg_frame_rate.den == 0 || avStream.avg_frame_rate.num == 0) {
305 frameRate = static_cast<double>(av_q2d(avStream.r_frame_rate));
306 } else {
307 frameRate = static_cast<double>(av_q2d(avStream.avg_frame_rate));
308 }
309 if (frameRate > 0) {
310 format.Set<Tag::VIDEO_FRAME_RATE>(frameRate);
311 } else {
312 MEDIA_LOG_D("Parse frame rate info failed: " PUBLIC_LOG_F ".", frameRate);
313 }
314
315 AVDictionaryEntry *valPtr = nullptr;
316 valPtr = av_dict_get(avStream.metadata, "rotate", nullptr, AV_DICT_MATCH_CASE);
317 if (valPtr == nullptr) {
318 valPtr = av_dict_get(avStream.metadata, "ROTATE", nullptr, AV_DICT_MATCH_CASE);
319 }
320 if (valPtr == nullptr) {
321 MEDIA_LOG_D("Parse rotate info failed.");
322 } else {
323 if (g_pFfRotationMap.count(std::string(valPtr->value)) > 0) {
324 format.Set<Tag::VIDEO_ROTATION>(g_pFfRotationMap[std::string(valPtr->value)]);
325 }
326 }
327
328 if (avStream.codecpar->codec_id == AV_CODEC_ID_HEVC) {
329 ParseHvccBoxInfo(avStream, format);
330 ParseColorBoxInfo(avStream, format);
331 }
332 }
333
ParseImageTrackInfo(const AVStream & avStream,Meta & format)334 void FFmpegFormatHelper::ParseImageTrackInfo(const AVStream& avStream, Meta &format)
335 {
336 format.Set<Tag::VIDEO_WIDTH>(static_cast<uint32_t>(avStream.codecpar->width));
337 format.Set<Tag::VIDEO_HEIGHT>(static_cast<uint32_t>(avStream.codecpar->height));
338 AVPacket pkt = avStream.attached_pic;
339 if (pkt.size > 0 && pkt.data != nullptr) {
340 std::vector<uint8_t> cover(pkt.size);
341 cover.assign(pkt.data, pkt.data + pkt.size);
342 format.Set<Tag::MEDIA_COVER>(cover);
343 } else {
344 MEDIA_LOG_D("Parse cover info failed: " PUBLIC_LOG_D32 ".", pkt.size);
345 }
346 }
347
ParseAudioTrackInfo(const AVStream & avStream,Meta & format)348 void FFmpegFormatHelper::ParseAudioTrackInfo(const AVStream& avStream, Meta &format)
349 {
350 int sampelRate = avStream.codecpar->sample_rate;
351 int channels = avStream.codecpar->channels;
352 int frameSize = avStream.codecpar->frame_size;
353 if (sampelRate > 0) {
354 format.Set<Tag::AUDIO_SAMPLE_RATE>(static_cast<uint32_t>(sampelRate));
355 } else {
356 MEDIA_LOG_D("Parse sample rate info failed: " PUBLIC_LOG_D32 ".", sampelRate);
357 }
358 if (channels > 0) {
359 format.Set<Tag::AUDIO_OUTPUT_CHANNELS>(static_cast<uint32_t>(channels));
360 format.Set<Tag::AUDIO_CHANNEL_COUNT>(static_cast<uint32_t>(channels));
361 } else {
362 MEDIA_LOG_D("Parse channel count info failed: " PUBLIC_LOG_D32 ".", channels);
363 }
364 if (frameSize > 0) {
365 format.Set<Tag::AUDIO_SAMPLE_PER_FRAME>(static_cast<uint32_t>(frameSize));
366 } else {
367 MEDIA_LOG_D("Parse frame rate info failed: " PUBLIC_LOG_D32 ".", frameSize);
368 }
369 AudioChannelLayout channelLayout = FFMpegConverter::ConvertFFToOHAudioChannelLayoutV2(
370 avStream.codecpar->channel_layout, channels);
371 format.Set<Tag::AUDIO_OUTPUT_CHANNEL_LAYOUT>(channelLayout);
372 format.Set<Tag::AUDIO_CHANNEL_LAYOUT>(channelLayout);
373
374 AudioSampleFormat fmt;
375 if (!IsPCMStream(avStream.codecpar->codec_id)) {
376 fmt = FFMpegConverter::ConvertFFMpegToOHAudioFormat(static_cast<AVSampleFormat>(avStream.codecpar->format));
377 } else {
378 fmt = FFMpegConverter::ConvertFFMpegAVCodecIdToOHAudioFormat(avStream.codecpar->codec_id);
379 }
380 format.Set<Tag::AUDIO_SAMPLE_FORMAT>(fmt);
381
382 if (avStream.codecpar->codec_id == AV_CODEC_ID_AAC) {
383 format.Set<Tag::AUDIO_AAC_IS_ADTS>(1);
384 } else if (avStream.codecpar->codec_id == AV_CODEC_ID_AAC_LATM) {
385 format.Set<Tag::AUDIO_AAC_IS_ADTS>(0);
386 }
387 format.Set<Tag::AUDIO_BITS_PER_CODED_SAMPLE>(avStream.codecpar->bits_per_coded_sample);
388 }
389
ParseHvccBoxInfo(const AVStream & avStream,Meta & format)390 void FFmpegFormatHelper::ParseHvccBoxInfo(const AVStream& avStream, Meta &format)
391 {
392 HEVCProfile profile = FFMpegConverter::ConvertFFMpegToOHHEVCProfile(avStream.codecpar->profile);
393 if (profile != HEVCProfile::HEVC_PROFILE_UNKNOW) {
394 format.Set<Tag::VIDEO_H265_PROFILE>(profile);
395 format.Set<Tag::MEDIA_PROFILE>(profile);
396 } else {
397 MEDIA_LOG_D("Parse hevc profile info failed: " PUBLIC_LOG_D32 ".", profile);
398 }
399 HEVCLevel level = FFMpegConverter::ConvertFFMpegToOHHEVCLevel(avStream.codecpar->level);
400 if (level != HEVCLevel::HEVC_LEVEL_UNKNOW) {
401 format.Set<Tag::VIDEO_H265_LEVEL>(level);
402 format.Set<Tag::MEDIA_LEVEL>(level);
403 } else {
404 MEDIA_LOG_D("Parse hevc level info failed: " PUBLIC_LOG_D32 ".", level);
405 }
406 }
407
ParseColorBoxInfo(const AVStream & avStream,Meta & format)408 void FFmpegFormatHelper::ParseColorBoxInfo(const AVStream& avStream, Meta &format)
409 {
410 int colorRange = FFMpegConverter::ConvertFFMpegToOHColorRange(avStream.codecpar->color_range);
411 format.Set<Tag::VIDEO_COLOR_RANGE>(colorRange);
412
413 ColorPrimary colorPrimaries = FFMpegConverter::ConvertFFMpegToOHColorPrimaries(avStream.codecpar->color_primaries);
414 format.Set<Tag::VIDEO_COLOR_PRIMARIES>(colorPrimaries);
415
416 TransferCharacteristic colorTrans = FFMpegConverter::ConvertFFMpegToOHColorTrans(avStream.codecpar->color_trc);
417 format.Set<Tag::VIDEO_COLOR_TRC>(colorTrans);
418
419 MatrixCoefficient colorMatrix = FFMpegConverter::ConvertFFMpegToOHColorMatrix(avStream.codecpar->color_space);
420 format.Set<Tag::VIDEO_COLOR_MATRIX_COEFF>(colorMatrix);
421
422 ChromaLocation chromaLoc = FFMpegConverter::ConvertFFMpegToOHChromaLocation(avStream.codecpar->chroma_location);
423 format.Set<Tag::VIDEO_CHROMA_LOCATION>(chromaLoc);
424 }
425
ParseHevcInfo(const AVFormatContext & avFormatContext,HevcParseFormat parse,Meta & format)426 void FFmpegFormatHelper::ParseHevcInfo(const AVFormatContext &avFormatContext, HevcParseFormat parse, Meta &format)
427 {
428 if (parse.isHdrVivid) {
429 format.Set<Tag::VIDEO_IS_HDR_VIVID>(true);
430 }
431
432 format.Set<Tag::VIDEO_COLOR_RANGE>((bool)(parse.colorRange));
433
434 ColorPrimary colorPrimaries = FFMpegConverter::ConvertFFMpegToOHColorPrimaries(
435 static_cast<AVColorPrimaries>(parse.colorPrimaries));
436 format.Set<Tag::VIDEO_COLOR_PRIMARIES>(colorPrimaries);
437
438 TransferCharacteristic colorTrans = FFMpegConverter::ConvertFFMpegToOHColorTrans(
439 static_cast<AVColorTransferCharacteristic>(parse.colorTransfer));
440 format.Set<Tag::VIDEO_COLOR_TRC>(colorTrans);
441
442 MatrixCoefficient colorMatrix = FFMpegConverter::ConvertFFMpegToOHColorMatrix(
443 static_cast<AVColorSpace>(parse.colorMatrixCoeff));
444 format.Set<Tag::VIDEO_COLOR_MATRIX_COEFF>(colorMatrix);
445
446 ChromaLocation chromaLoc = FFMpegConverter::ConvertFFMpegToOHChromaLocation(
447 static_cast<AVChromaLocation>(parse.chromaLocation));
448 format.Set<Tag::VIDEO_CHROMA_LOCATION>(chromaLoc);
449
450 HEVCProfile profile = FFMpegConverter::ConvertFFMpegToOHHEVCProfile(static_cast<int>(parse.profile));
451 if (profile != HEVCProfile::HEVC_PROFILE_UNKNOW) {
452 format.Set<Tag::VIDEO_H265_PROFILE>(profile);
453 format.Set<Tag::MEDIA_PROFILE>(profile);
454 } else {
455 MEDIA_LOG_D("Parse hevc profile info failed: " PUBLIC_LOG_D32 ".", profile);
456 }
457 HEVCLevel level = FFMpegConverter::ConvertFFMpegToOHHEVCLevel(static_cast<int>(parse.level));
458 if (level != HEVCLevel::HEVC_LEVEL_UNKNOW) {
459 format.Set<Tag::VIDEO_H265_LEVEL>(level);
460 format.Set<Tag::MEDIA_LEVEL>(level);
461 } else {
462 MEDIA_LOG_D("Parse hevc level info failed: " PUBLIC_LOG_D32 ".", level);
463 }
464
465 if (GetFileTypeByName(avFormatContext) == FileType::MPEGTS) {
466 MEDIA_LOG_I("Updata info for mpegts from parser");
467 format.Set<Tag::VIDEO_WIDTH>(static_cast<uint32_t>(parse.picWidInLumaSamples));
468 format.Set<Tag::VIDEO_HEIGHT>(static_cast<uint32_t>(parse.picHetInLumaSamples));
469 }
470 }
471
ParseInfoFromMetadata(const AVDictionary * metadata,const TagType key,Meta & format)472 void FFmpegFormatHelper::ParseInfoFromMetadata(const AVDictionary* metadata, const TagType key, Meta &format)
473 {
474 AVDictionaryEntry *valPtr = nullptr;
475 valPtr = av_dict_get(metadata, g_formatToString[key].c_str(), nullptr, AV_DICT_MATCH_CASE);
476 if (valPtr == nullptr) {
477 valPtr = av_dict_get(metadata, SwitchCase(std::string(key)).c_str(), nullptr, AV_DICT_MATCH_CASE);
478 }
479 FALSE_RETURN_MSG(valPtr != nullptr, "Parse " PUBLIC_LOG_S " info failed.", key.c_str());
480 format.SetData(key, std::string(valPtr->value));
481 }
482 } // namespace Ffmpeg
483 } // namespace Plugins
484 } // namespace Media
485 } // namespace OHOS