1 /*
2 * Copyright (c) 2021-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 #include "ffmpeg_utils.h"
17
18 #include <algorithm>
19 #include <functional>
20
21 #include "foundation/log.h"
22 #include "plugin/common/plugin_audio_tags.h"
23 #include "plugin/common/plugin_time.h"
24
25 namespace OHOS {
26 namespace Media {
27 namespace Plugin {
28 namespace Ffmpeg {
29 // Internal definitions
30 namespace {
31 // Histreamer channel layout to ffmpeg channel layout
32 std::map<AudioChannelLayout, uint64_t> g_toFFMPEGChannelLayout = {
33 {AudioChannelLayout::MONO, AV_CH_LAYOUT_MONO},
34 {AudioChannelLayout::STEREO, AV_CH_LAYOUT_STEREO},
35 {AudioChannelLayout::CH_2POINT1, AV_CH_LAYOUT_2POINT1},
36 {AudioChannelLayout::CH_2_1, AV_CH_LAYOUT_2_1},
37 {AudioChannelLayout::SURROUND, AV_CH_LAYOUT_SURROUND},
38 {AudioChannelLayout::CH_3POINT1, AV_CH_LAYOUT_3POINT1},
39 {AudioChannelLayout::CH_4POINT0, AV_CH_LAYOUT_4POINT0},
40 {AudioChannelLayout::CH_4POINT1, AV_CH_LAYOUT_4POINT1},
41 {AudioChannelLayout::CH_2_2, AV_CH_LAYOUT_2_2},
42 {AudioChannelLayout::QUAD, AV_CH_LAYOUT_QUAD},
43 {AudioChannelLayout::CH_5POINT0, AV_CH_LAYOUT_5POINT0},
44 {AudioChannelLayout::CH_5POINT1, AV_CH_LAYOUT_5POINT1},
45 {AudioChannelLayout::CH_5POINT0_BACK, AV_CH_LAYOUT_5POINT0_BACK},
46 {AudioChannelLayout::CH_5POINT1_BACK, AV_CH_LAYOUT_5POINT1_BACK},
47 {AudioChannelLayout::CH_6POINT0, AV_CH_LAYOUT_6POINT0},
48 {AudioChannelLayout::CH_6POINT0_FRONT, AV_CH_LAYOUT_6POINT0_FRONT},
49 {AudioChannelLayout::HEXAGONAL, AV_CH_LAYOUT_HEXAGONAL},
50 {AudioChannelLayout::CH_6POINT1, AV_CH_LAYOUT_6POINT1},
51 {AudioChannelLayout::CH_6POINT1_BACK, AV_CH_LAYOUT_6POINT1_BACK},
52 {AudioChannelLayout::CH_6POINT1_FRONT, AV_CH_LAYOUT_6POINT1_FRONT},
53 {AudioChannelLayout::CH_7POINT0, AV_CH_LAYOUT_7POINT0},
54 {AudioChannelLayout::CH_7POINT0_FRONT, AV_CH_LAYOUT_7POINT0_FRONT},
55 {AudioChannelLayout::CH_7POINT1, AV_CH_LAYOUT_7POINT1},
56 {AudioChannelLayout::CH_7POINT1_WIDE, AV_CH_LAYOUT_7POINT1_WIDE},
57 {AudioChannelLayout::CH_7POINT1_WIDE_BACK, AV_CH_LAYOUT_7POINT1_WIDE_BACK},
58 {AudioChannelLayout::OCTAGONAL, AV_CH_LAYOUT_OCTAGONAL},
59 {AudioChannelLayout::HEXADECAGONAL, AV_CH_LAYOUT_HEXADECAGONAL},
60 {AudioChannelLayout::STEREO_DOWNMIX, AV_CH_LAYOUT_STEREO_DOWNMIX},
61 };
62
63 // ffmpeg channel layout to histreamer channel layout
64 std::map<uint64_t, AudioChannelMasks> g_fromFFMPEGChannelLayout = {
65 {AV_CH_FRONT_LEFT, AudioChannelMasks::FRONT_LEFT},
66 {AV_CH_FRONT_RIGHT, AudioChannelMasks::FRONT_RIGHT},
67 {AV_CH_FRONT_CENTER, AudioChannelMasks::FRONT_CENTER},
68 {AV_CH_LOW_FREQUENCY, AudioChannelMasks::LOW_FREQUENCY},
69 {AV_CH_BACK_LEFT, AudioChannelMasks::BACK_LEFT},
70 {AV_CH_BACK_RIGHT, AudioChannelMasks::BACK_RIGHT},
71 {AV_CH_FRONT_LEFT_OF_CENTER, AudioChannelMasks::FRONT_LEFT_OF_CENTER},
72 {AV_CH_FRONT_RIGHT_OF_CENTER, AudioChannelMasks::FRONT_RIGHT_OF_CENTER},
73 {AV_CH_BACK_CENTER, AudioChannelMasks::BACK_CENTER},
74 {AV_CH_SIDE_LEFT, AudioChannelMasks::SIDE_LEFT},
75 {AV_CH_SIDE_RIGHT, AudioChannelMasks::SIDE_RIGHT},
76 {AV_CH_TOP_CENTER, AudioChannelMasks::TOP_CENTER},
77 {AV_CH_TOP_FRONT_LEFT, AudioChannelMasks::TOP_FRONT_LEFT},
78 {AV_CH_TOP_FRONT_CENTER, AudioChannelMasks::TOP_FRONT_CENTER},
79 {AV_CH_TOP_FRONT_RIGHT, AudioChannelMasks::TOP_FRONT_RIGHT},
80 {AV_CH_TOP_BACK_LEFT, AudioChannelMasks::TOP_BACK_LEFT},
81 {AV_CH_TOP_BACK_CENTER, AudioChannelMasks::TOP_BACK_CENTER},
82 {AV_CH_TOP_BACK_RIGHT, AudioChannelMasks::TOP_BACK_RIGHT},
83 {AV_CH_STEREO_LEFT, AudioChannelMasks::STEREO_LEFT},
84 {AV_CH_STEREO_RIGHT, AudioChannelMasks::STEREO_RIGHT},
85 {AV_CH_WIDE_LEFT, AudioChannelMasks::WIDE_LEFT},
86 {AV_CH_WIDE_RIGHT, AudioChannelMasks::WIDE_RIGHT},
87 {AV_CH_SURROUND_DIRECT_LEFT, AudioChannelMasks::SURROUND_DIRECT_LEFT},
88 {AV_CH_SURROUND_DIRECT_RIGHT, AudioChannelMasks::SURROUND_DIRECT_RIGHT},
89 {AV_CH_LOW_FREQUENCY_2, AudioChannelMasks::LOW_FREQUENCY_2},
90 {AV_CH_TOP_SIDE_LEFT, AudioChannelMasks::TOP_SIDE_LEFT},
91 {AV_CH_TOP_SIDE_RIGHT, AudioChannelMasks::TOP_SIDE_RIGHT},
92 {AV_CH_BOTTOM_FRONT_CENTER, AudioChannelMasks::BOTTOM_FRONT_CENTER},
93 {AV_CH_BOTTOM_FRONT_LEFT, AudioChannelMasks::BOTTOM_FRONT_LEFT},
94 {AV_CH_BOTTOM_FRONT_RIGHT, AudioChannelMasks::BOTTOM_FRONT_RIGHT},
95 };
96
97 const std::map<std::string, Tag> g_tagMap = {
98 {"title", Tag::MEDIA_TITLE},
99 {"artist", Tag::MEDIA_ARTIST},
100 {"lyricist", Tag::MEDIA_LYRICIST},
101 {"album", Tag::MEDIA_ALBUM},
102 {"album-artist", Tag::MEDIA_ALBUM_ARTIST},
103 {"date", Tag::MEDIA_DATE},
104 {"comment", Tag::MEDIA_COMMENT},
105 {"genre", Tag::MEDIA_GENRE},
106 {"copyright", Tag::MEDIA_COPYRIGHT},
107 {"language", Tag::MEDIA_LANGUAGE},
108 {"description", Tag::MEDIA_DESCRIPTION},
109 {"lyrics", Tag::MEDIA_LYRICS},
110 };
111
112 std::map<std::string, std::function<void(Meta&, AVDictionaryEntry*)>> g_MediaMap = {
__anon6423ce540202() 113 {"title", [](Meta& meta, AVDictionaryEntry* tag) {meta.Set<Tag::MEDIA_TITLE>(tag->value); }},
__anon6423ce540302() 114 {"artist", [](Meta& meta, AVDictionaryEntry* tag) {meta.Set<Tag::MEDIA_ARTIST>(tag->value); }},
__anon6423ce540402() 115 {"lyricist", [](Meta& meta, AVDictionaryEntry* tag) {meta.Set<Tag::MEDIA_LYRICIST>(tag->value); }},
__anon6423ce540502() 116 {"album", [](Meta& meta, AVDictionaryEntry* tag) {meta.Set<Tag::MEDIA_ALBUM>(tag->value); }},
__anon6423ce540602() 117 {"album-artist", [](Meta& meta, AVDictionaryEntry* tag) {meta.Set<Tag::MEDIA_ALBUM_ARTIST>(tag->value); }},
__anon6423ce540702() 118 {"date", [](Meta& meta, AVDictionaryEntry* tag) {
119 uint32_t year;
120 uint32_t month;
121 uint32_t day = 0;
122 if (sscanf_s(tag->value, "%04u-%02u-%02u", &year, &month, &day) == 3) { // 3
123 meta.Set<Tag::MEDIA_DATE>(RemoveDelimiter(tag->value, '-'));
124 }
125 }},
__anon6423ce540802() 126 {"comment", [](Meta& meta, AVDictionaryEntry* tag) {meta.Set<Tag::MEDIA_COMMENT>(tag->value); }},
__anon6423ce540902() 127 {"genre", [](Meta& meta, AVDictionaryEntry* tag) {meta.Set<Tag::MEDIA_GENRE>(tag->value); }},
__anon6423ce540a02() 128 {"copyright", [](Meta& meta, AVDictionaryEntry* tag) {meta.Set<Tag::MEDIA_COPYRIGHT>(tag->value); }},
__anon6423ce540b02() 129 {"language", [](Meta& meta, AVDictionaryEntry* tag) {meta.Set<Tag::MEDIA_LANGUAGE>(tag->value); }},
__anon6423ce540c02() 130 {"description", [](Meta& meta, AVDictionaryEntry* tag) {meta.Set<Tag::MEDIA_DESCRIPTION>(tag->value); }},
__anon6423ce540d02() 131 {"lyrics", [](Meta& meta, AVDictionaryEntry* tag) {meta.Set<Tag::MEDIA_LYRICS>(tag->value); }}
132 };
133
134 const std::vector<std::pair<AudioAacProfile, int32_t>> g_AacProfileMap = {
135 {AudioAacProfile::MAIN, FF_PROFILE_AAC_MAIN},
136 {AudioAacProfile::LC, FF_PROFILE_AAC_LOW},
137 {AudioAacProfile::SSR, FF_PROFILE_AAC_SSR},
138 {AudioAacProfile::LTP, FF_PROFILE_AAC_LTP},
139 {AudioAacProfile::HE, FF_PROFILE_AAC_HE},
140 {AudioAacProfile::HE_PS, FF_PROFILE_AAC_HE_V2},
141 {AudioAacProfile::LD, FF_PROFILE_AAC_LD},
142 {AudioAacProfile::ELD, FF_PROFILE_AAC_ELD},
143 };
144
145 // Histreamer pixel format to ffmpeg pixel format
146 std::map<VideoPixelFormat, AVPixelFormat> g_pixelFormatMap = {
147 {VideoPixelFormat::YUV410P, AV_PIX_FMT_YUV410P},
148 {VideoPixelFormat::YUV411P, AV_PIX_FMT_YUV411P},
149 {VideoPixelFormat::YUV420P, AV_PIX_FMT_YUV420P},
150 {VideoPixelFormat::NV12, AV_PIX_FMT_NV12},
151 {VideoPixelFormat::NV21, AV_PIX_FMT_NV21},
152 {VideoPixelFormat::YUYV422, AV_PIX_FMT_YUYV422},
153 {VideoPixelFormat::YUV422P, AV_PIX_FMT_YUV422P},
154 {VideoPixelFormat::YUV444P, AV_PIX_FMT_YUV444P},
155 {VideoPixelFormat::RGBA, AV_PIX_FMT_RGBA},
156 {VideoPixelFormat::ARGB, AV_PIX_FMT_ARGB},
157 {VideoPixelFormat::ABGR, AV_PIX_FMT_ABGR},
158 {VideoPixelFormat::BGRA, AV_PIX_FMT_BGRA},
159 {VideoPixelFormat::RGB24, AV_PIX_FMT_RGB24},
160 {VideoPixelFormat::BGR24, AV_PIX_FMT_BGR24},
161 {VideoPixelFormat::PAL8, AV_PIX_FMT_PAL8},
162 {VideoPixelFormat::GRAY8, AV_PIX_FMT_GRAY8},
163 {VideoPixelFormat::MONOWHITE, AV_PIX_FMT_MONOWHITE},
164 {VideoPixelFormat::MONOBLACK, AV_PIX_FMT_MONOBLACK},
165 {VideoPixelFormat::YUVJ420P, AV_PIX_FMT_YUVJ420P},
166 {VideoPixelFormat::YUVJ422P, AV_PIX_FMT_YUVJ422P},
167 {VideoPixelFormat::YUVJ444P, AV_PIX_FMT_YUVJ444P},
168 };
169
170 std::map<VideoH264Profile, int32_t> g_H264ProfileMap = {
171 {VideoH264Profile::BASELINE, FF_PROFILE_H264_BASELINE},
172 {VideoH264Profile::MAIN, FF_PROFILE_H264_MAIN},
173 {VideoH264Profile::EXTENDED, FF_PROFILE_H264_EXTENDED},
174 {VideoH264Profile::HIGH, FF_PROFILE_H264_HIGH},
175 {VideoH264Profile::HIGH10, FF_PROFILE_H264_HIGH_10},
176 {VideoH264Profile::HIGH422, FF_PROFILE_H264_HIGH_422},
177 {VideoH264Profile::HIGH444, FF_PROFILE_H264_HIGH_444}
178 };
179 std::vector<std::pair<AudioSampleFormat, AVSampleFormat>> g_pFfSampleFmtMap = {
180 {AudioSampleFormat::U8, AVSampleFormat::AV_SAMPLE_FMT_U8},
181 {AudioSampleFormat::U8P, AVSampleFormat::AV_SAMPLE_FMT_U8P},
182 {AudioSampleFormat::S16, AVSampleFormat::AV_SAMPLE_FMT_S16},
183 {AudioSampleFormat::S16P, AVSampleFormat::AV_SAMPLE_FMT_S16P},
184 {AudioSampleFormat::S32, AVSampleFormat::AV_SAMPLE_FMT_S32},
185 {AudioSampleFormat::S32P, AVSampleFormat::AV_SAMPLE_FMT_S32P},
186 {AudioSampleFormat::F32, AVSampleFormat::AV_SAMPLE_FMT_FLT},
187 {AudioSampleFormat::F32P, AVSampleFormat::AV_SAMPLE_FMT_FLTP},
188 {AudioSampleFormat::F64, AVSampleFormat::AV_SAMPLE_FMT_DBL},
189 {AudioSampleFormat::F64P, AVSampleFormat::AV_SAMPLE_FMT_DBLP},
190 {AudioSampleFormat::S64, AVSampleFormat::AV_SAMPLE_FMT_S64},
191 {AudioSampleFormat::S64P, AVSampleFormat::AV_SAMPLE_FMT_S64P},
192 };
193 } // namespace
194
AVStrError(int errnum)195 std::string AVStrError(int errnum)
196 {
197 char errbuf[AV_ERROR_MAX_STRING_SIZE] = {0};
198 av_strerror(errnum, errbuf, AV_ERROR_MAX_STRING_SIZE);
199 return std::string(errbuf);
200 }
201
ConvertTimeFromFFmpeg(int64_t pts,AVRational base)202 int64_t ConvertTimeFromFFmpeg(int64_t pts, AVRational base)
203 {
204 int64_t out;
205 if (pts == AV_NOPTS_VALUE) {
206 out = -1;
207 } else {
208 AVRational bq = {1, HST_SECOND};
209 out = av_rescale_q(pts, base, bq);
210 }
211 return out;
212 }
213
ConvertTimeToFFmpeg(int64_t timestampUs,AVRational base)214 int64_t ConvertTimeToFFmpeg(int64_t timestampUs, AVRational base)
215 {
216 int64_t result;
217 if (base.num == 0) {
218 result = AV_NOPTS_VALUE;
219 } else {
220 AVRational bq = {1, HST_SECOND};
221 result = av_rescale_q(timestampUs, bq, base);
222 }
223 return result;
224 }
225
FillAVPicture(AVFrame * picture,uint8_t * ptr,enum AVPixelFormat pixFmt,int width,int height)226 int FillAVPicture(AVFrame* picture, uint8_t* ptr, enum AVPixelFormat pixFmt, int width, int height)
227 {
228 (void)picture;
229 (void)ptr;
230 (void)pixFmt;
231 (void)width;
232 (void)height;
233 return 0;
234 }
235
GetAVPictureSize(int pixFmt,int width,int height)236 int GetAVPictureSize(int pixFmt, int width, int height)
237 {
238 AVFrame dummy;
239 return FillAVPicture(&dummy, nullptr, static_cast<AVPixelFormat>(pixFmt), width, height);
240 }
241
RemoveDelimiter(const char * str,char delimiter)242 std::string RemoveDelimiter(const char* str, char delimiter)
243 {
244 std::string tmp(str);
245 RemoveDelimiter(delimiter, tmp);
246 return tmp;
247 }
248
RemoveDelimiter(char delimiter,std::string & str)249 void RemoveDelimiter(char delimiter, std::string& str)
250 {
251 for (auto it = std::find(str.begin(), str.end(), delimiter); it != str.end();) {
252 it = str.erase(it);
253 if (*it != delimiter) {
254 it = std::find(it, str.end(), delimiter);
255 }
256 }
257 }
258
ReplaceDelimiter(const std::string & delmiters,char newDelimiter,std::string & str)259 void ReplaceDelimiter(const std::string& delmiters, char newDelimiter, std::string& str)
260 {
261 for (auto it = str.begin(); it != str.end(); ++it) {
262 if (delmiters.find(newDelimiter) != std::string::npos) {
263 *it = newDelimiter;
264 }
265 }
266 }
267
SplitString(const char * str,char delimiter)268 std::vector<std::string> SplitString(const char* str, char delimiter)
269 {
270 std::vector<std::string> rtv;
271 if (str) {
272 SplitString(std::string(str), delimiter).swap(rtv);
273 }
274 return rtv;
275 }
276
SplitString(const std::string & str,char delimiter)277 std::vector<std::string> SplitString(const std::string& str, char delimiter)
278 {
279 if (str.empty()) {
280 return {};
281 }
282 std::vector<std::string> rtv;
283 std::string::size_type startPos = 0;
284 std::string::size_type endPos = str.find_first_of(delimiter, startPos);
285 while (startPos != endPos) {
286 rtv.emplace_back(str.substr(startPos, endPos - startPos));
287 if (endPos == std::string::npos) {
288 break;
289 }
290 startPos = endPos + 1;
291 endPos = str.find_first_of(delimiter, startPos);
292 }
293 return rtv;
294 }
295
ConvFf2PSampleFmt(AVSampleFormat sampleFormat)296 AudioSampleFormat ConvFf2PSampleFmt(AVSampleFormat sampleFormat)
297 {
298 auto ite = std::find_if(g_pFfSampleFmtMap.begin(), g_pFfSampleFmtMap.end(),
299 [&sampleFormat] (const std::pair<AudioSampleFormat, AVSampleFormat>& item) ->bool {
300 return item.second == sampleFormat;
301 });
302 if (ite == g_pFfSampleFmtMap.end()) {
303 return AudioSampleFormat::NONE;
304 }
305 return ite->first;
306 }
307
ConvP2FfSampleFmt(AudioSampleFormat sampleFormat)308 AVSampleFormat ConvP2FfSampleFmt(AudioSampleFormat sampleFormat)
309 {
310 auto ite = std::find_if(g_pFfSampleFmtMap.begin(), g_pFfSampleFmtMap.end(),
311 [&sampleFormat] (const std::pair<AudioSampleFormat, AVSampleFormat>& item) ->bool {
312 return item.first == sampleFormat;
313 });
314 if (ite == g_pFfSampleFmtMap.end()) {
315 return AV_SAMPLE_FMT_NONE;
316 }
317 return ite->second;
318 }
319
GetDefaultChannelLayout(int channels)320 AudioChannelLayout GetDefaultChannelLayout(int channels)
321 {
322 AudioChannelLayout ret;
323 switch (channels) {
324 case 1: { // 1: MONO
325 ret = AudioChannelLayout::MONO;
326 break;
327 }
328 case 2: { // 2: STEREO
329 ret = AudioChannelLayout::STEREO;
330 break;
331 }
332 case 4: { // 4: CH_4POINT0
333 ret = AudioChannelLayout::CH_4POINT0;
334 break;
335 }
336 case 6: { // 6: CH_5POINT1
337 ret = AudioChannelLayout::CH_5POINT1;
338 break;
339 }
340 case 8: { // 8: CH_5POINT1POINT2 or CH_7POINT1
341 ret = AudioChannelLayout::CH_5POINT1POINT2;
342 break;
343 }
344 case 10: { // 10: CH_7POINT1POINT2 or CH_5POINT1POINT4 ?
345 ret = AudioChannelLayout::CH_7POINT1POINT2;
346 break;
347 }
348 case 12: { // 12: CH_7POINT1POINT4 or CH_10POINT2 ?
349 ret = AudioChannelLayout::CH_7POINT1POINT4;
350 break;
351 }
352 case 14: { // 14: CH_9POINT1POINT4
353 ret = AudioChannelLayout::CH_9POINT1POINT4;
354 break;
355 }
356 case 16: { // 16: CH_9POINT1POINT6
357 ret = AudioChannelLayout::CH_9POINT1POINT6;
358 break;
359 }
360 case 24: { // 24: CH_22POINT2
361 ret = AudioChannelLayout::CH_22POINT2;
362 break;
363 }
364 default: {
365 ret = AudioChannelLayout::UNKNOWN;
366 break;
367 }
368 }
369 return ret;
370 }
371
ConvertChannelLayoutFromFFmpeg(int channels,uint64_t ffChannelLayout)372 AudioChannelLayout ConvertChannelLayoutFromFFmpeg(int channels, uint64_t ffChannelLayout)
373 {
374 uint64_t channelLayout = 0;
375 uint64_t mask;
376 for (uint8_t bitPos = 0, channelNum = 0; (bitPos < 64) && (channelNum < channels); ++bitPos) { // 64
377 mask = 1ULL << bitPos;
378 if (!(mask & ffChannelLayout)) {
379 continue;
380 }
381 channelNum++;
382 auto it = g_fromFFMPEGChannelLayout.find(mask);
383 if (it != g_fromFFMPEGChannelLayout.end()) {
384 channelLayout |= static_cast<uint64_t>(it->second);
385 } else {
386 MEDIA_LOG_W("unsupported audio channel layout: " PUBLIC_LOG_U64, mask);
387 }
388 }
389 auto ret = static_cast<AudioChannelLayout>(channelLayout);
390 if (ffChannelLayout == 0) {
391 ret = GetDefaultChannelLayout(channels);
392 }
393 return ret;
394 }
395
ConvertChannelLayoutToFFmpeg(AudioChannelLayout channelLayout)396 uint64_t ConvertChannelLayoutToFFmpeg(AudioChannelLayout channelLayout)
397 {
398 auto it = g_toFFMPEGChannelLayout.find(channelLayout);
399 if (it == g_toFFMPEGChannelLayout.end()) {
400 MEDIA_LOG_E("ConvertChannelLayoutToFFmpeg: unknown audio channel layout: " PUBLIC_LOG_U64, channelLayout);
401 return 0;
402 }
403 return it->second;
404 }
405
FindAvMetaNameByTag(Tag tag,std::string & metaName)406 bool FindAvMetaNameByTag(Tag tag, std::string& metaName)
407 {
408 for (const auto& pair : g_tagMap) {
409 if (pair.second == tag) {
410 metaName = pair.first;
411 return true;
412 }
413 }
414 return false;
415 }
416
InsertMediaTag(Meta & meta,AVDictionaryEntry * tag)417 void InsertMediaTag(Meta& meta, AVDictionaryEntry* tag)
418 {
419 for (auto e : g_MediaMap) {
420 if (e.first == tag->key) {
421 e.second(meta, tag);
422 return;
423 }
424 }
425 }
426
ConvAacProfileFromFfmpeg(int32_t ffmpegProfile)427 AudioAacProfile ConvAacProfileFromFfmpeg(int32_t ffmpegProfile)
428 {
429 auto ite = std::find_if(g_AacProfileMap.begin(), g_AacProfileMap.end(),
430 [&] (const std::pair<AudioAacProfile, int32_t>& tmp) -> bool {
431 return tmp.second == ffmpegProfile;
432 });
433 return ite == g_AacProfileMap.end() ? AudioAacProfile::NONE : ite->first;
434 }
435
ConvAacProfileToFfmpeg(AudioAacProfile profile)436 int32_t ConvAacProfileToFfmpeg(AudioAacProfile profile)
437 {
438 auto ite = std::find_if(g_AacProfileMap.begin(), g_AacProfileMap.end(),
439 [&] (const std::pair<AudioAacProfile, int32_t>& tmp) -> bool {
440 return tmp.first == profile;
441 });
442 return ite == g_AacProfileMap.end() ? FF_PROFILE_UNKNOWN : ite->second;
443 }
444
ConvertPixelFormatFromFFmpeg(int32_t ffmpegPixelFormat)445 VideoPixelFormat ConvertPixelFormatFromFFmpeg(int32_t ffmpegPixelFormat)
446 {
447 auto iter = std::find_if(g_pixelFormatMap.begin(), g_pixelFormatMap.end(),
448 [&] (const std::pair<VideoPixelFormat, AVPixelFormat>& tmp) -> bool {
449 return tmp.second == ffmpegPixelFormat;
450 });
451 return iter == g_pixelFormatMap.end() ? VideoPixelFormat::UNKNOWN : iter->first;
452 }
453
ConvertPixelFormatToFFmpeg(VideoPixelFormat pixelFormat)454 AVPixelFormat ConvertPixelFormatToFFmpeg(VideoPixelFormat pixelFormat)
455 {
456 auto iter = std::find_if(g_pixelFormatMap.begin(), g_pixelFormatMap.end(),
457 [&] (const std::pair<VideoPixelFormat, AVPixelFormat>& tmp) -> bool {
458 return tmp.first == pixelFormat;
459 });
460 return iter == g_pixelFormatMap.end() ? AV_PIX_FMT_NONE : iter->second;
461 }
462
IsYuvFormat(AVPixelFormat format)463 bool IsYuvFormat(AVPixelFormat format)
464 {
465 return (format == AV_PIX_FMT_YUV420P || format == AV_PIX_FMT_NV12 || format == AV_PIX_FMT_NV21 ||
466 format == AV_PIX_FMT_YUYV422 || format == AV_PIX_FMT_YUV422P || format == AV_PIX_FMT_YUV444P ||
467 format == AV_PIX_FMT_YUV410P || format == AV_PIX_FMT_YUV411P || format == AV_PIX_FMT_YUVJ420P ||
468 format == AV_PIX_FMT_YUVJ422P || format == AV_PIX_FMT_YUVJ444P);
469 }
470
IsRgbFormat(AVPixelFormat format)471 bool IsRgbFormat(AVPixelFormat format)
472 {
473 return (format == AV_PIX_FMT_ABGR || format == AV_PIX_FMT_ARGB || format == AV_PIX_FMT_RGBA ||
474 format == AV_PIX_FMT_BGRA || format == AV_PIX_FMT_RGB24 || format == AV_PIX_FMT_BGR24);
475 }
476
ConvH264ProfileFromFfmpeg(int32_t ffmpegProfile)477 VideoH264Profile ConvH264ProfileFromFfmpeg(int32_t ffmpegProfile)
478 {
479 auto iter = std::find_if(g_H264ProfileMap.begin(), g_H264ProfileMap.end(),
480 [&] (const std::pair<VideoH264Profile, int32_t>& tmp) -> bool {
481 return tmp.second == ffmpegProfile;
482 });
483 return (iter == g_H264ProfileMap.end()) ? VideoH264Profile::UNKNOWN : iter->first;
484 }
485
ConvH264ProfileToFfmpeg(VideoH264Profile profile)486 int32_t ConvH264ProfileToFfmpeg(VideoH264Profile profile)
487 {
488 auto iter = std::find_if(g_H264ProfileMap.begin(), g_H264ProfileMap.end(),
489 [&] (const std::pair<VideoH264Profile, int32_t>& tmp) -> bool {
490 return tmp.first == profile;
491 });
492 return (iter == g_H264ProfileMap.end()) ? FF_PROFILE_UNKNOWN : iter->second;
493 }
494 } // namespace Ffmpeg
495 } // namespace Plugin
496 } // namespace Media
497 } // namespace OHOS
498