| 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 |