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 // Implements a Demuxer that can switch among different data sources mid-stream. | 5 // Implements a Demuxer that can switch among different data sources mid-stream. |
6 // Uses FFmpegDemuxer under the covers, so see the caveats at the top of | 6 // Uses FFmpegDemuxer under the covers, so see the caveats at the top of |
7 // ffmpeg_demuxer.h. | 7 // ffmpeg_demuxer.h. |
8 | 8 |
9 #include "media/filters/chunk_demuxer.h" | 9 #include "media/filters/chunk_demuxer.h" |
10 | 10 |
(...skipping 13 matching lines...) Expand all Loading... | |
24 | 24 |
25 namespace media { | 25 namespace media { |
26 | 26 |
27 // WebM File Header. This is prepended to the INFO & TRACKS | 27 // WebM File Header. This is prepended to the INFO & TRACKS |
28 // data passed to Init() before handing it to FFmpeg. Essentially | 28 // data passed to Init() before handing it to FFmpeg. Essentially |
29 // we are making the INFO & TRACKS data look like a small WebM | 29 // we are making the INFO & TRACKS data look like a small WebM |
30 // file so we can use FFmpeg to initialize the AVFormatContext. | 30 // file so we can use FFmpeg to initialize the AVFormatContext. |
31 // | 31 // |
32 // TODO(acolwell): Remove this once GetAVStream() has been removed from | 32 // TODO(acolwell): Remove this once GetAVStream() has been removed from |
33 // the DemuxerStream interface. | 33 // the DemuxerStream interface. |
34 // ^^^^^^^^^^^ IS THIS STILL NEEDED? ^^^^^^^^^^^^ | |
acolwell GONE FROM CHROMIUM
2011/10/26 17:09:13
For now yes since we still need an AVStream to con
scherkus (not reviewing)
2011/10/26 19:08:00
Done.
| |
34 static const uint8 kWebMHeader[] = { | 35 static const uint8 kWebMHeader[] = { |
35 0x1A, 0x45, 0xDF, 0xA3, 0x9F, // EBML (size = 0x1f) | 36 0x1A, 0x45, 0xDF, 0xA3, 0x9F, // EBML (size = 0x1f) |
36 0x42, 0x86, 0x81, 0x01, // EBMLVersion = 1 | 37 0x42, 0x86, 0x81, 0x01, // EBMLVersion = 1 |
37 0x42, 0xF7, 0x81, 0x01, // EBMLReadVersion = 1 | 38 0x42, 0xF7, 0x81, 0x01, // EBMLReadVersion = 1 |
38 0x42, 0xF2, 0x81, 0x04, // EBMLMaxIDLength = 4 | 39 0x42, 0xF2, 0x81, 0x04, // EBMLMaxIDLength = 4 |
39 0x42, 0xF3, 0x81, 0x08, // EBMLMaxSizeLength = 8 | 40 0x42, 0xF3, 0x81, 0x08, // EBMLMaxSizeLength = 8 |
40 0x42, 0x82, 0x84, 0x77, 0x65, 0x62, 0x6D, // DocType = "webm" | 41 0x42, 0x82, 0x84, 0x77, 0x65, 0x62, 0x6D, // DocType = "webm" |
41 0x42, 0x87, 0x81, 0x02, // DocTypeVersion = 2 | 42 0x42, 0x87, 0x81, 0x02, // DocTypeVersion = 2 |
42 0x42, 0x85, 0x81, 0x02, // DocTypeReadVersion = 2 | 43 0x42, 0x85, 0x81, 0x02, // DocTypeReadVersion = 2 |
43 // EBML end | 44 // EBML end |
(...skipping 28 matching lines...) Expand all Loading... | |
72 | 73 |
73 void AddBuffers(const BufferQueue& buffers); | 74 void AddBuffers(const BufferQueue& buffers); |
74 void Shutdown(); | 75 void Shutdown(); |
75 | 76 |
76 bool GetLastBufferTimestamp(base::TimeDelta* timestamp) const; | 77 bool GetLastBufferTimestamp(base::TimeDelta* timestamp) const; |
77 | 78 |
78 // DemuxerStream methods. | 79 // DemuxerStream methods. |
79 virtual void Read(const ReadCallback& read_callback); | 80 virtual void Read(const ReadCallback& read_callback); |
80 virtual Type type(); | 81 virtual Type type(); |
81 virtual void EnableBitstreamConverter(); | 82 virtual void EnableBitstreamConverter(); |
82 virtual AVStream* GetAVStream(); | |
83 virtual const AudioDecoderConfig& audio_decoder_config(); | 83 virtual const AudioDecoderConfig& audio_decoder_config(); |
84 virtual const VideoDecoderConfig& video_decoder_config(); | |
84 | 85 |
85 private: | 86 private: |
86 Type type_; | 87 Type type_; |
87 AVStream* av_stream_; | 88 AVStream* av_stream_; |
88 AudioDecoderConfig audio_config_; | 89 AudioDecoderConfig audio_config_; |
90 VideoDecoderConfig video_config_; | |
89 | 91 |
90 mutable base::Lock lock_; | 92 mutable base::Lock lock_; |
91 ReadCBQueue read_cbs_; | 93 ReadCBQueue read_cbs_; |
92 BufferQueue buffers_; | 94 BufferQueue buffers_; |
93 bool shutdown_called_; | 95 bool shutdown_called_; |
94 bool received_end_of_stream_; | 96 bool received_end_of_stream_; |
95 | 97 |
96 // Keeps track of the timestamp of the last buffer we have | 98 // Keeps track of the timestamp of the last buffer we have |
97 // added to |buffers_|. This is used to enforce buffers with strictly | 99 // added to |buffers_|. This is used to enforce buffers with strictly |
98 // monotonically increasing timestamps. | 100 // monotonically increasing timestamps. |
99 base::TimeDelta last_buffer_timestamp_; | 101 base::TimeDelta last_buffer_timestamp_; |
100 | 102 |
101 DISALLOW_IMPLICIT_CONSTRUCTORS(ChunkDemuxerStream); | 103 DISALLOW_IMPLICIT_CONSTRUCTORS(ChunkDemuxerStream); |
102 }; | 104 }; |
103 | 105 |
104 ChunkDemuxerStream::ChunkDemuxerStream(Type type, AVStream* stream) | 106 ChunkDemuxerStream::ChunkDemuxerStream(Type type, AVStream* stream) |
105 : type_(type), | 107 : type_(type), |
106 av_stream_(stream), | 108 av_stream_(stream), |
107 shutdown_called_(false), | 109 shutdown_called_(false), |
108 received_end_of_stream_(false), | 110 received_end_of_stream_(false), |
109 last_buffer_timestamp_(kNoTimestamp) { | 111 last_buffer_timestamp_(kNoTimestamp) { |
110 if (type_ == AUDIO) { | 112 if (type_ == AUDIO) { |
111 AVCodecContextToAudioDecoderConfig(stream->codec, &audio_config_); | 113 AVCodecContextToAudioDecoderConfig(stream->codec, &audio_config_); |
114 } else if (type_ == VIDEO) { | |
115 AVCodecContextToVideoDecoderConfig(stream->codec, | |
116 stream->r_frame_rate, | |
117 GetAspectRatio(stream), | |
118 &video_config_); | |
112 } | 119 } |
113 } | 120 } |
114 | 121 |
115 ChunkDemuxerStream::~ChunkDemuxerStream() {} | 122 ChunkDemuxerStream::~ChunkDemuxerStream() {} |
116 | 123 |
117 void ChunkDemuxerStream::Flush() { | 124 void ChunkDemuxerStream::Flush() { |
118 VLOG(1) << "Flush()"; | 125 VLOG(1) << "Flush()"; |
119 base::AutoLock auto_lock(lock_); | 126 base::AutoLock auto_lock(lock_); |
120 buffers_.clear(); | 127 buffers_.clear(); |
121 received_end_of_stream_ = false; | 128 received_end_of_stream_ = false; |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
264 } | 271 } |
265 | 272 |
266 DCHECK(buffer.get()); | 273 DCHECK(buffer.get()); |
267 read_callback.Run(buffer); | 274 read_callback.Run(buffer); |
268 } | 275 } |
269 | 276 |
270 DemuxerStream::Type ChunkDemuxerStream::type() { return type_; } | 277 DemuxerStream::Type ChunkDemuxerStream::type() { return type_; } |
271 | 278 |
272 void ChunkDemuxerStream::EnableBitstreamConverter() {} | 279 void ChunkDemuxerStream::EnableBitstreamConverter() {} |
273 | 280 |
274 AVStream* ChunkDemuxerStream::GetAVStream() { return av_stream_; } | |
275 | |
276 const AudioDecoderConfig& ChunkDemuxerStream::audio_decoder_config() { | 281 const AudioDecoderConfig& ChunkDemuxerStream::audio_decoder_config() { |
277 CHECK_EQ(type_, AUDIO); | 282 CHECK_EQ(type_, AUDIO); |
278 return audio_config_; | 283 return audio_config_; |
279 } | 284 } |
280 | 285 |
286 const VideoDecoderConfig& ChunkDemuxerStream::video_decoder_config() { | |
287 CHECK_EQ(type_, VIDEO); | |
288 return video_config_; | |
289 } | |
290 | |
281 ChunkDemuxer::ChunkDemuxer(ChunkDemuxerClient* client) | 291 ChunkDemuxer::ChunkDemuxer(ChunkDemuxerClient* client) |
282 : state_(WAITING_FOR_INIT), | 292 : state_(WAITING_FOR_INIT), |
283 client_(client), | 293 client_(client), |
284 format_context_(NULL), | 294 format_context_(NULL), |
285 buffered_bytes_(0), | 295 buffered_bytes_(0), |
286 seek_waits_for_data_(true) { | 296 seek_waits_for_data_(true) { |
287 DCHECK(client); | 297 DCHECK(client); |
288 } | 298 } |
289 | 299 |
290 ChunkDemuxer::~ChunkDemuxer() { | 300 ChunkDemuxer::~ChunkDemuxer() { |
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
731 base::AutoUnlock auto_unlock(lock_); | 741 base::AutoUnlock auto_unlock(lock_); |
732 if (cb.is_null()) { | 742 if (cb.is_null()) { |
733 host()->SetError(error); | 743 host()->SetError(error); |
734 return; | 744 return; |
735 } | 745 } |
736 cb.Run(error); | 746 cb.Run(error); |
737 } | 747 } |
738 } | 748 } |
739 | 749 |
740 } // namespace media | 750 } // namespace media |
OLD | NEW |