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