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

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

Issue 14348007: Reland: Remove reference counting from media::VideoDecoder and friends. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixes Created 7 years, 8 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/video_decoder_selector.h" 5 #include "media/filters/video_decoder_selector.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback_helpers.h" 8 #include "base/callback_helpers.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/message_loop_proxy.h" 10 #include "base/message_loop_proxy.h"
11 #include "media/base/bind_to_loop.h" 11 #include "media/base/bind_to_loop.h"
12 #include "media/base/demuxer_stream.h" 12 #include "media/base/demuxer_stream.h"
13 #include "media/base/pipeline.h" 13 #include "media/base/pipeline.h"
14 #include "media/base/video_decoder_config.h" 14 #include "media/base/video_decoder_config.h"
15 #include "media/filters/decrypting_demuxer_stream.h" 15 #include "media/filters/decrypting_demuxer_stream.h"
16 #include "media/filters/decrypting_video_decoder.h" 16 #include "media/filters/decrypting_video_decoder.h"
17 17
18 namespace media { 18 namespace media {
19 19
20 VideoDecoderSelector::VideoDecoderSelector( 20 VideoDecoderSelector::VideoDecoderSelector(
21 const scoped_refptr<base::MessageLoopProxy>& message_loop, 21 const scoped_refptr<base::MessageLoopProxy>& message_loop,
22 const VideoDecoderList& decoders, 22 ScopedVector<VideoDecoder> decoders,
23 const SetDecryptorReadyCB& set_decryptor_ready_cb) 23 const SetDecryptorReadyCB& set_decryptor_ready_cb)
24 : message_loop_(message_loop), 24 : message_loop_(message_loop),
25 decoders_(decoders), 25 decoders_(decoders.Pass()),
26 set_decryptor_ready_cb_(set_decryptor_ready_cb), 26 set_decryptor_ready_cb_(set_decryptor_ready_cb),
27 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { 27 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
28 } 28 }
29 29
30 VideoDecoderSelector::~VideoDecoderSelector() {} 30 VideoDecoderSelector::~VideoDecoderSelector() {}
31 31
32 void VideoDecoderSelector::SelectVideoDecoder( 32 void VideoDecoderSelector::SelectVideoDecoder(
33 const scoped_refptr<DemuxerStream>& stream, 33 const scoped_refptr<DemuxerStream>& stream,
34 const StatisticsCB& statistics_cb, 34 const StatisticsCB& statistics_cb,
35 const SelectDecoderCB& select_decoder_cb) { 35 const SelectDecoderCB& select_decoder_cb) {
36 DVLOG(2) << "SelectVideoDecoder()"; 36 DVLOG(2) << "SelectVideoDecoder()";
37 DCHECK(message_loop_->BelongsToCurrentThread()); 37 DCHECK(message_loop_->BelongsToCurrentThread());
38 DCHECK(stream); 38 DCHECK(stream);
39 39
40 // Make sure |select_decoder_cb| runs on a different execution stack. 40 // Make sure |select_decoder_cb| runs on a different execution stack.
41 select_decoder_cb_ = BindToCurrentLoop(select_decoder_cb); 41 select_decoder_cb_ = BindToCurrentLoop(select_decoder_cb);
42 42
43 const VideoDecoderConfig& config = stream->video_decoder_config(); 43 const VideoDecoderConfig& config = stream->video_decoder_config();
44 if (!config.IsValidConfig()) { 44 if (!config.IsValidConfig()) {
45 DLOG(ERROR) << "Invalid video stream config."; 45 DLOG(ERROR) << "Invalid video stream config.";
46 base::ResetAndReturn(&select_decoder_cb_).Run(NULL, NULL); 46 base::ResetAndReturn(&select_decoder_cb_).Run(
47 scoped_ptr<VideoDecoder>(), NULL);
47 return; 48 return;
48 } 49 }
49 50
50 input_stream_ = stream; 51 input_stream_ = stream;
51 statistics_cb_ = statistics_cb; 52 statistics_cb_ = statistics_cb;
52 53
53 if (!config.is_encrypted()) { 54 if (!config.is_encrypted()) {
54 if (decoders_.empty()) { 55 InitializeDecoder(decoders_.begin());
55 DLOG(ERROR) << "No video decoder can be used to decode the input stream.";
56 base::ResetAndReturn(&select_decoder_cb_).Run(NULL, NULL);
57 return;
58 }
59
60 InitializeNextDecoder();
61 return; 56 return;
62 } 57 }
63 58
64 // This could happen if Encrypted Media Extension (EME) is not enabled. 59 // This could happen if Encrypted Media Extension (EME) is not enabled.
65 if (set_decryptor_ready_cb_.is_null()) { 60 if (set_decryptor_ready_cb_.is_null()) {
66 base::ResetAndReturn(&select_decoder_cb_).Run(NULL, NULL); 61 base::ResetAndReturn(&select_decoder_cb_).Run(
62 scoped_ptr<VideoDecoder>(), NULL);
67 return; 63 return;
68 } 64 }
69 65
70 video_decoder_ = new DecryptingVideoDecoder(message_loop_, 66 video_decoder_.reset(new DecryptingVideoDecoder(
71 set_decryptor_ready_cb_); 67 message_loop_, set_decryptor_ready_cb_));
72 68
73 video_decoder_->Initialize( 69 video_decoder_->Initialize(
74 input_stream_, 70 input_stream_,
75 BindToCurrentLoop(base::Bind( 71 BindToCurrentLoop(base::Bind(
76 &VideoDecoderSelector::DecryptingVideoDecoderInitDone, 72 &VideoDecoderSelector::DecryptingVideoDecoderInitDone,
77 weak_ptr_factory_.GetWeakPtr())), 73 weak_ptr_factory_.GetWeakPtr())),
78 statistics_cb_); 74 statistics_cb_);
79 } 75 }
80 76
81 void VideoDecoderSelector::DecryptingVideoDecoderInitDone( 77 void VideoDecoderSelector::DecryptingVideoDecoderInitDone(
82 PipelineStatus status) { 78 PipelineStatus status) {
83 DCHECK(message_loop_->BelongsToCurrentThread()); 79 DCHECK(message_loop_->BelongsToCurrentThread());
84 80
85 if (status == PIPELINE_OK) { 81 if (status == PIPELINE_OK) {
86 decoders_.clear(); 82 base::ResetAndReturn(&select_decoder_cb_).Run(video_decoder_.Pass(), NULL);
87 base::ResetAndReturn(&select_decoder_cb_).Run(video_decoder_, NULL);
88 return; 83 return;
89 } 84 }
90 85
91 video_decoder_ = NULL;
92
93 if (decoders_.empty()) {
94 DLOG(ERROR) << "No video 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( 86 decrypted_stream_ = new DecryptingDemuxerStream(
100 message_loop_, set_decryptor_ready_cb_); 87 message_loop_, set_decryptor_ready_cb_);
101 88
102 decrypted_stream_->Initialize( 89 decrypted_stream_->Initialize(
103 input_stream_, 90 input_stream_,
104 BindToCurrentLoop(base::Bind( 91 BindToCurrentLoop(base::Bind(
105 &VideoDecoderSelector::DecryptingDemuxerStreamInitDone, 92 &VideoDecoderSelector::DecryptingDemuxerStreamInitDone,
106 weak_ptr_factory_.GetWeakPtr()))); 93 weak_ptr_factory_.GetWeakPtr())));
107 } 94 }
108 95
109 void VideoDecoderSelector::DecryptingDemuxerStreamInitDone( 96 void VideoDecoderSelector::DecryptingDemuxerStreamInitDone(
110 PipelineStatus status) { 97 PipelineStatus status) {
111 DCHECK(message_loop_->BelongsToCurrentThread()); 98 DCHECK(message_loop_->BelongsToCurrentThread());
112 99
113 if (status != PIPELINE_OK) { 100 if (status != PIPELINE_OK) {
114 decrypted_stream_ = NULL; 101 decrypted_stream_ = NULL;
115 base::ResetAndReturn(&select_decoder_cb_).Run(NULL, NULL); 102 base::ResetAndReturn(&select_decoder_cb_).Run(
103 scoped_ptr<VideoDecoder>(), NULL);
116 return; 104 return;
117 } 105 }
118 106
119 DCHECK(!decrypted_stream_->video_decoder_config().is_encrypted()); 107 DCHECK(!decrypted_stream_->video_decoder_config().is_encrypted());
120 input_stream_ = decrypted_stream_; 108 input_stream_ = decrypted_stream_;
121 InitializeNextDecoder(); 109 InitializeDecoder(decoders_.begin());
122 } 110 }
123 111
124 void VideoDecoderSelector::InitializeNextDecoder() { 112 void VideoDecoderSelector::InitializeDecoder(
113 ScopedVector<VideoDecoder>::iterator iter) {
125 DCHECK(message_loop_->BelongsToCurrentThread()); 114 DCHECK(message_loop_->BelongsToCurrentThread());
126 DCHECK(!decoders_.empty());
127 115
128 video_decoder_ = decoders_.front(); 116 if (iter == decoders_.end()) {
129 decoders_.pop_front(); 117 base::ResetAndReturn(&select_decoder_cb_).Run(
130 DCHECK(video_decoder_); 118 scoped_ptr<VideoDecoder>(), NULL);
131 video_decoder_->Initialize(input_stream_, 119 return;
132 BindToCurrentLoop(base::Bind( 120 }
133 &VideoDecoderSelector::DecoderInitDone, 121
134 weak_ptr_factory_.GetWeakPtr())), 122 (*iter)->Initialize(
135 statistics_cb_); 123 input_stream_,
124 BindToCurrentLoop(base::Bind(
125 &VideoDecoderSelector::DecoderInitDone,
126 weak_ptr_factory_.GetWeakPtr(),
127 iter)),
128 statistics_cb_);
136 } 129 }
137 130
138 void VideoDecoderSelector::DecoderInitDone(PipelineStatus status) { 131 void VideoDecoderSelector::DecoderInitDone(
132 ScopedVector<VideoDecoder>::iterator iter, PipelineStatus status) {
139 DCHECK(message_loop_->BelongsToCurrentThread()); 133 DCHECK(message_loop_->BelongsToCurrentThread());
140 134
141 if (status != PIPELINE_OK) { 135 if (status != PIPELINE_OK) {
142 if (!decoders_.empty()) 136 InitializeDecoder(++iter);
143 InitializeNextDecoder();
144 else
145 base::ResetAndReturn(&select_decoder_cb_).Run(NULL, NULL);
146 return; 137 return;
147 } 138 }
148 139
149 decoders_.clear(); 140 scoped_ptr<VideoDecoder> video_decoder(*iter);
150 base::ResetAndReturn(&select_decoder_cb_).Run(video_decoder_, 141 decoders_.weak_erase(iter);
142
143 base::ResetAndReturn(&select_decoder_cb_).Run(video_decoder.Pass(),
151 decrypted_stream_); 144 decrypted_stream_);
152 } 145 }
153 146
154 } // namespace media 147 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/video_decoder_selector.h ('k') | media/filters/video_decoder_selector_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698