Chromium Code Reviews| 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/filters/ffmpeg_demuxer.h" | 5 #include "media/filters/ffmpeg_demuxer.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/base64.h" | 10 #include "base/base64.h" |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/callback.h" | 12 #include "base/callback.h" |
| 13 #include "base/callback_helpers.h" | 13 #include "base/callback_helpers.h" |
| 14 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
| 15 #include "base/message_loop/message_loop_proxy.h" | 15 #include "base/message_loop/message_loop_proxy.h" |
| 16 #include "base/metrics/sparse_histogram.h" | 16 #include "base/metrics/sparse_histogram.h" |
| 17 #include "base/strings/string_number_conversions.h" | |
| 17 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
| 18 #include "base/strings/stringprintf.h" | 19 #include "base/strings/stringprintf.h" |
| 19 #include "base/sys_byteorder.h" | 20 #include "base/sys_byteorder.h" |
| 20 #include "base/task_runner_util.h" | 21 #include "base/task_runner_util.h" |
| 21 #include "base/time/time.h" | 22 #include "base/time/time.h" |
| 22 #include "media/base/audio_decoder_config.h" | 23 #include "media/base/audio_decoder_config.h" |
| 23 #include "media/base/bind_to_current_loop.h" | 24 #include "media/base/bind_to_current_loop.h" |
| 24 #include "media/base/decoder_buffer.h" | 25 #include "media/base/decoder_buffer.h" |
| 25 #include "media/base/decrypt_config.h" | 26 #include "media/base/decrypt_config.h" |
| 26 #include "media/base/limits.h" | 27 #include "media/base/limits.h" |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 84 // | 85 // |
| 85 // FFmpegDemuxerStream | 86 // FFmpegDemuxerStream |
| 86 // | 87 // |
| 87 FFmpegDemuxerStream::FFmpegDemuxerStream(FFmpegDemuxer* demuxer, | 88 FFmpegDemuxerStream::FFmpegDemuxerStream(FFmpegDemuxer* demuxer, |
| 88 AVStream* stream) | 89 AVStream* stream) |
| 89 : demuxer_(demuxer), | 90 : demuxer_(demuxer), |
| 90 task_runner_(base::MessageLoopProxy::current()), | 91 task_runner_(base::MessageLoopProxy::current()), |
| 91 stream_(stream), | 92 stream_(stream), |
| 92 type_(UNKNOWN), | 93 type_(UNKNOWN), |
| 93 end_of_stream_(false), | 94 end_of_stream_(false), |
| 94 last_packet_timestamp_(kNoTimestamp()), | 95 last_packet_timestamp_(kNoTimestamp()), |
|
scherkus (not reviewing)
2014/07/07 23:58:45
don't forget to initialize video_rotation_!
| |
| 95 bitstream_converter_enabled_(false), | 96 bitstream_converter_enabled_(false), |
| 96 fixup_negative_ogg_timestamps_(false) { | 97 fixup_negative_ogg_timestamps_(false) { |
| 97 DCHECK(demuxer_); | 98 DCHECK(demuxer_); |
| 98 | 99 |
| 99 bool is_encrypted = false; | 100 bool is_encrypted = false; |
| 101 int rotation = 0; | |
| 102 AVDictionaryEntry* rotation_entry = NULL; | |
| 100 | 103 |
| 101 // Determine our media format. | 104 // Determine our media format. |
| 102 switch (stream->codec->codec_type) { | 105 switch (stream->codec->codec_type) { |
| 103 case AVMEDIA_TYPE_AUDIO: | 106 case AVMEDIA_TYPE_AUDIO: |
| 104 type_ = AUDIO; | 107 type_ = AUDIO; |
| 105 AVStreamToAudioDecoderConfig(stream, &audio_config_, true); | 108 AVStreamToAudioDecoderConfig(stream, &audio_config_, true); |
| 106 is_encrypted = audio_config_.is_encrypted(); | 109 is_encrypted = audio_config_.is_encrypted(); |
| 107 break; | 110 break; |
| 108 case AVMEDIA_TYPE_VIDEO: | 111 case AVMEDIA_TYPE_VIDEO: |
| 109 type_ = VIDEO; | 112 type_ = VIDEO; |
| 110 AVStreamToVideoDecoderConfig(stream, &video_config_, true); | 113 AVStreamToVideoDecoderConfig(stream, &video_config_, true); |
| 111 is_encrypted = video_config_.is_encrypted(); | 114 is_encrypted = video_config_.is_encrypted(); |
| 115 | |
| 116 // Extract rotation metadata | |
|
scherkus (not reviewing)
2014/07/07 23:58:45
add period to ... or just remove the comment entir
| |
| 117 rotation_entry = av_dict_get(stream->metadata, "rotate", NULL, 0); | |
| 118 if (rotation_entry && rotation_entry->value && rotation_entry->value[0]) | |
| 119 base::StringToInt(rotation_entry->value, &rotation); | |
| 120 | |
| 121 switch (rotation) { | |
| 122 case 90: | |
| 123 set_video_rotation(VIDEO_ROTATION_90); | |
|
scherkus (not reviewing)
2014/07/07 23:58:45
instead of these setters, just set video_rotation_
| |
| 124 break; | |
| 125 case 180: | |
| 126 set_video_rotation(VIDEO_ROTATION_180); | |
| 127 break; | |
| 128 case 270: | |
| 129 set_video_rotation(VIDEO_ROTATION_270); | |
| 130 break; | |
| 131 case 0: | |
| 132 set_video_rotation(VIDEO_ROTATION_0); | |
| 133 break; | |
| 134 default: | |
| 135 set_video_rotation(VIDEO_ROTATION_0); | |
|
scherkus (not reviewing)
2014/07/07 23:58:45
nit: since you'll have initialized this in the cto
| |
| 136 LOG(ERROR) << "Unsupported video rotation metadata: " << rotation; | |
| 137 break; | |
| 138 } | |
| 139 | |
| 112 break; | 140 break; |
| 113 case AVMEDIA_TYPE_SUBTITLE: | 141 case AVMEDIA_TYPE_SUBTITLE: |
| 114 type_ = TEXT; | 142 type_ = TEXT; |
| 115 break; | 143 break; |
| 116 default: | 144 default: |
| 117 NOTREACHED(); | 145 NOTREACHED(); |
| 118 break; | 146 break; |
| 119 } | 147 } |
| 120 | 148 |
| 121 // Calculate the duration. | 149 // Calculate the duration. |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 373 CHECK_EQ(type_, AUDIO); | 401 CHECK_EQ(type_, AUDIO); |
| 374 return audio_config_; | 402 return audio_config_; |
| 375 } | 403 } |
| 376 | 404 |
| 377 VideoDecoderConfig FFmpegDemuxerStream::video_decoder_config() { | 405 VideoDecoderConfig FFmpegDemuxerStream::video_decoder_config() { |
| 378 DCHECK(task_runner_->BelongsToCurrentThread()); | 406 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 379 CHECK_EQ(type_, VIDEO); | 407 CHECK_EQ(type_, VIDEO); |
| 380 return video_config_; | 408 return video_config_; |
| 381 } | 409 } |
| 382 | 410 |
| 411 VideoRotation FFmpegDemuxerStream::video_rotation() { | |
| 412 return video_rotation_; | |
| 413 } | |
| 414 | |
| 415 void FFmpegDemuxerStream::set_video_rotation(VideoRotation video_rotation) { | |
| 416 video_rotation_ = video_rotation; | |
| 417 } | |
| 418 | |
| 383 FFmpegDemuxerStream::~FFmpegDemuxerStream() { | 419 FFmpegDemuxerStream::~FFmpegDemuxerStream() { |
| 384 DCHECK(!demuxer_); | 420 DCHECK(!demuxer_); |
| 385 DCHECK(read_cb_.is_null()); | 421 DCHECK(read_cb_.is_null()); |
| 386 DCHECK(buffer_queue_.IsEmpty()); | 422 DCHECK(buffer_queue_.IsEmpty()); |
| 387 } | 423 } |
| 388 | 424 |
| 389 base::TimeDelta FFmpegDemuxerStream::GetElapsedTime() const { | 425 base::TimeDelta FFmpegDemuxerStream::GetElapsedTime() const { |
| 390 return ConvertStreamTimestamp(stream_->time_base, stream_->cur_dts); | 426 return ConvertStreamTimestamp(stream_->time_base, stream_->cur_dts); |
| 391 } | 427 } |
| 392 | 428 |
| (...skipping 774 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1167 } | 1203 } |
| 1168 for (size_t i = 0; i < buffered.size(); ++i) | 1204 for (size_t i = 0; i < buffered.size(); ++i) |
| 1169 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i)); | 1205 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i)); |
| 1170 } | 1206 } |
| 1171 | 1207 |
| 1172 void FFmpegDemuxer::OnDataSourceError() { | 1208 void FFmpegDemuxer::OnDataSourceError() { |
| 1173 host_->OnDemuxerError(PIPELINE_ERROR_READ); | 1209 host_->OnDemuxerError(PIPELINE_ERROR_READ); |
| 1174 } | 1210 } |
| 1175 | 1211 |
| 1176 } // namespace media | 1212 } // namespace media |
| OLD | NEW |