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 <linux/videodev2.h> | 8 #include <linux/videodev2.h> |
9 #include <poll.h> | 9 #include <poll.h> |
10 #include <sys/eventfd.h> | 10 #include <sys/eventfd.h> |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 V4L2VideoDecodeAccelerator::PictureRecord::~PictureRecord() {} | 151 V4L2VideoDecodeAccelerator::PictureRecord::~PictureRecord() {} |
152 | 152 |
153 V4L2VideoDecodeAccelerator::V4L2VideoDecodeAccelerator( | 153 V4L2VideoDecodeAccelerator::V4L2VideoDecodeAccelerator( |
154 EGLDisplay egl_display, | 154 EGLDisplay egl_display, |
155 const base::WeakPtr<Client>& io_client, | 155 const base::WeakPtr<Client>& io_client, |
156 const base::Callback<bool(void)>& make_context_current, | 156 const base::Callback<bool(void)>& make_context_current, |
157 scoped_ptr<V4L2Device> device, | 157 scoped_ptr<V4L2Device> device, |
158 const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy) | 158 const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy) |
159 : child_message_loop_proxy_(base::MessageLoopProxy::current()), | 159 : child_message_loop_proxy_(base::MessageLoopProxy::current()), |
160 io_message_loop_proxy_(io_message_loop_proxy), | 160 io_message_loop_proxy_(io_message_loop_proxy), |
161 weak_this_(base::AsWeakPtr(this)), | |
162 io_client_(io_client), | 161 io_client_(io_client), |
163 decoder_thread_("V4L2DecoderThread"), | 162 decoder_thread_("V4L2DecoderThread"), |
164 decoder_state_(kUninitialized), | 163 decoder_state_(kUninitialized), |
165 device_(device.Pass()), | 164 device_(device.Pass()), |
166 decoder_delay_bitstream_buffer_id_(-1), | 165 decoder_delay_bitstream_buffer_id_(-1), |
167 decoder_current_input_buffer_(-1), | 166 decoder_current_input_buffer_(-1), |
168 decoder_decode_buffer_tasks_scheduled_(0), | 167 decoder_decode_buffer_tasks_scheduled_(0), |
169 decoder_frames_at_client_(0), | 168 decoder_frames_at_client_(0), |
170 decoder_flushing_(false), | 169 decoder_flushing_(false), |
171 resolution_change_pending_(false), | 170 resolution_change_pending_(false), |
172 resolution_change_reset_pending_(false), | 171 resolution_change_reset_pending_(false), |
173 decoder_partial_frame_pending_(false), | 172 decoder_partial_frame_pending_(false), |
174 input_streamon_(false), | 173 input_streamon_(false), |
175 input_buffer_queued_count_(0), | 174 input_buffer_queued_count_(0), |
176 output_streamon_(false), | 175 output_streamon_(false), |
177 output_buffer_queued_count_(0), | 176 output_buffer_queued_count_(0), |
178 output_buffer_pixelformat_(0), | 177 output_buffer_pixelformat_(0), |
179 output_dpb_size_(0), | 178 output_dpb_size_(0), |
180 output_planes_count_(0), | 179 output_planes_count_(0), |
181 picture_clearing_count_(0), | 180 picture_clearing_count_(0), |
182 pictures_assigned_(false, false), | 181 pictures_assigned_(false, false), |
183 device_poll_thread_("V4L2DevicePollThread"), | 182 device_poll_thread_("V4L2DevicePollThread"), |
184 make_context_current_(make_context_current), | 183 make_context_current_(make_context_current), |
185 egl_display_(egl_display), | 184 egl_display_(egl_display), |
186 video_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN) {} | 185 video_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN), |
| 186 weak_this_factory_(this) { |
| 187 weak_this_ = weak_this_factory_.GetWeakPtr(); |
| 188 } |
187 | 189 |
188 V4L2VideoDecodeAccelerator::~V4L2VideoDecodeAccelerator() { | 190 V4L2VideoDecodeAccelerator::~V4L2VideoDecodeAccelerator() { |
189 DCHECK(!decoder_thread_.IsRunning()); | 191 DCHECK(!decoder_thread_.IsRunning()); |
190 DCHECK(!device_poll_thread_.IsRunning()); | 192 DCHECK(!device_poll_thread_.IsRunning()); |
191 | 193 |
192 DestroyInputBuffers(); | 194 DestroyInputBuffers(); |
193 DestroyOutputBuffers(); | 195 DestroyOutputBuffers(); |
194 | 196 |
195 // These maps have members that should be manually destroyed, e.g. file | 197 // These maps have members that should be manually destroyed, e.g. file |
196 // descriptors, mmap() segments, etc. | 198 // descriptors, mmap() segments, etc. |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 decoder_h264_parser_.reset(new media::H264Parser()); | 283 decoder_h264_parser_.reset(new media::H264Parser()); |
282 } | 284 } |
283 | 285 |
284 if (!decoder_thread_.Start()) { | 286 if (!decoder_thread_.Start()) { |
285 DLOG(ERROR) << "Initialize(): decoder thread failed to start"; | 287 DLOG(ERROR) << "Initialize(): decoder thread failed to start"; |
286 NOTIFY_ERROR(PLATFORM_FAILURE); | 288 NOTIFY_ERROR(PLATFORM_FAILURE); |
287 return false; | 289 return false; |
288 } | 290 } |
289 | 291 |
290 // StartDevicePoll will NOTIFY_ERROR on failure, so IgnoreResult is fine here. | 292 // StartDevicePoll will NOTIFY_ERROR on failure, so IgnoreResult is fine here. |
291 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 293 decoder_thread_.message_loop()->PostTask( |
292 base::IgnoreResult(&V4L2VideoDecodeAccelerator::StartDevicePoll), | 294 FROM_HERE, |
293 base::Unretained(this))); | 295 base::Bind( |
| 296 base::IgnoreResult(&V4L2VideoDecodeAccelerator::StartDevicePoll), |
| 297 base::Unretained(this))); |
294 | 298 |
295 SetDecoderState(kInitialized); | 299 SetDecoderState(kInitialized); |
296 | |
297 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( | |
298 &Client::NotifyInitializeDone, client_)); | |
299 return true; | 300 return true; |
300 } | 301 } |
301 | 302 |
302 void V4L2VideoDecodeAccelerator::Decode( | 303 void V4L2VideoDecodeAccelerator::Decode( |
303 const media::BitstreamBuffer& bitstream_buffer) { | 304 const media::BitstreamBuffer& bitstream_buffer) { |
304 DVLOG(1) << "Decode(): input_id=" << bitstream_buffer.id() | 305 DVLOG(1) << "Decode(): input_id=" << bitstream_buffer.id() |
305 << ", size=" << bitstream_buffer.size(); | 306 << ", size=" << bitstream_buffer.size(); |
306 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 307 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
307 | 308 |
308 // DecodeTask() will take care of running a DecodeBufferTask(). | 309 // DecodeTask() will take care of running a DecodeBufferTask(). |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 410 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
410 &V4L2VideoDecodeAccelerator::ResetTask, base::Unretained(this))); | 411 &V4L2VideoDecodeAccelerator::ResetTask, base::Unretained(this))); |
411 } | 412 } |
412 | 413 |
413 void V4L2VideoDecodeAccelerator::Destroy() { | 414 void V4L2VideoDecodeAccelerator::Destroy() { |
414 DVLOG(3) << "Destroy()"; | 415 DVLOG(3) << "Destroy()"; |
415 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 416 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); |
416 | 417 |
417 // We're destroying; cancel all callbacks. | 418 // We're destroying; cancel all callbacks. |
418 client_ptr_factory_.reset(); | 419 client_ptr_factory_.reset(); |
| 420 weak_this_factory_.InvalidateWeakPtrs(); |
419 | 421 |
420 // If the decoder thread is running, destroy using posted task. | 422 // If the decoder thread is running, destroy using posted task. |
421 if (decoder_thread_.IsRunning()) { | 423 if (decoder_thread_.IsRunning()) { |
422 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 424 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
423 &V4L2VideoDecodeAccelerator::DestroyTask, base::Unretained(this))); | 425 &V4L2VideoDecodeAccelerator::DestroyTask, base::Unretained(this))); |
424 pictures_assigned_.Signal(); | 426 pictures_assigned_.Signal(); |
425 // DestroyTask() will cause the decoder_thread_ to flush all tasks. | 427 // DestroyTask() will cause the decoder_thread_ to flush all tasks. |
426 decoder_thread_.Stop(); | 428 decoder_thread_.Stop(); |
427 } else { | 429 } else { |
428 // Otherwise, call the destroy task directly. | 430 // Otherwise, call the destroy task directly. |
(...skipping 1486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1915 gfx::Size new_size(base::checked_cast<int>(format.fmt.pix_mp.width), | 1917 gfx::Size new_size(base::checked_cast<int>(format.fmt.pix_mp.width), |
1916 base::checked_cast<int>(format.fmt.pix_mp.height)); | 1918 base::checked_cast<int>(format.fmt.pix_mp.height)); |
1917 if (frame_buffer_size_ != new_size) { | 1919 if (frame_buffer_size_ != new_size) { |
1918 DVLOG(3) << "IsResolutionChangeNecessary(): Resolution change detected"; | 1920 DVLOG(3) << "IsResolutionChangeNecessary(): Resolution change detected"; |
1919 return true; | 1921 return true; |
1920 } | 1922 } |
1921 return false; | 1923 return false; |
1922 } | 1924 } |
1923 | 1925 |
1924 } // namespace content | 1926 } // namespace content |
OLD | NEW |