OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/ffmpeg/ffmpeg_common.h" | 5 #include "media/ffmpeg/ffmpeg_common.h" |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "media/base/decoder_buffer.h" | 9 #include "media/base/decoder_buffer.h" |
10 #include "media/base/video_frame.h" | 10 #include "media/base/video_frame.h" |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 switch (codec_id) { | 61 switch (codec_id) { |
62 case CODEC_ID_AAC: | 62 case CODEC_ID_AAC: |
63 return kCodecAAC; | 63 return kCodecAAC; |
64 case CODEC_ID_MP3: | 64 case CODEC_ID_MP3: |
65 return kCodecMP3; | 65 return kCodecMP3; |
66 case CODEC_ID_VORBIS: | 66 case CODEC_ID_VORBIS: |
67 return kCodecVorbis; | 67 return kCodecVorbis; |
68 case CODEC_ID_PCM_U8: | 68 case CODEC_ID_PCM_U8: |
69 case CODEC_ID_PCM_S16LE: | 69 case CODEC_ID_PCM_S16LE: |
70 case CODEC_ID_PCM_S24LE: | 70 case CODEC_ID_PCM_S24LE: |
| 71 case CODEC_ID_PCM_F32LE: |
71 return kCodecPCM; | 72 return kCodecPCM; |
72 case CODEC_ID_PCM_S16BE: | 73 case CODEC_ID_PCM_S16BE: |
73 return kCodecPCM_S16BE; | 74 return kCodecPCM_S16BE; |
74 case CODEC_ID_PCM_S24BE: | 75 case CODEC_ID_PCM_S24BE: |
75 return kCodecPCM_S24BE; | 76 return kCodecPCM_S24BE; |
76 case CODEC_ID_FLAC: | 77 case CODEC_ID_FLAC: |
77 return kCodecFLAC; | 78 return kCodecFLAC; |
78 case CODEC_ID_AMR_NB: | 79 case CODEC_ID_AMR_NB: |
79 return kCodecAMR_NB; | 80 return kCodecAMR_NB; |
80 case CODEC_ID_AMR_WB: | 81 case CODEC_ID_AMR_WB: |
81 return kCodecAMR_WB; | 82 return kCodecAMR_WB; |
82 case CODEC_ID_GSM_MS: | 83 case CODEC_ID_GSM_MS: |
83 return kCodecGSM_MS; | 84 return kCodecGSM_MS; |
84 case CODEC_ID_PCM_MULAW: | 85 case CODEC_ID_PCM_MULAW: |
85 return kCodecPCM_MULAW; | 86 return kCodecPCM_MULAW; |
86 case CODEC_ID_OPUS: | 87 case CODEC_ID_OPUS: |
87 return kCodecOpus; | 88 return kCodecOpus; |
88 default: | 89 default: |
89 DVLOG(1) << "Unknown audio CodecID: " << codec_id; | 90 DVLOG(1) << "Unknown audio CodecID: " << codec_id; |
90 } | 91 } |
91 return kUnknownAudioCodec; | 92 return kUnknownAudioCodec; |
92 } | 93 } |
93 | 94 |
94 static CodecID AudioCodecToCodecID(AudioCodec audio_codec, | 95 static CodecID AudioCodecToCodecID(AudioCodec audio_codec, |
95 int bits_per_channel) { | 96 SampleFormat sample_format) { |
96 switch (audio_codec) { | 97 switch (audio_codec) { |
97 case kCodecAAC: | 98 case kCodecAAC: |
98 return CODEC_ID_AAC; | 99 return CODEC_ID_AAC; |
99 case kCodecMP3: | 100 case kCodecMP3: |
100 return CODEC_ID_MP3; | 101 return CODEC_ID_MP3; |
101 case kCodecPCM: | 102 case kCodecPCM: |
102 switch (bits_per_channel) { | 103 switch (sample_format) { |
103 case 8: | 104 case kSampleFormatU8: |
104 return CODEC_ID_PCM_U8; | 105 return CODEC_ID_PCM_U8; |
105 case 16: | 106 case kSampleFormatS16: |
106 return CODEC_ID_PCM_S16LE; | 107 return CODEC_ID_PCM_S16LE; |
107 case 32: | 108 case kSampleFormatS32: |
108 return CODEC_ID_PCM_S24LE; | 109 return CODEC_ID_PCM_S24LE; |
| 110 case kSampleFormatF32: |
| 111 return CODEC_ID_PCM_F32LE; |
109 default: | 112 default: |
110 DVLOG(1) << "Unsupported bits per channel: " << bits_per_channel; | 113 DVLOG(1) << "Unsupported sample format: " << sample_format; |
111 } | 114 } |
112 break; | 115 break; |
113 case kCodecPCM_S16BE: | 116 case kCodecPCM_S16BE: |
114 return CODEC_ID_PCM_S16BE; | 117 return CODEC_ID_PCM_S16BE; |
115 case kCodecPCM_S24BE: | 118 case kCodecPCM_S24BE: |
116 return CODEC_ID_PCM_S24BE; | 119 return CODEC_ID_PCM_S24BE; |
117 case kCodecVorbis: | 120 case kCodecVorbis: |
118 return CODEC_ID_VORBIS; | 121 return CODEC_ID_VORBIS; |
119 case kCodecFLAC: | 122 case kCodecFLAC: |
120 return CODEC_ID_FLAC; | 123 return CODEC_ID_FLAC; |
121 case kCodecAMR_NB: | 124 case kCodecAMR_NB: |
122 return CODEC_ID_AMR_NB; | 125 return CODEC_ID_AMR_NB; |
123 case kCodecAMR_WB: | 126 case kCodecAMR_WB: |
124 return CODEC_ID_AMR_WB; | 127 return CODEC_ID_AMR_WB; |
125 case kCodecGSM_MS: | 128 case kCodecGSM_MS: |
126 return CODEC_ID_GSM_MS; | 129 return CODEC_ID_GSM_MS; |
127 case kCodecPCM_MULAW: | 130 case kCodecPCM_MULAW: |
128 return CODEC_ID_PCM_MULAW; | 131 return CODEC_ID_PCM_MULAW; |
129 case kCodecOpus: | 132 case kCodecOpus: |
130 return CODEC_ID_OPUS; | 133 return CODEC_ID_OPUS; |
131 default: | 134 default: |
132 DVLOG(1) << "Unknown AudioCodec: " << audio_codec; | 135 DVLOG(1) << "Unknown AudioCodec: " << audio_codec; |
133 } | 136 } |
134 return CODEC_ID_NONE; | 137 return CODEC_ID_NONE; |
135 } | 138 } |
136 | 139 |
137 VideoCodec CodecIDToVideoCodec(CodecID codec_id) { | 140 VideoCodec CodecIDToVideoCodec(CodecID codec_id) { |
138 switch (codec_id) { | 141 switch (codec_id) { |
139 case CODEC_ID_VC1: | |
140 return kCodecVC1; | |
141 case CODEC_ID_H264: | 142 case CODEC_ID_H264: |
142 return kCodecH264; | 143 return kCodecH264; |
143 case CODEC_ID_THEORA: | 144 case CODEC_ID_THEORA: |
144 return kCodecTheora; | 145 return kCodecTheora; |
145 case CODEC_ID_MPEG2VIDEO: | |
146 return kCodecMPEG2; | |
147 case CODEC_ID_MPEG4: | 146 case CODEC_ID_MPEG4: |
148 return kCodecMPEG4; | 147 return kCodecMPEG4; |
149 case CODEC_ID_VP8: | 148 case CODEC_ID_VP8: |
150 return kCodecVP8; | 149 return kCodecVP8; |
151 default: | 150 default: |
152 DVLOG(1) << "Unknown video CodecID: " << codec_id; | 151 DVLOG(1) << "Unknown video CodecID: " << codec_id; |
153 } | 152 } |
154 return kUnknownVideoCodec; | 153 return kUnknownVideoCodec; |
155 } | 154 } |
156 | 155 |
157 static CodecID VideoCodecToCodecID(VideoCodec video_codec) { | 156 static CodecID VideoCodecToCodecID(VideoCodec video_codec) { |
158 switch (video_codec) { | 157 switch (video_codec) { |
159 case kCodecVC1: | |
160 return CODEC_ID_VC1; | |
161 case kCodecH264: | 158 case kCodecH264: |
162 return CODEC_ID_H264; | 159 return CODEC_ID_H264; |
163 case kCodecTheora: | 160 case kCodecTheora: |
164 return CODEC_ID_THEORA; | 161 return CODEC_ID_THEORA; |
165 case kCodecMPEG2: | |
166 return CODEC_ID_MPEG2VIDEO; | |
167 case kCodecMPEG4: | 162 case kCodecMPEG4: |
168 return CODEC_ID_MPEG4; | 163 return CODEC_ID_MPEG4; |
169 case kCodecVP8: | 164 case kCodecVP8: |
170 return CODEC_ID_VP8; | 165 return CODEC_ID_VP8; |
171 default: | 166 default: |
172 DVLOG(1) << "Unknown VideoCodec: " << video_codec; | 167 DVLOG(1) << "Unknown VideoCodec: " << video_codec; |
173 } | 168 } |
174 return CODEC_ID_NONE; | 169 return CODEC_ID_NONE; |
175 } | 170 } |
176 | 171 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 case H264PROFILE_HIGH422PROFILE: | 210 case H264PROFILE_HIGH422PROFILE: |
216 return FF_PROFILE_H264_HIGH_422; | 211 return FF_PROFILE_H264_HIGH_422; |
217 case H264PROFILE_HIGH444PREDICTIVEPROFILE: | 212 case H264PROFILE_HIGH444PREDICTIVEPROFILE: |
218 return FF_PROFILE_H264_HIGH_444_PREDICTIVE; | 213 return FF_PROFILE_H264_HIGH_444_PREDICTIVE; |
219 default: | 214 default: |
220 DVLOG(1) << "Unknown VideoCodecProfile: " << profile; | 215 DVLOG(1) << "Unknown VideoCodecProfile: " << profile; |
221 } | 216 } |
222 return FF_PROFILE_UNKNOWN; | 217 return FF_PROFILE_UNKNOWN; |
223 } | 218 } |
224 | 219 |
| 220 static SampleFormat AVSampleFormatToSampleFormat(AVSampleFormat sample_format) { |
| 221 switch (sample_format) { |
| 222 case AV_SAMPLE_FMT_U8: |
| 223 return kSampleFormatU8; |
| 224 case AV_SAMPLE_FMT_S16: |
| 225 return kSampleFormatS16; |
| 226 case AV_SAMPLE_FMT_S32: |
| 227 return kSampleFormatS32; |
| 228 case AV_SAMPLE_FMT_FLT: |
| 229 return kSampleFormatF32; |
| 230 case AV_SAMPLE_FMT_S16P: |
| 231 return kSampleFormatPlanarS16; |
| 232 case AV_SAMPLE_FMT_FLTP: |
| 233 return kSampleFormatPlanarF32; |
| 234 default: |
| 235 DVLOG(1) << "Unknown AVSampleFormat: " << sample_format; |
| 236 } |
| 237 return kUnknownSampleFormat; |
| 238 } |
| 239 |
| 240 static AVSampleFormat SampleFormatToAVSampleFormat(SampleFormat sample_format) { |
| 241 switch (sample_format) { |
| 242 case kSampleFormatU8: |
| 243 return AV_SAMPLE_FMT_U8; |
| 244 case kSampleFormatS16: |
| 245 return AV_SAMPLE_FMT_S16; |
| 246 case kSampleFormatS32: |
| 247 return AV_SAMPLE_FMT_S32; |
| 248 case kSampleFormatF32: |
| 249 return AV_SAMPLE_FMT_FLT; |
| 250 case kSampleFormatPlanarS16: |
| 251 return AV_SAMPLE_FMT_S16P; |
| 252 case kSampleFormatPlanarF32: |
| 253 return AV_SAMPLE_FMT_FLTP; |
| 254 default: |
| 255 DVLOG(1) << "Unknown SampleFormat: " << sample_format; |
| 256 } |
| 257 return AV_SAMPLE_FMT_NONE; |
| 258 } |
| 259 |
225 void AVCodecContextToAudioDecoderConfig( | 260 void AVCodecContextToAudioDecoderConfig( |
226 const AVCodecContext* codec_context, | 261 const AVCodecContext* codec_context, |
227 AudioDecoderConfig* config) { | 262 AudioDecoderConfig* config) { |
228 DCHECK_EQ(codec_context->codec_type, AVMEDIA_TYPE_AUDIO); | 263 DCHECK_EQ(codec_context->codec_type, AVMEDIA_TYPE_AUDIO); |
229 | 264 |
230 AudioCodec codec = CodecIDToAudioCodec(codec_context->codec_id); | 265 AudioCodec codec = CodecIDToAudioCodec(codec_context->codec_id); |
231 | 266 |
232 AVSampleFormat sample_format = codec_context->sample_fmt; | 267 SampleFormat sample_format = |
| 268 AVSampleFormatToSampleFormat(codec_context->sample_fmt); |
| 269 |
233 if (codec == kCodecOpus) { | 270 if (codec == kCodecOpus) { |
234 // TODO(tomfinegan): |sample_fmt| in |codec_context| is -1... because | 271 // TODO(tomfinegan): |sample_fmt| in |codec_context| is -1... because |
235 // libopusdec.c isn't built into ffmpegsumo...? Maybe it's not *that* big | 272 // libopusdec.c isn't built into ffmpegsumo...? Maybe it's not *that* big |
236 // a deal since libopus will produce either float or S16 samples, and | 273 // a deal since libopus will produce either float or S16 samples, and |
237 // OpusAudioDecoder is the only provider of Opus support. | 274 // OpusAudioDecoder is the only provider of Opus support. |
238 sample_format = AV_SAMPLE_FMT_S16; | 275 sample_format = kSampleFormatS16; |
239 } | 276 } |
240 | 277 |
241 int bytes_per_channel = av_get_bytes_per_sample(sample_format); | 278 ChannelLayout channel_layout = ChannelLayoutToChromeChannelLayout( |
242 ChannelLayout channel_layout = | 279 codec_context->channel_layout, codec_context->channels); |
243 ChannelLayoutToChromeChannelLayout(codec_context->channel_layout, | |
244 codec_context->channels); | |
245 int samples_per_second = codec_context->sample_rate; | |
246 | |
247 config->Initialize(codec, | 280 config->Initialize(codec, |
248 bytes_per_channel << 3, | 281 sample_format, |
249 channel_layout, | 282 channel_layout, |
250 samples_per_second, | 283 codec_context->sample_rate, |
251 codec_context->extradata, | 284 codec_context->extradata, |
252 codec_context->extradata_size, | 285 codec_context->extradata_size, |
253 false, // Not encrypted. | 286 false, // Not encrypted. |
254 true); | 287 true); |
| 288 DCHECK_EQ(av_get_bytes_per_sample(codec_context->sample_fmt) * 8, |
| 289 config->bits_per_channel()); |
255 } | 290 } |
256 | 291 |
257 void AudioDecoderConfigToAVCodecContext(const AudioDecoderConfig& config, | 292 void AudioDecoderConfigToAVCodecContext(const AudioDecoderConfig& config, |
258 AVCodecContext* codec_context) { | 293 AVCodecContext* codec_context) { |
259 codec_context->codec_type = AVMEDIA_TYPE_AUDIO; | 294 codec_context->codec_type = AVMEDIA_TYPE_AUDIO; |
260 codec_context->codec_id = AudioCodecToCodecID(config.codec(), | 295 codec_context->codec_id = AudioCodecToCodecID(config.codec(), |
261 config.bits_per_channel()); | 296 config.sample_format()); |
262 | 297 codec_context->sample_fmt = SampleFormatToAVSampleFormat( |
263 switch (config.bits_per_channel()) { | 298 config.sample_format()); |
264 case 8: | |
265 codec_context->sample_fmt = AV_SAMPLE_FMT_U8; | |
266 break; | |
267 case 16: | |
268 codec_context->sample_fmt = AV_SAMPLE_FMT_S16; | |
269 break; | |
270 case 32: | |
271 codec_context->sample_fmt = AV_SAMPLE_FMT_S32; | |
272 break; | |
273 default: | |
274 DVLOG(1) << "Unsupported bits per channel: " << config.bits_per_channel(); | |
275 codec_context->sample_fmt = AV_SAMPLE_FMT_NONE; | |
276 } | |
277 | 299 |
278 // TODO(scherkus): should we set |channel_layout|? I'm not sure if FFmpeg uses | 300 // TODO(scherkus): should we set |channel_layout|? I'm not sure if FFmpeg uses |
279 // said information to decode. | 301 // said information to decode. |
280 codec_context->channels = | 302 codec_context->channels = |
281 ChannelLayoutToChannelCount(config.channel_layout()); | 303 ChannelLayoutToChannelCount(config.channel_layout()); |
282 codec_context->sample_rate = config.samples_per_second(); | 304 codec_context->sample_rate = config.samples_per_second(); |
283 | 305 |
284 if (config.extra_data()) { | 306 if (config.extra_data()) { |
285 codec_context->extradata_size = config.extra_data_size(); | 307 codec_context->extradata_size = config.extra_data_size(); |
286 codec_context->extradata = reinterpret_cast<uint8_t*>( | 308 codec_context->extradata = reinterpret_cast<uint8_t*>( |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 return PIX_FMT_YUV422P; | 457 return PIX_FMT_YUV422P; |
436 case VideoFrame::YV12: | 458 case VideoFrame::YV12: |
437 return PIX_FMT_YUV420P; | 459 return PIX_FMT_YUV420P; |
438 default: | 460 default: |
439 DVLOG(1) << "Unsupported VideoFrame::Format: " << video_format; | 461 DVLOG(1) << "Unsupported VideoFrame::Format: " << video_format; |
440 } | 462 } |
441 return PIX_FMT_NONE; | 463 return PIX_FMT_NONE; |
442 } | 464 } |
443 | 465 |
444 } // namespace media | 466 } // namespace media |
OLD | NEW |