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 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
60 NOTREACHED() << "Unsupported bits_per_channel: " << bits_per_channel; | 60 NOTREACHED() << "Unsupported bits_per_channel: " << bits_per_channel; |
61 } | 61 } |
62 case kCodecVorbis: | 62 case kCodecVorbis: |
63 return CODEC_ID_VORBIS; | 63 return CODEC_ID_VORBIS; |
64 default: | 64 default: |
65 NOTREACHED(); | 65 NOTREACHED(); |
66 } | 66 } |
67 return CODEC_ID_NONE; | 67 return CODEC_ID_NONE; |
68 } | 68 } |
69 | 69 |
70 static VideoCodec CodecIDToVideoCodec(CodecID codec_id) { | |
71 switch (codec_id) { | |
72 case CODEC_ID_VC1: | |
73 return kCodecVC1; | |
74 case CODEC_ID_H264: | |
75 return kCodecH264; | |
76 case CODEC_ID_THEORA: | |
77 return kCodecTheora; | |
78 case CODEC_ID_MPEG2VIDEO: | |
79 return kCodecMPEG2; | |
80 case CODEC_ID_MPEG4: | |
81 return kCodecMPEG4; | |
82 case CODEC_ID_VP8: | |
83 return kCodecVP8; | |
84 default: | |
85 NOTREACHED(); | |
86 } | |
87 return kUnknownVideoCodec; | |
88 } | |
89 | |
90 static CodecID VideoCodecToCodecID(VideoCodec video_codec) { | |
91 switch (video_codec) { | |
92 case kUnknownVideoCodec: | |
93 return CODEC_ID_NONE; | |
94 case kCodecVC1: | |
95 return CODEC_ID_VC1; | |
96 case kCodecH264: | |
97 return CODEC_ID_H264; | |
98 case kCodecTheora: | |
99 return CODEC_ID_THEORA; | |
100 case kCodecMPEG2: | |
101 return CODEC_ID_MPEG2VIDEO; | |
102 case kCodecMPEG4: | |
103 return CODEC_ID_MPEG4; | |
104 case kCodecVP8: | |
105 return CODEC_ID_VP8; | |
106 default: | |
107 NOTREACHED(); | |
108 } | |
109 return CODEC_ID_NONE; | |
110 } | |
111 | |
70 void AVCodecContextToAudioDecoderConfig( | 112 void AVCodecContextToAudioDecoderConfig( |
71 const AVCodecContext* codec_context, | 113 const AVCodecContext* codec_context, |
72 AudioDecoderConfig* config) { | 114 AudioDecoderConfig* config) { |
73 DCHECK_EQ(codec_context->codec_type, AVMEDIA_TYPE_AUDIO); | 115 DCHECK_EQ(codec_context->codec_type, AVMEDIA_TYPE_AUDIO); |
74 | 116 |
75 AudioCodec codec = CodecIDToAudioCodec(codec_context->codec_id); | 117 AudioCodec codec = CodecIDToAudioCodec(codec_context->codec_id); |
76 int bits_per_channel = av_get_bits_per_sample_fmt(codec_context->sample_fmt); | 118 int bits_per_channel = av_get_bits_per_sample_fmt(codec_context->sample_fmt); |
77 ChannelLayout channel_layout = | 119 ChannelLayout channel_layout = |
78 ChannelLayoutToChromeChannelLayout(codec_context->channel_layout, | 120 ChannelLayoutToChromeChannelLayout(codec_context->channel_layout, |
79 codec_context->channels); | 121 codec_context->channels); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
121 memcpy(codec_context->extradata, config.extra_data(), | 163 memcpy(codec_context->extradata, config.extra_data(), |
122 config.extra_data_size()); | 164 config.extra_data_size()); |
123 memset(codec_context->extradata + config.extra_data_size(), '\0', | 165 memset(codec_context->extradata + config.extra_data_size(), '\0', |
124 FF_INPUT_BUFFER_PADDING_SIZE); | 166 FF_INPUT_BUFFER_PADDING_SIZE); |
125 } else { | 167 } else { |
126 codec_context->extradata = NULL; | 168 codec_context->extradata = NULL; |
127 codec_context->extradata_size = 0; | 169 codec_context->extradata_size = 0; |
128 } | 170 } |
129 } | 171 } |
130 | 172 |
131 VideoCodec CodecIDToVideoCodec(CodecID codec_id) { | 173 void AVCodecContextToVideoDecoderConfig( |
132 switch (codec_id) { | 174 const AVCodecContext* codec_context, |
vrk (LEFT CHROMIUM)
2011/10/26 18:07:12
nit: const ref
scherkus (not reviewing)
2011/10/26 19:08:00
we tend to keep FFmpeg as pointers since that's ho
| |
133 case CODEC_ID_VC1: | 175 const AVRational& frame_rate, |
134 return kCodecVC1; | 176 const AVRational& aspect_ratio, |
135 case CODEC_ID_H264: | 177 VideoDecoderConfig* config) { |
136 return kCodecH264; | 178 |
137 case CODEC_ID_THEORA: | 179 gfx::Size coded_size(codec_context->coded_width, |
138 return kCodecTheora; | 180 codec_context->coded_height); |
vrk (LEFT CHROMIUM)
2011/10/26 18:07:12
nit: move to line above?
scherkus (not reviewing)
2011/10/26 19:08:00
Done.
| |
139 case CODEC_ID_MPEG2VIDEO: | 181 |
140 return kCodecMPEG2; | 182 // TODO(vrk): This assumes decoded frame data starts at (0, 0), which is true |
141 case CODEC_ID_MPEG4: | 183 // for now, but may not always be true forever. Fix this in the future. |
142 return kCodecMPEG4; | 184 gfx::Rect visible_rect(codec_context->width, |
143 case CODEC_ID_VP8: | 185 codec_context->height); |
vrk (LEFT CHROMIUM)
2011/10/26 18:07:12
nit: move to line above?
scherkus (not reviewing)
2011/10/26 19:08:00
Done.
| |
144 return kCodecVP8; | 186 |
145 default: | 187 config->Initialize(CodecIDToVideoCodec(codec_context->codec_id), |
146 NOTREACHED(); | 188 PixelFormatToVideoFormat(codec_context->pix_fmt), |
147 } | 189 coded_size, visible_rect, |
148 return kUnknownVideoCodec; | 190 frame_rate.num, |
191 frame_rate.den, | |
192 aspect_ratio.num, | |
193 aspect_ratio.den, | |
194 codec_context->extradata, | |
195 codec_context->extradata_size); | |
149 } | 196 } |
150 | 197 |
151 CodecID VideoCodecToCodecID(VideoCodec video_codec) { | 198 void VideoDecoderConfigToAVCodecContext( |
152 switch (video_codec) { | 199 const VideoDecoderConfig& config, |
153 case kUnknownVideoCodec: | 200 AVCodecContext* codec_context) { |
154 return CODEC_ID_NONE; | 201 codec_context->codec_type = AVMEDIA_TYPE_VIDEO; |
155 case kCodecVC1: | 202 codec_context->codec_id = VideoCodecToCodecID(config.codec()); |
156 return CODEC_ID_VC1; | 203 codec_context->coded_width = config.coded_size().width(); |
157 case kCodecH264: | 204 codec_context->coded_height = config.coded_size().height(); |
158 return CODEC_ID_H264; | 205 codec_context->pix_fmt = VideoFormatToPixelFormat(config.format()); |
159 case kCodecTheora: | 206 |
160 return CODEC_ID_THEORA; | 207 if (config.extra_data()) { |
161 case kCodecMPEG2: | 208 codec_context->extradata_size = config.extra_data_size(); |
162 return CODEC_ID_MPEG2VIDEO; | 209 codec_context->extradata = reinterpret_cast<uint8_t*>( |
163 case kCodecMPEG4: | 210 av_malloc(config.extra_data_size() + FF_INPUT_BUFFER_PADDING_SIZE)); |
164 return CODEC_ID_MPEG4; | 211 memcpy(codec_context->extradata, config.extra_data(), |
165 case kCodecVP8: | 212 config.extra_data_size()); |
166 return CODEC_ID_VP8; | 213 memset(codec_context->extradata + config.extra_data_size(), '\0', |
167 default: | 214 FF_INPUT_BUFFER_PADDING_SIZE); |
168 NOTREACHED(); | 215 } else { |
216 codec_context->extradata = NULL; | |
217 codec_context->extradata_size = 0; | |
169 } | 218 } |
170 return CODEC_ID_NONE; | |
171 } | 219 } |
172 | 220 |
173 ChannelLayout ChannelLayoutToChromeChannelLayout(int64_t layout, | 221 ChannelLayout ChannelLayoutToChromeChannelLayout(int64_t layout, |
174 int channels) { | 222 int channels) { |
175 switch (layout) { | 223 switch (layout) { |
176 case CH_LAYOUT_MONO: | 224 case CH_LAYOUT_MONO: |
177 return CHANNEL_LAYOUT_MONO; | 225 return CHANNEL_LAYOUT_MONO; |
178 case CH_LAYOUT_STEREO: | 226 case CH_LAYOUT_STEREO: |
179 return CHANNEL_LAYOUT_STEREO; | 227 return CHANNEL_LAYOUT_STEREO; |
180 case CH_LAYOUT_2_1: | 228 case CH_LAYOUT_2_1: |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
232 case VideoFrame::YV16: | 280 case VideoFrame::YV16: |
233 return PIX_FMT_YUV422P; | 281 return PIX_FMT_YUV422P; |
234 case VideoFrame::YV12: | 282 case VideoFrame::YV12: |
235 return PIX_FMT_YUV420P; | 283 return PIX_FMT_YUV420P; |
236 default: | 284 default: |
237 NOTREACHED() << "Unsupported VideoFrame Format: " << video_format; | 285 NOTREACHED() << "Unsupported VideoFrame Format: " << video_format; |
238 } | 286 } |
239 return PIX_FMT_NONE; | 287 return PIX_FMT_NONE; |
240 } | 288 } |
241 | 289 |
242 base::TimeDelta GetFrameDuration(AVStream* stream) { | 290 base::TimeDelta GetFrameDuration(const VideoDecoderConfig& config) { |
243 AVRational time_base = { stream->r_frame_rate.den, stream->r_frame_rate.num }; | 291 AVRational time_base = { |
292 config.frame_rate_denominator(), | |
293 config.frame_rate_numerator() | |
294 }; | |
244 return ConvertFromTimeBase(time_base, 1); | 295 return ConvertFromTimeBase(time_base, 1); |
245 } | 296 } |
246 | 297 |
247 gfx::Size GetNaturalSize(AVStream* stream) { | 298 AVRational GetAspectRatio(AVStream* stream) { |
248 double aspect_ratio = 1.0; | 299 if (stream->sample_aspect_ratio.num) |
300 return stream->sample_aspect_ratio; | |
249 | 301 |
250 if (stream->sample_aspect_ratio.num) | 302 if (stream->codec->sample_aspect_ratio.num) |
251 aspect_ratio = av_q2d(stream->sample_aspect_ratio); | 303 return stream->codec->sample_aspect_ratio; |
252 else if (stream->codec->sample_aspect_ratio.num) | |
253 aspect_ratio = av_q2d(stream->codec->sample_aspect_ratio); | |
254 | 304 |
255 int height = stream->codec->height; | 305 return { 1, 1 }; |
256 int width = floor(stream->codec->width * aspect_ratio + 0.5); | 306 } |
307 | |
308 gfx::Size GetNaturalSize(const VideoDecoderConfig& config) { | |
309 AVRational aspect_ratio = { | |
310 config.aspect_ratio_denominator(), | |
311 config.aspect_ratio_numerator() | |
312 }; | |
313 | |
314 int height = config.visible_rect().height(); | |
315 int width = floor(config.visible_rect().width() * av_q2d(aspect_ratio) + 0.5); | |
257 | 316 |
258 // An even width makes things easier for YV12 and appears to be the behavior | 317 // An even width makes things easier for YV12 and appears to be the behavior |
259 // expected by WebKit layout tests. | 318 // expected by WebKit layout tests. |
260 return gfx::Size(width & ~1, height); | 319 return gfx::Size(width & ~1, height); |
261 } | 320 } |
262 | 321 |
263 void DestroyAVFormatContext(AVFormatContext* format_context) { | 322 void DestroyAVFormatContext(AVFormatContext* format_context) { |
264 DCHECK(format_context); | 323 DCHECK(format_context); |
265 | 324 |
266 // Iterate each stream and destroy each one of them. | 325 // Iterate each stream and destroy each one of them. |
(...skipping 13 matching lines...) Expand all Loading... | |
280 avcodec_close(stream->codec); | 339 avcodec_close(stream->codec); |
281 } | 340 } |
282 } | 341 } |
283 } | 342 } |
284 | 343 |
285 // Then finally cleanup the format context. | 344 // Then finally cleanup the format context. |
286 av_close_input_file(format_context); | 345 av_close_input_file(format_context); |
287 } | 346 } |
288 | 347 |
289 } // namespace media | 348 } // namespace media |
OLD | NEW |