Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(192)

Side by Side Diff: services/media/framework_ffmpeg/av_codec_context.cc

Issue 1902183002: Motown: Change media type (stream type) representation (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Changes per review feedback. Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "base/logging.h" 5 #include "base/logging.h"
6 #include "services/media/framework_ffmpeg/av_codec_context.h" 6 #include "services/media/framework_ffmpeg/av_codec_context.h"
7 #include "services/media/framework_ffmpeg/ffmpeg_init.h" 7 #include "services/media/framework_ffmpeg/ffmpeg_init.h"
8 extern "C" { 8 extern "C" {
9 #include "third_party/ffmpeg/libavformat/avformat.h" 9 #include "third_party/ffmpeg/libavformat/avformat.h"
10 } 10 }
11 11
12 // Ffmeg defines this...undefine. 12 // Ffmeg defines this...undefine.
13 #undef PixelFormat 13 #undef PixelFormat
14 14
15 namespace mojo { 15 namespace mojo {
16 namespace media { 16 namespace media {
17 17
18 namespace { 18 namespace {
19 19
20 // Converts an AVSampleFormat into an LpcmStreamType::SampleFormat. 20 // Converts an AVSampleFormat into an AudioStreamType::SampleFormat.
21 LpcmStreamType::SampleFormat Convert(AVSampleFormat av_sample_format) { 21 AudioStreamType::SampleFormat Convert(AVSampleFormat av_sample_format) {
22 switch (av_sample_format) { 22 switch (av_sample_format) {
23 case AV_SAMPLE_FMT_U8: 23 case AV_SAMPLE_FMT_U8:
24 case AV_SAMPLE_FMT_U8P: 24 case AV_SAMPLE_FMT_U8P:
25 return LpcmStreamType::SampleFormat::kUnsigned8; 25 return AudioStreamType::SampleFormat::kUnsigned8;
26 case AV_SAMPLE_FMT_S16: 26 case AV_SAMPLE_FMT_S16:
27 case AV_SAMPLE_FMT_S16P: 27 case AV_SAMPLE_FMT_S16P:
28 return LpcmStreamType::SampleFormat::kSigned16; 28 return AudioStreamType::SampleFormat::kSigned16;
29 case AV_SAMPLE_FMT_S32: 29 case AV_SAMPLE_FMT_S32:
30 case AV_SAMPLE_FMT_S32P: 30 case AV_SAMPLE_FMT_S32P:
31 return LpcmStreamType::SampleFormat::kSigned24In32; 31 return AudioStreamType::SampleFormat::kSigned24In32;
32 case AV_SAMPLE_FMT_FLT: 32 case AV_SAMPLE_FMT_FLT:
33 case AV_SAMPLE_FMT_FLTP: 33 case AV_SAMPLE_FMT_FLTP:
34 return LpcmStreamType::SampleFormat::kFloat; 34 return AudioStreamType::SampleFormat::kFloat;
35 case AV_SAMPLE_FMT_NONE: 35 case AV_SAMPLE_FMT_NONE:
36 case AV_SAMPLE_FMT_DBL: 36 case AV_SAMPLE_FMT_DBL:
37 case AV_SAMPLE_FMT_DBLP: 37 case AV_SAMPLE_FMT_DBLP:
38 case AV_SAMPLE_FMT_NB: 38 case AV_SAMPLE_FMT_NB:
39 default: 39 default:
40 NOTREACHED() << "unsupported av_sample_format " << av_sample_format; 40 LOG(ERROR) << "unsupported av_sample_format " << av_sample_format;
41 return LpcmStreamType::SampleFormat::kUnknown; 41 abort();
42 } 42 }
43 } 43 }
44 44
45 // Copies a buffer from Bytes into context->extradata. The result is malloc'ed 45 // Copies a buffer from Bytes into context->extradata. The result is malloc'ed
46 // and must be freed. 46 // and must be freed.
47 void ExtraDataFromBytes(const Bytes& bytes, const AvCodecContextPtr& context) { 47 void ExtraDataFromBytes(const Bytes& bytes, const AvCodecContextPtr& context) {
48 size_t byte_count = bytes.size(); 48 size_t byte_count = bytes.size();
49 uint8_t* copy = reinterpret_cast<uint8_t*>(malloc(byte_count)); 49 uint8_t* copy = reinterpret_cast<uint8_t*>(malloc(byte_count));
50 std::memcpy(copy, bytes.data(), byte_count); 50 std::memcpy(copy, bytes.data(), byte_count);
51 context->extradata = copy; 51 context->extradata = copy;
52 context->extradata_size = byte_count; 52 context->extradata_size = byte_count;
53 } 53 }
54 54
55 // Creates a StreamType from an AVCodecContext describing an LPCM type. 55 // Creates a StreamType from an AVCodecContext describing an LPCM type.
56 std::unique_ptr<StreamType> StreamTypeFromLpcmCodecContext( 56 std::unique_ptr<StreamType> StreamTypeFromLpcmCodecContext(
57 const AVCodecContext& from) { 57 const AVCodecContext& from) {
58 return LpcmStreamType::Create(Convert(from.sample_fmt), from.channels, 58 return AudioStreamType::Create(StreamType::kAudioEncodingLpcm, nullptr,
59 from.sample_rate); 59 Convert(from.sample_fmt), from.channels,
60 from.sample_rate);
60 } 61 }
61 62
62 // Creates a StreamType from an AVCodecContext describing a compressed audio 63 // Creates a StreamType from an AVCodecContext describing a compressed audio
63 // type. 64 // type.
64 std::unique_ptr<StreamType> StreamTypeFromCompressedAudioCodecContext( 65 std::unique_ptr<StreamType> StreamTypeFromCompressedAudioCodecContext(
65 const AVCodecContext& from) { 66 const AVCodecContext& from) {
66 CompressedAudioStreamType::AudioEncoding encoding; 67 const char* encoding;
67 switch (from.codec_id) { 68 switch (from.codec_id) {
68 case CODEC_ID_VORBIS: 69 case CODEC_ID_VORBIS:
69 encoding = CompressedAudioStreamType::AudioEncoding::kVorbis; 70 encoding = StreamType::kAudioEncodingVorbis;
70 break; 71 break;
71 default: 72 default:
72 encoding = CompressedAudioStreamType::AudioEncoding::kUnknown; 73 LOG(ERROR) << "unsupported codec_id " << from.codec_id;
73 break; 74 abort();
74 } 75 }
75 76
76 return CompressedAudioStreamType::Create( 77 return AudioStreamType::Create(
77 encoding, Convert(from.sample_fmt), from.channels, from.sample_rate, 78 encoding, from.extradata_size == 0
78 from.extradata_size == 0 ? nullptr : Bytes::Create(from.extradata, 79 ? nullptr
79 from.extradata_size)); 80 : Bytes::Create(from.extradata, from.extradata_size),
81 Convert(from.sample_fmt), from.channels, from.sample_rate);
80 } 82 }
81 83
82 // Converts AVColorSpace and AVColorRange to ColorSpace. 84 // Converts AVColorSpace and AVColorRange to ColorSpace.
83 VideoStreamType::ColorSpace ColorSpaceFromAVColorSpaceAndRange( 85 VideoStreamType::ColorSpace ColorSpaceFromAVColorSpaceAndRange(
84 AVColorSpace color_space, 86 AVColorSpace color_space,
85 AVColorRange color_range) { 87 AVColorRange color_range) {
86 // TODO(dalesat): Blindly copied from Chromium. 88 // TODO(dalesat): Blindly copied from Chromium.
87 if (color_range == AVCOL_RANGE_JPEG) { 89 if (color_range == AVCOL_RANGE_JPEG) {
88 return VideoStreamType::ColorSpace::kJpeg; 90 return VideoStreamType::ColorSpace::kJpeg;
89 } 91 }
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 case VideoStreamType::PixelFormat::kMjpeg: 179 case VideoStreamType::PixelFormat::kMjpeg:
178 case VideoStreamType::PixelFormat::kMt21: 180 case VideoStreamType::PixelFormat::kMt21:
179 default: 181 default:
180 return AV_PIX_FMT_NONE; 182 return AV_PIX_FMT_NONE;
181 } 183 }
182 } 184 }
183 185
184 // Creates a StreamType from an AVCodecContext describing a video type. 186 // Creates a StreamType from an AVCodecContext describing a video type.
185 std::unique_ptr<StreamType> StreamTypeFromVideoCodecContext( 187 std::unique_ptr<StreamType> StreamTypeFromVideoCodecContext(
186 const AVCodecContext& from) { 188 const AVCodecContext& from) {
187 VideoStreamType::VideoEncoding encoding; 189 const char* encoding;
188 switch (from.codec_id) { 190 switch (from.codec_id) {
189 case AV_CODEC_ID_THEORA: 191 case AV_CODEC_ID_THEORA:
190 encoding = VideoStreamType::VideoEncoding::kTheora; 192 encoding = StreamType::kVideoEncodingTheora;
191 break;
192 case CODEC_ID_VP8:
193 encoding = VideoStreamType::VideoEncoding::kVp8;
194 break; 193 break;
195 default: 194 default:
196 encoding = VideoStreamType::VideoEncoding::kUnknown; 195 LOG(ERROR) << "unsupported codec_id " << from.codec_id;
197 break; 196 abort();
198 } 197 }
199 198
200 return VideoStreamType::Create( 199 return VideoStreamType::Create(
201 encoding, VideoStreamType::VideoProfile::kNotApplicable, 200 encoding, from.extradata_size == 0
201 ? nullptr
202 : Bytes::Create(from.extradata, from.extradata_size),
203 VideoStreamType::VideoProfile::kNotApplicable,
202 PixelFormatFromAVPixelFormat(from.pix_fmt), 204 PixelFormatFromAVPixelFormat(from.pix_fmt),
203 ColorSpaceFromAVColorSpaceAndRange(from.colorspace, from.color_range), 205 ColorSpaceFromAVColorSpaceAndRange(from.colorspace, from.color_range),
204 from.width, from.height, from.coded_width, from.coded_height, 206 from.width, from.height, from.coded_width, from.coded_height);
205 from.extradata_size == 0 ? nullptr : Bytes::Create(from.extradata,
206 from.extradata_size));
207 } 207 }
208 208
209 // Creates a StreamType from an AVCodecContext describing a data type. 209 // Creates a StreamType from an AVCodecContext describing a data type.
210 std::unique_ptr<StreamType> StreamTypeFromDataCodecContext( 210 std::unique_ptr<StreamType> StreamTypeFromDataCodecContext(
211 const AVCodecContext& from) { 211 const AVCodecContext& from) {
212 // TODO(dalesat): Implement. 212 // TODO(dalesat): Implement.
213 return StreamType::Create(StreamType::Scheme::kUnknown); 213 LOG(ERROR) << "StreamTypeFromDataCodecContext not implemented";
214 abort();
214 } 215 }
215 216
216 // Creates a StreamType from an AVCodecContext describing a subtitle type. 217 // Creates a StreamType from an AVCodecContext describing a subtitle type.
217 std::unique_ptr<StreamType> StreamTypeFromSubtitleCodecContext( 218 std::unique_ptr<StreamType> StreamTypeFromSubtitleCodecContext(
218 const AVCodecContext& from) { 219 const AVCodecContext& from) {
219 // TODO(dalesat): Implement. 220 // TODO(dalesat): Implement.
220 return StreamType::Create(StreamType::Scheme::kUnknown); 221 LOG(ERROR) << "StreamTypeFromSubtitleCodecContext not implemented";
222 abort();
221 } 223 }
222 224
223 // Creates an AVCodecContext from LpcmStreamType. 225 // Creates an AVCodecContext from an AudioStreamType.
224 AvCodecContextPtr CodecContextFromLpcmDetails( 226 AvCodecContextPtr AVCodecContextFromAudioStreamType(
225 const LpcmStreamType& stream_type) { 227 const AudioStreamType& stream_type) {
228 DCHECK(stream_type.medium() == StreamType::Medium::kAudio);
229
226 AVCodecID codec_id; 230 AVCodecID codec_id;
227 AVSampleFormat sample_format; 231 AVSampleFormat sample_format;
228 232
229 switch (stream_type.sample_format()) { 233 if (stream_type.encoding() == StreamType::kAudioEncodingLpcm) {
230 case LpcmStreamType::SampleFormat::kUnsigned8: 234 switch (stream_type.sample_format()) {
231 codec_id = AV_CODEC_ID_PCM_U8; 235 case AudioStreamType::SampleFormat::kUnsigned8:
232 sample_format = AV_SAMPLE_FMT_U8; 236 codec_id = AV_CODEC_ID_PCM_U8;
233 break; 237 sample_format = AV_SAMPLE_FMT_U8;
234 case LpcmStreamType::SampleFormat::kSigned16: 238 break;
235 codec_id = AV_CODEC_ID_PCM_S16LE; 239 case AudioStreamType::SampleFormat::kSigned16:
236 sample_format = AV_SAMPLE_FMT_S16; 240 codec_id = AV_CODEC_ID_PCM_S16LE;
237 break; 241 sample_format = AV_SAMPLE_FMT_S16;
238 case LpcmStreamType::SampleFormat::kSigned24In32: 242 break;
239 codec_id = AV_CODEC_ID_PCM_S24LE; 243 case AudioStreamType::SampleFormat::kSigned24In32:
240 sample_format = AV_SAMPLE_FMT_S32; 244 codec_id = AV_CODEC_ID_PCM_S24LE;
241 break; 245 sample_format = AV_SAMPLE_FMT_S32;
242 case LpcmStreamType::SampleFormat::kFloat: 246 break;
243 codec_id = AV_CODEC_ID_PCM_F32LE; 247 case AudioStreamType::SampleFormat::kFloat:
244 sample_format = AV_SAMPLE_FMT_FLT; 248 codec_id = AV_CODEC_ID_PCM_F32LE;
245 break; 249 sample_format = AV_SAMPLE_FMT_FLT;
246 default: 250 break;
247 return nullptr; 251 default:
252 LOG(ERROR) << "unsupported sample format";
253 abort();
254 }
255 } else if (stream_type.encoding() == StreamType::kAudioEncodingVorbis) {
256 codec_id = AV_CODEC_ID_VORBIS;
257 sample_format = AV_SAMPLE_FMT_S16;
258 } else {
259 LOG(ERROR) << "unsupported encoding " << stream_type.encoding();
260 abort();
248 } 261 }
249 262
250 AvCodecContextPtr context(avcodec_alloc_context3(nullptr)); 263 AvCodecContextPtr context(avcodec_alloc_context3(nullptr));
251
252 context->codec_type = AVMEDIA_TYPE_AUDIO;
253 context->codec_id = codec_id;
254 context->sample_fmt = sample_format;
255 context->channels = stream_type.channels();
256 context->sample_rate = stream_type.frames_per_second();
257
258 return context;
259 }
260
261 // Creates an AVCodecContext from CompressedAudioStreamType.
262 AvCodecContextPtr AVCodecContextFromCompressedAudioStreamType(
263 const CompressedAudioStreamType& stream_type) {
264 AVCodecID codec_id = AV_CODEC_ID_NONE;
265 AVSampleFormat sample_format;
266
267 switch (stream_type.encoding()) {
268 case CompressedAudioStreamType::AudioEncoding::kVorbis:
269 codec_id = AV_CODEC_ID_VORBIS;
270 sample_format = AV_SAMPLE_FMT_S16;
271 break;
272 default:
273 return nullptr;
274 }
275
276 if (codec_id == AV_CODEC_ID_NONE) {
277 return nullptr;
278 }
279
280 AvCodecContextPtr context(avcodec_alloc_context3(nullptr));
281 264
282 context->codec_type = AVMEDIA_TYPE_AUDIO; 265 context->codec_type = AVMEDIA_TYPE_AUDIO;
283 context->codec_id = codec_id; 266 context->codec_id = codec_id;
284 context->sample_fmt = sample_format; 267 context->sample_fmt = sample_format;
285 context->channels = stream_type.channels(); 268 context->channels = stream_type.channels();
286 context->sample_rate = stream_type.frames_per_second(); 269 context->sample_rate = stream_type.frames_per_second();
287 270
288 if (stream_type.encoding_details()) { 271 if (stream_type.encoding_parameters()) {
289 ExtraDataFromBytes(*stream_type.encoding_details(), context); 272 ExtraDataFromBytes(*stream_type.encoding_parameters(), context);
290 } 273 }
291 274
292 return context; 275 return context;
293 } 276 }
294 277
295 // Creats an AVCodecContext from VideoStreamTypeDetails. 278 // Creats an AVCodecContext from a VideoStreamType.
296 AvCodecContextPtr AVCodecContextFromVideoStreamType( 279 AvCodecContextPtr AVCodecContextFromVideoStreamType(
297 const VideoStreamType& stream_type) { 280 const VideoStreamType& stream_type) {
298 AVCodecID codec_id = AV_CODEC_ID_NONE; 281 AVCodecID codec_id = AV_CODEC_ID_NONE;
299 282
300 // TODO(dalesat): codec_id 283 // TODO(dalesat): codec_id
301 284
302 if (codec_id == AV_CODEC_ID_NONE) { 285 if (codec_id == AV_CODEC_ID_NONE) {
303 return nullptr; 286 return nullptr;
304 } 287 }
305 288
306 AvCodecContextPtr context(avcodec_alloc_context3(nullptr)); 289 AvCodecContextPtr context(avcodec_alloc_context3(nullptr));
307 290
308 context->codec_type = AVMEDIA_TYPE_VIDEO; 291 context->codec_type = AVMEDIA_TYPE_VIDEO;
309 context->codec_id = codec_id; 292 context->codec_id = codec_id;
310 context->profile = FfmpegProfileFromVideoProfile(stream_type.profile()); 293 context->profile = FfmpegProfileFromVideoProfile(stream_type.profile());
311 context->pix_fmt = AVPixelFormatFromPixelFormat(stream_type.pixel_format()); 294 context->pix_fmt = AVPixelFormatFromPixelFormat(stream_type.pixel_format());
312 if (stream_type.color_space() == VideoStreamType::ColorSpace::kJpeg) { 295 if (stream_type.color_space() == VideoStreamType::ColorSpace::kJpeg) {
313 context->color_range = AVCOL_RANGE_JPEG; 296 context->color_range = AVCOL_RANGE_JPEG;
314 } 297 }
315 context->coded_width = stream_type.coded_width(); 298 context->coded_width = stream_type.coded_width();
316 context->coded_height = stream_type.coded_height(); 299 context->coded_height = stream_type.coded_height();
317 300
318 if (stream_type.encoding_details()) { 301 if (stream_type.encoding_parameters()) {
319 ExtraDataFromBytes(*stream_type.encoding_details(), context); 302 ExtraDataFromBytes(*stream_type.encoding_parameters(), context);
320 } 303 }
321 304
322 return context; 305 return context;
323 } 306 }
324 307
308 // Creats an AVCodecContext from a TextStreamType.
309 AvCodecContextPtr AVCodecContextFromTextStreamType(
310 const TextStreamType& stream_type) {
311 // TODO(dalesat): Implement.
312 LOG(ERROR) << "AVCodecContextFromTextStreamType not implemented";
313 abort();
314 }
315
316 // Creats an AVCodecContext from a SubpictureStreamType.
317 AvCodecContextPtr AVCodecContextFromSubpictureStreamType(
318 const SubpictureStreamType& stream_type) {
319 // TODO(dalesat): Implement.
320 LOG(ERROR) << "AVCodecContextFromSupictureStreamType not implemented";
321 abort();
322 }
323
325 } // namespace 324 } // namespace
326 325
327 // static 326 // static
328 std::unique_ptr<StreamType> AvCodecContext::GetStreamType( 327 std::unique_ptr<StreamType> AvCodecContext::GetStreamType(
329 const AVCodecContext& from) { 328 const AVCodecContext& from) {
330 switch (from.codec_type) { 329 switch (from.codec_type) {
331 case AVMEDIA_TYPE_AUDIO: 330 case AVMEDIA_TYPE_AUDIO:
332 switch (from.codec_id) { 331 switch (from.codec_id) {
333 case CODEC_ID_PCM_S16BE: 332 case CODEC_ID_PCM_S16BE:
334 case CODEC_ID_PCM_S16LE: 333 case CODEC_ID_PCM_S16LE:
(...skipping 12 matching lines...) Expand all
347 return StreamTypeFromVideoCodecContext(from); 346 return StreamTypeFromVideoCodecContext(from);
348 case AVMEDIA_TYPE_UNKNOWN: 347 case AVMEDIA_TYPE_UNKNOWN:
349 // Treated as AVMEDIA_TYPE_DATA. 348 // Treated as AVMEDIA_TYPE_DATA.
350 case AVMEDIA_TYPE_DATA: 349 case AVMEDIA_TYPE_DATA:
351 return StreamTypeFromDataCodecContext(from); 350 return StreamTypeFromDataCodecContext(from);
352 case AVMEDIA_TYPE_SUBTITLE: 351 case AVMEDIA_TYPE_SUBTITLE:
353 return StreamTypeFromSubtitleCodecContext(from); 352 return StreamTypeFromSubtitleCodecContext(from);
354 case AVMEDIA_TYPE_ATTACHMENT: 353 case AVMEDIA_TYPE_ATTACHMENT:
355 case AVMEDIA_TYPE_NB: 354 case AVMEDIA_TYPE_NB:
356 default: 355 default:
357 return StreamType::Create(StreamType::Scheme::kUnknown); 356 LOG(ERROR) << "unsupported code type " << from.codec_type;
357 abort();
358 } 358 }
359 } 359 }
360 360
361 // static 361 // static
362 AvCodecContextPtr AvCodecContext::Create(const StreamType& stream_type) { 362 AvCodecContextPtr AvCodecContext::Create(const StreamType& stream_type) {
363 InitFfmpeg(); 363 InitFfmpeg();
364 364
365 switch (stream_type.scheme()) { 365 switch (stream_type.medium()) {
366 case StreamType::Scheme::kLpcm: 366 case StreamType::Medium::kAudio:
367 return CodecContextFromLpcmDetails(*stream_type.lpcm()); 367 return AVCodecContextFromAudioStreamType(*stream_type.audio());
368 case StreamType::Scheme::kCompressedAudio: 368 case StreamType::Medium::kVideo:
369 return AVCodecContextFromCompressedAudioStreamType(
370 *stream_type.compressed_audio());
371 case StreamType::Scheme::kVideo:
372 return AVCodecContextFromVideoStreamType(*stream_type.video()); 369 return AVCodecContextFromVideoStreamType(*stream_type.video());
370 case StreamType::Medium::kText:
371 return AVCodecContextFromTextStreamType(*stream_type.text());
372 case StreamType::Medium::kSubpicture:
373 return AVCodecContextFromSubpictureStreamType(*stream_type.subpicture());
373 default: 374 default:
374 return nullptr; 375 return nullptr;
375 } 376 }
376 } 377 }
377 378
378 } // namespace media 379 } // namespace media
379 } // namespace mojo 380 } // namespace mojo
OLDNEW
« no previous file with comments | « services/media/framework/stream_type.cc ('k') | services/media/framework_ffmpeg/ffmpeg_audio_decoder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698