OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "content/common/gpu/media/exynos_video_encode_accelerator.h" | 5 #include "content/common/gpu/media/exynos_video_encode_accelerator.h" |
6 | 6 |
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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 : at_device(false), mfc_input(-1) {} | 75 : at_device(false), mfc_input(-1) {} |
76 | 76 |
77 ExynosVideoEncodeAccelerator::MfcInputRecord::MfcInputRecord() | 77 ExynosVideoEncodeAccelerator::MfcInputRecord::MfcInputRecord() |
78 : at_device(false) { | 78 : at_device(false) { |
79 fd[0] = fd[1] = -1; | 79 fd[0] = fd[1] = -1; |
80 } | 80 } |
81 | 81 |
82 ExynosVideoEncodeAccelerator::MfcOutputRecord::MfcOutputRecord() | 82 ExynosVideoEncodeAccelerator::MfcOutputRecord::MfcOutputRecord() |
83 : at_device(false), address(NULL), length(0) {} | 83 : at_device(false), address(NULL), length(0) {} |
84 | 84 |
85 ExynosVideoEncodeAccelerator::ExynosVideoEncodeAccelerator( | 85 ExynosVideoEncodeAccelerator::ExynosVideoEncodeAccelerator() |
86 media::VideoEncodeAccelerator::Client* client) | |
87 : child_message_loop_proxy_(base::MessageLoopProxy::current()), | 86 : child_message_loop_proxy_(base::MessageLoopProxy::current()), |
88 weak_this_ptr_factory_(this), | 87 weak_this_ptr_factory_(this), |
89 weak_this_(weak_this_ptr_factory_.GetWeakPtr()), | 88 weak_this_(weak_this_ptr_factory_.GetWeakPtr()), |
90 client_ptr_factory_(client), | |
91 client_(client_ptr_factory_.GetWeakPtr()), | |
92 encoder_thread_("ExynosEncoderThread"), | 89 encoder_thread_("ExynosEncoderThread"), |
93 encoder_state_(kUninitialized), | 90 encoder_state_(kUninitialized), |
94 output_buffer_byte_size_(0), | 91 output_buffer_byte_size_(0), |
95 stream_header_size_(0), | 92 stream_header_size_(0), |
96 input_format_fourcc_(0), | 93 input_format_fourcc_(0), |
97 output_format_fourcc_(0), | 94 output_format_fourcc_(0), |
98 gsc_fd_(-1), | 95 gsc_fd_(-1), |
99 gsc_input_streamon_(false), | 96 gsc_input_streamon_(false), |
100 gsc_input_buffer_queued_count_(0), | 97 gsc_input_buffer_queued_count_(0), |
101 gsc_output_streamon_(false), | 98 gsc_output_streamon_(false), |
102 gsc_output_buffer_queued_count_(0), | 99 gsc_output_buffer_queued_count_(0), |
103 mfc_fd_(-1), | 100 mfc_fd_(-1), |
104 mfc_input_streamon_(false), | 101 mfc_input_streamon_(false), |
105 mfc_input_buffer_queued_count_(0), | 102 mfc_input_buffer_queued_count_(0), |
106 mfc_output_streamon_(false), | 103 mfc_output_streamon_(false), |
107 mfc_output_buffer_queued_count_(0), | 104 mfc_output_buffer_queued_count_(0), |
108 device_poll_thread_("ExynosEncoderDevicePollThread"), | 105 device_poll_thread_("ExynosEncoderDevicePollThread"), |
109 device_poll_interrupt_fd_(-1) { | 106 device_poll_interrupt_fd_(-1) {} |
110 DCHECK(client_); | |
111 } | |
112 | 107 |
113 ExynosVideoEncodeAccelerator::~ExynosVideoEncodeAccelerator() { | 108 ExynosVideoEncodeAccelerator::~ExynosVideoEncodeAccelerator() { |
114 DCHECK(!encoder_thread_.IsRunning()); | 109 DCHECK(!encoder_thread_.IsRunning()); |
115 DCHECK(!device_poll_thread_.IsRunning()); | 110 DCHECK(!device_poll_thread_.IsRunning()); |
116 | 111 |
117 if (device_poll_interrupt_fd_ != -1) { | 112 if (device_poll_interrupt_fd_ != -1) { |
118 close(device_poll_interrupt_fd_); | 113 close(device_poll_interrupt_fd_); |
119 device_poll_interrupt_fd_ = -1; | 114 device_poll_interrupt_fd_ = -1; |
120 } | 115 } |
121 if (gsc_fd_ != -1) { | 116 if (gsc_fd_ != -1) { |
122 DestroyGscInputBuffers(); | 117 DestroyGscInputBuffers(); |
123 DestroyGscOutputBuffers(); | 118 DestroyGscOutputBuffers(); |
124 close(gsc_fd_); | 119 close(gsc_fd_); |
125 gsc_fd_ = -1; | 120 gsc_fd_ = -1; |
126 } | 121 } |
127 if (mfc_fd_ != -1) { | 122 if (mfc_fd_ != -1) { |
128 DestroyMfcInputBuffers(); | 123 DestroyMfcInputBuffers(); |
129 DestroyMfcOutputBuffers(); | 124 DestroyMfcOutputBuffers(); |
130 close(mfc_fd_); | 125 close(mfc_fd_); |
131 mfc_fd_ = -1; | 126 mfc_fd_ = -1; |
132 } | 127 } |
133 } | 128 } |
134 | 129 |
135 void ExynosVideoEncodeAccelerator::Initialize( | 130 void ExynosVideoEncodeAccelerator::Initialize( |
136 media::VideoFrame::Format input_format, | 131 media::VideoFrame::Format input_format, |
137 const gfx::Size& input_visible_size, | 132 const gfx::Size& input_visible_size, |
138 media::VideoCodecProfile output_profile, | 133 media::VideoCodecProfile output_profile, |
139 uint32 initial_bitrate) { | 134 uint32 initial_bitrate, |
| 135 Client* client) { |
140 DVLOG(3) << "Initialize(): input_format=" << input_format | 136 DVLOG(3) << "Initialize(): input_format=" << input_format |
141 << ", input_visible_size=" << input_visible_size.ToString() | 137 << ", input_visible_size=" << input_visible_size.ToString() |
142 << ", output_profile=" << output_profile | 138 << ", output_profile=" << output_profile |
143 << ", initial_bitrate=" << initial_bitrate; | 139 << ", initial_bitrate=" << initial_bitrate; |
144 | 140 |
| 141 client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client)); |
| 142 client_ = client_ptr_factory_->GetWeakPtr(); |
| 143 |
145 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 144 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); |
146 DCHECK_EQ(encoder_state_, kUninitialized); | 145 DCHECK_EQ(encoder_state_, kUninitialized); |
147 | 146 |
148 input_visible_size_ = input_visible_size; | 147 input_visible_size_ = input_visible_size; |
149 input_allocated_size_.SetSize((input_visible_size_.width() + 0xF) & ~0xF, | 148 input_allocated_size_.SetSize((input_visible_size_.width() + 0xF) & ~0xF, |
150 (input_visible_size_.height() + 0xF) & ~0xF); | 149 (input_visible_size_.height() + 0xF) & ~0xF); |
151 converted_visible_size_.SetSize((input_visible_size_.width() + 0x1) & ~0x1, | 150 converted_visible_size_.SetSize((input_visible_size_.width() + 0x1) & ~0x1, |
152 (input_visible_size_.height() + 0x1) & ~0x1); | 151 (input_visible_size_.height() + 0x1) & ~0x1); |
153 converted_allocated_size_.SetSize( | 152 converted_allocated_size_.SetSize( |
154 (converted_visible_size_.width() + 0xF) & ~0xF, | 153 (converted_visible_size_.width() + 0xF) & ~0xF, |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 base::Unretained(this), | 337 base::Unretained(this), |
339 bitrate, | 338 bitrate, |
340 framerate)); | 339 framerate)); |
341 } | 340 } |
342 | 341 |
343 void ExynosVideoEncodeAccelerator::Destroy() { | 342 void ExynosVideoEncodeAccelerator::Destroy() { |
344 DVLOG(3) << "Destroy()"; | 343 DVLOG(3) << "Destroy()"; |
345 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 344 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); |
346 | 345 |
347 // We're destroying; cancel all callbacks. | 346 // We're destroying; cancel all callbacks. |
348 client_ptr_factory_.InvalidateWeakPtrs(); | 347 client_ptr_factory_.reset(); |
349 | 348 |
350 // If the encoder thread is running, destroy using posted task. | 349 // If the encoder thread is running, destroy using posted task. |
351 if (encoder_thread_.IsRunning()) { | 350 if (encoder_thread_.IsRunning()) { |
352 encoder_thread_.message_loop()->PostTask( | 351 encoder_thread_.message_loop()->PostTask( |
353 FROM_HERE, | 352 FROM_HERE, |
354 base::Bind(&ExynosVideoEncodeAccelerator::DestroyTask, | 353 base::Bind(&ExynosVideoEncodeAccelerator::DestroyTask, |
355 base::Unretained(this))); | 354 base::Unretained(this))); |
356 // DestroyTask() will put the encoder into kError state and cause all tasks | 355 // DestroyTask() will put the encoder into kError state and cause all tasks |
357 // to no-op. | 356 // to no-op. |
358 encoder_thread_.Stop(); | 357 encoder_thread_.Stop(); |
(...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1101 if (!child_message_loop_proxy_->BelongsToCurrentThread()) { | 1100 if (!child_message_loop_proxy_->BelongsToCurrentThread()) { |
1102 child_message_loop_proxy_->PostTask( | 1101 child_message_loop_proxy_->PostTask( |
1103 FROM_HERE, | 1102 FROM_HERE, |
1104 base::Bind( | 1103 base::Bind( |
1105 &ExynosVideoEncodeAccelerator::NotifyError, weak_this_, error)); | 1104 &ExynosVideoEncodeAccelerator::NotifyError, weak_this_, error)); |
1106 return; | 1105 return; |
1107 } | 1106 } |
1108 | 1107 |
1109 if (client_) { | 1108 if (client_) { |
1110 client_->NotifyError(error); | 1109 client_->NotifyError(error); |
1111 client_ptr_factory_.InvalidateWeakPtrs(); | 1110 client_ptr_factory_.reset(); |
1112 } | 1111 } |
1113 } | 1112 } |
1114 | 1113 |
1115 void ExynosVideoEncodeAccelerator::SetEncoderState(State state) { | 1114 void ExynosVideoEncodeAccelerator::SetEncoderState(State state) { |
1116 DVLOG(3) << "SetEncoderState(): state=" << state; | 1115 DVLOG(3) << "SetEncoderState(): state=" << state; |
1117 | 1116 |
1118 // We can touch encoder_state_ only if this is the encoder thread or the | 1117 // We can touch encoder_state_ only if this is the encoder thread or the |
1119 // encoder thread isn't running. | 1118 // encoder thread isn't running. |
1120 if (encoder_thread_.message_loop() != NULL && | 1119 if (encoder_thread_.message_loop() != NULL && |
1121 encoder_thread_.message_loop() != base::MessageLoop::current()) { | 1120 encoder_thread_.message_loop() != base::MessageLoop::current()) { |
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1538 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 1537 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
1539 reqbufs.memory = V4L2_MEMORY_MMAP; | 1538 reqbufs.memory = V4L2_MEMORY_MMAP; |
1540 if (HANDLE_EINTR(ioctl(mfc_fd_, VIDIOC_REQBUFS, &reqbufs)) != 0) | 1539 if (HANDLE_EINTR(ioctl(mfc_fd_, VIDIOC_REQBUFS, &reqbufs)) != 0) |
1541 DPLOG(ERROR) << "DestroyMfcOutputBuffers(): ioctl() failed: VIDIOC_REQBUFS"; | 1540 DPLOG(ERROR) << "DestroyMfcOutputBuffers(): ioctl() failed: VIDIOC_REQBUFS"; |
1542 | 1541 |
1543 mfc_output_buffer_map_.clear(); | 1542 mfc_output_buffer_map_.clear(); |
1544 mfc_free_output_buffers_.clear(); | 1543 mfc_free_output_buffers_.clear(); |
1545 } | 1544 } |
1546 | 1545 |
1547 } // namespace content | 1546 } // namespace content |
OLD | NEW |