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_video_decoder.h" | 5 #include "media/filters/ffmpeg_video_decoder.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
126 | 126 |
127 // The FFmpeg API expects us to zero the data pointers in | 127 // The FFmpeg API expects us to zero the data pointers in |
128 // this callback | 128 // this callback |
129 memset(frame->data, 0, sizeof(frame->data)); | 129 memset(frame->data, 0, sizeof(frame->data)); |
130 frame->opaque = NULL; | 130 frame->opaque = NULL; |
131 } | 131 } |
132 | 132 |
133 void FFmpegVideoDecoder::Initialize(const scoped_refptr<DemuxerStream>& stream, | 133 void FFmpegVideoDecoder::Initialize(const scoped_refptr<DemuxerStream>& stream, |
134 const PipelineStatusCB& status_cb, | 134 const PipelineStatusCB& status_cb, |
135 const StatisticsCB& statistics_cb) { | 135 const StatisticsCB& statistics_cb) { |
136 if (!message_loop_->BelongsToCurrentThread()) { | 136 DCHECK(message_loop_->BelongsToCurrentThread()); |
137 message_loop_->PostTask(FROM_HERE, base::Bind( | |
138 &FFmpegVideoDecoder::Initialize, this, | |
139 stream, status_cb, statistics_cb)); | |
140 return; | |
141 } | |
142 | 137 |
143 FFmpegGlue::InitializeFFmpeg(); | 138 FFmpegGlue::InitializeFFmpeg(); |
144 DCHECK(!demuxer_stream_) << "Already initialized."; | 139 DCHECK(!demuxer_stream_) << "Already initialized."; |
145 | 140 |
146 if (!stream) { | 141 if (!stream) { |
147 status_cb.Run(PIPELINE_ERROR_DECODE); | 142 status_cb.Run(PIPELINE_ERROR_DECODE); |
148 return; | 143 return; |
149 } | 144 } |
150 | 145 |
151 demuxer_stream_ = stream; | 146 demuxer_stream_ = stream; |
152 statistics_cb_ = statistics_cb; | 147 statistics_cb_ = statistics_cb; |
153 | 148 |
154 if (!ConfigureDecoder()) { | 149 if (!ConfigureDecoder()) { |
155 status_cb.Run(PIPELINE_ERROR_DECODE); | 150 status_cb.Run(PIPELINE_ERROR_DECODE); |
156 return; | 151 return; |
157 } | 152 } |
158 | 153 |
159 // Success! | 154 // Success! |
160 state_ = kNormal; | 155 state_ = kNormal; |
161 status_cb.Run(PIPELINE_OK); | 156 status_cb.Run(PIPELINE_OK); |
162 } | 157 } |
163 | 158 |
164 void FFmpegVideoDecoder::Read(const ReadCB& read_cb) { | 159 void FFmpegVideoDecoder::Read(const ReadCB& read_cb) { |
165 // Complete operation asynchronously on different stack of execution as per | 160 DCHECK(message_loop_->BelongsToCurrentThread()); |
166 // the API contract of VideoDecoder::Read() | 161 DoRead(read_cb); |
Ami GONE FROM CHROMIUM
2012/11/29 23:34:23
Either force-post or change the API contract of Vi
scherkus (not reviewing)
2012/11/29 23:45:56
This was lazy prototyping. Inlining the code took
| |
167 message_loop_->PostTask(FROM_HERE, base::Bind( | |
168 &FFmpegVideoDecoder::DoRead, this, read_cb)); | |
169 } | 162 } |
170 | 163 |
171 void FFmpegVideoDecoder::Reset(const base::Closure& closure) { | 164 void FFmpegVideoDecoder::Reset(const base::Closure& closure) { |
172 if (!message_loop_->BelongsToCurrentThread()) { | 165 DCHECK(message_loop_->BelongsToCurrentThread()); |
173 message_loop_->PostTask(FROM_HERE, base::Bind( | |
174 &FFmpegVideoDecoder::Reset, this, closure)); | |
175 return; | |
176 } | |
177 | |
178 DCHECK(reset_cb_.is_null()); | 166 DCHECK(reset_cb_.is_null()); |
179 reset_cb_ = closure; | 167 reset_cb_ = closure; |
180 | 168 |
181 if (decryptor_) | 169 if (decryptor_) |
182 decryptor_->CancelDecrypt(Decryptor::kVideo); | 170 decryptor_->CancelDecrypt(Decryptor::kVideo); |
183 | 171 |
184 // Defer the reset if a read is pending. | 172 // Defer the reset if a read is pending. |
185 if (!read_cb_.is_null()) | 173 if (!read_cb_.is_null()) |
186 return; | 174 return; |
187 | 175 |
188 DoReset(); | 176 DoReset(); |
189 } | 177 } |
190 | 178 |
191 void FFmpegVideoDecoder::DoReset() { | 179 void FFmpegVideoDecoder::DoReset() { |
192 DCHECK(read_cb_.is_null()); | 180 DCHECK(read_cb_.is_null()); |
193 | 181 |
194 avcodec_flush_buffers(codec_context_); | 182 avcodec_flush_buffers(codec_context_); |
195 state_ = kNormal; | 183 state_ = kNormal; |
196 reset_cb_.Run(); | 184 reset_cb_.Run(); |
197 reset_cb_.Reset(); | 185 reset_cb_.Reset(); |
198 } | 186 } |
199 | 187 |
200 void FFmpegVideoDecoder::Stop(const base::Closure& closure) { | 188 void FFmpegVideoDecoder::Stop(const base::Closure& closure) { |
201 if (!message_loop_->BelongsToCurrentThread()) { | 189 DCHECK(message_loop_->BelongsToCurrentThread()); |
202 message_loop_->PostTask(FROM_HERE, base::Bind( | |
203 &FFmpegVideoDecoder::Stop, this, closure)); | |
204 return; | |
205 } | |
206 | 190 |
207 if (state_ == kUninitialized) { | 191 if (state_ == kUninitialized) { |
208 closure.Run(); | 192 closure.Run(); |
209 return; | 193 return; |
210 } | 194 } |
211 | 195 |
212 if (decryptor_) | 196 if (decryptor_) |
213 decryptor_->CancelDecrypt(Decryptor::kVideo); | 197 decryptor_->CancelDecrypt(Decryptor::kVideo); |
214 | 198 |
215 if (!read_cb_.is_null()) | 199 if (!read_cb_.is_null()) |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
519 if (!codec || avcodec_open2(codec_context_, codec, NULL) < 0) { | 503 if (!codec || avcodec_open2(codec_context_, codec, NULL) < 0) { |
520 ReleaseFFmpegResources(); | 504 ReleaseFFmpegResources(); |
521 return false; | 505 return false; |
522 } | 506 } |
523 | 507 |
524 av_frame_ = avcodec_alloc_frame(); | 508 av_frame_ = avcodec_alloc_frame(); |
525 return true; | 509 return true; |
526 } | 510 } |
527 | 511 |
528 } // namespace media | 512 } // namespace media |
OLD | NEW |