OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/logging.h" | 7 #include "base/logging.h" |
8 | 8 |
9 namespace media { | 9 namespace media { |
10 | 10 |
11 static const AVRational kMicrosBase = { 1, base::Time::kMicrosecondsPerSecond }; | 11 static const AVRational kMicrosBase = { 1, base::Time::kMicrosecondsPerSecond }; |
12 | 12 |
13 base::TimeDelta ConvertFromTimeBase(const AVRational& time_base, | 13 base::TimeDelta ConvertFromTimeBase(const AVRational& time_base, |
14 int64 timestamp) { | 14 int64 timestamp) { |
15 int64 microseconds = av_rescale_q(timestamp, time_base, kMicrosBase); | 15 int64 microseconds = av_rescale_q(timestamp, time_base, kMicrosBase); |
16 return base::TimeDelta::FromMicroseconds(microseconds); | 16 return base::TimeDelta::FromMicroseconds(microseconds); |
17 } | 17 } |
18 | 18 |
19 int64 ConvertToTimeBase(const AVRational& time_base, | 19 int64 ConvertToTimeBase(const AVRational& time_base, |
20 const base::TimeDelta& timestamp) { | 20 const base::TimeDelta& timestamp) { |
21 return av_rescale_q(timestamp.InMicroseconds(), kMicrosBase, time_base); | 21 return av_rescale_q(timestamp.InMicroseconds(), kMicrosBase, time_base); |
22 } | 22 } |
23 | 23 |
| 24 static AudioCodec CodecIDToAudioCodec(CodecID codec_id) { |
| 25 switch (codec_id) { |
| 26 case CODEC_ID_AAC: |
| 27 return kCodecAAC; |
| 28 case CODEC_ID_MP3: |
| 29 return kCodecMP3; |
| 30 case CODEC_ID_VORBIS: |
| 31 return kCodecVorbis; |
| 32 case CODEC_ID_PCM_U8: |
| 33 case CODEC_ID_PCM_S16LE: |
| 34 case CODEC_ID_PCM_S32LE: |
| 35 return kCodecPCM; |
| 36 default: |
| 37 NOTREACHED(); |
| 38 } |
| 39 return kUnknownAudioCodec; |
| 40 } |
| 41 |
| 42 static CodecID AudioCodecToCodecID(AudioCodec audio_codec, |
| 43 int bits_per_channel) { |
| 44 switch (audio_codec) { |
| 45 case kUnknownAudioCodec: |
| 46 return CODEC_ID_NONE; |
| 47 case kCodecAAC: |
| 48 return CODEC_ID_AAC; |
| 49 case kCodecMP3: |
| 50 return CODEC_ID_MP3; |
| 51 case kCodecPCM: |
| 52 switch (bits_per_channel) { |
| 53 case 8: |
| 54 return CODEC_ID_PCM_U8; |
| 55 case 16: |
| 56 return CODEC_ID_PCM_S16LE; |
| 57 case 32: |
| 58 return CODEC_ID_PCM_S32LE; |
| 59 default: |
| 60 NOTREACHED() << "Unsupported bits_per_channel: " << bits_per_channel; |
| 61 } |
| 62 case kCodecVorbis: |
| 63 return CODEC_ID_VORBIS; |
| 64 default: |
| 65 NOTREACHED(); |
| 66 } |
| 67 return CODEC_ID_NONE; |
| 68 } |
| 69 |
| 70 AudioDecoderConfig* AVCodecContextToAudioDecoderConfig( |
| 71 AVCodecContext* codec_context) { |
| 72 DCHECK_EQ(codec_context->codec_type, AVMEDIA_TYPE_AUDIO); |
| 73 |
| 74 AudioCodec codec = CodecIDToAudioCodec(codec_context->codec_id); |
| 75 int bits_per_channel = av_get_bits_per_sample_fmt(codec_context->sample_fmt); |
| 76 ChannelLayout channel_layout = |
| 77 ChannelLayoutToChromeChannelLayout(codec_context->channel_layout, |
| 78 codec_context->channels); |
| 79 int sample_rate = codec_context->sample_rate; |
| 80 |
| 81 return new AudioDecoderConfig(codec, |
| 82 bits_per_channel, |
| 83 channel_layout, |
| 84 sample_rate, |
| 85 codec_context->extradata, |
| 86 codec_context->extradata_size); |
| 87 } |
| 88 |
| 89 void AudioDecoderConfigToAVCodecContext(const AudioDecoderConfig* config, |
| 90 AVCodecContext* codec_context) { |
| 91 codec_context->codec_type = AVMEDIA_TYPE_AUDIO; |
| 92 codec_context->codec_id = AudioCodecToCodecID(config->codec(), |
| 93 config->bits_per_channel()); |
| 94 |
| 95 switch (config->bits_per_channel()) { |
| 96 case 8: |
| 97 codec_context->sample_fmt = AV_SAMPLE_FMT_U8; |
| 98 break; |
| 99 case 16: |
| 100 codec_context->sample_fmt = AV_SAMPLE_FMT_S16; |
| 101 break; |
| 102 case 32: |
| 103 codec_context->sample_fmt = AV_SAMPLE_FMT_S32; |
| 104 break; |
| 105 default: |
| 106 NOTIMPLEMENTED() << "TODO(scherkus): DO SOMETHING BETTER HERE?"; |
| 107 codec_context->sample_fmt = AV_SAMPLE_FMT_NONE; |
| 108 } |
| 109 |
| 110 // TODO(scherkus): should we set |channel_layout|? I'm not sure if FFmpeg uses |
| 111 // said information to decode. |
| 112 codec_context->channels = |
| 113 ChannelLayoutToChannelCount(config->channel_layout()); |
| 114 codec_context->sample_rate = config->sample_rate(); |
| 115 |
| 116 if (config->extra_data()) { |
| 117 codec_context->extradata_size = config->extra_data_size(); |
| 118 codec_context->extradata = reinterpret_cast<uint8_t*>( |
| 119 av_malloc(config->extra_data_size() + FF_INPUT_BUFFER_PADDING_SIZE)); |
| 120 memcpy(codec_context->extradata, config->extra_data(), |
| 121 config->extra_data_size()); |
| 122 memset(codec_context->extradata + config->extra_data_size(), '\0', |
| 123 FF_INPUT_BUFFER_PADDING_SIZE); |
| 124 } else { |
| 125 codec_context->extradata = NULL; |
| 126 codec_context->extradata_size = 0; |
| 127 } |
| 128 } |
| 129 |
24 VideoCodec CodecIDToVideoCodec(CodecID codec_id) { | 130 VideoCodec CodecIDToVideoCodec(CodecID codec_id) { |
25 switch (codec_id) { | 131 switch (codec_id) { |
26 case CODEC_ID_VC1: | 132 case CODEC_ID_VC1: |
27 return kCodecVC1; | 133 return kCodecVC1; |
28 case CODEC_ID_H264: | 134 case CODEC_ID_H264: |
29 return kCodecH264; | 135 return kCodecH264; |
30 case CODEC_ID_THEORA: | 136 case CODEC_ID_THEORA: |
31 return kCodecTheora; | 137 return kCodecTheora; |
32 case CODEC_ID_MPEG2VIDEO: | 138 case CODEC_ID_MPEG2VIDEO: |
33 return kCodecMPEG2; | 139 return kCodecMPEG2; |
34 case CODEC_ID_MPEG4: | 140 case CODEC_ID_MPEG4: |
35 return kCodecMPEG4; | 141 return kCodecMPEG4; |
36 case CODEC_ID_VP8: | 142 case CODEC_ID_VP8: |
37 return kCodecVP8; | 143 return kCodecVP8; |
38 default: | 144 default: |
39 NOTREACHED(); | 145 NOTREACHED(); |
40 } | 146 } |
41 return kUnknown; | 147 return kUnknownVideoCodec; |
42 } | 148 } |
43 | 149 |
44 CodecID VideoCodecToCodecID(VideoCodec video_codec) { | 150 CodecID VideoCodecToCodecID(VideoCodec video_codec) { |
45 switch (video_codec) { | 151 switch (video_codec) { |
46 case kUnknown: | 152 case kUnknownVideoCodec: |
47 return CODEC_ID_NONE; | 153 return CODEC_ID_NONE; |
48 case kCodecVC1: | 154 case kCodecVC1: |
49 return CODEC_ID_VC1; | 155 return CODEC_ID_VC1; |
50 case kCodecH264: | 156 case kCodecH264: |
51 return CODEC_ID_H264; | 157 return CODEC_ID_H264; |
52 case kCodecTheora: | 158 case kCodecTheora: |
53 return CODEC_ID_THEORA; | 159 return CODEC_ID_THEORA; |
54 case kCodecMPEG2: | 160 case kCodecMPEG2: |
55 return CODEC_ID_MPEG2VIDEO; | 161 return CODEC_ID_MPEG2VIDEO; |
56 case kCodecMPEG4: | 162 case kCodecMPEG4: |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 avcodec_close(stream->codec); | 334 avcodec_close(stream->codec); |
229 } | 335 } |
230 } | 336 } |
231 } | 337 } |
232 | 338 |
233 // Then finally cleanup the format context. | 339 // Then finally cleanup the format context. |
234 av_close_input_file(format_context); | 340 av_close_input_file(format_context); |
235 } | 341 } |
236 | 342 |
237 } // namespace media | 343 } // namespace media |
OLD | NEW |