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

Side by Side Diff: media/filters/chunk_demuxer.cc

Issue 12713004: Add Chromium-side changes for MediaSource::isTypeSupported() (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Relax DEPS strictness to media/filters & rebased. Created 7 years, 9 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 | Annotate | Revision Log
OLDNEW
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/chunk_demuxer.h" 5 #include "media/filters/chunk_demuxer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <deque> 8 #include <deque>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/callback_helpers.h" 11 #include "base/callback_helpers.h"
12 #include "base/location.h" 12 #include "base/location.h"
13 #include "base/logging.h"
14 #include "base/message_loop_proxy.h" 13 #include "base/message_loop_proxy.h"
15 #include "base/string_number_conversions.h"
16 #include "base/string_util.h"
17 #include "media/base/audio_decoder_config.h" 14 #include "media/base/audio_decoder_config.h"
18 #include "media/base/stream_parser_buffer.h" 15 #include "media/base/stream_parser_buffer.h"
19 #include "media/base/video_decoder_config.h" 16 #include "media/base/video_decoder_config.h"
20 #if defined(GOOGLE_CHROME_BUILD) || defined(USE_PROPRIETARY_CODECS) 17 #include "media/filters/stream_parser_factory.h"
21 #include "media/mp4/es_descriptor.h"
22 #include "media/mp4/mp4_stream_parser.h"
23 #endif
24 #include "media/webm/webm_stream_parser.h"
25 18
26 using base::TimeDelta; 19 using base::TimeDelta;
27 20
28 namespace media { 21 namespace media {
29 22
30 struct CodecInfo {
31 const char* pattern;
32 DemuxerStream::Type type;
33 };
34
35 typedef StreamParser* (*ParserFactoryFunction)(
36 const std::vector<std::string>& codecs, const LogCB& log_cb);
37
38 struct SupportedTypeInfo {
39 const char* type;
40 const ParserFactoryFunction factory_function;
41 const CodecInfo** codecs;
42 };
43
44 static const CodecInfo kVP8CodecInfo = { "vp8", DemuxerStream::VIDEO };
45 static const CodecInfo kVorbisCodecInfo = { "vorbis", DemuxerStream::AUDIO };
46
47 static const CodecInfo* kVideoWebMCodecs[] = {
48 &kVP8CodecInfo,
49 &kVorbisCodecInfo,
50 NULL
51 };
52
53 static const CodecInfo* kAudioWebMCodecs[] = {
54 &kVorbisCodecInfo,
55 NULL
56 };
57
58 static StreamParser* BuildWebMParser(const std::vector<std::string>& codecs,
59 const LogCB& log_cb) {
60 return new WebMStreamParser();
61 }
62
63 #if defined(GOOGLE_CHROME_BUILD) || defined(USE_PROPRIETARY_CODECS)
64 static const CodecInfo kH264CodecInfo = { "avc1.*", DemuxerStream::VIDEO };
65 static const CodecInfo kMPEG4AACCodecInfo = {
66 "mp4a.40.*", DemuxerStream::AUDIO
67 };
68
69 static const CodecInfo kMPEG2AACLCCodecInfo = {
70 "mp4a.67", DemuxerStream::AUDIO
71 };
72
73 static const CodecInfo* kVideoMP4Codecs[] = {
74 &kH264CodecInfo,
75 &kMPEG4AACCodecInfo,
76 &kMPEG2AACLCCodecInfo,
77 NULL
78 };
79
80 static const CodecInfo* kAudioMP4Codecs[] = {
81 &kMPEG4AACCodecInfo,
82 &kMPEG2AACLCCodecInfo,
83 NULL
84 };
85
86 // AAC Object Type IDs that Chrome supports.
87 static const int kAACLCObjectType = 2;
88 static const int kAACSBRObjectType = 5;
89
90 static StreamParser* BuildMP4Parser(const std::vector<std::string>& codecs,
91 const LogCB& log_cb) {
92 std::set<int> audio_object_types;
93 bool has_sbr = false;
94 for (size_t i = 0; i < codecs.size(); ++i) {
95 if (MatchPattern(codecs[i], kMPEG2AACLCCodecInfo.pattern)) {
96 audio_object_types.insert(mp4::kISO_13818_7_AAC_LC);
97 } else if (MatchPattern(codecs[i], kMPEG4AACCodecInfo.pattern)) {
98 std::vector<std::string> tokens;
99 int audio_object_type;
100 if (Tokenize(codecs[i], ".", &tokens) != 3 ||
101 !base::HexStringToInt(tokens[2], &audio_object_type)) {
102 MEDIA_LOG(log_cb) << "Malformed mimetype codec '" << codecs[i] << "'";
103 return NULL;
104 }
105
106 if (audio_object_type != kAACLCObjectType &&
107 audio_object_type != kAACSBRObjectType) {
108 MEDIA_LOG(log_cb) << "Unsupported audio object type "
109 << "0x" << std::hex << audio_object_type
110 << " in codec '" << codecs[i] << "'";
111 return NULL;
112 }
113
114 audio_object_types.insert(mp4::kISO_14496_3);
115
116 if (audio_object_type == kAACSBRObjectType) {
117 has_sbr = true;
118 break;
119 }
120 }
121 }
122
123 return new mp4::MP4StreamParser(audio_object_types, has_sbr);
124 }
125 #endif
126
127 static const SupportedTypeInfo kSupportedTypeInfo[] = {
128 { "video/webm", &BuildWebMParser, kVideoWebMCodecs },
129 { "audio/webm", &BuildWebMParser, kAudioWebMCodecs },
130 #if defined(GOOGLE_CHROME_BUILD) || defined(USE_PROPRIETARY_CODECS)
131 { "video/mp4", &BuildMP4Parser, kVideoMP4Codecs },
132 { "audio/mp4", &BuildMP4Parser, kAudioMP4Codecs },
133 #endif
134 };
135
136 // Checks to see if the specified |type| and |codecs| list are supported.
137 // Returns true if |type| and all codecs listed in |codecs| are supported.
138 // |factory_function| contains a function that can build a StreamParser
139 // for this type.
140 // |has_audio| is true if an audio codec was specified.
141 // |has_video| is true if a video codec was specified.
142 // Returns false otherwise. The values of |factory_function|, |has_audio|,
143 // and |has_video| are undefined.
144 static bool IsSupported(const std::string& type,
145 std::vector<std::string>& codecs,
146 const LogCB& log_cb,
147 ParserFactoryFunction* factory_function,
148 bool* has_audio,
149 bool* has_video) {
150 *factory_function = NULL;
151 *has_audio = false;
152 *has_video = false;
153
154 // Search for the SupportedTypeInfo for |type|.
155 for (size_t i = 0; i < arraysize(kSupportedTypeInfo); ++i) {
156 const SupportedTypeInfo& type_info = kSupportedTypeInfo[i];
157 if (type == type_info.type) {
158 // Make sure all the codecs specified in |codecs| are
159 // in the supported type info.
160 for (size_t j = 0; j < codecs.size(); ++j) {
161 // Search the type info for a match.
162 bool found_codec = false;
163 DemuxerStream::Type codec_type = DemuxerStream::UNKNOWN;
164
165 for (int k = 0; type_info.codecs[k]; ++k) {
166 if (MatchPattern(codecs[j], type_info.codecs[k]->pattern)) {
167 found_codec = true;
168 codec_type = type_info.codecs[k]->type;
169 break;
170 }
171 }
172
173 if (!found_codec) {
174 MEDIA_LOG(log_cb) << "Codec '" << codecs[j]
175 <<"' is not supported for '" << type << "'";
176 return false;
177 }
178
179 switch (codec_type) {
180 case DemuxerStream::AUDIO:
181 *has_audio = true;
182 break;
183 case DemuxerStream::VIDEO:
184 *has_video = true;
185 break;
186 default:
187 MEDIA_LOG(log_cb) << "Unsupported codec type '"<< codec_type
188 << "' for " << codecs[j];
189 return false;
190 }
191 }
192
193 *factory_function = type_info.factory_function;
194
195 // All codecs were supported by this |type|.
196 return true;
197 }
198 }
199
200 // |type| didn't match any of the supported types.
201 return false;
202 }
203 23
204 class ChunkDemuxerStream : public DemuxerStream { 24 class ChunkDemuxerStream : public DemuxerStream {
205 public: 25 public:
206 typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue; 26 typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue;
207 typedef std::deque<ReadCB> ReadCBQueue; 27 typedef std::deque<ReadCB> ReadCBQueue;
208 typedef std::deque<base::Closure> ClosureQueue; 28 typedef std::deque<base::Closure> ClosureQueue;
209 29
210 ChunkDemuxerStream(const AudioDecoderConfig& audio_config, 30 ChunkDemuxerStream(const AudioDecoderConfig& audio_config,
211 const LogCB& log_cb); 31 const LogCB& log_cb);
212 ChunkDemuxerStream(const VideoDecoderConfig& video_config, 32 ChunkDemuxerStream(const VideoDecoderConfig& video_config,
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 std::vector<std::string>& codecs) { 530 std::vector<std::string>& codecs) {
711 DCHECK_GT(codecs.size(), 0u); 531 DCHECK_GT(codecs.size(), 0u);
712 base::AutoLock auto_lock(lock_); 532 base::AutoLock auto_lock(lock_);
713 533
714 if ((state_ != WAITING_FOR_INIT && state_ != INITIALIZING) || 534 if ((state_ != WAITING_FOR_INIT && state_ != INITIALIZING) ||
715 stream_parser_map_.count(id) > 0u) 535 stream_parser_map_.count(id) > 0u)
716 return kReachedIdLimit; 536 return kReachedIdLimit;
717 537
718 bool has_audio = false; 538 bool has_audio = false;
719 bool has_video = false; 539 bool has_video = false;
720 ParserFactoryFunction factory_function = NULL; 540 scoped_ptr<media::StreamParser> stream_parser(
721 std::string error; 541 StreamParserFactory::Create(type, codecs, log_cb_,
722 if (!IsSupported(type, codecs, log_cb_, &factory_function, &has_audio, 542 &has_audio, &has_video));
723 &has_video)) { 543
724 return kNotSupported; 544 if (!stream_parser)
725 } 545 return ChunkDemuxer::kNotSupported;
726 546
727 if ((has_audio && !source_id_audio_.empty()) || 547 if ((has_audio && !source_id_audio_.empty()) ||
728 (has_video && !source_id_video_.empty())) 548 (has_video && !source_id_video_.empty()))
729 return kReachedIdLimit; 549 return kReachedIdLimit;
730 550
731 StreamParser::NewBuffersCB audio_cb; 551 StreamParser::NewBuffersCB audio_cb;
732 StreamParser::NewBuffersCB video_cb; 552 StreamParser::NewBuffersCB video_cb;
733 553
734 scoped_ptr<StreamParser> stream_parser(factory_function(codecs, log_cb_));
735 if (!stream_parser)
736 return kNotSupported;
737
738 if (has_audio) { 554 if (has_audio) {
739 source_id_audio_ = id; 555 source_id_audio_ = id;
740 audio_cb = base::Bind(&ChunkDemuxer::OnAudioBuffers, 556 audio_cb = base::Bind(&ChunkDemuxer::OnAudioBuffers,
741 base::Unretained(this)); 557 base::Unretained(this));
742 } 558 }
743 559
744 if (has_video) { 560 if (has_video) {
745 source_id_video_ = id; 561 source_id_video_ = id;
746 video_cb = base::Bind(&ChunkDemuxer::OnVideoBuffers, 562 video_cb = base::Bind(&ChunkDemuxer::OnVideoBuffers,
747 base::Unretained(this)); 563 base::Unretained(this));
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after
1335 1151
1336 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges() const { 1152 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges() const {
1337 if (audio_ && !video_) 1153 if (audio_ && !video_)
1338 return audio_->GetBufferedRanges(duration_); 1154 return audio_->GetBufferedRanges(duration_);
1339 else if (!audio_ && video_) 1155 else if (!audio_ && video_)
1340 return video_->GetBufferedRanges(duration_); 1156 return video_->GetBufferedRanges(duration_);
1341 return ComputeIntersection(); 1157 return ComputeIntersection();
1342 } 1158 }
1343 1159
1344 } // namespace media 1160 } // namespace media
OLDNEW
« no previous file with comments | « content/worker/worker_webkitplatformsupport_impl.cc ('k') | media/filters/stream_parser_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698