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 #include "ffmpeg_format_helper.h"
17 #include "media_description.h"
18 #include "av_common.h"
19 #include "avcodec_common.h"
20 #include "avcodec_errors.h"
21 #include "avcodec_trace.h"
22 #include "avcodec_log.h"
23 #include "avcodec_info.h"
24 #include "ffmpeg_converter.h"
25
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 #include "libavutil/avutil.h"
30 #include "libavutil/mastering_display_metadata.h"
31 #ifdef __cplusplus
32 }
33 #endif
34
35 namespace OHOS {
36 namespace MediaAVCodec {
37 namespace Plugin {
38 namespace {
39 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "FFmpegFormatHelper"};
40
41 static std::map<AVMediaType, MediaType> g_convertFfmpegTrackType = {
42 {AVMEDIA_TYPE_VIDEO, MediaType::MEDIA_TYPE_VID},
43 {AVMEDIA_TYPE_AUDIO, MediaType::MEDIA_TYPE_AUD},
44 };
45
46 static std::map<AVCodecID, std::string_view> g_codecIdToMime = {
47 {AV_CODEC_ID_MP3, CodecMimeType::AUDIO_MPEG},
48 {AV_CODEC_ID_FLAC, CodecMimeType::AUDIO_FLAC},
49 {AV_CODEC_ID_AAC, CodecMimeType::AUDIO_AAC},
50 {AV_CODEC_ID_VORBIS, CodecMimeType::AUDIO_VORBIS},
51 {AV_CODEC_ID_OPUS, CodecMimeType::AUDIO_OPUS},
52 {AV_CODEC_ID_AMR_NB, CodecMimeType::AUDIO_AMR_NB},
53 {AV_CODEC_ID_AMR_WB, CodecMimeType::AUDIO_AMR_WB},
54 {AV_CODEC_ID_H264, CodecMimeType::VIDEO_AVC},
55 {AV_CODEC_ID_MPEG4, CodecMimeType::VIDEO_MPEG4},
56 {AV_CODEC_ID_MJPEG, CodecMimeType::IMAGE_JPG},
57 {AV_CODEC_ID_PNG, CodecMimeType::IMAGE_PNG},
58 {AV_CODEC_ID_BMP, CodecMimeType::IMAGE_BMP},
59 {AV_CODEC_ID_H263, CodecMimeType::VIDEO_H263},
60 {AV_CODEC_ID_MPEG2TS, CodecMimeType::VIDEO_MPEG2},
61 {AV_CODEC_ID_MPEG2VIDEO, CodecMimeType::VIDEO_MPEG2},
62 {AV_CODEC_ID_HEVC, CodecMimeType::VIDEO_HEVC},
63 {AV_CODEC_ID_VP8, CodecMimeType::VIDEO_VP8},
64 {AV_CODEC_ID_VP9, CodecMimeType::VIDEO_VP9},
65 {AV_CODEC_ID_AVS3DA, CodecMimeType::AUDIO_AVS3DA},
66 };
67
68 static std::map<std::string, FileType> g_convertFfmpegFileType = {
69 {"mpegts", FileType::FILE_TYPE_MPEGTS},
70 {"matroska,webm", FileType::FILE_TYPE_MKV},
71 {"amr", FileType::FILE_TYPE_AMR},
72 {"aac", FileType::FILE_TYPE_AAC},
73 {"mp3", FileType::FILE_TYPE_MP3},
74 {"flac", FileType::FILE_TYPE_FLAC},
75 {"ogg", FileType::FILE_TYPE_OGG},
76 {"wav", FileType::FILE_TYPE_WAV},
77 };
78
79 static std::map<std::string_view, std::string> g_formatToString = {
80 {MediaDescriptionKey::MD_KEY_ROTATION_ANGLE, "rotate"},
81 };
82
83 static std::vector<std::string_view> g_supportSourceFormat = {
84 AVSourceFormat::SOURCE_TITLE,
85 AVSourceFormat::SOURCE_ARTIST,
86 AVSourceFormat::SOURCE_ALBUM,
87 AVSourceFormat::SOURCE_ALBUM_ARTIST,
88 AVSourceFormat::SOURCE_DATE,
89 AVSourceFormat::SOURCE_COMMENT,
90 AVSourceFormat::SOURCE_GENRE,
91 AVSourceFormat::SOURCE_COPYRIGHT,
92 AVSourceFormat::SOURCE_LANGUAGE,
93 AVSourceFormat::SOURCE_DESCRIPTION,
94 AVSourceFormat::SOURCE_LYRICS,
95 AVSourceFormat::SOURCE_AUTHOR,
96 AVSourceFormat::SOURCE_COMPOSER,
97 };
98
SwitchCase(std::string str)99 std::string SwitchCase(std::string str)
100 {
101 std::string res;
102 for (char c : str) {
103 if (c == '_') {
104 res += c;
105 } else {
106 res += std::toupper(c);
107 }
108 }
109 AVCODEC_LOGW("Parse meta %{public}s failed, try to parse %{public}s", str.c_str(), res.c_str());
110 return res;
111 }
112
113 static std::vector<AVCodecID> g_imageCodecID = {
114 AV_CODEC_ID_MJPEG,
115 AV_CODEC_ID_PNG,
116 AV_CODEC_ID_PAM,
117 AV_CODEC_ID_BMP,
118 AV_CODEC_ID_JPEG2000,
119 AV_CODEC_ID_TARGA,
120 AV_CODEC_ID_TIFF,
121 AV_CODEC_ID_GIF,
122 AV_CODEC_ID_PCX,
123 AV_CODEC_ID_XWD,
124 AV_CODEC_ID_XBM,
125 AV_CODEC_ID_WEBP,
126 AV_CODEC_ID_APNG,
127 AV_CODEC_ID_XPM,
128 AV_CODEC_ID_SVG,
129 };
130
StartWith(const char * name,const char * chars)131 bool StartWith(const char* name, const char* chars)
132 {
133 return !strncmp(name, chars, strlen(chars));
134 }
135
IsPCMStream(AVCodecID codecID)136 bool IsPCMStream(AVCodecID codecID)
137 {
138 return StartWith(avcodec_get_name(codecID), "pcm_");
139 }
140
GetFileTypeByName(const AVFormatContext & avFormatContext)141 FileType GetFileTypeByName(const AVFormatContext& avFormatContext)
142 {
143 const char *fileName = avFormatContext.iformat->name;
144 FileType fileType = FileType::FILE_TYPE_UNKNOW;
145 if (StartWith(fileName, "mov,mp4,m4a")) {
146 fileType = FileType::FILE_TYPE_MP4;
147 const AVDictionaryEntry *type = av_dict_get(avFormatContext.metadata, "major_brand", NULL, 0);
148 if (type != nullptr && (StartWith(type->value, "m4a") || StartWith(type->value, "M4A"))) {
149 fileType = FileType::FILE_TYPE_M4A;
150 }
151 } else {
152 if (g_convertFfmpegFileType.count(fileName) != 0) {
153 fileType = g_convertFfmpegFileType[fileName];
154 }
155 }
156 return fileType;
157 }
158 }
159
ParseMediaInfo(const AVFormatContext & avFormatContext,Format & format)160 void FFmpegFormatHelper::ParseMediaInfo(const AVFormatContext& avFormatContext, Format &format)
161 {
162 PutInfoToFormat(MediaDescriptionKey::MD_KEY_TRACK_COUNT, static_cast<int32_t>(avFormatContext.nb_streams), format);
163
164 bool hasVideo = false;
165 bool hasAudio = false;
166 for (uint32_t i = 0; i < avFormatContext.nb_streams; ++i) {
167 if (avFormatContext.streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
168 AVCodecID codecID = avFormatContext.streams[i]->codecpar->codec_id;
169 if (std::count(g_imageCodecID.begin(), g_imageCodecID.end(), codecID) <= 0) {
170 hasVideo = true;
171 }
172 } else if (avFormatContext.streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
173 hasAudio = true;
174 }
175 }
176 PutInfoToFormat(AVSourceFormat::SOURCE_HAS_VIDEO, static_cast<int32_t>(hasVideo), format);
177 PutInfoToFormat(AVSourceFormat::SOURCE_HAS_AUDIO, static_cast<int32_t>(hasAudio), format);
178
179 PutInfoToFormat(AVSourceFormat::SOURCE_FILE_TYPE,
180 static_cast<int32_t>(GetFileTypeByName(avFormatContext)), format);
181
182 int64_t duration = avFormatContext.duration;
183 if (duration == AV_NOPTS_VALUE) {
184 duration = 0;
185 const AVDictionaryEntry *metaDuration = av_dict_get(avFormatContext.metadata, "DURATION", NULL, 0);
186 int64_t us;
187 if (metaDuration && (av_parse_time(&us, metaDuration->value, 1) == 0)) {
188 if (us > duration) {
189 duration = us;
190 }
191 }
192 }
193 if (duration <= 0) {
194 for (uint32_t i = 0; i < avFormatContext.nb_streams; ++i) {
195 auto streamDuration = avFormatContext.streams[i]->duration;
196 if (streamDuration > duration) {
197 duration = streamDuration;
198 }
199 }
200 }
201 if (duration > 0) {
202 PutInfoToFormat(MediaDescriptionKey::MD_KEY_DURATION, static_cast<int64_t>(duration), format);
203 } else {
204 AVCODEC_LOGW("Parse duration info failed: %{public}" PRId64, duration);
205 }
206
207 for (std::string_view key: g_supportSourceFormat) {
208 ParseInfoFromMetadata(avFormatContext.metadata, key, format);
209 }
210 }
211
ParseTrackInfo(const AVStream & avStream,Format & format)212 void FFmpegFormatHelper::ParseTrackInfo(const AVStream& avStream, Format &format)
213 {
214 ParseBaseTrackInfo(avStream, format);
215 if (avStream.codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
216 if ((avStream.disposition & AV_DISPOSITION_ATTACHED_PIC) ||
217 (std::count(g_imageCodecID.begin(), g_imageCodecID.end(), avStream.codecpar->codec_id) > 0)) {
218 ParseImageTrackInfo(avStream, format);
219 } else {
220 ParseAVTrackInfo(avStream, format);
221 ParseVideoTrackInfo(avStream, format);
222 }
223 } else if (avStream.codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
224 ParseAVTrackInfo(avStream, format);
225 ParseAudioTrackInfo(avStream, format);
226 }
227 }
228
ParseHevcInfo(const AVFormatContext & avFormatContext,HevcParseFormat parse,Format & format)229 void FFmpegFormatHelper::ParseHevcInfo(const AVFormatContext &avFormatContext, HevcParseFormat parse, Format &format)
230 {
231 if (parse.isHdrVivid) {
232 PutInfoToFormat(MediaDescriptionKey::MD_KEY_VIDEO_IS_HDR_VIVID, parse.isHdrVivid, format);
233 }
234
235 PutInfoToFormat(MediaDescriptionKey::MD_KEY_RANGE_FLAG, parse.colorRange, format);
236
237 int32_t colorPrimaries = static_cast<int32_t>(FFMpegConverter::ConvertFFMpegToOHColorPrimaries(
238 static_cast<AVColorPrimaries>(parse.colorPrimaries)));
239 PutInfoToFormat(MediaDescriptionKey::MD_KEY_COLOR_PRIMARIES, colorPrimaries, format);
240
241 int32_t colorTransfer = static_cast<int32_t>(FFMpegConverter::ConvertFFMpegToOHColorTrans(
242 static_cast<AVColorTransferCharacteristic>(parse.colorTransfer)));
243 PutInfoToFormat(MediaDescriptionKey::MD_KEY_TRANSFER_CHARACTERISTICS, colorTransfer, format);
244
245 int32_t colorMatrixCoeff = static_cast<int32_t>(FFMpegConverter::ConvertFFMpegToOHColorMatrix(
246 static_cast<AVColorSpace>(parse.colorMatrixCoeff)));
247 PutInfoToFormat(MediaDescriptionKey::MD_KEY_MATRIX_COEFFICIENTS, colorMatrixCoeff, format);
248
249 int32_t profile = static_cast<int32_t>(FFMpegConverter::ConvertFFMpegToOHHEVCProfile(
250 static_cast<int>(parse.profile)));
251 PutInfoToFormat(MediaDescriptionKey::MD_KEY_PROFILE, profile, format);
252
253 int32_t level = static_cast<int32_t>(FFMpegConverter::ConvertFFMpegToOHHEVCLevel(
254 static_cast<int>(parse.level)));
255 PutInfoToFormat(MediaDescriptionKey::MD_KEY_LEVEL, level, format);
256
257 int32_t chromaLocation = static_cast<int32_t>(FFMpegConverter::ConvertFFMpegToOHChromaLocation(
258 static_cast<AVChromaLocation>(parse.chromaLocation)));
259 PutInfoToFormat(MediaDescriptionKey::MD_KEY_CHROMA_LOCATION, chromaLocation, format);
260
261 if (GetFileTypeByName(avFormatContext) == FileType::FILE_TYPE_MPEGTS) {
262 AVCODEC_LOGI("Updata info for mpegts from parser");
263 PutInfoToFormat(MediaDescriptionKey::MD_KEY_WIDTH, static_cast<int32_t>(parse.picWidInLumaSamples), format);
264 PutInfoToFormat(MediaDescriptionKey::MD_KEY_HEIGHT, static_cast<int32_t>(parse.picHetInLumaSamples), format);
265 }
266 }
267
ParseBaseTrackInfo(const AVStream & avStream,Format & format)268 void FFmpegFormatHelper::ParseBaseTrackInfo(const AVStream& avStream, Format &format)
269 {
270 if (g_codecIdToMime.count(avStream.codecpar->codec_id) != 0) {
271 PutInfoToFormat(MediaDescriptionKey::MD_KEY_CODEC_MIME, g_codecIdToMime[avStream.codecpar->codec_id], format);
272 } else if (IsPCMStream(avStream.codecpar->codec_id)) {
273 PutInfoToFormat(MediaDescriptionKey::MD_KEY_CODEC_MIME, CodecMimeType::AUDIO_RAW, format);
274 } else {
275 AVCODEC_LOGW("Parse mime type info failed: %{public}d", static_cast<int32_t>(avStream.codecpar->codec_id));
276 }
277
278 AVMediaType mediaType = avStream.codecpar->codec_type;
279 if (g_convertFfmpegTrackType.count(mediaType) > 0) {
280 PutInfoToFormat(MediaDescriptionKey::MD_KEY_TRACK_TYPE, g_convertFfmpegTrackType[mediaType], format);
281 } else {
282 AVCODEC_LOGW("Parse track type info failed: %{public}d", static_cast<int32_t>(avStream.codecpar->codec_type));
283 }
284 }
285
ParseAVTrackInfo(const AVStream & avStream,Format & format)286 void FFmpegFormatHelper::ParseAVTrackInfo(const AVStream& avStream, Format &format)
287 {
288 int64_t bitRate = static_cast<int64_t>(avStream.codecpar->bit_rate);
289 if (bitRate > 0) {
290 PutInfoToFormat(MediaDescriptionKey::MD_KEY_BITRATE, bitRate, format);
291 } else {
292 AVCODEC_LOGW("Parse bitrate info failed: %{public}" PRId64, bitRate);
293 }
294
295 if (avStream.codecpar->extradata_size > 0 && avStream.codecpar->extradata != nullptr) {
296 PutBufferToFormat(MediaDescriptionKey::MD_KEY_CODEC_CONFIG, avStream.codecpar->extradata,
297 avStream.codecpar->extradata_size, format);
298 } else {
299 AVCODEC_LOGW("Parse codec config info failed");
300 }
301 }
302
ParseVideoTrackInfo(const AVStream & avStream,Format & format)303 void FFmpegFormatHelper::ParseVideoTrackInfo(const AVStream& avStream, Format &format)
304 {
305 PutInfoToFormat(MediaDescriptionKey::MD_KEY_WIDTH, static_cast<int32_t>(avStream.codecpar->width), format);
306 PutInfoToFormat(MediaDescriptionKey::MD_KEY_HEIGHT, static_cast<int32_t>(avStream.codecpar->height), format);
307 PutInfoToFormat(MediaDescriptionKey::MD_KEY_VIDEO_DELAY,
308 static_cast<int32_t>(avStream.codecpar->video_delay), format);
309
310 double frameRate = 0;
311 if (avStream.avg_frame_rate.den == 0 || avStream.avg_frame_rate.num == 0) {
312 frameRate = static_cast<double>(av_q2d(avStream.r_frame_rate));
313 } else {
314 frameRate = static_cast<double>(av_q2d(avStream.avg_frame_rate));
315 }
316 if (frameRate > 0) {
317 PutInfoToFormat(MediaDescriptionKey::MD_KEY_FRAME_RATE, frameRate, format);
318 } else {
319 AVCODEC_LOGW("Parse frame rate info failed: %{public}f", frameRate);
320 }
321
322 ParseInfoFromMetadata(avStream.metadata, MediaDescriptionKey::MD_KEY_ROTATION_ANGLE, format);
323
324 if (avStream.codecpar->codec_id == AV_CODEC_ID_HEVC) {
325 ParseHvccBoxInfo(avStream, format);
326 ParseColorBoxInfo(avStream, format);
327 }
328 }
329
ParseHvccBoxInfo(const AVStream & avStream,Format & format)330 void FFmpegFormatHelper::ParseHvccBoxInfo(const AVStream& avStream, Format &format)
331 {
332 int32_t profile = static_cast<int32_t>(FFMpegConverter::ConvertFFMpegToOHHEVCProfile(avStream.codecpar->profile));
333 if (profile >= 0) {
334 PutInfoToFormat(MediaDescriptionKey::MD_KEY_PROFILE, profile, format);
335 } else {
336 AVCODEC_LOGW("Parse hevc profile info failed: %{public}d", profile);
337 }
338 int32_t level = static_cast<int32_t>(FFMpegConverter::ConvertFFMpegToOHHEVCLevel(avStream.codecpar->level));
339 if (level >= 0) {
340 PutInfoToFormat(MediaDescriptionKey::MD_KEY_LEVEL, level, format);
341 } else {
342 AVCODEC_LOGW("Parse hevc level info failed: %{public}d", level);
343 }
344 }
345
ParseColorBoxInfo(const AVStream & avStream,Format & format)346 void FFmpegFormatHelper::ParseColorBoxInfo(const AVStream& avStream, Format &format)
347 {
348 int colorRange = FFMpegConverter::ConvertFFMpegToOHColorRange(avStream.codecpar->color_range);
349 PutInfoToFormat(MediaDescriptionKey::MD_KEY_RANGE_FLAG, static_cast<int32_t>(colorRange), format);
350
351 ColorPrimary colorPrimaries = FFMpegConverter::ConvertFFMpegToOHColorPrimaries(avStream.codecpar->color_primaries);
352 PutInfoToFormat(MediaDescriptionKey::MD_KEY_COLOR_PRIMARIES, static_cast<int32_t>(colorPrimaries), format);
353
354 TransferCharacteristic colorTrans = FFMpegConverter::ConvertFFMpegToOHColorTrans(avStream.codecpar->color_trc);
355 PutInfoToFormat(MediaDescriptionKey::MD_KEY_TRANSFER_CHARACTERISTICS, static_cast<int32_t>(colorTrans), format);
356
357 MatrixCoefficient colorMatrix = FFMpegConverter::ConvertFFMpegToOHColorMatrix(avStream.codecpar->color_space);
358 PutInfoToFormat(MediaDescriptionKey::MD_KEY_MATRIX_COEFFICIENTS, static_cast<int32_t>(colorMatrix), format);
359
360 ChromaLocation chromaLoc = FFMpegConverter::ConvertFFMpegToOHChromaLocation(avStream.codecpar->chroma_location);
361 PutInfoToFormat(MediaDescriptionKey::MD_KEY_CHROMA_LOCATION, static_cast<int32_t>(chromaLoc), format);
362 }
363
ParseImageTrackInfo(const AVStream & avStream,Format & format)364 void FFmpegFormatHelper::ParseImageTrackInfo(const AVStream& avStream, Format &format)
365 {
366 PutInfoToFormat(MediaDescriptionKey::MD_KEY_WIDTH, static_cast<int32_t>(avStream.codecpar->width), format);
367 PutInfoToFormat(MediaDescriptionKey::MD_KEY_HEIGHT, static_cast<int32_t>(avStream.codecpar->height), format);
368 AVPacket pkt = avStream.attached_pic;
369 if (pkt.size > 0) {
370 PutBufferToFormat(MediaDescriptionKey::MD_KEY_COVER, pkt.data, pkt.size, format);
371 } else {
372 AVCODEC_LOGW("Parse cover info failed: %{public}d", pkt.size);
373 }
374 }
375
ParseAudioTrackInfo(const AVStream & avStream,Format & format)376 void FFmpegFormatHelper::ParseAudioTrackInfo(const AVStream& avStream, Format &format)
377 {
378 int32_t sampelRate = static_cast<int32_t>(avStream.codecpar->sample_rate);
379 int32_t channels = static_cast<int32_t>(avStream.codecpar->channels);
380 int32_t frameSize = static_cast<int32_t>(avStream.codecpar->frame_size);
381 if (sampelRate > 0) {
382 PutInfoToFormat(MediaDescriptionKey::MD_KEY_SAMPLE_RATE, sampelRate, format);
383 } else {
384 AVCODEC_LOGW("Parse sample rate info failed: %{public}d", sampelRate);
385 }
386 if (channels > 0) {
387 PutInfoToFormat(MediaDescriptionKey::MD_KEY_CHANNEL_COUNT, channels, format);
388 } else {
389 AVCODEC_LOGW("Parse channel count info failed: %{public}d", channels);
390 }
391 if (frameSize > 0) {
392 PutInfoToFormat(MediaDescriptionKey::MD_KEY_AUDIO_SAMPLES_PER_FRAME, frameSize, format);
393 } else {
394 AVCODEC_LOGW("Parse frame rate info failed: %{public}d", frameSize);
395 }
396 int64_t channelLayout = static_cast<int64_t>(FFMpegConverter::ConvertFFToOHAudioChannelLayoutV2(
397 avStream.codecpar->channel_layout, channels));
398 PutInfoToFormat(MediaDescriptionKey::MD_KEY_CHANNEL_LAYOUT, channelLayout, format);
399
400 AudioSampleFormat fmt;
401 if (!IsPCMStream(avStream.codecpar->codec_id)) {
402 fmt = FFMpegConverter::ConvertFFMpegToOHAudioFormat(static_cast<AVSampleFormat>(avStream.codecpar->format));
403 } else {
404 fmt = FFMpegConverter::ConvertFFMpegAVCodecIdToOHAudioFormat(avStream.codecpar->codec_id);
405 }
406 PutInfoToFormat(MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT, static_cast<int32_t>(fmt), format);
407
408 if (avStream.codecpar->codec_id == AV_CODEC_ID_AAC) {
409 PutInfoToFormat(MediaDescriptionKey::MD_KEY_AAC_IS_ADTS, 1, format);
410 } else if (avStream.codecpar->codec_id == AV_CODEC_ID_AAC_LATM) {
411 PutInfoToFormat(MediaDescriptionKey::MD_KEY_AAC_IS_ADTS, 0, format);
412 }
413 }
414
ParseInfoFromMetadata(const AVDictionary * metadata,const std::string_view key,Format & format)415 void FFmpegFormatHelper::ParseInfoFromMetadata(const AVDictionary* metadata, const std::string_view key, Format &format)
416 {
417 AVDictionaryEntry *valPtr = nullptr;
418 if (g_formatToString.count(key) != 0) {
419 valPtr = av_dict_get(metadata, g_formatToString[key].c_str(), nullptr, AV_DICT_MATCH_CASE);
420 } else {
421 valPtr = av_dict_get(metadata, key.data(), nullptr, AV_DICT_MATCH_CASE);
422 }
423 if (valPtr == nullptr) {
424 valPtr = av_dict_get(metadata, SwitchCase(std::string(key)).c_str(), nullptr, AV_DICT_MATCH_CASE);
425 }
426 if (valPtr == nullptr) {
427 AVCODEC_LOGW("Parse %{public}s info failed", key.data());
428 } else {
429 if (key == MediaDescriptionKey::MD_KEY_ROTATION_ANGLE) {
430 PutInfoToFormat(key, static_cast<int32_t>(std::stoi(valPtr->value)), format);
431 } else {
432 PutInfoToFormat(key, valPtr->value, format);
433 }
434 }
435 }
436
PutInfoToFormat(const std::string_view & key,int32_t value,Format & format)437 void FFmpegFormatHelper::PutInfoToFormat(const std::string_view &key, int32_t value, Format& format)
438 {
439 bool ret = format.PutIntValue(key, value);
440 CHECK_AND_RETURN_LOG(ret, "Put %{public}s info failed", key.data());
441 }
442
PutInfoToFormat(const std::string_view & key,int64_t value,Format & format)443 void FFmpegFormatHelper::PutInfoToFormat(const std::string_view &key, int64_t value, Format& format)
444 {
445 bool ret = format.PutLongValue(key, value);
446 CHECK_AND_RETURN_LOG(ret, "Put %{public}s info failed", key.data());
447 }
448
PutInfoToFormat(const std::string_view & key,float value,Format & format)449 void FFmpegFormatHelper::PutInfoToFormat(const std::string_view &key, float value, Format& format)
450 {
451 bool ret = format.PutFloatValue(key, value);
452 CHECK_AND_RETURN_LOG(ret, "Put %{public}s info failed", key.data());
453 }
454
PutInfoToFormat(const std::string_view & key,double value,Format & format)455 void FFmpegFormatHelper::PutInfoToFormat(const std::string_view &key, double value, Format& format)
456 {
457 bool ret = format.PutDoubleValue(key, value);
458 CHECK_AND_RETURN_LOG(ret, "Put %{public}s info failed", key.data());
459 }
460
PutInfoToFormat(const std::string_view & key,const std::string_view & value,Format & format)461 void FFmpegFormatHelper::PutInfoToFormat(const std::string_view &key, const std::string_view &value, Format& format)
462 {
463 bool ret = format.PutStringValue(key, value);
464 CHECK_AND_RETURN_LOG(ret, "Put %{public}s info failed", key.data());
465 }
466
PutBufferToFormat(const std::string_view & key,const uint8_t * addr,size_t size,Format & format)467 void FFmpegFormatHelper::PutBufferToFormat(const std::string_view &key, const uint8_t *addr,
468 size_t size, Format &format)
469 {
470 bool ret = format.PutBuffer(key, addr, size);
471 CHECK_AND_RETURN_LOG(ret, "Put %{public}s info failed", key.data());
472 }
473 } // namespace Plugin
474 } // namespace MediaAVCodec
475 } // namespace OHOS