• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 const std::vector<std::pair<AudioChannelLayout, std::string_view>> g_ChannelLayoutToString = {
68     {AudioChannelLayout::UNKNOWN_CHANNEL_LAYOUT, "UNKNOW"},
69     {AudioChannelLayout::MONO, "MONO"},
70     {AudioChannelLayout::STEREO, "STEREO"},
71     {AudioChannelLayout::CH_2POINT1, "2POINT1"},
72     {AudioChannelLayout::CH_2_1, "CH_2_1"},
73     {AudioChannelLayout::SURROUND, "SURROUND"},
74     {AudioChannelLayout::CH_3POINT1, "3POINT1"},
75     {AudioChannelLayout::CH_4POINT0, "4POINT0"},
76     {AudioChannelLayout::CH_4POINT1, "4POINT1"},
77     {AudioChannelLayout::CH_2_2, "CH_2_2"},
78     {AudioChannelLayout::QUAD, "QUAD"},
79     {AudioChannelLayout::CH_5POINT0, "5POINT0"},
80     {AudioChannelLayout::CH_5POINT1, "5POINT1"},
81     {AudioChannelLayout::CH_5POINT0_BACK, "5POINT0_BACK"},
82     {AudioChannelLayout::CH_5POINT1_BACK, "5POINT1_BACK"},
83     {AudioChannelLayout::CH_6POINT0, "6POINT0"},
84     {AudioChannelLayout::CH_6POINT0_FRONT, "6POINT0_FRONT"},
85     {AudioChannelLayout::HEXAGONAL, "HEXAGONAL"},
86     {AudioChannelLayout::CH_6POINT1, "6POINT1"},
87     {AudioChannelLayout::CH_6POINT1_BACK, "6POINT1_BACK"},
88     {AudioChannelLayout::CH_6POINT1_FRONT, "6POINT1_FRONT"},
89     {AudioChannelLayout::CH_7POINT0, "7POINT0"},
90     {AudioChannelLayout::CH_7POINT0_FRONT, "7POINT0_FRONT"},
91     {AudioChannelLayout::CH_7POINT1, "7POINT1"},
92     {AudioChannelLayout::CH_7POINT1_WIDE, "7POINT1_WIDE"},
93     {AudioChannelLayout::CH_7POINT1_WIDE_BACK, "7POINT1_WIDE_BACK"},
94     {AudioChannelLayout::CH_3POINT1POINT2, "CH_3POINT1POINT2"},
95     {AudioChannelLayout::CH_5POINT1POINT2, "CH_5POINT1POINT2"},
96     {AudioChannelLayout::CH_5POINT1POINT4, "CH_5POINT1POINT4"},
97     {AudioChannelLayout::CH_7POINT1POINT2, "CH_7POINT1POINT2"},
98     {AudioChannelLayout::CH_7POINT1POINT4, "CH_7POINT1POINT4"},
99     {AudioChannelLayout::CH_9POINT1POINT4, "CH_9POINT1POINT4"},
100     {AudioChannelLayout::CH_9POINT1POINT6, "CH_9POINT1POINT6"},
101     {AudioChannelLayout::CH_10POINT2, "CH_10POINT2"},
102     {AudioChannelLayout::CH_22POINT2, "CH_22POINT2"},
103     {AudioChannelLayout::OCTAGONAL, "OCTAGONAL"},
104     {AudioChannelLayout::HEXADECAGONAL, "HEXADECAGONAL"},
105     {AudioChannelLayout::STEREO_DOWNMIX, "STEREO_DOWNMIX"},
106     {AudioChannelLayout::HOA_FIRST, "HOA_FIRST"},
107     {AudioChannelLayout::HOA_SECOND, "HOA_SECOND"},
108     {AudioChannelLayout::HOA_THIRD, "HOA_THIRD"},
109 };
110 
ConvertFFMpegToOHAudioFormat(AVSampleFormat ffSampleFormat)111 AudioSampleFormat FFMpegConverter::ConvertFFMpegToOHAudioFormat(AVSampleFormat ffSampleFormat)
112 {
113     auto ite = std::find_if(g_pFfSampleFmtMap.begin(), g_pFfSampleFmtMap.end(),
114                             [&ffSampleFormat](const auto &item) -> bool { return item.first == ffSampleFormat; });
115     CHECK_AND_RETURN_RET_LOGW(ite != g_pFfSampleFmtMap.end(), AudioSampleFormat::INVALID_WIDTH,
116                               "Convert sample format failed: %{public}d", static_cast<int32_t>(ffSampleFormat));
117     return ite->second;
118 }
119 
ConvertOHAudioFormatToFFMpeg(AudioSampleFormat sampleFormat)120 AVSampleFormat FFMpegConverter::ConvertOHAudioFormatToFFMpeg(AudioSampleFormat sampleFormat)
121 {
122     auto ite = std::find_if(g_pFfSampleFmtMap.begin(), g_pFfSampleFmtMap.end(),
123                             [&sampleFormat](const auto &item) -> bool { return item.second == sampleFormat; });
124     CHECK_AND_RETURN_RET_LOGW(ite != g_pFfSampleFmtMap.end(), AVSampleFormat::AV_SAMPLE_FMT_NONE,
125                               "Convert sample format failed: %{public}d", static_cast<int32_t>(sampleFormat));
126     return ite->first;
127 }
128 
ConvertFFToOHAudioChannelLayout(uint64_t ffChannelLayout)129 AudioChannelLayout FFMpegConverter::ConvertFFToOHAudioChannelLayout(uint64_t ffChannelLayout)
130 {
131     auto ite = std::find_if(g_toFFMPEGChannelLayout.begin(), g_toFFMPEGChannelLayout.end(),
132                             [&ffChannelLayout](const auto &item) -> bool { return item.second == ffChannelLayout; });
133     CHECK_AND_RETURN_RET_LOGW(ite != g_toFFMPEGChannelLayout.end(), AudioChannelLayout::MONO,
134                               "Convert channel layout failed: %{public}" PRIu64, ffChannelLayout);
135     return ite->first;
136 }
137 
ConvertOHAudioChannelLayoutToFFMpeg(AudioChannelLayout channelLayout)138 uint64_t FFMpegConverter::ConvertOHAudioChannelLayoutToFFMpeg(AudioChannelLayout channelLayout)
139 {
140     auto ite = std::find_if(g_toFFMPEGChannelLayout.begin(), g_toFFMPEGChannelLayout.end(),
141                             [&channelLayout](const auto &item) -> bool { return item.first == channelLayout; });
142     if (ite == g_toFFMPEGChannelLayout.end()) {
143         AVCODEC_LOGW("Convert channel layout failed: %{public}d", static_cast<int32_t>(channelLayout));
144         return AV_CH_LAYOUT_NATIVE;
145     }
146     return ite->second;
147 }
148 
ConvertOHAudioChannelLayoutToString(AudioChannelLayout layout)149 std::string_view FFMpegConverter::ConvertOHAudioChannelLayoutToString(AudioChannelLayout layout)
150 {
151     auto ite = std::find_if(g_ChannelLayoutToString.begin(), g_ChannelLayoutToString.end(),
152                             [&layout](const auto &item) -> bool { return item.first == layout; });
153     CHECK_AND_RETURN_RET_LOGW(ite != g_ChannelLayoutToString.end(), g_ChannelLayoutToString[0].second,
154                               "Convert channel layout failed: %{public}d", static_cast<int32_t>(layout));
155     return ite->second;
156 }
157 
ConvertAudioPtsToUs(int64_t pts,AVRational base)158 int64_t FFMpegConverter::ConvertAudioPtsToUs(int64_t pts, AVRational base)
159 {
160     CHECK_AND_RETURN_RET_LOG(pts != AV_NOPTS_VALUE, -1, "pts is invalid: %{public}" PRIu64, pts);
161     AVRational us = {1, US_PER_SECOND};
162     return av_rescale_q(pts, base, us);
163 }
164 
AVStrError(int errnum)165 std::string FFMpegConverter::AVStrError(int errnum)
166 {
167     char errbuf[AV_ERROR_MAX_STRING_SIZE] = {0};
168     av_strerror(errnum, errbuf, AV_ERROR_MAX_STRING_SIZE);
169     return std::string(errbuf);
170 }
171 } // namespace MediaAVCodec
172 } // namespace OHOS