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

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

Issue 11492003: Encrypted Media: Support Audio Decrypt-Only. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: resolved comments and fixed unittest Created 8 years 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "media/filters/audio_decoder_selector.h"
6
7 #include "base/bind.h"
8 #include "base/callback_helpers.h"
9 #include "base/logging.h"
10 #include "base/message_loop_proxy.h"
11 #include "media/base/audio_decoder_config.h"
12 #include "media/base/bind_to_loop.h"
13 #include "media/base/demuxer_stream.h"
14 #include "media/base/pipeline.h"
15 #include "media/filters/decrypting_audio_decoder.h"
16 #include "media/filters/decrypting_demuxer_stream.h"
17
18 namespace media {
19
20 AudioDecoderSelector::AudioDecoderSelector(
21 const scoped_refptr<base::MessageLoopProxy>& message_loop,
22 const AudioDecoderList& clear_decoders,
23 const SetDecryptorReadyCB& set_decryptor_ready_cb)
24 : message_loop_(message_loop),
25 clear_decoders_(clear_decoders),
26 set_decryptor_ready_cb_(set_decryptor_ready_cb),
27 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)),
28 weak_this_(weak_ptr_factory_.GetWeakPtr()) {
scherkus (not reviewing) 2012/12/13 23:39:07 nit: if this is created on the same thread as Sele
xhwang 2012/12/14 03:16:21 Done.
29 }
30
31 AudioDecoderSelector::~AudioDecoderSelector() {}
32
33 void AudioDecoderSelector::SelectAudioDecoder(
34 const scoped_refptr<DemuxerStream>& stream,
35 const StatisticsCB& statistics_cb,
36 const SelectDecoderCB& select_decoder_cb) {
37 DVLOG(2) << "SelectAudioDecoder()";
38 DCHECK(message_loop_->BelongsToCurrentThread());
39 DCHECK(stream);
40
41 // Make sure the |selected_decoder_cb| on a different execution stack.
42 select_decoder_cb_ = BindToCurrentLoop(select_decoder_cb);
43
44 const AudioDecoderConfig& config = stream->audio_decoder_config();
45 if (!config.IsValidConfig()) {
46 DLOG(ERROR) << "Invalid audio stream config.";
47 base::ResetAndReturn(&select_decoder_cb_).Run(NULL, NULL);
48 return;
49 }
50
51 input_stream_ = stream;
scherkus (not reviewing) 2012/12/13 23:39:07 nit: your call, but I think we can be fancy here a
xhwang 2012/12/14 03:16:21 hmm, I'd keep the current way.. Passing them aroun
52 statistics_cb_ = statistics_cb;
53
54 if (!config.is_encrypted()) {
55 if (clear_decoders_.empty()) {
56 DLOG(ERROR) << "No audio decoder can be used to decode the input stream.";
57 base::ResetAndReturn(&select_decoder_cb_).Run(NULL, NULL);
58 return;
59 }
60
61 InitializeNextClearDecoder();
62 return;
63 }
64
65 // This could happen if Encrypted Media Extension (EME) is not enabled.
66 if (set_decryptor_ready_cb_.is_null()) {
67 base::ResetAndReturn(&select_decoder_cb_).Run(NULL, NULL);
68 return;
69 }
70
71 audio_decoder_ = new DecryptingAudioDecoder(message_loop_,
72 set_decryptor_ready_cb_);
73
74 audio_decoder_->Initialize(
75 input_stream_,
76 BindToCurrentLoop(base::Bind(
scherkus (not reviewing) 2012/12/13 23:39:07 hmmm... we really shouldn't be so paranoid about b
xhwang 2012/12/14 03:16:21 Now FFmpegAudioDecoder and AudioDecoderImpl all ru
77 &AudioDecoderSelector::DecryptingAudioDecoderInitDone, weak_this_)),
78 statistics_cb_);
79 }
80
81 void AudioDecoderSelector::DecryptingAudioDecoderInitDone(
82 PipelineStatus status) {
83 DCHECK(message_loop_->BelongsToCurrentThread());
84
85 if (status == PIPELINE_OK) {
86 clear_decoders_.clear();
87 base::ResetAndReturn(&select_decoder_cb_).Run(audio_decoder_, NULL);
88 return;
89 }
90
91 audio_decoder_ = NULL;
92
93 if (clear_decoders_.empty()) {
94 DLOG(ERROR) << "No audio decoder can be used to decode the input stream.";
95 base::ResetAndReturn(&select_decoder_cb_).Run(NULL, NULL);
96 return;
97 }
98
99 decrypted_stream_ = new DecryptingDemuxerStream(
100 message_loop_, set_decryptor_ready_cb_);
101
102 decrypted_stream_->Initialize(
103 input_stream_,
104 BindToCurrentLoop(base::Bind(
105 &AudioDecoderSelector::DecryptingDemuxerStreamInitDone, weak_this_)));
106 }
107
108 void AudioDecoderSelector::DecryptingDemuxerStreamInitDone(
109 PipelineStatus status) {
110 DCHECK(message_loop_->BelongsToCurrentThread());
111
112 if (status != PIPELINE_OK) {
113 decrypted_stream_ = NULL;
114 base::ResetAndReturn(&select_decoder_cb_).Run(NULL, NULL);
115 return;
116 }
117
118 DCHECK(!decrypted_stream_->audio_decoder_config().is_encrypted());
119 input_stream_ = decrypted_stream_;
120 InitializeNextClearDecoder();
121 }
122
123 void AudioDecoderSelector::InitializeNextClearDecoder() {
124 DCHECK(message_loop_->BelongsToCurrentThread());
125 DCHECK(!clear_decoders_.empty());
126
127 audio_decoder_ = clear_decoders_.front();
128 clear_decoders_.pop_front();
129 DCHECK(audio_decoder_);
130 audio_decoder_->Initialize(
131 input_stream_,
132 BindToCurrentLoop(base::Bind(
133 &AudioDecoderSelector::ClearDecoderInitDone, weak_this_)),
134 statistics_cb_);
135 }
136
137 void AudioDecoderSelector::ClearDecoderInitDone(PipelineStatus status) {
138 DCHECK(message_loop_->BelongsToCurrentThread());
139
140 if (status != PIPELINE_OK) {
141 if (!clear_decoders_.empty())
142 InitializeNextClearDecoder();
143 else
144 base::ResetAndReturn(&select_decoder_cb_).Run(NULL, NULL);
145 return;
146 }
147
148 clear_decoders_.clear();
149 base::ResetAndReturn(&select_decoder_cb_).Run(audio_decoder_,
150 decrypted_stream_);
151 }
152
153 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698