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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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()), |
| 96 video_rotation_(VIDEO_ROTATION_0), |
95 bitstream_converter_enabled_(false), | 97 bitstream_converter_enabled_(false), |
96 fixup_negative_ogg_timestamps_(false) { | 98 fixup_negative_ogg_timestamps_(false) { |
97 DCHECK(demuxer_); | 99 DCHECK(demuxer_); |
98 | 100 |
99 bool is_encrypted = false; | 101 bool is_encrypted = false; |
| 102 int rotation = 0; |
| 103 AVDictionaryEntry* rotation_entry = NULL; |
100 | 104 |
101 // Determine our media format. | 105 // Determine our media format. |
102 switch (stream->codec->codec_type) { | 106 switch (stream->codec->codec_type) { |
103 case AVMEDIA_TYPE_AUDIO: | 107 case AVMEDIA_TYPE_AUDIO: |
104 type_ = AUDIO; | 108 type_ = AUDIO; |
105 AVStreamToAudioDecoderConfig(stream, &audio_config_, true); | 109 AVStreamToAudioDecoderConfig(stream, &audio_config_, true); |
106 is_encrypted = audio_config_.is_encrypted(); | 110 is_encrypted = audio_config_.is_encrypted(); |
107 break; | 111 break; |
108 case AVMEDIA_TYPE_VIDEO: | 112 case AVMEDIA_TYPE_VIDEO: |
109 type_ = VIDEO; | 113 type_ = VIDEO; |
110 AVStreamToVideoDecoderConfig(stream, &video_config_, true); | 114 AVStreamToVideoDecoderConfig(stream, &video_config_, true); |
111 is_encrypted = video_config_.is_encrypted(); | 115 is_encrypted = video_config_.is_encrypted(); |
| 116 |
| 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 0: |
| 123 break; |
| 124 case 90: |
| 125 video_rotation_ = VIDEO_ROTATION_90; |
| 126 break; |
| 127 case 180: |
| 128 video_rotation_ = VIDEO_ROTATION_180; |
| 129 break; |
| 130 case 270: |
| 131 video_rotation_ = VIDEO_ROTATION_270; |
| 132 break; |
| 133 default: |
| 134 LOG(ERROR) << "Unsupported video rotation metadata: " << rotation; |
| 135 break; |
| 136 } |
| 137 |
112 break; | 138 break; |
113 case AVMEDIA_TYPE_SUBTITLE: | 139 case AVMEDIA_TYPE_SUBTITLE: |
114 type_ = TEXT; | 140 type_ = TEXT; |
115 break; | 141 break; |
116 default: | 142 default: |
117 NOTREACHED(); | 143 NOTREACHED(); |
118 break; | 144 break; |
119 } | 145 } |
120 | 146 |
121 // Calculate the duration. | 147 // Calculate the duration. |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 CHECK_EQ(type_, AUDIO); | 399 CHECK_EQ(type_, AUDIO); |
374 return audio_config_; | 400 return audio_config_; |
375 } | 401 } |
376 | 402 |
377 VideoDecoderConfig FFmpegDemuxerStream::video_decoder_config() { | 403 VideoDecoderConfig FFmpegDemuxerStream::video_decoder_config() { |
378 DCHECK(task_runner_->BelongsToCurrentThread()); | 404 DCHECK(task_runner_->BelongsToCurrentThread()); |
379 CHECK_EQ(type_, VIDEO); | 405 CHECK_EQ(type_, VIDEO); |
380 return video_config_; | 406 return video_config_; |
381 } | 407 } |
382 | 408 |
| 409 VideoRotation FFmpegDemuxerStream::video_rotation() { |
| 410 return video_rotation_; |
| 411 } |
| 412 |
383 FFmpegDemuxerStream::~FFmpegDemuxerStream() { | 413 FFmpegDemuxerStream::~FFmpegDemuxerStream() { |
384 DCHECK(!demuxer_); | 414 DCHECK(!demuxer_); |
385 DCHECK(read_cb_.is_null()); | 415 DCHECK(read_cb_.is_null()); |
386 DCHECK(buffer_queue_.IsEmpty()); | 416 DCHECK(buffer_queue_.IsEmpty()); |
387 } | 417 } |
388 | 418 |
389 base::TimeDelta FFmpegDemuxerStream::GetElapsedTime() const { | 419 base::TimeDelta FFmpegDemuxerStream::GetElapsedTime() const { |
390 return ConvertStreamTimestamp(stream_->time_base, stream_->cur_dts); | 420 return ConvertStreamTimestamp(stream_->time_base, stream_->cur_dts); |
391 } | 421 } |
392 | 422 |
(...skipping 774 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1167 } | 1197 } |
1168 for (size_t i = 0; i < buffered.size(); ++i) | 1198 for (size_t i = 0; i < buffered.size(); ++i) |
1169 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i)); | 1199 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i)); |
1170 } | 1200 } |
1171 | 1201 |
1172 void FFmpegDemuxer::OnDataSourceError() { | 1202 void FFmpegDemuxer::OnDataSourceError() { |
1173 host_->OnDemuxerError(PIPELINE_ERROR_READ); | 1203 host_->OnDemuxerError(PIPELINE_ERROR_READ); |
1174 } | 1204 } |
1175 | 1205 |
1176 } // namespace media | 1206 } // namespace media |
OLD | NEW |