OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 <dlfcn.h> | 5 #include <dlfcn.h> |
6 #include <errno.h> | 6 #include <errno.h> |
7 #include <fcntl.h> | 7 #include <fcntl.h> |
8 #include <libdrm/drm_fourcc.h> | 8 #include <libdrm/drm_fourcc.h> |
9 #include <linux/videodev2.h> | 9 #include <linux/videodev2.h> |
10 #include <poll.h> | 10 #include <poll.h> |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 | 147 |
148 V4L2VideoDecodeAccelerator::PictureRecord::PictureRecord( | 148 V4L2VideoDecodeAccelerator::PictureRecord::PictureRecord( |
149 bool cleared, | 149 bool cleared, |
150 const media::Picture& picture) | 150 const media::Picture& picture) |
151 : cleared(cleared), picture(picture) {} | 151 : cleared(cleared), picture(picture) {} |
152 | 152 |
153 V4L2VideoDecodeAccelerator::PictureRecord::~PictureRecord() {} | 153 V4L2VideoDecodeAccelerator::PictureRecord::~PictureRecord() {} |
154 | 154 |
155 V4L2VideoDecodeAccelerator::V4L2VideoDecodeAccelerator( | 155 V4L2VideoDecodeAccelerator::V4L2VideoDecodeAccelerator( |
156 EGLDisplay egl_display, | 156 EGLDisplay egl_display, |
157 Client* client, | |
158 const base::WeakPtr<Client>& io_client, | 157 const base::WeakPtr<Client>& io_client, |
159 const base::Callback<bool(void)>& make_context_current, | 158 const base::Callback<bool(void)>& make_context_current, |
160 scoped_ptr<V4L2Device> device, | 159 scoped_ptr<V4L2Device> device, |
161 const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy) | 160 const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy) |
162 : child_message_loop_proxy_(base::MessageLoopProxy::current()), | 161 : child_message_loop_proxy_(base::MessageLoopProxy::current()), |
163 io_message_loop_proxy_(io_message_loop_proxy), | 162 io_message_loop_proxy_(io_message_loop_proxy), |
164 weak_this_(base::AsWeakPtr(this)), | 163 weak_this_(base::AsWeakPtr(this)), |
165 client_ptr_factory_(client), | |
166 client_(client_ptr_factory_.GetWeakPtr()), | |
167 io_client_(io_client), | 164 io_client_(io_client), |
168 decoder_thread_("V4L2DecoderThread"), | 165 decoder_thread_("V4L2DecoderThread"), |
169 decoder_state_(kUninitialized), | 166 decoder_state_(kUninitialized), |
170 device_(device.Pass()), | 167 device_(device.Pass()), |
171 decoder_delay_bitstream_buffer_id_(-1), | 168 decoder_delay_bitstream_buffer_id_(-1), |
172 decoder_current_input_buffer_(-1), | 169 decoder_current_input_buffer_(-1), |
173 decoder_decode_buffer_tasks_scheduled_(0), | 170 decoder_decode_buffer_tasks_scheduled_(0), |
174 decoder_frames_at_client_(0), | 171 decoder_frames_at_client_(0), |
175 decoder_flushing_(false), | 172 decoder_flushing_(false), |
176 resolution_change_pending_(false), | 173 resolution_change_pending_(false), |
(...skipping 18 matching lines...) Expand all Loading... |
195 | 192 |
196 DestroyInputBuffers(); | 193 DestroyInputBuffers(); |
197 DestroyOutputBuffers(); | 194 DestroyOutputBuffers(); |
198 | 195 |
199 // These maps have members that should be manually destroyed, e.g. file | 196 // These maps have members that should be manually destroyed, e.g. file |
200 // descriptors, mmap() segments, etc. | 197 // descriptors, mmap() segments, etc. |
201 DCHECK(input_buffer_map_.empty()); | 198 DCHECK(input_buffer_map_.empty()); |
202 DCHECK(output_buffer_map_.empty()); | 199 DCHECK(output_buffer_map_.empty()); |
203 } | 200 } |
204 | 201 |
205 bool V4L2VideoDecodeAccelerator::Initialize( | 202 bool V4L2VideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, |
206 media::VideoCodecProfile profile) { | 203 Client* client) { |
207 DVLOG(3) << "Initialize()"; | 204 DVLOG(3) << "Initialize()"; |
208 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 205 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); |
209 DCHECK_EQ(decoder_state_, kUninitialized); | 206 DCHECK_EQ(decoder_state_, kUninitialized); |
210 | 207 |
| 208 client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client)); |
| 209 client_ = client_ptr_factory_->GetWeakPtr(); |
| 210 |
211 switch (profile) { | 211 switch (profile) { |
212 case media::H264PROFILE_BASELINE: | 212 case media::H264PROFILE_BASELINE: |
213 DVLOG(2) << "Initialize(): profile H264PROFILE_BASELINE"; | 213 DVLOG(2) << "Initialize(): profile H264PROFILE_BASELINE"; |
214 break; | 214 break; |
215 case media::H264PROFILE_MAIN: | 215 case media::H264PROFILE_MAIN: |
216 DVLOG(2) << "Initialize(): profile H264PROFILE_MAIN"; | 216 DVLOG(2) << "Initialize(): profile H264PROFILE_MAIN"; |
217 break; | 217 break; |
218 case media::H264PROFILE_HIGH: | 218 case media::H264PROFILE_HIGH: |
219 DVLOG(2) << "Initialize(): profile H264PROFILE_HIGH"; | 219 DVLOG(2) << "Initialize(): profile H264PROFILE_HIGH"; |
220 break; | 220 break; |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 420 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); |
421 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 421 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
422 &V4L2VideoDecodeAccelerator::ResetTask, base::Unretained(this))); | 422 &V4L2VideoDecodeAccelerator::ResetTask, base::Unretained(this))); |
423 } | 423 } |
424 | 424 |
425 void V4L2VideoDecodeAccelerator::Destroy() { | 425 void V4L2VideoDecodeAccelerator::Destroy() { |
426 DVLOG(3) << "Destroy()"; | 426 DVLOG(3) << "Destroy()"; |
427 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 427 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); |
428 | 428 |
429 // We're destroying; cancel all callbacks. | 429 // We're destroying; cancel all callbacks. |
430 client_ptr_factory_.InvalidateWeakPtrs(); | 430 client_ptr_factory_.reset(); |
431 | 431 |
432 // If the decoder thread is running, destroy using posted task. | 432 // If the decoder thread is running, destroy using posted task. |
433 if (decoder_thread_.IsRunning()) { | 433 if (decoder_thread_.IsRunning()) { |
434 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 434 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
435 &V4L2VideoDecodeAccelerator::DestroyTask, base::Unretained(this))); | 435 &V4L2VideoDecodeAccelerator::DestroyTask, base::Unretained(this))); |
436 pictures_assigned_.Signal(); | 436 pictures_assigned_.Signal(); |
437 // DestroyTask() will cause the decoder_thread_ to flush all tasks. | 437 // DestroyTask() will cause the decoder_thread_ to flush all tasks. |
438 decoder_thread_.Stop(); | 438 decoder_thread_.Stop(); |
439 } else { | 439 } else { |
440 // Otherwise, call the destroy task directly. | 440 // Otherwise, call the destroy task directly. |
(...skipping 1139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1580 DVLOG(2) << "NotifyError()"; | 1580 DVLOG(2) << "NotifyError()"; |
1581 | 1581 |
1582 if (!child_message_loop_proxy_->BelongsToCurrentThread()) { | 1582 if (!child_message_loop_proxy_->BelongsToCurrentThread()) { |
1583 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 1583 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
1584 &V4L2VideoDecodeAccelerator::NotifyError, weak_this_, error)); | 1584 &V4L2VideoDecodeAccelerator::NotifyError, weak_this_, error)); |
1585 return; | 1585 return; |
1586 } | 1586 } |
1587 | 1587 |
1588 if (client_) { | 1588 if (client_) { |
1589 client_->NotifyError(error); | 1589 client_->NotifyError(error); |
1590 client_ptr_factory_.InvalidateWeakPtrs(); | 1590 client_ptr_factory_.reset(); |
1591 } | 1591 } |
1592 } | 1592 } |
1593 | 1593 |
1594 void V4L2VideoDecodeAccelerator::SetDecoderState(State state) { | 1594 void V4L2VideoDecodeAccelerator::SetDecoderState(State state) { |
1595 DVLOG(3) << "SetDecoderState(): state=" << state; | 1595 DVLOG(3) << "SetDecoderState(): state=" << state; |
1596 | 1596 |
1597 // We can touch decoder_state_ only if this is the decoder thread or the | 1597 // We can touch decoder_state_ only if this is the decoder thread or the |
1598 // decoder thread isn't running. | 1598 // decoder thread isn't running. |
1599 if (decoder_thread_.message_loop() != NULL && | 1599 if (decoder_thread_.message_loop() != NULL && |
1600 decoder_thread_.message_loop() != base::MessageLoop::current()) { | 1600 decoder_thread_.message_loop() != base::MessageLoop::current()) { |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1919 | 1919 |
1920 void V4L2VideoDecodeAccelerator::PictureCleared() { | 1920 void V4L2VideoDecodeAccelerator::PictureCleared() { |
1921 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_; | 1921 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_; |
1922 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1922 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
1923 DCHECK_GT(picture_clearing_count_, 0); | 1923 DCHECK_GT(picture_clearing_count_, 0); |
1924 picture_clearing_count_--; | 1924 picture_clearing_count_--; |
1925 SendPictureReady(); | 1925 SendPictureReady(); |
1926 } | 1926 } |
1927 | 1927 |
1928 } // namespace content | 1928 } // namespace content |
OLD | NEW |