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 #include <vector>
16 #include "avcodec_log.h"
17 #include "ffmpeg_converter.h"
18 namespace {
19     constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_AUDIO, "FFmpegConverter"};
20     constexpr int US_PER_SECOND = 1000000;
21 }
22 namespace OHOS {
23 namespace MediaAVCodec {
24 // ffmpeg channel layout to histreamer channel layout
25 const std::vector<std::pair<AudioChannelLayout, uint64_t>> g_toFFMPEGChannelLayout = {
26     {AudioChannelLayout::MONO, AV_CH_LAYOUT_MONO},
27     {AudioChannelLayout::STEREO, AV_CH_LAYOUT_STEREO},
28     {AudioChannelLayout::CH_2POINT1, AV_CH_LAYOUT_2POINT1},
29     {AudioChannelLayout::CH_2_1, AV_CH_LAYOUT_2_1},
30     {AudioChannelLayout::SURROUND, AV_CH_LAYOUT_SURROUND},
31     {AudioChannelLayout::CH_3POINT1, AV_CH_LAYOUT_3POINT1},
32     {AudioChannelLayout::CH_4POINT0, AV_CH_LAYOUT_4POINT0},
33     {AudioChannelLayout::CH_4POINT1, AV_CH_LAYOUT_4POINT1},
34     {AudioChannelLayout::CH_2_2, AV_CH_LAYOUT_2_2},
35     {AudioChannelLayout::QUAD, AV_CH_LAYOUT_QUAD},
36     {AudioChannelLayout::CH_5POINT0, AV_CH_LAYOUT_5POINT0},
37     {AudioChannelLayout::CH_5POINT1, AV_CH_LAYOUT_5POINT1},
38     {AudioChannelLayout::CH_5POINT0_BACK, AV_CH_LAYOUT_5POINT0_BACK},
39     {AudioChannelLayout::CH_5POINT1_BACK, AV_CH_LAYOUT_5POINT1_BACK},
40     {AudioChannelLayout::CH_6POINT0, AV_CH_LAYOUT_6POINT0},
41     {AudioChannelLayout::CH_6POINT0_FRONT, AV_CH_LAYOUT_6POINT0_FRONT},
42     {AudioChannelLayout::HEXAGONAL, AV_CH_LAYOUT_HEXAGONAL},
43     {AudioChannelLayout::CH_6POINT1, AV_CH_LAYOUT_6POINT1},
44     {AudioChannelLayout::CH_6POINT1_BACK, AV_CH_LAYOUT_6POINT1_BACK},
45     {AudioChannelLayout::CH_6POINT1_FRONT, AV_CH_LAYOUT_6POINT1_FRONT},
46     {AudioChannelLayout::CH_7POINT0, AV_CH_LAYOUT_7POINT0},
47     {AudioChannelLayout::CH_7POINT0_FRONT, AV_CH_LAYOUT_7POINT0_FRONT},
48     {AudioChannelLayout::CH_7POINT1, AV_CH_LAYOUT_7POINT1},
49     {AudioChannelLayout::CH_7POINT1_WIDE, AV_CH_LAYOUT_7POINT1_WIDE},
50     {AudioChannelLayout::CH_7POINT1_WIDE_BACK, AV_CH_LAYOUT_7POINT1_WIDE_BACK},
51     {AudioChannelLayout::OCTAGONAL, AV_CH_LAYOUT_OCTAGONAL},
52     {AudioChannelLayout::HEXADECAGONAL, AV_CH_LAYOUT_HEXADECAGONAL},
53     {AudioChannelLayout::STEREO_DOWNMIX, AV_CH_LAYOUT_STEREO_DOWNMIX},
54 };
55 
56 const std::vector<std::pair<AVSampleFormat, AudioSampleFormat>> g_pFfSampleFmtMap = {
57     {AVSampleFormat::AV_SAMPLE_FMT_U8, AudioSampleFormat::SAMPLE_U8},
58     {AVSampleFormat::AV_SAMPLE_FMT_S16, AudioSampleFormat::SAMPLE_S16LE},
59     {AVSampleFormat::AV_SAMPLE_FMT_S32, AudioSampleFormat::SAMPLE_S32LE},
60     {AVSampleFormat::AV_SAMPLE_FMT_FLT, AudioSampleFormat::SAMPLE_F32LE},
61     {AVSampleFormat::AV_SAMPLE_FMT_U8P, AudioSampleFormat::SAMPLE_U8P},
62     {AVSampleFormat::AV_SAMPLE_FMT_S16P, AudioSampleFormat::SAMPLE_S16P},
63     {AVSampleFormat::AV_SAMPLE_FMT_S32P, AudioSampleFormat::SAMPLE_S32P},
64     {AVSampleFormat::AV_SAMPLE_FMT_FLTP, AudioSampleFormat::SAMPLE_F32P},
65 };
66 
67 // align with player framework capability.
68 const std::vector<std::pair<AVCodecID, AudioSampleFormat>> g_pFfCodeIDToSampleFmtMap = {
69     {AVCodecID::AV_CODEC_ID_PCM_U8, AudioSampleFormat::SAMPLE_U8},
70     {AVCodecID::AV_CODEC_ID_PCM_S16LE, AudioSampleFormat::SAMPLE_S16LE},
71     {AVCodecID::AV_CODEC_ID_PCM_S24LE, AudioSampleFormat::SAMPLE_S24LE},
72     {AVCodecID::AV_CODEC_ID_PCM_S32LE, AudioSampleFormat::SAMPLE_S32LE},
73     {AVCodecID::AV_CODEC_ID_PCM_F32LE, AudioSampleFormat::SAMPLE_F32LE},
74 };
75 
76 const std::vector<std::pair<AudioChannelLayout, std::string_view>> g_ChannelLayoutToString = {
77     {AudioChannelLayout::UNKNOWN_CHANNEL_LAYOUT, "UNKNOW"},
78     {AudioChannelLayout::MONO, "MONO"},
79     {AudioChannelLayout::STEREO, "STEREO"},
80     {AudioChannelLayout::CH_2POINT1, "2POINT1"},
81     {AudioChannelLayout::CH_2_1, "CH_2_1"},
82     {AudioChannelLayout::SURROUND, "SURROUND"},
83     {AudioChannelLayout::CH_3POINT1, "3POINT1"},
84     {AudioChannelLayout::CH_4POINT0, "4POINT0"},
85     {AudioChannelLayout::CH_4POINT1, "4POINT1"},
86     {AudioChannelLayout::CH_2_2, "CH_2_2"},
87     {AudioChannelLayout::QUAD, "QUAD"},
88     {AudioChannelLayout::CH_5POINT0, "5POINT0"},
89     {AudioChannelLayout::CH_5POINT1, "5POINT1"},
90     {AudioChannelLayout::CH_5POINT0_BACK, "5POINT0_BACK"},
91     {AudioChannelLayout::CH_5POINT1_BACK, "5POINT1_BACK"},
92     {AudioChannelLayout::CH_6POINT0, "6POINT0"},
93     {AudioChannelLayout::CH_6POINT0_FRONT, "6POINT0_FRONT"},
94     {AudioChannelLayout::HEXAGONAL, "HEXAGONAL"},
95     {AudioChannelLayout::CH_6POINT1, "6POINT1"},
96     {AudioChannelLayout::CH_6POINT1_BACK, "6POINT1_BACK"},
97     {AudioChannelLayout::CH_6POINT1_FRONT, "6POINT1_FRONT"},
98     {AudioChannelLayout::CH_7POINT0, "7POINT0"},
99     {AudioChannelLayout::CH_7POINT0_FRONT, "7POINT0_FRONT"},
100     {AudioChannelLayout::CH_7POINT1, "7POINT1"},
101     {AudioChannelLayout::CH_7POINT1_WIDE, "7POINT1_WIDE"},
102     {AudioChannelLayout::CH_7POINT1_WIDE_BACK, "7POINT1_WIDE_BACK"},
103     {AudioChannelLayout::CH_3POINT1POINT2, "CH_3POINT1POINT2"},
104     {AudioChannelLayout::CH_5POINT1POINT2, "CH_5POINT1POINT2"},
105     {AudioChannelLayout::CH_5POINT1POINT4, "CH_5POINT1POINT4"},
106     {AudioChannelLayout::CH_7POINT1POINT2, "CH_7POINT1POINT2"},
107     {AudioChannelLayout::CH_7POINT1POINT4, "CH_7POINT1POINT4"},
108     {AudioChannelLayout::CH_9POINT1POINT4, "CH_9POINT1POINT4"},
109     {AudioChannelLayout::CH_9POINT1POINT6, "CH_9POINT1POINT6"},
110     {AudioChannelLayout::CH_10POINT2, "CH_10POINT2"},
111     {AudioChannelLayout::CH_22POINT2, "CH_22POINT2"},
112     {AudioChannelLayout::OCTAGONAL, "OCTAGONAL"},
113     {AudioChannelLayout::HEXADECAGONAL, "HEXADECAGONAL"},
114     {AudioChannelLayout::STEREO_DOWNMIX, "STEREO_DOWNMIX"},
115     {AudioChannelLayout::HOA_FIRST, "HOA_FIRST"},
116     {AudioChannelLayout::HOA_SECOND, "HOA_SECOND"},
117     {AudioChannelLayout::HOA_THIRD, "HOA_THIRD"},
118 };
119 
120 const std::vector<std::pair<AVColorPrimaries, ColorPrimary>> g_pFfColorPrimariesMap = {
121     {AVColorPrimaries::AVCOL_PRI_BT709, ColorPrimary::COLOR_PRIMARY_BT709},
122     {AVColorPrimaries::AVCOL_PRI_UNSPECIFIED, ColorPrimary::COLOR_PRIMARY_UNSPECIFIED},
123     {AVColorPrimaries::AVCOL_PRI_BT470M, ColorPrimary::COLOR_PRIMARY_BT470_M},
124     {AVColorPrimaries::AVCOL_PRI_BT470BG, ColorPrimary::COLOR_PRIMARY_BT601_625},
125     {AVColorPrimaries::AVCOL_PRI_SMPTE170M, ColorPrimary::COLOR_PRIMARY_BT601_525},
126     {AVColorPrimaries::AVCOL_PRI_SMPTE240M, ColorPrimary::COLOR_PRIMARY_SMPTE_ST240},
127     {AVColorPrimaries::AVCOL_PRI_FILM, ColorPrimary::COLOR_PRIMARY_GENERIC_FILM},
128     {AVColorPrimaries::AVCOL_PRI_BT2020, ColorPrimary::COLOR_PRIMARY_BT2020},
129     {AVColorPrimaries::AVCOL_PRI_SMPTE428, ColorPrimary::COLOR_PRIMARY_SMPTE_ST428},
130     {AVColorPrimaries::AVCOL_PRI_SMPTEST428_1, ColorPrimary::COLOR_PRIMARY_SMPTE_ST428},
131     {AVColorPrimaries::AVCOL_PRI_SMPTE431, ColorPrimary::COLOR_PRIMARY_P3DCI},
132     {AVColorPrimaries::AVCOL_PRI_SMPTE432, ColorPrimary::COLOR_PRIMARY_P3D65},
133 };
134 
135 const std::vector<std::pair<AVColorTransferCharacteristic, TransferCharacteristic>> g_pFfTransferCharacteristicMap = {
136     {AVColorTransferCharacteristic::AVCOL_TRC_BT709, TransferCharacteristic::TRANSFER_CHARACTERISTIC_BT709},
137     {AVColorTransferCharacteristic::AVCOL_TRC_UNSPECIFIED, TransferCharacteristic::TRANSFER_CHARACTERISTIC_UNSPECIFIED},
138     {AVColorTransferCharacteristic::AVCOL_TRC_GAMMA22, TransferCharacteristic::TRANSFER_CHARACTERISTIC_GAMMA_2_2},
139     {AVColorTransferCharacteristic::AVCOL_TRC_GAMMA28, TransferCharacteristic::TRANSFER_CHARACTERISTIC_GAMMA_2_8},
140     {AVColorTransferCharacteristic::AVCOL_TRC_SMPTE170M, TransferCharacteristic::TRANSFER_CHARACTERISTIC_BT601},
141     {AVColorTransferCharacteristic::AVCOL_TRC_SMPTE240M, TransferCharacteristic::TRANSFER_CHARACTERISTIC_SMPTE_ST240},
142     {AVColorTransferCharacteristic::AVCOL_TRC_LINEAR, TransferCharacteristic::TRANSFER_CHARACTERISTIC_LINEAR},
143     {AVColorTransferCharacteristic::AVCOL_TRC_LOG, TransferCharacteristic::TRANSFER_CHARACTERISTIC_LOG},
144     {AVColorTransferCharacteristic::AVCOL_TRC_LOG_SQRT, TransferCharacteristic::TRANSFER_CHARACTERISTIC_LOG_SQRT},
145     {AVColorTransferCharacteristic::AVCOL_TRC_IEC61966_2_4,
146         TransferCharacteristic::TRANSFER_CHARACTERISTIC_IEC_61966_2_4},
147     {AVColorTransferCharacteristic::AVCOL_TRC_BT1361_ECG, TransferCharacteristic::TRANSFER_CHARACTERISTIC_BT1361},
148     {AVColorTransferCharacteristic::AVCOL_TRC_IEC61966_2_1,
149         TransferCharacteristic::TRANSFER_CHARACTERISTIC_IEC_61966_2_1},
150     {AVColorTransferCharacteristic::AVCOL_TRC_BT2020_10, TransferCharacteristic::TRANSFER_CHARACTERISTIC_BT2020_10BIT},
151     {AVColorTransferCharacteristic::AVCOL_TRC_BT2020_12, TransferCharacteristic::TRANSFER_CHARACTERISTIC_BT2020_12BIT},
152     {AVColorTransferCharacteristic::AVCOL_TRC_SMPTE2084, TransferCharacteristic::TRANSFER_CHARACTERISTIC_PQ},
153     {AVColorTransferCharacteristic::AVCOL_TRC_SMPTEST2084, TransferCharacteristic::TRANSFER_CHARACTERISTIC_PQ},
154     {AVColorTransferCharacteristic::AVCOL_TRC_SMPTE428, TransferCharacteristic::TRANSFER_CHARACTERISTIC_SMPTE_ST428},
155     {AVColorTransferCharacteristic::AVCOL_TRC_SMPTEST428_1,
156         TransferCharacteristic::TRANSFER_CHARACTERISTIC_SMPTE_ST428},
157     {AVColorTransferCharacteristic::AVCOL_TRC_ARIB_STD_B67, TransferCharacteristic::TRANSFER_CHARACTERISTIC_HLG},
158 };
159 
160 const std::vector<std::pair<AVColorSpace, MatrixCoefficient>> g_pFfMatrixCoefficientMap = {
161     {AVColorSpace::AVCOL_SPC_RGB, MatrixCoefficient::MATRIX_COEFFICIENT_IDENTITY},
162     {AVColorSpace::AVCOL_SPC_BT709, MatrixCoefficient::MATRIX_COEFFICIENT_BT709},
163     {AVColorSpace::AVCOL_SPC_UNSPECIFIED, MatrixCoefficient::MATRIX_COEFFICIENT_UNSPECIFIED},
164     {AVColorSpace::AVCOL_SPC_FCC, MatrixCoefficient::MATRIX_COEFFICIENT_FCC},
165     {AVColorSpace::AVCOL_SPC_BT470BG, MatrixCoefficient::MATRIX_COEFFICIENT_BT601_625},
166     {AVColorSpace::AVCOL_SPC_SMPTE170M, MatrixCoefficient::MATRIX_COEFFICIENT_BT601_525},
167     {AVColorSpace::AVCOL_SPC_SMPTE240M, MatrixCoefficient::MATRIX_COEFFICIENT_SMPTE_ST240},
168     {AVColorSpace::AVCOL_SPC_YCGCO, MatrixCoefficient::MATRIX_COEFFICIENT_YCGCO},
169     {AVColorSpace::AVCOL_SPC_YCOCG, MatrixCoefficient::MATRIX_COEFFICIENT_YCGCO},
170     {AVColorSpace::AVCOL_SPC_BT2020_NCL, MatrixCoefficient::MATRIX_COEFFICIENT_BT2020_NCL},
171     {AVColorSpace::AVCOL_SPC_BT2020_CL, MatrixCoefficient::MATRIX_COEFFICIENT_BT2020_CL },
172     {AVColorSpace::AVCOL_SPC_SMPTE2085, MatrixCoefficient::MATRIX_COEFFICIENT_SMPTE_ST2085 },
173     {AVColorSpace::AVCOL_SPC_CHROMA_DERIVED_NCL, MatrixCoefficient::MATRIX_COEFFICIENT_CHROMATICITY_NCL },
174     {AVColorSpace::AVCOL_SPC_CHROMA_DERIVED_CL, MatrixCoefficient::MATRIX_COEFFICIENT_CHROMATICITY_CL },
175     {AVColorSpace::AVCOL_SPC_ICTCP, MatrixCoefficient::MATRIX_COEFFICIENT_ICTCP },
176 };
177 
178 const std::vector<std::pair<AVColorRange, int>> g_pFfColorRangeMap = {
179     {AVColorRange::AVCOL_RANGE_MPEG, 0},
180     {AVColorRange::AVCOL_RANGE_JPEG, 1},
181 };
182 
183 const std::vector<std::pair<AVChromaLocation, ChromaLocation>> g_pFfChromaLocationMap = {
184     {AVChromaLocation::AVCHROMA_LOC_UNSPECIFIED, ChromaLocation::CHROMA_LOC_UNSPECIFIED},
185     {AVChromaLocation::AVCHROMA_LOC_LEFT, ChromaLocation::CHROMA_LOC_LEFT},
186     {AVChromaLocation::AVCHROMA_LOC_CENTER, ChromaLocation::CHROMA_LOC_CENTER},
187     {AVChromaLocation::AVCHROMA_LOC_TOPLEFT, ChromaLocation::CHROMA_LOC_TOPLEFT},
188     {AVChromaLocation::AVCHROMA_LOC_TOP, ChromaLocation::CHROMA_LOC_TOP},
189     {AVChromaLocation::AVCHROMA_LOC_BOTTOMLEFT, ChromaLocation::CHROMA_LOC_BOTTOMLEFT},
190     {AVChromaLocation::AVCHROMA_LOC_BOTTOM, ChromaLocation::CHROMA_LOC_BOTTOM},
191 };
192 
193 const std::vector<std::pair<int, HEVCProfile>> g_pFfHEVCProfileMap = {
194     {FF_PROFILE_HEVC_MAIN, HEVCProfile::HEVC_PROFILE_MAIN},
195     {FF_PROFILE_HEVC_MAIN_10, HEVCProfile::HEVC_PROFILE_MAIN_10},
196     {FF_PROFILE_HEVC_MAIN_STILL_PICTURE, HEVCProfile::HEVC_PROFILE_MAIN_STILL},
197 };
198 
199 const std::vector<std::pair<int, HEVCLevel>> g_pFfHEVCLevelMap = {
200     {30, HEVCLevel::HEVC_LEVEL_1},
201     {60, HEVCLevel::HEVC_LEVEL_2},
202     {63, HEVCLevel::HEVC_LEVEL_21},
203     {90, HEVCLevel::HEVC_LEVEL_3},
204     {93, HEVCLevel::HEVC_LEVEL_31},
205     {120, HEVCLevel::HEVC_LEVEL_4},
206     {123, HEVCLevel::HEVC_LEVEL_41},
207     {150, HEVCLevel::HEVC_LEVEL_5},
208     {153, HEVCLevel::HEVC_LEVEL_51},
209     {156, HEVCLevel::HEVC_LEVEL_52},
210     {180, HEVCLevel::HEVC_LEVEL_6},
211     {183, HEVCLevel::HEVC_LEVEL_61},
212     {186, HEVCLevel::HEVC_LEVEL_62},
213 };
214 
ConvertFFMpegToOHHEVCLevel(int ffHEVCLevel)215 HEVCLevel FFMpegConverter::ConvertFFMpegToOHHEVCLevel(int ffHEVCLevel)
216 {
217     auto ite = std::find_if(g_pFfHEVCLevelMap.begin(), g_pFfHEVCLevelMap.end(),
218                             [&ffHEVCLevel](const auto &item) -> bool { return item.first == ffHEVCLevel; });
219     if (ite == g_pFfHEVCLevelMap.end()) {
220         AVCODEC_LOGW("Convert hevc level failed: %{public}d", ffHEVCLevel);
221         return HEVCLevel::HEVC_LEVEL_UNKNOW;
222     }
223     return ite->second;
224 }
225 
ConvertFFMpegToOHHEVCProfile(int ffHEVCProfile)226 HEVCProfile FFMpegConverter::ConvertFFMpegToOHHEVCProfile(int ffHEVCProfile)
227 {
228     auto ite = std::find_if(g_pFfHEVCProfileMap.begin(), g_pFfHEVCProfileMap.end(),
229                             [&ffHEVCProfile](const auto &item) -> bool { return item.first == ffHEVCProfile; });
230     if (ite == g_pFfHEVCProfileMap.end()) {
231         AVCODEC_LOGW("Convert hevc profile failed: %{public}d", ffHEVCProfile);
232         return HEVCProfile::HEVC_PROFILE_UNKNOW;
233     }
234     return ite->second;
235 }
236 
ConvertFFMpegToOHColorPrimaries(AVColorPrimaries ffColorPrimaries)237 ColorPrimary FFMpegConverter::ConvertFFMpegToOHColorPrimaries(AVColorPrimaries ffColorPrimaries)
238 {
239     auto ite = std::find_if(g_pFfColorPrimariesMap.begin(), g_pFfColorPrimariesMap.end(),
240                             [&ffColorPrimaries](const auto &item) -> bool { return item.first == ffColorPrimaries; });
241     if (ite == g_pFfColorPrimariesMap.end()) {
242         AVCODEC_LOGW("Convert color primaries failed: %{public}d", static_cast<int32_t>(ffColorPrimaries));
243         return ColorPrimary::COLOR_PRIMARY_UNSPECIFIED;
244     }
245     return ite->second;
246 }
247 
ConvertFFMpegToOHColorTrans(AVColorTransferCharacteristic ffColorTrans)248 TransferCharacteristic FFMpegConverter::ConvertFFMpegToOHColorTrans(AVColorTransferCharacteristic ffColorTrans)
249 {
250     auto ite = std::find_if(g_pFfTransferCharacteristicMap.begin(), g_pFfTransferCharacteristicMap.end(),
251                             [&ffColorTrans](const auto &item) -> bool { return item.first == ffColorTrans; });
252     if (ite == g_pFfTransferCharacteristicMap.end()) {
253         AVCODEC_LOGW("Convert color trans failed: %{public}d", static_cast<int32_t>(ffColorTrans));
254         return TransferCharacteristic::TRANSFER_CHARACTERISTIC_UNSPECIFIED;
255     }
256     return ite->second;
257 }
258 
ConvertFFMpegToOHColorMatrix(AVColorSpace ffColorSpace)259 MatrixCoefficient FFMpegConverter::ConvertFFMpegToOHColorMatrix(AVColorSpace ffColorSpace)
260 {
261     auto ite = std::find_if(g_pFfMatrixCoefficientMap.begin(), g_pFfMatrixCoefficientMap.end(),
262                             [&ffColorSpace](const auto &item) -> bool { return item.first == ffColorSpace; });
263     if (ite == g_pFfMatrixCoefficientMap.end()) {
264         AVCODEC_LOGW("Convert color matrix failed: %{public}d", static_cast<int32_t>(ffColorSpace));
265         return MatrixCoefficient::MATRIX_COEFFICIENT_UNSPECIFIED;
266     }
267     return ite->second;
268 }
269 
ConvertFFMpegToOHColorRange(AVColorRange ffColorRange)270 int FFMpegConverter::ConvertFFMpegToOHColorRange(AVColorRange ffColorRange)
271 {
272     auto ite = std::find_if(g_pFfColorRangeMap.begin(), g_pFfColorRangeMap.end(),
273                             [&ffColorRange](const auto &item) -> bool { return item.first == ffColorRange; });
274     if (ite == g_pFfColorRangeMap.end()) {
275         AVCODEC_LOGW("Convert color range failed: %{public}d", static_cast<int32_t>(ffColorRange));
276         return 0;
277     }
278     return ite->second;
279 }
280 
ConvertFFMpegToOHChromaLocation(AVChromaLocation ffChromaLocation)281 ChromaLocation FFMpegConverter::ConvertFFMpegToOHChromaLocation(AVChromaLocation ffChromaLocation)
282 {
283     auto ite = std::find_if(g_pFfChromaLocationMap.begin(), g_pFfChromaLocationMap.end(),
284                             [&ffChromaLocation](const auto &item) -> bool { return item.first == ffChromaLocation; });
285     if (ite == g_pFfChromaLocationMap.end()) {
286         AVCODEC_LOGW("Convert chroma location failed: %{public}d", static_cast<int32_t>(ffChromaLocation));
287         return ChromaLocation::CHROMA_LOC_UNSPECIFIED;
288     }
289     return ite->second;
290 }
291 
ConvertFFMpegAVCodecIdToOHAudioFormat(AVCodecID codecId)292 AudioSampleFormat FFMpegConverter::ConvertFFMpegAVCodecIdToOHAudioFormat(AVCodecID codecId)
293 {
294     auto ite = std::find_if(g_pFfCodeIDToSampleFmtMap.begin(), g_pFfCodeIDToSampleFmtMap.end(),
295                             [&codecId](const auto &item) -> bool { return item.first == codecId; });
296     if (ite == g_pFfCodeIDToSampleFmtMap.end()) {
297         AVCODEC_LOGW("Convert codec id failed: %{public}d", static_cast<int32_t>(codecId));
298         return AudioSampleFormat::INVALID_WIDTH;
299     }
300     return ite->second;
301 }
302 
ConvertFFMpegToOHAudioFormat(AVSampleFormat ffSampleFormat)303 AudioSampleFormat FFMpegConverter::ConvertFFMpegToOHAudioFormat(AVSampleFormat ffSampleFormat)
304 {
305     auto ite = std::find_if(g_pFfSampleFmtMap.begin(), g_pFfSampleFmtMap.end(),
306                             [&ffSampleFormat](const auto &item) -> bool { return item.first == ffSampleFormat; });
307     if (ite == g_pFfSampleFmtMap.end()) {
308         AVCODEC_LOGW("Convert sample format failed: %{public}d", static_cast<int32_t>(ffSampleFormat));
309         return AudioSampleFormat::INVALID_WIDTH;
310     }
311     return ite->second;
312 }
313 
ConvertOHAudioFormatToFFMpeg(AudioSampleFormat sampleFormat)314 AVSampleFormat FFMpegConverter::ConvertOHAudioFormatToFFMpeg(AudioSampleFormat sampleFormat)
315 {
316     auto ite = std::find_if(g_pFfSampleFmtMap.begin(), g_pFfSampleFmtMap.end(),
317                             [&sampleFormat](const auto &item) -> bool { return item.second == sampleFormat; });
318     if (ite == g_pFfSampleFmtMap.end()) {
319         AVCODEC_LOGW("Convert sample format failed: %{public}d", static_cast<int32_t>(sampleFormat));
320         return AVSampleFormat::AV_SAMPLE_FMT_NONE;
321     }
322     return ite->first;
323 }
324 
ConvertFFToOHAudioChannelLayout(uint64_t ffChannelLayout)325 AudioChannelLayout FFMpegConverter::ConvertFFToOHAudioChannelLayout(uint64_t ffChannelLayout)
326 {
327     auto ite = std::find_if(g_toFFMPEGChannelLayout.begin(), g_toFFMPEGChannelLayout.end(),
328                             [&ffChannelLayout](const auto &item) -> bool { return item.second == ffChannelLayout; });
329     if (ite == g_toFFMPEGChannelLayout.end()) {
330         AVCODEC_LOGW("Convert channel layout failed: %{public}" PRIu64, ffChannelLayout);
331         return AudioChannelLayout::MONO;
332     }
333     return ite->first;
334 }
335 
GetDefaultChannelLayout(int channels)336 AudioChannelLayout FFMpegConverter::GetDefaultChannelLayout(int channels)
337 {
338     AudioChannelLayout ret;
339     switch (channels) {
340         case 2: { // 2: STEREO
341             ret = AudioChannelLayout::STEREO;
342             break;
343         }
344         case 4: { // 4: CH_4POINT0
345             ret = AudioChannelLayout::CH_4POINT0;
346             break;
347         }
348         case 6: { // 6: CH_5POINT1
349             ret = AudioChannelLayout::CH_5POINT1;
350             break;
351         }
352         case 8: { // 8: CH_5POINT1POINT2
353             ret = AudioChannelLayout::CH_5POINT1POINT2;
354             break;
355         }
356         case 10: { // 10: CH_7POINT1POINT2 or CH_5POINT1POINT4 ?
357             ret = AudioChannelLayout::CH_7POINT1POINT2;
358             break;
359         }
360         case 12: { // 12: CH_7POINT1POINT4
361             ret = AudioChannelLayout::CH_7POINT1POINT4;
362             break;
363         }
364         case 14: { // 14: CH_9POINT1POINT4
365             ret = AudioChannelLayout::CH_9POINT1POINT4;
366             break;
367         }
368         case 16: { // 16: CH_9POINT1POINT6
369             ret = AudioChannelLayout::CH_9POINT1POINT6;
370             break;
371         }
372         case 24: { // 24: CH_22POINT2
373             ret = AudioChannelLayout::CH_22POINT2;
374             break;
375         }
376         default: {
377             ret = AudioChannelLayout::MONO;
378             break;
379         }
380     }
381     AVCODEC_LOGW("Get default channel layout: %{public}s", ConvertOHAudioChannelLayoutToString(ret).data());
382     return ret;
383 }
384 
ConvertFFToOHAudioChannelLayoutV2(uint64_t ffChannelLayout,int channels)385 AudioChannelLayout FFMpegConverter::ConvertFFToOHAudioChannelLayoutV2(uint64_t ffChannelLayout, int channels)
386 {
387     auto ite = std::find_if(g_toFFMPEGChannelLayout.begin(), g_toFFMPEGChannelLayout.end(),
388                             [&ffChannelLayout](const auto &item) -> bool { return item.second == ffChannelLayout; });
389     if (ite == g_toFFMPEGChannelLayout.end()) {
390         AVCODEC_LOGW("Convert channel layout failed: %{public}" PRIu64, ffChannelLayout);
391         return GetDefaultChannelLayout(channels);
392     }
393     return ite->first;
394 }
395 
ConvertOHAudioChannelLayoutToFFMpeg(AudioChannelLayout channelLayout)396 uint64_t FFMpegConverter::ConvertOHAudioChannelLayoutToFFMpeg(AudioChannelLayout channelLayout)
397 {
398     auto ite = std::find_if(g_toFFMPEGChannelLayout.begin(), g_toFFMPEGChannelLayout.end(),
399                             [&channelLayout](const auto &item) -> bool { return item.first == channelLayout; });
400     if (ite == g_toFFMPEGChannelLayout.end()) {
401         AVCODEC_LOGW("Convert channel layout failed: %{public}d", static_cast<int32_t>(channelLayout));
402         return AV_CH_LAYOUT_NATIVE;
403     }
404     return ite->second;
405 }
406 
ConvertOHAudioChannelLayoutToString(AudioChannelLayout layout)407 std::string_view FFMpegConverter::ConvertOHAudioChannelLayoutToString(AudioChannelLayout layout)
408 {
409     auto ite = std::find_if(g_ChannelLayoutToString.begin(), g_ChannelLayoutToString.end(),
410                             [&layout](const auto &item) -> bool { return item.first == layout; });
411     if (ite == g_ChannelLayoutToString.end()) {
412         AVCODEC_LOGW("Convert channel layout failed: %{public}d", static_cast<int32_t>(layout));
413         return g_ChannelLayoutToString[0].second;
414     }
415     return ite->second;
416 }
417 
ConvertAudioPtsToUs(int64_t pts,AVRational base)418 int64_t FFMpegConverter::ConvertAudioPtsToUs(int64_t pts, AVRational base)
419 {
420     if (pts == AV_NOPTS_VALUE) {
421         return -1;
422     }
423     AVRational us = {1, US_PER_SECOND};
424     return av_rescale_q(pts, base, us);
425 }
426 
AVStrError(int errnum)427 std::string FFMpegConverter::AVStrError(int errnum)
428 {
429     char errbuf[AV_ERROR_MAX_STRING_SIZE] = {0};
430     av_strerror(errnum, errbuf, AV_ERROR_MAX_STRING_SIZE);
431     return std::string(errbuf);
432 }
433 } // namespace MediaAVCodec
434 } // namespace OHOS