Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(656)

Side by Side Diff: content/common/gpu/media/exynos_video_decode_accelerator.cc

Issue 68713007: Revert 235128 "Remove GSC usage from ExynosVideoDecodeAccelerator." (Closed) Base URL: svn://svn.chromium.org/chrome/branches/1710/src/
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 <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>
9 #include <linux/videodev2.h> 8 #include <linux/videodev2.h>
10 #include <poll.h> 9 #include <poll.h>
11 #include <sys/eventfd.h> 10 #include <sys/eventfd.h>
12 #include <sys/ioctl.h> 11 #include <sys/ioctl.h>
13 #include <sys/mman.h> 12 #include <sys/mman.h>
14 13
15 #include "base/bind.h" 14 #include "base/bind.h"
16 #include "base/debug/trace_event.h" 15 #include "base/debug/trace_event.h"
17 #include "base/memory/shared_memory.h" 16 #include "base/memory/shared_memory.h"
18 #include "base/message_loop/message_loop.h" 17 #include "base/message_loop/message_loop.h"
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 } while (0) 49 } while (0)
51 50
52 namespace { 51 namespace {
53 52
54 // TODO(posciak): remove once we update linux-headers. 53 // TODO(posciak): remove once we update linux-headers.
55 #ifndef V4L2_EVENT_RESOLUTION_CHANGE 54 #ifndef V4L2_EVENT_RESOLUTION_CHANGE
56 #define V4L2_EVENT_RESOLUTION_CHANGE 5 55 #define V4L2_EVENT_RESOLUTION_CHANGE 5
57 #endif 56 #endif
58 57
59 const char kExynosMfcDevice[] = "/dev/mfc-dec"; 58 const char kExynosMfcDevice[] = "/dev/mfc-dec";
59 const char kExynosGscDevice[] = "/dev/gsc1";
60 const char kMaliDriver[] = "libmali.so";
60 61
62 typedef EGLBoolean (*MaliEglImageGetBufferExtPhandleFunc)(EGLImageKHR, EGLint*,
63 void*);
64
65 void* libmali_handle = NULL;
66 MaliEglImageGetBufferExtPhandleFunc
67 mali_egl_image_get_buffer_ext_phandle = NULL;
61 } // anonymous namespace 68 } // anonymous namespace
62 69
63 struct ExynosVideoDecodeAccelerator::BitstreamBufferRef { 70 struct ExynosVideoDecodeAccelerator::BitstreamBufferRef {
64 BitstreamBufferRef( 71 BitstreamBufferRef(
65 base::WeakPtr<Client>& client, 72 base::WeakPtr<Client>& client,
66 scoped_refptr<base::MessageLoopProxy>& client_message_loop_proxy, 73 scoped_refptr<base::MessageLoopProxy>& client_message_loop_proxy,
67 base::SharedMemory* shm, 74 base::SharedMemory* shm,
68 size_t size, 75 size_t size,
69 int32 input_id); 76 int32 input_id);
70 ~BitstreamBufferRef(); 77 ~BitstreamBufferRef();
71 const base::WeakPtr<Client> client; 78 const base::WeakPtr<Client> client;
72 const scoped_refptr<base::MessageLoopProxy> client_message_loop_proxy; 79 const scoped_refptr<base::MessageLoopProxy> client_message_loop_proxy;
73 const scoped_ptr<base::SharedMemory> shm; 80 const scoped_ptr<base::SharedMemory> shm;
74 const size_t size; 81 const size_t size;
75 off_t bytes_used; 82 off_t bytes_used;
76 const int32 input_id; 83 const int32 input_id;
77 }; 84 };
78 85
79 struct ExynosVideoDecodeAccelerator::PictureBufferArrayRef { 86 struct ExynosVideoDecodeAccelerator::PictureBufferArrayRef {
80 PictureBufferArrayRef(EGLDisplay egl_display); 87 PictureBufferArrayRef(EGLDisplay egl_display, size_t count);
81 ~PictureBufferArrayRef(); 88 ~PictureBufferArrayRef();
82 89
83 struct PictureBufferRef { 90 struct PictureBufferRef {
84 PictureBufferRef(EGLImageKHR egl_image, int32 picture_id)
85 : egl_image(egl_image), picture_id(picture_id) {}
86 EGLImageKHR egl_image; 91 EGLImageKHR egl_image;
87 int32 picture_id; 92 int egl_image_fd;
93 int32 client_id;
88 }; 94 };
89 95
90 EGLDisplay const egl_display; 96 EGLDisplay const egl_display;
91 std::vector<PictureBufferRef> picture_buffers; 97 std::vector<PictureBufferRef> picture_buffers;
92 }; 98 };
93 99
94 struct ExynosVideoDecodeAccelerator::EGLSyncKHRRef { 100 struct ExynosVideoDecodeAccelerator::EGLSyncKHRRef {
95 EGLSyncKHRRef(EGLDisplay egl_display, EGLSyncKHR egl_sync); 101 EGLSyncKHRRef(EGLDisplay egl_display, EGLSyncKHR egl_sync);
96 ~EGLSyncKHRRef(); 102 ~EGLSyncKHRRef();
97 EGLDisplay const egl_display; 103 EGLDisplay const egl_display;
(...skipping 20 matching lines...) Expand all
118 } 124 }
119 125
120 ExynosVideoDecodeAccelerator::BitstreamBufferRef::~BitstreamBufferRef() { 126 ExynosVideoDecodeAccelerator::BitstreamBufferRef::~BitstreamBufferRef() {
121 if (input_id >= 0) { 127 if (input_id >= 0) {
122 client_message_loop_proxy->PostTask(FROM_HERE, base::Bind( 128 client_message_loop_proxy->PostTask(FROM_HERE, base::Bind(
123 &Client::NotifyEndOfBitstreamBuffer, client, input_id)); 129 &Client::NotifyEndOfBitstreamBuffer, client, input_id));
124 } 130 }
125 } 131 }
126 132
127 ExynosVideoDecodeAccelerator::PictureBufferArrayRef::PictureBufferArrayRef( 133 ExynosVideoDecodeAccelerator::PictureBufferArrayRef::PictureBufferArrayRef(
128 EGLDisplay egl_display) 134 EGLDisplay egl_display, size_t count)
129 : egl_display(egl_display) {} 135 : egl_display(egl_display),
136 picture_buffers(count) {
137 for (size_t i = 0; i < picture_buffers.size(); ++i) {
138 PictureBufferRef& buffer = picture_buffers[i];
139 buffer.egl_image = EGL_NO_IMAGE_KHR;
140 buffer.egl_image_fd = -1;
141 buffer.client_id = -1;
142 }
143 }
130 144
131 ExynosVideoDecodeAccelerator::PictureBufferArrayRef::~PictureBufferArrayRef() { 145 ExynosVideoDecodeAccelerator::PictureBufferArrayRef::~PictureBufferArrayRef() {
132 for (size_t i = 0; i < picture_buffers.size(); ++i) { 146 for (size_t i = 0; i < picture_buffers.size(); ++i) {
133 EGLImageKHR egl_image = picture_buffers[i].egl_image; 147 PictureBufferRef& buffer = picture_buffers[i];
134 if (egl_image != EGL_NO_IMAGE_KHR) 148 if (buffer.egl_image != EGL_NO_IMAGE_KHR)
135 eglDestroyImageKHR(egl_display, egl_image); 149 eglDestroyImageKHR(egl_display, buffer.egl_image);
150 if (buffer.egl_image_fd != -1)
151 HANDLE_EINTR(close(buffer.egl_image_fd));
136 } 152 }
137 } 153 }
138 154
139 ExynosVideoDecodeAccelerator::EGLSyncKHRRef::EGLSyncKHRRef( 155 ExynosVideoDecodeAccelerator::EGLSyncKHRRef::EGLSyncKHRRef(
140 EGLDisplay egl_display, EGLSyncKHR egl_sync) 156 EGLDisplay egl_display, EGLSyncKHR egl_sync)
141 : egl_display(egl_display), 157 : egl_display(egl_display),
142 egl_sync(egl_sync) { 158 egl_sync(egl_sync) {
143 } 159 }
144 160
145 ExynosVideoDecodeAccelerator::EGLSyncKHRRef::~EGLSyncKHRRef() { 161 ExynosVideoDecodeAccelerator::EGLSyncKHRRef::~EGLSyncKHRRef() {
146 if (egl_sync != EGL_NO_SYNC_KHR) 162 if (egl_sync != EGL_NO_SYNC_KHR)
147 eglDestroySyncKHR(egl_display, egl_sync); 163 eglDestroySyncKHR(egl_display, egl_sync);
148 } 164 }
149 165
150 ExynosVideoDecodeAccelerator::MfcInputRecord::MfcInputRecord() 166 ExynosVideoDecodeAccelerator::MfcInputRecord::MfcInputRecord()
151 : at_device(false), 167 : at_device(false),
152 address(NULL), 168 address(NULL),
153 length(0), 169 length(0),
154 bytes_used(0), 170 bytes_used(0),
155 input_id(-1) { 171 input_id(-1) {
156 } 172 }
157 173
158 ExynosVideoDecodeAccelerator::MfcInputRecord::~MfcInputRecord() { 174 ExynosVideoDecodeAccelerator::MfcInputRecord::~MfcInputRecord() {
159 } 175 }
160 176
161 ExynosVideoDecodeAccelerator::MfcOutputRecord::MfcOutputRecord() 177 ExynosVideoDecodeAccelerator::MfcOutputRecord::MfcOutputRecord()
162 : at_device(false), 178 : at_device(false),
179 input_id(-1) {
180 bytes_used[0] = 0;
181 bytes_used[1] = 0;
182 address[0] = NULL;
183 address[1] = NULL;
184 length[0] = 0;
185 length[1] = 0;
186 }
187
188 ExynosVideoDecodeAccelerator::MfcOutputRecord::~MfcOutputRecord() {
189 }
190
191 ExynosVideoDecodeAccelerator::GscInputRecord::GscInputRecord()
192 : at_device(false),
193 mfc_output(-1) {
194 }
195
196 ExynosVideoDecodeAccelerator::GscInputRecord::~GscInputRecord() {
197 }
198
199 ExynosVideoDecodeAccelerator::GscOutputRecord::GscOutputRecord()
200 : at_device(false),
163 at_client(false), 201 at_client(false),
202 fd(-1),
164 egl_image(EGL_NO_IMAGE_KHR), 203 egl_image(EGL_NO_IMAGE_KHR),
165 egl_sync(EGL_NO_SYNC_KHR), 204 egl_sync(EGL_NO_SYNC_KHR),
166 picture_id(-1), 205 picture_id(-1),
167 cleared(false) { 206 cleared(false) {}
168 for (size_t i = 0; i < arraysize(fds); ++i) 207
169 fds[i] = -1; 208 ExynosVideoDecodeAccelerator::GscOutputRecord::~GscOutputRecord() {
170 } 209 }
171 210
172 ExynosVideoDecodeAccelerator::MfcOutputRecord::~MfcOutputRecord() {}
173
174 ExynosVideoDecodeAccelerator::PictureRecord::PictureRecord( 211 ExynosVideoDecodeAccelerator::PictureRecord::PictureRecord(
175 bool cleared, 212 bool cleared,
176 const media::Picture& picture) 213 const media::Picture& picture)
177 : cleared(cleared), picture(picture) {} 214 : cleared(cleared), picture(picture) {}
178 215
179 ExynosVideoDecodeAccelerator::PictureRecord::~PictureRecord() {} 216 ExynosVideoDecodeAccelerator::PictureRecord::~PictureRecord() {}
180 217
181 ExynosVideoDecodeAccelerator::ExynosVideoDecodeAccelerator( 218 ExynosVideoDecodeAccelerator::ExynosVideoDecodeAccelerator(
182 EGLDisplay egl_display, 219 EGLDisplay egl_display,
183 EGLContext egl_context, 220 EGLContext egl_context,
(...skipping 17 matching lines...) Expand all
201 resolution_change_pending_(false), 238 resolution_change_pending_(false),
202 resolution_change_reset_pending_(false), 239 resolution_change_reset_pending_(false),
203 decoder_partial_frame_pending_(false), 240 decoder_partial_frame_pending_(false),
204 mfc_fd_(-1), 241 mfc_fd_(-1),
205 mfc_input_streamon_(false), 242 mfc_input_streamon_(false),
206 mfc_input_buffer_queued_count_(0), 243 mfc_input_buffer_queued_count_(0),
207 mfc_output_streamon_(false), 244 mfc_output_streamon_(false),
208 mfc_output_buffer_queued_count_(0), 245 mfc_output_buffer_queued_count_(0),
209 mfc_output_buffer_pixelformat_(0), 246 mfc_output_buffer_pixelformat_(0),
210 mfc_output_dpb_size_(0), 247 mfc_output_dpb_size_(0),
248 gsc_fd_(-1),
249 gsc_input_streamon_(false),
250 gsc_input_buffer_queued_count_(0),
251 gsc_output_streamon_(false),
252 gsc_output_buffer_queued_count_(0),
211 picture_clearing_count_(0), 253 picture_clearing_count_(0),
212 device_poll_thread_("ExynosDevicePollThread"), 254 device_poll_thread_("ExynosDevicePollThread"),
213 device_poll_interrupt_fd_(-1), 255 device_poll_interrupt_fd_(-1),
214 make_context_current_(make_context_current), 256 make_context_current_(make_context_current),
215 egl_display_(egl_display), 257 egl_display_(egl_display),
216 egl_context_(egl_context), 258 egl_context_(egl_context),
217 video_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN) {} 259 video_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN) {}
218 260
219 ExynosVideoDecodeAccelerator::~ExynosVideoDecodeAccelerator() { 261 ExynosVideoDecodeAccelerator::~ExynosVideoDecodeAccelerator() {
220 DCHECK(!decoder_thread_.IsRunning()); 262 DCHECK(!decoder_thread_.IsRunning());
221 DCHECK(!device_poll_thread_.IsRunning()); 263 DCHECK(!device_poll_thread_.IsRunning());
222 264
223 if (device_poll_interrupt_fd_ != -1) { 265 if (device_poll_interrupt_fd_ != -1) {
224 HANDLE_EINTR(close(device_poll_interrupt_fd_)); 266 HANDLE_EINTR(close(device_poll_interrupt_fd_));
225 device_poll_interrupt_fd_ = -1; 267 device_poll_interrupt_fd_ = -1;
226 } 268 }
269 if (gsc_fd_ != -1) {
270 DestroyGscInputBuffers();
271 DestroyGscOutputBuffers();
272 HANDLE_EINTR(close(gsc_fd_));
273 gsc_fd_ = -1;
274 }
227 if (mfc_fd_ != -1) { 275 if (mfc_fd_ != -1) {
228 DestroyMfcInputBuffers(); 276 DestroyMfcInputBuffers();
229 DestroyMfcOutputBuffers(); 277 DestroyMfcOutputBuffers();
230 HANDLE_EINTR(close(mfc_fd_)); 278 HANDLE_EINTR(close(mfc_fd_));
231 mfc_fd_ = -1; 279 mfc_fd_ = -1;
232 } 280 }
233 281
234 // These maps have members that should be manually destroyed, e.g. file 282 // These maps have members that should be manually destroyed, e.g. file
235 // descriptors, mmap() segments, etc. 283 // descriptors, mmap() segments, etc.
236 DCHECK(mfc_input_buffer_map_.empty()); 284 DCHECK(mfc_input_buffer_map_.empty());
237 DCHECK(mfc_output_buffer_map_.empty()); 285 DCHECK(mfc_output_buffer_map_.empty());
286 DCHECK(gsc_input_buffer_map_.empty());
287 DCHECK(gsc_output_buffer_map_.empty());
238 } 288 }
239 289
240 bool ExynosVideoDecodeAccelerator::Initialize( 290 bool ExynosVideoDecodeAccelerator::Initialize(
241 media::VideoCodecProfile profile) { 291 media::VideoCodecProfile profile) {
242 DVLOG(3) << "Initialize()"; 292 DVLOG(3) << "Initialize()";
243 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 293 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
244 DCHECK_EQ(decoder_state_, kUninitialized); 294 DCHECK_EQ(decoder_state_, kUninitialized);
245 295
246 switch (profile) { 296 switch (profile) {
247 case media::H264PROFILE_BASELINE: 297 case media::H264PROFILE_BASELINE:
248 DVLOG(2) << "Initialize(): profile H264PROFILE_BASELINE"; 298 DVLOG(2) << "Initialize(): profile H264PROFILE_BASELINE";
249 break; 299 break;
250 case media::H264PROFILE_MAIN: 300 case media::H264PROFILE_MAIN:
251 DVLOG(2) << "Initialize(): profile H264PROFILE_MAIN"; 301 DVLOG(2) << "Initialize(): profile H264PROFILE_MAIN";
252 break; 302 break;
253 case media::H264PROFILE_HIGH: 303 case media::H264PROFILE_HIGH:
254 DVLOG(2) << "Initialize(): profile H264PROFILE_HIGH"; 304 DVLOG(2) << "Initialize(): profile H264PROFILE_HIGH";
255 break; 305 break;
256 case media::VP8PROFILE_MAIN: 306 case media::VP8PROFILE_MAIN:
257 DVLOG(2) << "Initialize(): profile VP8PROFILE_MAIN"; 307 DVLOG(2) << "Initialize(): profile VP8PROFILE_MAIN";
258 break; 308 break;
259 default: 309 default:
260 DLOG(ERROR) << "Initialize(): unsupported profile=" << profile; 310 DLOG(ERROR) << "Initialize(): unsupported profile=" << profile;
261 return false; 311 return false;
262 }; 312 };
263 video_profile_ = profile; 313 video_profile_ = profile;
264 314
315 static bool sandbox_initialized = PostSandboxInitialization();
316 if (!sandbox_initialized) {
317 DLOG(ERROR) << "Initialize(): PostSandboxInitialization() failed";
318 NOTIFY_ERROR(PLATFORM_FAILURE);
319 return false;
320 }
321
265 if (egl_display_ == EGL_NO_DISPLAY) { 322 if (egl_display_ == EGL_NO_DISPLAY) {
266 DLOG(ERROR) << "Initialize(): could not get EGLDisplay"; 323 DLOG(ERROR) << "Initialize(): could not get EGLDisplay";
267 NOTIFY_ERROR(PLATFORM_FAILURE); 324 NOTIFY_ERROR(PLATFORM_FAILURE);
268 return false; 325 return false;
269 } 326 }
270 327
271 if (egl_context_ == EGL_NO_CONTEXT) { 328 if (egl_context_ == EGL_NO_CONTEXT) {
272 DLOG(ERROR) << "Initialize(): could not get EGLContext"; 329 DLOG(ERROR) << "Initialize(): could not get EGLContext";
273 NOTIFY_ERROR(PLATFORM_FAILURE); 330 NOTIFY_ERROR(PLATFORM_FAILURE);
274 return false; 331 return false;
(...skipping 15 matching lines...) Expand all
290 // Open the video devices. 347 // Open the video devices.
291 DVLOG(2) << "Initialize(): opening MFC device: " << kExynosMfcDevice; 348 DVLOG(2) << "Initialize(): opening MFC device: " << kExynosMfcDevice;
292 mfc_fd_ = HANDLE_EINTR(open(kExynosMfcDevice, 349 mfc_fd_ = HANDLE_EINTR(open(kExynosMfcDevice,
293 O_RDWR | O_NONBLOCK | O_CLOEXEC)); 350 O_RDWR | O_NONBLOCK | O_CLOEXEC));
294 if (mfc_fd_ == -1) { 351 if (mfc_fd_ == -1) {
295 DPLOG(ERROR) << "Initialize(): could not open MFC device: " 352 DPLOG(ERROR) << "Initialize(): could not open MFC device: "
296 << kExynosMfcDevice; 353 << kExynosMfcDevice;
297 NOTIFY_ERROR(PLATFORM_FAILURE); 354 NOTIFY_ERROR(PLATFORM_FAILURE);
298 return false; 355 return false;
299 } 356 }
357 DVLOG(2) << "Initialize(): opening GSC device: " << kExynosGscDevice;
358 gsc_fd_ = HANDLE_EINTR(open(kExynosGscDevice,
359 O_RDWR | O_NONBLOCK | O_CLOEXEC));
360 if (gsc_fd_ == -1) {
361 DPLOG(ERROR) << "Initialize(): could not open GSC device: "
362 << kExynosGscDevice;
363 NOTIFY_ERROR(PLATFORM_FAILURE);
364 return false;
365 }
300 366
301 // Create the interrupt fd. 367 // Create the interrupt fd.
302 DCHECK_EQ(device_poll_interrupt_fd_, -1); 368 DCHECK_EQ(device_poll_interrupt_fd_, -1);
303 device_poll_interrupt_fd_ = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); 369 device_poll_interrupt_fd_ = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
304 if (device_poll_interrupt_fd_ == -1) { 370 if (device_poll_interrupt_fd_ == -1) {
305 DPLOG(ERROR) << "Initialize(): eventfd() failed"; 371 DPLOG(ERROR) << "Initialize(): eventfd() failed";
306 NOTIFY_ERROR(PLATFORM_FAILURE); 372 NOTIFY_ERROR(PLATFORM_FAILURE);
307 return false; 373 return false;
308 } 374 }
309 375
310 // Capabilities check. 376 // Capabilities check.
311 struct v4l2_capability caps; 377 struct v4l2_capability caps;
312 const __u32 kCapsRequired = 378 const __u32 kCapsRequired =
313 V4L2_CAP_VIDEO_CAPTURE_MPLANE | 379 V4L2_CAP_VIDEO_CAPTURE_MPLANE |
314 V4L2_CAP_VIDEO_OUTPUT_MPLANE | 380 V4L2_CAP_VIDEO_OUTPUT_MPLANE |
315 V4L2_CAP_STREAMING; 381 V4L2_CAP_STREAMING;
316 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QUERYCAP, &caps); 382 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QUERYCAP, &caps);
317 if ((caps.capabilities & kCapsRequired) != kCapsRequired) { 383 if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
318 DLOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP" 384 DLOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP"
319 ", caps check failed: 0x" << std::hex << caps.capabilities; 385 ", caps check failed: 0x" << std::hex << caps.capabilities;
320 NOTIFY_ERROR(PLATFORM_FAILURE); 386 NOTIFY_ERROR(PLATFORM_FAILURE);
321 return false; 387 return false;
322 } 388 }
389 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_QUERYCAP, &caps);
390 if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
391 DLOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP"
392 ", caps check failed: 0x" << std::hex << caps.capabilities;
393 NOTIFY_ERROR(PLATFORM_FAILURE);
394 return false;
395 }
323 396
324 if (!CreateMfcInputBuffers()) 397 if (!CreateMfcInputBuffers())
325 return false; 398 return false;
326 399
327 // MFC output format has to be setup before streaming starts. 400 // MFC output format has to be setup before streaming starts.
328 struct v4l2_format format; 401 struct v4l2_format format;
329 memset(&format, 0, sizeof(format)); 402 memset(&format, 0, sizeof(format));
330 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 403 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
331 format.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M; 404 format.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12MT_16X16;
332 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_S_FMT, &format); 405 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_S_FMT, &format);
333 406
334 // Subscribe to the resolution change event. 407 // Subscribe to the resolution change event.
335 struct v4l2_event_subscription sub; 408 struct v4l2_event_subscription sub;
336 memset(&sub, 0, sizeof(sub)); 409 memset(&sub, 0, sizeof(sub));
337 sub.type = V4L2_EVENT_RESOLUTION_CHANGE; 410 sub.type = V4L2_EVENT_RESOLUTION_CHANGE;
338 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_SUBSCRIBE_EVENT, &sub); 411 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_SUBSCRIBE_EVENT, &sub);
339 412
340 // Initialize format-specific bits. 413 // Initialize format-specific bits.
341 if (video_profile_ >= media::H264PROFILE_MIN && 414 if (video_profile_ >= media::H264PROFILE_MIN &&
(...skipping 24 matching lines...) Expand all
366 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 439 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
367 &ExynosVideoDecodeAccelerator::DecodeTask, base::Unretained(this), 440 &ExynosVideoDecodeAccelerator::DecodeTask, base::Unretained(this),
368 bitstream_buffer)); 441 bitstream_buffer));
369 } 442 }
370 443
371 void ExynosVideoDecodeAccelerator::AssignPictureBuffers( 444 void ExynosVideoDecodeAccelerator::AssignPictureBuffers(
372 const std::vector<media::PictureBuffer>& buffers) { 445 const std::vector<media::PictureBuffer>& buffers) {
373 DVLOG(3) << "AssignPictureBuffers(): buffer_count=" << buffers.size(); 446 DVLOG(3) << "AssignPictureBuffers(): buffer_count=" << buffers.size();
374 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 447 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
375 448
376 if (buffers.size() != mfc_output_buffer_map_.size()) { 449 if (buffers.size() != gsc_output_buffer_map_.size()) {
377 DLOG(ERROR) << "AssignPictureBuffers(): Failed to provide requested picture" 450 DLOG(ERROR) << "AssignPictureBuffers(): Failed to provide requested picture"
378 " buffers. (Got " << buffers.size() 451 " buffers. (Got " << buffers.size() << ", requested " <<
379 << ", requested " << mfc_output_buffer_map_.size() << ")"; 452 gsc_output_buffer_map_.size() << ")";
380 NOTIFY_ERROR(INVALID_ARGUMENT); 453 NOTIFY_ERROR(INVALID_ARGUMENT);
381 return; 454 return;
382 } 455 }
383 456
384 if (!make_context_current_.Run()) { 457 if (!make_context_current_.Run()) {
385 DLOG(ERROR) << "AssignPictureBuffers(): could not make context current"; 458 DLOG(ERROR) << "AssignPictureBuffers(): could not make context current";
386 NOTIFY_ERROR(PLATFORM_FAILURE); 459 NOTIFY_ERROR(PLATFORM_FAILURE);
387 return; 460 return;
388 } 461 }
389 462
390 scoped_ptr<PictureBufferArrayRef> picture_buffers_ref( 463 scoped_ptr<PictureBufferArrayRef> pic_buffers_ref(
391 new PictureBufferArrayRef(egl_display_)); 464 new PictureBufferArrayRef(egl_display_, buffers.size()));
392 gfx::ScopedTextureBinder bind_restore(GL_TEXTURE_EXTERNAL_OES, 0); 465
393 EGLint attrs[] = { 466 const static EGLint kImageAttrs[] = {
394 EGL_WIDTH, 0, EGL_HEIGHT, 0, 467 EGL_IMAGE_PRESERVED_KHR, 0,
395 EGL_LINUX_DRM_FOURCC_EXT, 0, EGL_DMA_BUF_PLANE0_FD_EXT, 0, 468 EGL_NONE,
396 EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, EGL_DMA_BUF_PLANE0_PITCH_EXT, 0, 469 };
397 EGL_DMA_BUF_PLANE1_FD_EXT, 0, EGL_DMA_BUF_PLANE1_OFFSET_EXT, 0, 470 Display* x_display = base::MessagePumpForUI::GetDefaultXDisplay();
398 EGL_DMA_BUF_PLANE1_PITCH_EXT, 0, EGL_NONE, }; 471 gfx::ScopedTextureBinder bind_restore(GL_TEXTURE_2D, 0);
399 attrs[1] = frame_buffer_size_.width(); 472 for (size_t i = 0; i < pic_buffers_ref->picture_buffers.size(); ++i) {
400 attrs[3] = frame_buffer_size_.height();
401 attrs[5] = DRM_FORMAT_NV12;
402 for (size_t i = 0; i < mfc_output_buffer_map_.size(); ++i) {
403 DCHECK(buffers[i].size() == frame_buffer_size_); 473 DCHECK(buffers[i].size() == frame_buffer_size_);
404 MfcOutputRecord& output_record = mfc_output_buffer_map_[i]; 474 PictureBufferArrayRef::PictureBufferRef& buffer =
405 attrs[7] = output_record.fds[0]; 475 pic_buffers_ref->picture_buffers[i];
406 attrs[9] = 0; 476 // Create the X pixmap and then create an EGLImageKHR from it, so we can
407 attrs[11] = frame_buffer_size_.width(); 477 // get dma_buf backing.
408 attrs[13] = output_record.fds[1]; 478 Pixmap pixmap = XCreatePixmap(x_display,
409 attrs[15] = 0; 479 RootWindow(x_display, 0),
410 attrs[17] = frame_buffer_size_.width(); 480 frame_buffer_size_.width(),
481 frame_buffer_size_.height(),
482 32);
483 if (!pixmap) {
484 DLOG(ERROR) << "AssignPictureBuffers(): could not create X pixmap";
485 NOTIFY_ERROR(PLATFORM_FAILURE);
486 return;
487 }
488 glBindTexture(GL_TEXTURE_2D, buffers[i].texture_id());
411 EGLImageKHR egl_image = eglCreateImageKHR( 489 EGLImageKHR egl_image = eglCreateImageKHR(
412 egl_display_, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attrs); 490 egl_display_, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR,
491 (EGLClientBuffer)pixmap, kImageAttrs);
492 // We can free the X pixmap immediately -- according to the
493 // EGL_KHR_image_base spec, the backing storage does not go away until the
494 // last referencing EGLImage is destroyed.
495 XFreePixmap(x_display, pixmap);
413 if (egl_image == EGL_NO_IMAGE_KHR) { 496 if (egl_image == EGL_NO_IMAGE_KHR) {
414 DLOG(ERROR) << "AssignPictureBuffers(): could not create EGLImageKHR"; 497 DLOG(ERROR) << "AssignPictureBuffers(): could not create EGLImageKHR";
415 NOTIFY_ERROR(PLATFORM_FAILURE); 498 NOTIFY_ERROR(PLATFORM_FAILURE);
416 return; 499 return;
417 } 500 }
418 501 buffer.egl_image = egl_image;
419 glBindTexture(GL_TEXTURE_EXTERNAL_OES, buffers[i].texture_id()); 502 int fd;
420 glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, egl_image); 503 if (!mali_egl_image_get_buffer_ext_phandle(buffer.egl_image, NULL, &fd)) {
421 picture_buffers_ref->picture_buffers.push_back( 504 DLOG(ERROR) << "AssignPictureBuffers(): "
422 PictureBufferArrayRef::PictureBufferRef(egl_image, buffers[i].id())); 505 << "could not get EGLImageKHR dmabuf fd";
506 NOTIFY_ERROR(PLATFORM_FAILURE);
507 return;
508 }
509 buffer.egl_image_fd = fd;
510 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, egl_image);
511 buffer.client_id = buffers[i].id();
423 } 512 }
424 decoder_thread_.message_loop()->PostTask( 513 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
425 FROM_HERE, 514 &ExynosVideoDecodeAccelerator::AssignPictureBuffersTask,
426 base::Bind(&ExynosVideoDecodeAccelerator::AssignPictureBuffersTask, 515 base::Unretained(this), base::Passed(&pic_buffers_ref)));
427 base::Unretained(this),
428 base::Passed(&picture_buffers_ref)));
429 } 516 }
430 517
431 void ExynosVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) { 518 void ExynosVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) {
432 DVLOG(3) << "ReusePictureBuffer(): picture_buffer_id=" << picture_buffer_id; 519 DVLOG(3) << "ReusePictureBuffer(): picture_buffer_id=" << picture_buffer_id;
433 // Must be run on child thread, as we'll insert a sync in the EGL context. 520 // Must be run on child thread, as we'll insert a sync in the EGL context.
434 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 521 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
435 522
436 if (!make_context_current_.Run()) { 523 if (!make_context_current_.Run()) {
437 DLOG(ERROR) << "ReusePictureBuffer(): could not make context current"; 524 DLOG(ERROR) << "ReusePictureBuffer(): could not make context current";
438 NOTIFY_ERROR(PLATFORM_FAILURE); 525 NOTIFY_ERROR(PLATFORM_FAILURE);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 } 574 }
488 575
489 // Set to kError state just in case. 576 // Set to kError state just in case.
490 SetDecoderState(kError); 577 SetDecoderState(kError);
491 578
492 delete this; 579 delete this;
493 } 580 }
494 581
495 bool ExynosVideoDecodeAccelerator::CanDecodeOnIOThread() { return true; } 582 bool ExynosVideoDecodeAccelerator::CanDecodeOnIOThread() { return true; }
496 583
584 // static
585 void ExynosVideoDecodeAccelerator::PreSandboxInitialization() {
586 DVLOG(3) << "PreSandboxInitialization()";
587 dlerror();
588
589 libmali_handle = dlopen(kMaliDriver, RTLD_LAZY | RTLD_LOCAL);
590 if (libmali_handle == NULL) {
591 DPLOG(ERROR) << "failed to dlopen() " << kMaliDriver << ": " << dlerror();
592 }
593 }
594
595 // static
596 bool ExynosVideoDecodeAccelerator::PostSandboxInitialization() {
597 DVLOG(3) << "PostSandboxInitialization()";
598 if (libmali_handle == NULL) {
599 DLOG(ERROR) << "PostSandboxInitialization(): no " << kMaliDriver
600 << " driver handle";
601 return false;
602 }
603
604 dlerror();
605 mali_egl_image_get_buffer_ext_phandle =
606 reinterpret_cast<MaliEglImageGetBufferExtPhandleFunc>(
607 dlsym(libmali_handle, "mali_egl_image_get_buffer_ext_phandle"));
608 if (mali_egl_image_get_buffer_ext_phandle == NULL) {
609 DPLOG(ERROR) << "PostSandboxInitialization(): failed to dlsym() "
610 << "mali_egl_image_get_buffer_ext_phandle: " << dlerror();
611 return false;
612 }
613
614 return true;
615 }
616
497 void ExynosVideoDecodeAccelerator::DecodeTask( 617 void ExynosVideoDecodeAccelerator::DecodeTask(
498 const media::BitstreamBuffer& bitstream_buffer) { 618 const media::BitstreamBuffer& bitstream_buffer) {
499 DVLOG(3) << "DecodeTask(): input_id=" << bitstream_buffer.id(); 619 DVLOG(3) << "DecodeTask(): input_id=" << bitstream_buffer.id();
500 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 620 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
501 DCHECK_NE(decoder_state_, kUninitialized); 621 DCHECK_NE(decoder_state_, kUninitialized);
502 TRACE_EVENT1("Video Decoder", "EVDA::DecodeTask", "input_id", 622 TRACE_EVENT1("Video Decoder", "EVDA::DecodeTask", "input_id",
503 bitstream_buffer.id()); 623 bitstream_buffer.id());
504 624
505 scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef( 625 scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef(
506 io_client_, io_message_loop_proxy_, 626 io_client_, io_message_loop_proxy_,
(...skipping 12 matching lines...) Expand all
519 // we're here, we know that this DecodeTask() was scheduled by a Decode() 639 // we're here, we know that this DecodeTask() was scheduled by a Decode()
520 // call that came after (in the client thread) the Reset() or Flush() call; 640 // call that came after (in the client thread) the Reset() or Flush() call;
521 // thus set up the delay if necessary. 641 // thus set up the delay if necessary.
522 if (decoder_delay_bitstream_buffer_id_ == -1) 642 if (decoder_delay_bitstream_buffer_id_ == -1)
523 decoder_delay_bitstream_buffer_id_ = bitstream_record->input_id; 643 decoder_delay_bitstream_buffer_id_ = bitstream_record->input_id;
524 } else if (decoder_state_ == kError) { 644 } else if (decoder_state_ == kError) {
525 DVLOG(2) << "DecodeTask(): early out: kError state"; 645 DVLOG(2) << "DecodeTask(): early out: kError state";
526 return; 646 return;
527 } 647 }
528 648
529 decoder_input_queue_.push( 649 decoder_input_queue_.push_back(
530 linked_ptr<BitstreamBufferRef>(bitstream_record.release())); 650 linked_ptr<BitstreamBufferRef>(bitstream_record.release()));
531 decoder_decode_buffer_tasks_scheduled_++; 651 decoder_decode_buffer_tasks_scheduled_++;
532 DecodeBufferTask(); 652 DecodeBufferTask();
533 } 653 }
534 654
535 void ExynosVideoDecodeAccelerator::DecodeBufferTask() { 655 void ExynosVideoDecodeAccelerator::DecodeBufferTask() {
536 DVLOG(3) << "DecodeBufferTask()"; 656 DVLOG(3) << "DecodeBufferTask()";
537 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 657 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
538 DCHECK_NE(decoder_state_, kUninitialized); 658 DCHECK_NE(decoder_state_, kUninitialized);
539 TRACE_EVENT0("Video Decoder", "EVDA::DecodeBufferTask"); 659 TRACE_EVENT0("Video Decoder", "EVDA::DecodeBufferTask");
(...skipping 17 matching lines...) Expand all
557 return; 677 return;
558 } 678 }
559 linked_ptr<BitstreamBufferRef>& buffer_ref = decoder_input_queue_.front(); 679 linked_ptr<BitstreamBufferRef>& buffer_ref = decoder_input_queue_.front();
560 if (decoder_delay_bitstream_buffer_id_ == buffer_ref->input_id) { 680 if (decoder_delay_bitstream_buffer_id_ == buffer_ref->input_id) {
561 // We're asked to delay decoding on this and subsequent buffers. 681 // We're asked to delay decoding on this and subsequent buffers.
562 return; 682 return;
563 } 683 }
564 684
565 // Setup to use the next buffer. 685 // Setup to use the next buffer.
566 decoder_current_bitstream_buffer_.reset(buffer_ref.release()); 686 decoder_current_bitstream_buffer_.reset(buffer_ref.release());
567 decoder_input_queue_.pop(); 687 decoder_input_queue_.pop_front();
568 DVLOG(3) << "DecodeBufferTask(): reading input_id=" 688 DVLOG(3) << "DecodeBufferTask(): reading input_id="
569 << decoder_current_bitstream_buffer_->input_id 689 << decoder_current_bitstream_buffer_->input_id
570 << ", addr=" << (decoder_current_bitstream_buffer_->shm ? 690 << ", addr=" << (decoder_current_bitstream_buffer_->shm ?
571 decoder_current_bitstream_buffer_->shm->memory() : 691 decoder_current_bitstream_buffer_->shm->memory() :
572 NULL) 692 NULL)
573 << ", size=" << decoder_current_bitstream_buffer_->size; 693 << ", size=" << decoder_current_bitstream_buffer_->size;
574 } 694 }
575 bool schedule_task = false; 695 bool schedule_task = false;
576 const size_t size = decoder_current_bitstream_buffer_->size; 696 const size_t size = decoder_current_bitstream_buffer_->size;
577 size_t decoded_size = 0; 697 size_t decoded_size = 0;
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
909 // buffer was prompted by a flush buffer, and should be queued even when 1029 // buffer was prompted by a flush buffer, and should be queued even when
910 // empty. 1030 // empty.
911 if (input_record.input_id >= 0 && input_record.bytes_used == 0) { 1031 if (input_record.input_id >= 0 && input_record.bytes_used == 0) {
912 input_record.input_id = -1; 1032 input_record.input_id = -1;
913 mfc_free_input_buffers_.push_back(decoder_current_input_buffer_); 1033 mfc_free_input_buffers_.push_back(decoder_current_input_buffer_);
914 decoder_current_input_buffer_ = -1; 1034 decoder_current_input_buffer_ = -1;
915 return true; 1035 return true;
916 } 1036 }
917 1037
918 // Queue it to MFC. 1038 // Queue it to MFC.
919 mfc_input_ready_queue_.push(decoder_current_input_buffer_); 1039 mfc_input_ready_queue_.push_back(decoder_current_input_buffer_);
920 decoder_current_input_buffer_ = -1; 1040 decoder_current_input_buffer_ = -1;
921 DVLOG(3) << "FlushInputFrame(): submitting input_id=" 1041 DVLOG(3) << "FlushInputFrame(): submitting input_id="
922 << input_record.input_id; 1042 << input_record.input_id;
923 // Kick the MFC once since there's new available input for it. 1043 // Kick the MFC once since there's new available input for it.
924 EnqueueMfc(); 1044 EnqueueMfc();
925 1045
926 return (decoder_state_ != kError); 1046 return (decoder_state_ != kError);
927 } 1047 }
928 1048
929 void ExynosVideoDecodeAccelerator::AssignPictureBuffersTask( 1049 void ExynosVideoDecodeAccelerator::AssignPictureBuffersTask(
930 scoped_ptr<PictureBufferArrayRef> pic_buffers) { 1050 scoped_ptr<PictureBufferArrayRef> pic_buffers) {
931 DVLOG(3) << "AssignPictureBuffersTask()"; 1051 DVLOG(3) << "AssignPictureBuffersTask()";
932 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1052 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
933 DCHECK_NE(decoder_state_, kUninitialized); 1053 DCHECK_NE(decoder_state_, kUninitialized);
934 TRACE_EVENT0("Video Decoder", "EVDA::AssignPictureBuffersTask"); 1054 TRACE_EVENT0("Video Decoder", "EVDA::AssignPictureBuffersTask");
935 1055
936 // We run AssignPictureBuffersTask even if we're in kResetting. 1056 // We run AssignPictureBuffersTask even if we're in kResetting.
937 if (decoder_state_ == kError) { 1057 if (decoder_state_ == kError) {
938 DVLOG(2) << "AssignPictureBuffersTask(): early out: kError state"; 1058 DVLOG(2) << "AssignPictureBuffersTask(): early out: kError state";
939 return; 1059 return;
940 } 1060 }
941 1061
942 DCHECK_EQ(pic_buffers->picture_buffers.size(), mfc_output_buffer_map_.size()); 1062 DCHECK_EQ(pic_buffers->picture_buffers.size(), gsc_output_buffer_map_.size());
943 for (size_t i = 0; i < mfc_output_buffer_map_.size(); ++i) { 1063 for (size_t i = 0; i < gsc_output_buffer_map_.size(); ++i) {
944 MfcOutputRecord& output_record = mfc_output_buffer_map_[i];
945 PictureBufferArrayRef::PictureBufferRef& buffer_ref =
946 pic_buffers->picture_buffers[i];
947 // We should be blank right now. 1064 // We should be blank right now.
948 DCHECK(!output_record.at_device); 1065 GscOutputRecord& output_record = gsc_output_buffer_map_[i];
949 DCHECK(!output_record.at_client); 1066 DCHECK_EQ(output_record.fd, -1);
950 DCHECK_EQ(output_record.egl_image, EGL_NO_IMAGE_KHR); 1067 DCHECK_EQ(output_record.egl_image, EGL_NO_IMAGE_KHR);
951 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); 1068 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR);
952 DCHECK_EQ(output_record.picture_id, -1); 1069 DCHECK_EQ(output_record.picture_id, -1);
953 DCHECK_EQ(output_record.cleared, false); 1070 DCHECK_EQ(output_record.cleared, false);
954 output_record.egl_image = buffer_ref.egl_image; 1071 PictureBufferArrayRef::PictureBufferRef& buffer =
955 output_record.picture_id = buffer_ref.picture_id; 1072 pic_buffers->picture_buffers[i];
956 mfc_free_output_buffers_.push(i); 1073 output_record.fd = buffer.egl_image_fd;
957 DVLOG(3) << "AssignPictureBuffersTask(): buffer[" << i 1074 output_record.egl_image = buffer.egl_image;
958 << "]: picture_id=" << buffer_ref.picture_id; 1075 output_record.picture_id = buffer.client_id;
1076
1077 // Take ownership of the EGLImage and fd.
1078 buffer.egl_image = EGL_NO_IMAGE_KHR;
1079 buffer.egl_image_fd = -1;
1080 // And add this buffer to the free list.
1081 gsc_free_output_buffers_.push_back(i);
959 } 1082 }
960 pic_buffers->picture_buffers.clear();
961 1083
962 // We got buffers! Kick the MFC. 1084 // We got buffers! Kick the GSC.
963 EnqueueMfc(); 1085 EnqueueGsc();
964 1086
965 if (decoder_state_ == kChangingResolution) 1087 if (decoder_state_ == kChangingResolution)
966 ResumeAfterResolutionChange(); 1088 ResumeAfterResolutionChange();
967 } 1089 }
968 1090
969 void ExynosVideoDecodeAccelerator::ServiceDeviceTask(bool mfc_event_pending) { 1091 void ExynosVideoDecodeAccelerator::ServiceDeviceTask(bool mfc_event_pending) {
970 DVLOG(3) << "ServiceDeviceTask()"; 1092 DVLOG(3) << "ServiceDeviceTask()";
971 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1093 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
972 DCHECK_NE(decoder_state_, kUninitialized); 1094 DCHECK_NE(decoder_state_, kUninitialized);
973 DCHECK_NE(decoder_state_, kInitialized); 1095 DCHECK_NE(decoder_state_, kInitialized);
974 DCHECK_NE(decoder_state_, kAfterReset); 1096 DCHECK_NE(decoder_state_, kAfterReset);
975 TRACE_EVENT0("Video Decoder", "EVDA::ServiceDeviceTask"); 1097 TRACE_EVENT0("Video Decoder", "EVDA::ServiceDeviceTask");
976 1098
977 if (decoder_state_ == kResetting) { 1099 if (decoder_state_ == kResetting) {
978 DVLOG(2) << "ServiceDeviceTask(): early out: kResetting state"; 1100 DVLOG(2) << "ServiceDeviceTask(): early out: kResetting state";
979 return; 1101 return;
980 } else if (decoder_state_ == kError) { 1102 } else if (decoder_state_ == kError) {
981 DVLOG(2) << "ServiceDeviceTask(): early out: kError state"; 1103 DVLOG(2) << "ServiceDeviceTask(): early out: kError state";
982 return; 1104 return;
983 } else if (decoder_state_ == kChangingResolution) { 1105 } else if (decoder_state_ == kChangingResolution) {
984 DVLOG(2) << "ServiceDeviceTask(): early out: kChangingResolution state"; 1106 DVLOG(2) << "ServiceDeviceTask(): early out: kChangingResolution state";
985 return; 1107 return;
986 } 1108 }
987 1109
988 if (mfc_event_pending) 1110 if (mfc_event_pending)
989 DequeueMfcEvents(); 1111 DequeueMfcEvents();
990 DequeueMfc(); 1112 DequeueMfc();
1113 DequeueGsc();
991 EnqueueMfc(); 1114 EnqueueMfc();
1115 EnqueueGsc();
992 1116
993 // Clear the interrupt fd. 1117 // Clear the interrupt fd.
994 if (!ClearDevicePollInterrupt()) 1118 if (!ClearDevicePollInterrupt())
995 return; 1119 return;
996 1120
997 unsigned int poll_fds = 0; 1121 unsigned int poll_fds = 0;
998 // Add MFC fd, if we should poll on it. 1122 // Add MFC fd, if we should poll on it.
999 // MFC can be polled as soon as either input or output buffers are queued. 1123 // MFC can be polled as soon as either input or output buffers are queued.
1000 if (mfc_input_buffer_queued_count_ + mfc_output_buffer_queued_count_ > 0) 1124 if (mfc_input_buffer_queued_count_ + mfc_output_buffer_queued_count_ > 0)
1001 poll_fds |= kPollMfc; 1125 poll_fds |= kPollMfc;
1126 // Add GSC fd, if we should poll on it.
1127 // GSC has to wait until both input and output buffers are queued.
1128 if (gsc_input_buffer_queued_count_ > 0 && gsc_output_buffer_queued_count_ > 0)
1129 poll_fds |= kPollGsc;
1002 1130
1003 // ServiceDeviceTask() should only ever be scheduled from DevicePollTask(), 1131 // ServiceDeviceTask() should only ever be scheduled from DevicePollTask(),
1004 // so either: 1132 // so either:
1005 // * device_poll_thread_ is running normally 1133 // * device_poll_thread_ is running normally
1006 // * device_poll_thread_ scheduled us, but then a ResetTask() or DestroyTask() 1134 // * device_poll_thread_ scheduled us, but then a ResetTask() or DestroyTask()
1007 // shut it down, in which case we're either in kResetting or kError states 1135 // shut it down, in which case we're either in kResetting or kError states
1008 // respectively, and we should have early-outed already. 1136 // respectively, and we should have early-outed already.
1009 DCHECK(device_poll_thread_.message_loop()); 1137 DCHECK(device_poll_thread_.message_loop());
1010 // Queue the DevicePollTask() now. 1138 // Queue the DevicePollTask() now.
1011 device_poll_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 1139 device_poll_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
1012 &ExynosVideoDecodeAccelerator::DevicePollTask, 1140 &ExynosVideoDecodeAccelerator::DevicePollTask,
1013 base::Unretained(this), 1141 base::Unretained(this),
1014 poll_fds)); 1142 poll_fds));
1015 1143
1016 DVLOG(1) << "ServiceDeviceTask(): buffer counts: DEC[" 1144 DVLOG(1) << "ServiceDeviceTask(): buffer counts: DEC["
1017 << decoder_input_queue_.size() << "->" 1145 << decoder_input_queue_.size() << "->"
1018 << mfc_input_ready_queue_.size() << "] => MFC[" 1146 << mfc_input_ready_queue_.size() << "] => MFC["
1019 << mfc_free_input_buffers_.size() << "+" 1147 << mfc_free_input_buffers_.size() << "+"
1020 << mfc_input_buffer_queued_count_ << "/" 1148 << mfc_input_buffer_queued_count_ << "/"
1021 << mfc_input_buffer_map_.size() << "->" 1149 << mfc_input_buffer_map_.size() << "->"
1022 << mfc_free_output_buffers_.size() << "+" 1150 << mfc_free_output_buffers_.size() << "+"
1023 << mfc_output_buffer_queued_count_ << "/" 1151 << mfc_output_buffer_queued_count_ << "/"
1024 << mfc_output_buffer_map_.size() << "] => VDA[" 1152 << mfc_output_buffer_map_.size() << "] => "
1153 << mfc_output_gsc_input_queue_.size() << " => GSC["
1154 << gsc_free_input_buffers_.size() << "+"
1155 << gsc_input_buffer_queued_count_ << "/"
1156 << gsc_input_buffer_map_.size() << "->"
1157 << gsc_free_output_buffers_.size() << "+"
1158 << gsc_output_buffer_queued_count_ << "/"
1159 << gsc_output_buffer_map_.size() << "] => VDA["
1025 << decoder_frames_at_client_ << "]"; 1160 << decoder_frames_at_client_ << "]";
1026 1161
1027 ScheduleDecodeBufferTaskIfNeeded(); 1162 ScheduleDecodeBufferTaskIfNeeded();
1028 StartResolutionChangeIfNeeded(); 1163 StartResolutionChangeIfNeeded();
1029 } 1164 }
1030 1165
1031 void ExynosVideoDecodeAccelerator::EnqueueMfc() { 1166 void ExynosVideoDecodeAccelerator::EnqueueMfc() {
1032 DVLOG(3) << "EnqueueMfc()"; 1167 DVLOG(3) << "EnqueueMfc()";
1033 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1168 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1034 DCHECK_NE(decoder_state_, kUninitialized); 1169 DCHECK_NE(decoder_state_, kUninitialized);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1143 if (errno == EAGAIN) { 1278 if (errno == EAGAIN) {
1144 // EAGAIN if we're just out of buffers to dequeue. 1279 // EAGAIN if we're just out of buffers to dequeue.
1145 break; 1280 break;
1146 } 1281 }
1147 DPLOG(ERROR) << "DequeueMfc(): ioctl() failed: VIDIOC_DQBUF"; 1282 DPLOG(ERROR) << "DequeueMfc(): ioctl() failed: VIDIOC_DQBUF";
1148 NOTIFY_ERROR(PLATFORM_FAILURE); 1283 NOTIFY_ERROR(PLATFORM_FAILURE);
1149 return; 1284 return;
1150 } 1285 }
1151 MfcOutputRecord& output_record = mfc_output_buffer_map_[dqbuf.index]; 1286 MfcOutputRecord& output_record = mfc_output_buffer_map_[dqbuf.index];
1152 DCHECK(output_record.at_device); 1287 DCHECK(output_record.at_device);
1153 DCHECK(!output_record.at_client);
1154 DCHECK_NE(output_record.egl_image, EGL_NO_IMAGE_KHR);
1155 DCHECK_NE(output_record.picture_id, -1);
1156 output_record.at_device = false; 1288 output_record.at_device = false;
1157 if (dqbuf.m.planes[0].bytesused + dqbuf.m.planes[1].bytesused == 0) { 1289 output_record.bytes_used[0] = dqbuf.m.planes[0].bytesused;
1290 output_record.bytes_used[1] = dqbuf.m.planes[1].bytesused;
1291 if (output_record.bytes_used[0] + output_record.bytes_used[1] == 0) {
1158 // This is an empty output buffer returned as part of a flush. 1292 // This is an empty output buffer returned as part of a flush.
1159 mfc_free_output_buffers_.push(dqbuf.index); 1293 mfc_free_output_buffers_.push_back(dqbuf.index);
1294 output_record.input_id = -1;
1160 } else { 1295 } else {
1161 DCHECK_GE(dqbuf.timestamp.tv_sec, 0); 1296 // This is an output buffer with contents to pass down the pipe.
1162 output_record.at_client = true; 1297 mfc_output_gsc_input_queue_.push_back(dqbuf.index);
1163 DVLOG(3) << "DequeueMfc(): returning input_id=" << dqbuf.timestamp.tv_sec 1298 output_record.input_id = dqbuf.timestamp.tv_sec;
1164 << " as picture_id=" << output_record.picture_id; 1299 DCHECK(output_record.input_id >= 0);
1165 const media::Picture& picture = 1300 DVLOG(3) << "DequeueMfc(): dequeued input_id=" << output_record.input_id;
1166 media::Picture(output_record.picture_id, dqbuf.timestamp.tv_sec); 1301 // We don't count this output buffer dequeued yet, or add it to the free
1167 pending_picture_ready_.push( 1302 // list, as it has data GSC needs to process.
1168 PictureRecord(output_record.cleared, picture)); 1303
1169 SendPictureReady(); 1304 // We have new frames in mfc_output_gsc_input_queue_. Kick the pipe.
1170 output_record.cleared = true; 1305 SetDevicePollInterrupt();
1171 decoder_frames_at_client_++;
1172 } 1306 }
1173 mfc_output_buffer_queued_count_--; 1307 mfc_output_buffer_queued_count_--;
1174 } 1308 }
1175 1309
1176 NotifyFlushDoneIfNeeded(); 1310 NotifyFlushDoneIfNeeded();
1177 } 1311 }
1178 1312
1313 void ExynosVideoDecodeAccelerator::EnqueueGsc() {
1314 DVLOG(3) << "EnqueueGsc()";
1315 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1316 DCHECK_NE(decoder_state_, kUninitialized);
1317 DCHECK_NE(decoder_state_, kInitialized);
1318 TRACE_EVENT0("Video Decoder", "EVDA::EnqueueGsc");
1319
1320 // Drain the pipe of completed MFC output buffers.
1321 const int old_gsc_inputs_queued = gsc_input_buffer_queued_count_;
1322 while (!mfc_output_gsc_input_queue_.empty() &&
1323 !gsc_free_input_buffers_.empty()) {
1324 if (!EnqueueGscInputRecord())
1325 return;
1326 }
1327 if (old_gsc_inputs_queued == 0 && gsc_input_buffer_queued_count_ != 0) {
1328 // We just started up a previously empty queue.
1329 // Queue state changed; signal interrupt.
1330 if (!SetDevicePollInterrupt())
1331 return;
1332 // Start VIDIOC_STREAMON if we haven't yet.
1333 if (!gsc_input_streamon_) {
1334 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1335 IOCTL_OR_ERROR_RETURN(gsc_fd_, VIDIOC_STREAMON, &type);
1336 gsc_input_streamon_ = true;
1337 }
1338 }
1339
1340 if (gsc_input_buffer_queued_count_ != 0 &&
1341 gsc_output_buffer_queued_count_ == 0 &&
1342 !gsc_free_output_buffers_.empty()) {
1343 const int old_gsc_outputs_queued = gsc_output_buffer_queued_count_;
1344 if (!EnqueueGscOutputRecord())
1345 return;
1346 if (old_gsc_outputs_queued == 0 && gsc_output_buffer_queued_count_ != 0) {
1347 // We just started up a previously empty queue.
1348 // Queue state changed; signal interrupt.
1349 if (!SetDevicePollInterrupt())
1350 return;
1351 // Start VIDIOC_STREAMON if we haven't yet.
1352 if (!gsc_output_streamon_) {
1353 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1354 IOCTL_OR_ERROR_RETURN(gsc_fd_, VIDIOC_STREAMON, &type);
1355 gsc_output_streamon_ = true;
1356 }
1357 }
1358 }
1359 // Bug check: GSC is liable to race conditions if more than one buffer is
1360 // simultaneously queued.
1361 DCHECK_GE(1, gsc_output_buffer_queued_count_);
1362 }
1363
1364 void ExynosVideoDecodeAccelerator::DequeueGsc() {
1365 DVLOG(3) << "DequeueGsc()";
1366 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1367 DCHECK_NE(decoder_state_, kUninitialized);
1368 DCHECK_NE(decoder_state_, kInitialized);
1369 DCHECK_NE(decoder_state_, kAfterReset);
1370 TRACE_EVENT0("Video Decoder", "EVDA::DequeueGsc");
1371
1372 // Dequeue completed GSC input (VIDEO_OUTPUT) buffers, and recycle to the free
1373 // list. Also recycle the corresponding MFC output buffers at this time.
1374 struct v4l2_buffer dqbuf;
1375 struct v4l2_plane planes[2];
1376 while (gsc_input_buffer_queued_count_ > 0) {
1377 DCHECK(gsc_input_streamon_);
1378 memset(&dqbuf, 0, sizeof(dqbuf));
1379 memset(planes, 0, sizeof(planes));
1380 dqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1381 dqbuf.memory = V4L2_MEMORY_DMABUF;
1382 dqbuf.m.planes = planes;
1383 dqbuf.length = 2;
1384 if (ioctl(gsc_fd_, VIDIOC_DQBUF, &dqbuf) != 0) {
1385 if (errno == EAGAIN) {
1386 // EAGAIN if we're just out of buffers to dequeue.
1387 break;
1388 }
1389 DPLOG(ERROR) << "DequeueGsc(): ioctl() failed: VIDIOC_DQBUF";
1390 NOTIFY_ERROR(PLATFORM_FAILURE);
1391 return;
1392 }
1393 GscInputRecord& input_record = gsc_input_buffer_map_[dqbuf.index];
1394 MfcOutputRecord& output_record =
1395 mfc_output_buffer_map_[input_record.mfc_output];
1396 DCHECK(input_record.at_device);
1397 gsc_free_input_buffers_.push_back(dqbuf.index);
1398 mfc_free_output_buffers_.push_back(input_record.mfc_output);
1399 input_record.at_device = false;
1400 input_record.mfc_output = -1;
1401 output_record.input_id = -1;
1402 gsc_input_buffer_queued_count_--;
1403 }
1404
1405 // Dequeue completed GSC output (VIDEO_CAPTURE) buffers, and send them off to
1406 // the client. Don't recycle to its free list yet -- we can't do that until
1407 // ReusePictureBuffer() returns it to us.
1408 while (gsc_output_buffer_queued_count_ > 0) {
1409 DCHECK(gsc_output_streamon_);
1410 memset(&dqbuf, 0, sizeof(dqbuf));
1411 memset(planes, 0, sizeof(planes));
1412 dqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1413 dqbuf.memory = V4L2_MEMORY_DMABUF;
1414 dqbuf.m.planes = planes;
1415 dqbuf.length = 1;
1416 if (ioctl(gsc_fd_, VIDIOC_DQBUF, &dqbuf) != 0) {
1417 if (errno == EAGAIN) {
1418 // EAGAIN if we're just out of buffers to dequeue.
1419 break;
1420 }
1421 DPLOG(ERROR) << "DequeueGsc(): ioctl() failed: VIDIOC_DQBUF";
1422 NOTIFY_ERROR(PLATFORM_FAILURE);
1423 return;
1424 }
1425 GscOutputRecord& output_record = gsc_output_buffer_map_[dqbuf.index];
1426 DCHECK(output_record.at_device);
1427 DCHECK(!output_record.at_client);
1428 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR);
1429 output_record.at_device = false;
1430 output_record.at_client = true;
1431 gsc_output_buffer_queued_count_--;
1432 DVLOG(3) << "DequeueGsc(): returning input_id=" << dqbuf.timestamp.tv_sec
1433 << " as picture_id=" << output_record.picture_id;
1434 const media::Picture& picture =
1435 media::Picture(output_record.picture_id, dqbuf.timestamp.tv_sec);
1436 pending_picture_ready_.push(PictureRecord(output_record.cleared, picture));
1437 SendPictureReady();
1438 output_record.cleared = true;
1439 decoder_frames_at_client_++;
1440 }
1441
1442 NotifyFlushDoneIfNeeded();
1443 }
1444
1179 bool ExynosVideoDecodeAccelerator::EnqueueMfcInputRecord() { 1445 bool ExynosVideoDecodeAccelerator::EnqueueMfcInputRecord() {
1180 DVLOG(3) << "EnqueueMfcInputRecord()"; 1446 DVLOG(3) << "EnqueueMfcInputRecord()";
1181 DCHECK(!mfc_input_ready_queue_.empty()); 1447 DCHECK(!mfc_input_ready_queue_.empty());
1182 1448
1183 // Enqueue a MFC input (VIDEO_OUTPUT) buffer. 1449 // Enqueue a MFC input (VIDEO_OUTPUT) buffer.
1184 const int buffer = mfc_input_ready_queue_.front(); 1450 const int buffer = mfc_input_ready_queue_.back();
1185 MfcInputRecord& input_record = mfc_input_buffer_map_[buffer]; 1451 MfcInputRecord& input_record = mfc_input_buffer_map_[buffer];
1186 DCHECK(!input_record.at_device); 1452 DCHECK(!input_record.at_device);
1187 struct v4l2_buffer qbuf; 1453 struct v4l2_buffer qbuf;
1188 struct v4l2_plane qbuf_plane; 1454 struct v4l2_plane qbuf_plane;
1189 memset(&qbuf, 0, sizeof(qbuf)); 1455 memset(&qbuf, 0, sizeof(qbuf));
1190 memset(&qbuf_plane, 0, sizeof(qbuf_plane)); 1456 memset(&qbuf_plane, 0, sizeof(qbuf_plane));
1191 qbuf.index = buffer; 1457 qbuf.index = buffer;
1192 qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1458 qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1193 qbuf.timestamp.tv_sec = input_record.input_id; 1459 qbuf.timestamp.tv_sec = input_record.input_id;
1194 qbuf.memory = V4L2_MEMORY_MMAP; 1460 qbuf.memory = V4L2_MEMORY_MMAP;
1195 qbuf.m.planes = &qbuf_plane; 1461 qbuf.m.planes = &qbuf_plane;
1196 qbuf.m.planes[0].bytesused = input_record.bytes_used; 1462 qbuf.m.planes[0].bytesused = input_record.bytes_used;
1197 qbuf.length = 1; 1463 qbuf.length = 1;
1198 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QBUF, &qbuf); 1464 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QBUF, &qbuf);
1199 mfc_input_ready_queue_.pop(); 1465 mfc_input_ready_queue_.pop_back();
1200 input_record.at_device = true; 1466 input_record.at_device = true;
1201 mfc_input_buffer_queued_count_++; 1467 mfc_input_buffer_queued_count_++;
1202 DVLOG(3) << "EnqueueMfcInputRecord(): enqueued input_id=" 1468 DVLOG(3) << "EnqueueMfcInputRecord(): enqueued input_id="
1203 << input_record.input_id; 1469 << input_record.input_id;
1204 return true; 1470 return true;
1205 } 1471 }
1206 1472
1207 bool ExynosVideoDecodeAccelerator::EnqueueMfcOutputRecord() { 1473 bool ExynosVideoDecodeAccelerator::EnqueueMfcOutputRecord() {
1208 DVLOG(3) << "EnqueueMfcOutputRecord()"; 1474 DVLOG(3) << "EnqueueMfcOutputRecord()";
1209 DCHECK(!mfc_free_output_buffers_.empty()); 1475 DCHECK(!mfc_free_output_buffers_.empty());
1210 1476
1211 // Enqueue a MFC output (VIDEO_CAPTURE) buffer. 1477 // Enqueue a MFC output (VIDEO_CAPTURE) buffer.
1212 const int buffer = mfc_free_output_buffers_.front(); 1478 const int buffer = mfc_free_output_buffers_.back();
1213 MfcOutputRecord& output_record = mfc_output_buffer_map_[buffer]; 1479 MfcOutputRecord& output_record = mfc_output_buffer_map_[buffer];
1214 DCHECK(!output_record.at_device); 1480 DCHECK(!output_record.at_device);
1481 DCHECK_EQ(output_record.input_id, -1);
1482 struct v4l2_buffer qbuf;
1483 struct v4l2_plane qbuf_planes[2];
1484 memset(&qbuf, 0, sizeof(qbuf));
1485 memset(qbuf_planes, 0, sizeof(qbuf_planes));
1486 qbuf.index = buffer;
1487 qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1488 qbuf.memory = V4L2_MEMORY_MMAP;
1489 qbuf.m.planes = qbuf_planes;
1490 qbuf.length = 2;
1491 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QBUF, &qbuf);
1492 mfc_free_output_buffers_.pop_back();
1493 output_record.at_device = true;
1494 mfc_output_buffer_queued_count_++;
1495 return true;
1496 }
1497
1498 bool ExynosVideoDecodeAccelerator::EnqueueGscInputRecord() {
1499 DVLOG(3) << "EnqueueGscInputRecord()";
1500 DCHECK(!gsc_free_input_buffers_.empty());
1501
1502 // Enqueue a GSC input (VIDEO_OUTPUT) buffer for a complete MFC output
1503 // (VIDEO_CAPTURE) buffer.
1504 const int mfc_buffer = mfc_output_gsc_input_queue_.front();
1505 const int gsc_buffer = gsc_free_input_buffers_.back();
1506 MfcOutputRecord& output_record = mfc_output_buffer_map_[mfc_buffer];
1507 DCHECK(!output_record.at_device);
1508 GscInputRecord& input_record = gsc_input_buffer_map_[gsc_buffer];
1509 DCHECK(!input_record.at_device);
1510 DCHECK_EQ(input_record.mfc_output, -1);
1511 struct v4l2_buffer qbuf;
1512 struct v4l2_plane qbuf_planes[2];
1513 memset(&qbuf, 0, sizeof(qbuf));
1514 memset(qbuf_planes, 0, sizeof(qbuf_planes));
1515 qbuf.index = gsc_buffer;
1516 qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1517 qbuf.timestamp.tv_sec = output_record.input_id;
1518 qbuf.memory = V4L2_MEMORY_USERPTR;
1519 qbuf.m.planes = qbuf_planes;
1520 qbuf.m.planes[0].bytesused = output_record.bytes_used[0];
1521 qbuf.m.planes[0].length = mfc_output_buffer_size_[0];
1522 qbuf.m.planes[0].m.userptr = (unsigned long)output_record.address[0];
1523 qbuf.m.planes[1].bytesused = output_record.bytes_used[1];
1524 qbuf.m.planes[1].length = mfc_output_buffer_size_[1];
1525 qbuf.m.planes[1].m.userptr = (unsigned long)output_record.address[1];
1526 qbuf.length = 2;
1527 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_QBUF, &qbuf);
1528 mfc_output_gsc_input_queue_.pop_front();
1529 gsc_free_input_buffers_.pop_back();
1530 input_record.at_device = true;
1531 input_record.mfc_output = mfc_buffer;
1532 output_record.bytes_used[0] = 0;
1533 output_record.bytes_used[1] = 0;
1534 gsc_input_buffer_queued_count_++;
1535 DVLOG(3) << "EnqueueGscInputRecord(): enqueued input_id="
1536 << output_record.input_id;
1537 return true;
1538 }
1539
1540 bool ExynosVideoDecodeAccelerator::EnqueueGscOutputRecord() {
1541 DVLOG(3) << "EnqueueGscOutputRecord()";
1542 DCHECK(!gsc_free_output_buffers_.empty());
1543
1544 // Enqueue a GSC output (VIDEO_CAPTURE) buffer.
1545 const int buffer = gsc_free_output_buffers_.front();
1546 GscOutputRecord& output_record = gsc_output_buffer_map_[buffer];
1547 DCHECK(!output_record.at_device);
1215 DCHECK(!output_record.at_client); 1548 DCHECK(!output_record.at_client);
1216 DCHECK_NE(output_record.egl_image, EGL_NO_IMAGE_KHR);
1217 DCHECK_NE(output_record.picture_id, -1);
1218 if (output_record.egl_sync != EGL_NO_SYNC_KHR) { 1549 if (output_record.egl_sync != EGL_NO_SYNC_KHR) {
1219 TRACE_EVENT0("Video Decoder", 1550 TRACE_EVENT0(
1220 "EVDA::EnqueueMfcOutputRecord: eglClientWaitSyncKHR"); 1551 "Video Decoder",
1552 "EVDA::EnqueueGscOutputRecord: eglClientWaitSyncKHR");
1221 // If we have to wait for completion, wait. Note that 1553 // If we have to wait for completion, wait. Note that
1222 // mfc_free_output_buffers_ is a FIFO queue, so we always wait on the 1554 // gsc_free_output_buffers_ is a FIFO queue, so we always wait on the
1223 // buffer that has been in the queue the longest. 1555 // buffer that has been in the queue the longest.
1224 eglClientWaitSyncKHR(egl_display_, output_record.egl_sync, 0, 1556 eglClientWaitSyncKHR(egl_display_, output_record.egl_sync, 0,
1225 EGL_FOREVER_KHR); 1557 EGL_FOREVER_KHR);
1226 eglDestroySyncKHR(egl_display_, output_record.egl_sync); 1558 eglDestroySyncKHR(egl_display_, output_record.egl_sync);
1227 output_record.egl_sync = EGL_NO_SYNC_KHR; 1559 output_record.egl_sync = EGL_NO_SYNC_KHR;
1228 } 1560 }
1229 struct v4l2_buffer qbuf; 1561 struct v4l2_buffer qbuf;
1230 struct v4l2_plane qbuf_planes[arraysize(output_record.fds)]; 1562 struct v4l2_plane qbuf_plane;
1231 memset(&qbuf, 0, sizeof(qbuf)); 1563 memset(&qbuf, 0, sizeof(qbuf));
1232 memset(qbuf_planes, 0, sizeof(qbuf_planes)); 1564 memset(&qbuf_plane, 0, sizeof(qbuf_plane));
1233 qbuf.index = buffer; 1565 qbuf.index = buffer;
1234 qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1566 qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1235 qbuf.memory = V4L2_MEMORY_MMAP; 1567 qbuf.memory = V4L2_MEMORY_DMABUF;
1236 qbuf.m.planes = qbuf_planes; 1568 qbuf.m.planes = &qbuf_plane;
1237 qbuf.length = arraysize(output_record.fds); 1569 qbuf.m.planes[0].m.fd = output_record.fd;
1238 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QBUF, &qbuf); 1570 qbuf.length = 1;
1239 mfc_free_output_buffers_.pop(); 1571 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_QBUF, &qbuf);
1572 gsc_free_output_buffers_.pop_front();
1240 output_record.at_device = true; 1573 output_record.at_device = true;
1241 mfc_output_buffer_queued_count_++; 1574 gsc_output_buffer_queued_count_++;
1242 return true; 1575 return true;
1243 } 1576 }
1244 1577
1245 void ExynosVideoDecodeAccelerator::ReusePictureBufferTask( 1578 void ExynosVideoDecodeAccelerator::ReusePictureBufferTask(
1246 int32 picture_buffer_id, scoped_ptr<EGLSyncKHRRef> egl_sync_ref) { 1579 int32 picture_buffer_id, scoped_ptr<EGLSyncKHRRef> egl_sync_ref) {
1247 DVLOG(3) << "ReusePictureBufferTask(): picture_buffer_id=" 1580 DVLOG(3) << "ReusePictureBufferTask(): picture_buffer_id="
1248 << picture_buffer_id; 1581 << picture_buffer_id;
1249 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1582 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1250 TRACE_EVENT0("Video Decoder", "EVDA::ReusePictureBufferTask"); 1583 TRACE_EVENT0("Video Decoder", "EVDA::ReusePictureBufferTask");
1251 1584
1252 // We run ReusePictureBufferTask even if we're in kResetting. 1585 // We run ReusePictureBufferTask even if we're in kResetting.
1253 if (decoder_state_ == kError) { 1586 if (decoder_state_ == kError) {
1254 DVLOG(2) << "ReusePictureBufferTask(): early out: kError state"; 1587 DVLOG(2) << "ReusePictureBufferTask(): early out: kError state";
1255 return; 1588 return;
1256 } 1589 }
1257 1590
1258 if (decoder_state_ == kChangingResolution) { 1591 if (decoder_state_ == kChangingResolution) {
1259 DVLOG(2) << "ReusePictureBufferTask(): early out: kChangingResolution"; 1592 DVLOG(2) << "ReusePictureBufferTask(): early out: kChangingResolution";
1260 return; 1593 return;
1261 } 1594 }
1262 1595
1263 size_t index; 1596 size_t index;
1264 for (index = 0; index < mfc_output_buffer_map_.size(); ++index) 1597 for (index = 0; index < gsc_output_buffer_map_.size(); ++index)
1265 if (mfc_output_buffer_map_[index].picture_id == picture_buffer_id) 1598 if (gsc_output_buffer_map_[index].picture_id == picture_buffer_id)
1266 break; 1599 break;
1267 1600
1268 if (index >= mfc_output_buffer_map_.size()) { 1601 if (index >= gsc_output_buffer_map_.size()) {
1269 DLOG(ERROR) << "ReusePictureBufferTask(): picture_buffer_id not found"; 1602 DLOG(ERROR) << "ReusePictureBufferTask(): picture_buffer_id not found";
1270 NOTIFY_ERROR(INVALID_ARGUMENT); 1603 NOTIFY_ERROR(INVALID_ARGUMENT);
1271 return; 1604 return;
1272 } 1605 }
1273 1606
1274 MfcOutputRecord& output_record = mfc_output_buffer_map_[index]; 1607 GscOutputRecord& output_record = gsc_output_buffer_map_[index];
1275 if (output_record.at_device || !output_record.at_client) { 1608 if (output_record.at_device || !output_record.at_client) {
1276 DLOG(ERROR) << "ReusePictureBufferTask(): picture_buffer_id not reusable"; 1609 DLOG(ERROR) << "ReusePictureBufferTask(): picture_buffer_id not reusable";
1277 NOTIFY_ERROR(INVALID_ARGUMENT); 1610 NOTIFY_ERROR(INVALID_ARGUMENT);
1278 return; 1611 return;
1279 } 1612 }
1280 1613
1281 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); 1614 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR);
1282 output_record.at_client = false; 1615 output_record.at_client = false;
1283 output_record.egl_sync = egl_sync_ref->egl_sync; 1616 output_record.egl_sync = egl_sync_ref->egl_sync;
1284 mfc_free_output_buffers_.push(index); 1617 gsc_free_output_buffers_.push_back(index);
1285 decoder_frames_at_client_--; 1618 decoder_frames_at_client_--;
1286 // Take ownership of the EGLSync. 1619 // Take ownership of the EGLSync.
1287 egl_sync_ref->egl_sync = EGL_NO_SYNC_KHR; 1620 egl_sync_ref->egl_sync = EGL_NO_SYNC_KHR;
1288 // We got a buffer back, so kick the MFC. 1621 // We got a buffer back, so kick the GSC.
1289 EnqueueMfc(); 1622 EnqueueGsc();
1290 } 1623 }
1291 1624
1292 void ExynosVideoDecodeAccelerator::FlushTask() { 1625 void ExynosVideoDecodeAccelerator::FlushTask() {
1293 DVLOG(3) << "FlushTask()"; 1626 DVLOG(3) << "FlushTask()";
1294 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1627 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1295 TRACE_EVENT0("Video Decoder", "EVDA::FlushTask"); 1628 TRACE_EVENT0("Video Decoder", "EVDA::FlushTask");
1296 1629
1297 // Flush outstanding buffers. 1630 // Flush outstanding buffers.
1298 if (decoder_state_ == kInitialized || decoder_state_ == kAfterReset) { 1631 if (decoder_state_ == kInitialized || decoder_state_ == kAfterReset) {
1299 // There's nothing in the pipe, so return done immediately. 1632 // There's nothing in the pipe, so return done immediately.
1300 DVLOG(3) << "FlushTask(): returning flush"; 1633 DVLOG(3) << "FlushTask(): returning flush";
1301 child_message_loop_proxy_->PostTask( 1634 child_message_loop_proxy_->PostTask(
1302 FROM_HERE, base::Bind(&Client::NotifyFlushDone, client_)); 1635 FROM_HERE, base::Bind(&Client::NotifyFlushDone, client_));
1303 return; 1636 return;
1304 } else if (decoder_state_ == kError) { 1637 } else if (decoder_state_ == kError) {
1305 DVLOG(2) << "FlushTask(): early out: kError state"; 1638 DVLOG(2) << "FlushTask(): early out: kError state";
1306 return; 1639 return;
1307 } 1640 }
1308 1641
1309 // We don't support stacked flushing. 1642 // We don't support stacked flushing.
1310 DCHECK(!decoder_flushing_); 1643 DCHECK(!decoder_flushing_);
1311 1644
1312 // Queue up an empty buffer -- this triggers the flush. 1645 // Queue up an empty buffer -- this triggers the flush.
1313 decoder_input_queue_.push( 1646 decoder_input_queue_.push_back(linked_ptr<BitstreamBufferRef>(
1314 linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef( 1647 new BitstreamBufferRef(io_client_, io_message_loop_proxy_, NULL, 0,
1315 io_client_, io_message_loop_proxy_, NULL, 0, kFlushBufferId))); 1648 kFlushBufferId)));
1316 decoder_flushing_ = true; 1649 decoder_flushing_ = true;
1317 SendPictureReady(); // Send all pending PictureReady. 1650 SendPictureReady(); // Send all pending PictureReady.
1318 1651
1319 ScheduleDecodeBufferTaskIfNeeded(); 1652 ScheduleDecodeBufferTaskIfNeeded();
1320 } 1653 }
1321 1654
1322 void ExynosVideoDecodeAccelerator::NotifyFlushDoneIfNeeded() { 1655 void ExynosVideoDecodeAccelerator::NotifyFlushDoneIfNeeded() {
1323 if (!decoder_flushing_) 1656 if (!decoder_flushing_)
1324 return; 1657 return;
1325 1658
1326 // Pipeline is empty when: 1659 // Pipeline is empty when:
1327 // * Decoder input queue is empty of non-delayed buffers. 1660 // * Decoder input queue is empty of non-delayed buffers.
1328 // * There is no currently filling input buffer. 1661 // * There is no currently filling input buffer.
1329 // * MFC input holding queue is empty. 1662 // * MFC input holding queue is empty.
1330 // * All MFC input (VIDEO_OUTPUT) buffers are returned. 1663 // * All MFC input (VIDEO_OUTPUT) buffers are returned.
1664 // * MFC -> GSC holding queue is empty.
1665 // * All GSC input (VIDEO_OUTPUT) buffers are returned.
1331 if (!decoder_input_queue_.empty()) { 1666 if (!decoder_input_queue_.empty()) {
1332 if (decoder_input_queue_.front()->input_id != 1667 if (decoder_input_queue_.front()->input_id !=
1333 decoder_delay_bitstream_buffer_id_) 1668 decoder_delay_bitstream_buffer_id_)
1334 return; 1669 return;
1335 } 1670 }
1336 if (decoder_current_input_buffer_ != -1) 1671 if (decoder_current_input_buffer_ != -1)
1337 return; 1672 return;
1338 if ((mfc_input_ready_queue_.size() + mfc_input_buffer_queued_count_) != 0) 1673 if ((mfc_input_ready_queue_.size() +
1674 mfc_input_buffer_queued_count_ + mfc_output_gsc_input_queue_.size() +
1675 gsc_input_buffer_queued_count_ + gsc_output_buffer_queued_count_ ) != 0)
1339 return; 1676 return;
1340 1677
1341 // TODO(posciak): crbug.com/270039. MFC requires a streamoff-streamon 1678 // TODO(posciak): crbug.com/270039. MFC requires a streamoff-streamon
1342 // sequence after flush to continue, even if we are not resetting. This would 1679 // sequence after flush to continue, even if we are not resetting. This would
1343 // make sense, because we don't really want to resume from a non-resume point 1680 // make sense, because we don't really want to resume from a non-resume point
1344 // (e.g. not from an IDR) if we are flushed. 1681 // (e.g. not from an IDR) if we are flushed.
1345 // MSE player however triggers a Flush() on chunk end, but never Reset(). One 1682 // MSE player however triggers a Flush() on chunk end, but never Reset(). One
1346 // could argue either way, or even say that Flush() is not needed/harmful when 1683 // could argue either way, or even say that Flush() is not needed/harmful when
1347 // transitioning to next chunk. 1684 // transitioning to next chunk.
1348 // For now, do the streamoff-streamon cycle to satisfy MFC and not freeze when 1685 // For now, do the streamoff-streamon cycle to satisfy MFC and not freeze when
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1386 // We stop streaming and clear buffer tracking info (not preserving 1723 // We stop streaming and clear buffer tracking info (not preserving
1387 // MFC inputs). 1724 // MFC inputs).
1388 // StopDevicePoll() unconditionally does _not_ destroy buffers, however. 1725 // StopDevicePoll() unconditionally does _not_ destroy buffers, however.
1389 if (!StopDevicePoll(false)) 1726 if (!StopDevicePoll(false))
1390 return; 1727 return;
1391 1728
1392 DequeueMfcEvents(); 1729 DequeueMfcEvents();
1393 1730
1394 resolution_change_pending_ = false; 1731 resolution_change_pending_ = false;
1395 decoder_current_bitstream_buffer_.reset(); 1732 decoder_current_bitstream_buffer_.reset();
1396 while (!decoder_input_queue_.empty()) 1733 decoder_input_queue_.clear();
1397 decoder_input_queue_.pop();
1398 1734
1399 decoder_current_input_buffer_ = -1; 1735 decoder_current_input_buffer_ = -1;
1400 1736
1401 // If we were flushing, we'll never return any more BitstreamBuffers or 1737 // If we were flushing, we'll never return any more BitstreamBuffers or
1402 // PictureBuffers; they have all been dropped and returned by now. 1738 // PictureBuffers; they have all been dropped and returned by now.
1403 NotifyFlushDoneIfNeeded(); 1739 NotifyFlushDoneIfNeeded();
1404 1740
1405 // Mark that we're resetting, then enqueue a ResetDoneTask(). All intervening 1741 // Mark that we're resetting, then enqueue a ResetDoneTask(). All intervening
1406 // jobs will early-out in the kResetting state. 1742 // jobs will early-out in the kResetting state.
1407 decoder_state_ = kResetting; 1743 decoder_state_ = kResetting;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1444 1780
1445 // DestroyTask() should run regardless of decoder_state_. 1781 // DestroyTask() should run regardless of decoder_state_.
1446 1782
1447 // Stop streaming and the device_poll_thread_. 1783 // Stop streaming and the device_poll_thread_.
1448 StopDevicePoll(false); 1784 StopDevicePoll(false);
1449 1785
1450 decoder_current_bitstream_buffer_.reset(); 1786 decoder_current_bitstream_buffer_.reset();
1451 decoder_current_input_buffer_ = -1; 1787 decoder_current_input_buffer_ = -1;
1452 decoder_decode_buffer_tasks_scheduled_ = 0; 1788 decoder_decode_buffer_tasks_scheduled_ = 0;
1453 decoder_frames_at_client_ = 0; 1789 decoder_frames_at_client_ = 0;
1454 while (!decoder_input_queue_.empty()) 1790 decoder_input_queue_.clear();
1455 decoder_input_queue_.pop();
1456 decoder_flushing_ = false; 1791 decoder_flushing_ = false;
1457 1792
1458 // Set our state to kError. Just in case. 1793 // Set our state to kError. Just in case.
1459 decoder_state_ = kError; 1794 decoder_state_ = kError;
1460 } 1795 }
1461 1796
1462 bool ExynosVideoDecodeAccelerator::StartDevicePoll() { 1797 bool ExynosVideoDecodeAccelerator::StartDevicePoll() {
1463 DVLOG(3) << "StartDevicePoll()"; 1798 DVLOG(3) << "StartDevicePoll()";
1464 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1799 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1465 DCHECK(!device_poll_thread_.IsRunning()); 1800 DCHECK(!device_poll_thread_.IsRunning());
(...skipping 30 matching lines...) Expand all
1496 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1831 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1497 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_STREAMOFF, &type); 1832 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_STREAMOFF, &type);
1498 } 1833 }
1499 mfc_input_streamon_ = false; 1834 mfc_input_streamon_ = false;
1500 } 1835 }
1501 if (mfc_output_streamon_) { 1836 if (mfc_output_streamon_) {
1502 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1837 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1503 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_STREAMOFF, &type); 1838 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_STREAMOFF, &type);
1504 } 1839 }
1505 mfc_output_streamon_ = false; 1840 mfc_output_streamon_ = false;
1841 if (gsc_input_streamon_) {
1842 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1843 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_STREAMOFF, &type);
1844 }
1845 gsc_input_streamon_ = false;
1846 if (gsc_output_streamon_) {
1847 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1848 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_STREAMOFF, &type);
1849 }
1850 gsc_output_streamon_ = false;
1506 1851
1507 // Reset all our accounting info. 1852 // Reset all our accounting info.
1508 if (!keep_mfc_input_state) { 1853 if (!keep_mfc_input_state) {
1509 while (!mfc_input_ready_queue_.empty()) 1854 mfc_input_ready_queue_.clear();
1510 mfc_input_ready_queue_.pop();
1511 mfc_free_input_buffers_.clear(); 1855 mfc_free_input_buffers_.clear();
1512 for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) { 1856 for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) {
1513 mfc_free_input_buffers_.push_back(i); 1857 mfc_free_input_buffers_.push_back(i);
1514 mfc_input_buffer_map_[i].at_device = false; 1858 mfc_input_buffer_map_[i].at_device = false;
1515 mfc_input_buffer_map_[i].bytes_used = 0; 1859 mfc_input_buffer_map_[i].bytes_used = 0;
1516 mfc_input_buffer_map_[i].input_id = -1; 1860 mfc_input_buffer_map_[i].input_id = -1;
1517 } 1861 }
1518 mfc_input_buffer_queued_count_ = 0; 1862 mfc_input_buffer_queued_count_ = 0;
1519 } 1863 }
1520 while (!mfc_free_output_buffers_.empty()) 1864 mfc_free_output_buffers_.clear();
1521 mfc_free_output_buffers_.pop();
1522 for (size_t i = 0; i < mfc_output_buffer_map_.size(); ++i) { 1865 for (size_t i = 0; i < mfc_output_buffer_map_.size(); ++i) {
1523 MfcOutputRecord& output_record = mfc_output_buffer_map_[i]; 1866 mfc_free_output_buffers_.push_back(i);
1524 // Only mark those free that aren't being held by the VDA client. 1867 mfc_output_buffer_map_[i].at_device = false;
1525 if (!output_record.at_client) { 1868 mfc_output_buffer_map_[i].input_id = -1;
1526 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); 1869 }
1527 mfc_free_output_buffers_.push(i); 1870 mfc_output_buffer_queued_count_ = 0;
1528 mfc_output_buffer_map_[i].at_device = false; 1871 mfc_output_gsc_input_queue_.clear();
1872 gsc_free_input_buffers_.clear();
1873 for (size_t i = 0; i < gsc_input_buffer_map_.size(); ++i) {
1874 gsc_free_input_buffers_.push_back(i);
1875 gsc_input_buffer_map_[i].at_device = false;
1876 gsc_input_buffer_map_[i].mfc_output = -1;
1877 }
1878 gsc_input_buffer_queued_count_ = 0;
1879 gsc_free_output_buffers_.clear();
1880 for (size_t i = 0; i < gsc_output_buffer_map_.size(); ++i) {
1881 // Only mark those free that aren't being held by the VDA.
1882 if (!gsc_output_buffer_map_[i].at_client) {
1883 gsc_free_output_buffers_.push_back(i);
1884 gsc_output_buffer_map_[i].at_device = false;
1529 } 1885 }
1530 } 1886 }
1531 mfc_output_buffer_queued_count_ = 0; 1887 gsc_output_buffer_queued_count_ = 0;
1532 1888
1533 DVLOG(3) << "StopDevicePoll(): device poll stopped"; 1889 DVLOG(3) << "StopDevicePoll(): device poll stopped";
1534 return true; 1890 return true;
1535 } 1891 }
1536 1892
1537 bool ExynosVideoDecodeAccelerator::SetDevicePollInterrupt() { 1893 bool ExynosVideoDecodeAccelerator::SetDevicePollInterrupt() {
1538 DVLOG(3) << "SetDevicePollInterrupt()"; 1894 DVLOG(3) << "SetDevicePollInterrupt()";
1539 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1895 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1540 1896
1541 const uint64 buf = 1; 1897 const uint64 buf = 1;
(...skipping 23 matching lines...) Expand all
1565 return true; 1921 return true;
1566 } 1922 }
1567 1923
1568 void ExynosVideoDecodeAccelerator::StartResolutionChangeIfNeeded() { 1924 void ExynosVideoDecodeAccelerator::StartResolutionChangeIfNeeded() {
1569 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1925 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1570 DCHECK_EQ(decoder_state_, kDecoding); 1926 DCHECK_EQ(decoder_state_, kDecoding);
1571 1927
1572 if (!resolution_change_pending_) 1928 if (!resolution_change_pending_)
1573 return; 1929 return;
1574 1930
1575 DVLOG(3) << "No more work, initiate resolution change"; 1931 if (!mfc_output_gsc_input_queue_.empty() ||
1932 gsc_input_buffer_queued_count_ + gsc_output_buffer_queued_count_ > 0) {
1933 DVLOG(3) << "StartResolutionChangeIfNeeded(): waiting for GSC to finish.";
1934 return;
1935 }
1936
1937 DVLOG(3) << "No more work for GSC, initiate resolution change";
1576 1938
1577 // Keep MFC input queue. 1939 // Keep MFC input queue.
1578 if (!StopDevicePoll(true)) 1940 if (!StopDevicePoll(true))
1579 return; 1941 return;
1580 1942
1581 decoder_state_ = kChangingResolution; 1943 decoder_state_ = kChangingResolution;
1582 DCHECK(resolution_change_pending_); 1944 DCHECK(resolution_change_pending_);
1583 resolution_change_pending_ = false; 1945 resolution_change_pending_ = false;
1584 1946
1585 // Post a task to clean up buffers on child thread. This will also ensure 1947 // Post a task to clean up buffers on child thread. This will also ensure
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1626 if (resolution_change_reset_pending_) { 1988 if (resolution_change_reset_pending_) {
1627 resolution_change_reset_pending_ = false; 1989 resolution_change_reset_pending_ = false;
1628 ResetTask(); 1990 ResetTask();
1629 return; 1991 return;
1630 } 1992 }
1631 1993
1632 if (!StartDevicePoll()) 1994 if (!StartDevicePoll())
1633 return; 1995 return;
1634 1996
1635 EnqueueMfc(); 1997 EnqueueMfc();
1998 // Gsc will get enqueued in AssignPictureBuffersTask().
1636 ScheduleDecodeBufferTaskIfNeeded(); 1999 ScheduleDecodeBufferTaskIfNeeded();
1637 } 2000 }
1638 2001
1639 void ExynosVideoDecodeAccelerator::DevicePollTask(unsigned int poll_fds) { 2002 void ExynosVideoDecodeAccelerator::DevicePollTask(unsigned int poll_fds) {
1640 DVLOG(3) << "DevicePollTask()"; 2003 DVLOG(3) << "DevicePollTask()";
1641 DCHECK_EQ(device_poll_thread_.message_loop(), base::MessageLoop::current()); 2004 DCHECK_EQ(device_poll_thread_.message_loop(), base::MessageLoop::current());
1642 TRACE_EVENT0("Video Decoder", "EVDA::DevicePollTask"); 2005 TRACE_EVENT0("Video Decoder", "EVDA::DevicePollTask");
1643 2006
1644 // This routine just polls the set of device fds, and schedules a 2007 // This routine just polls the set of device fds, and schedules a
1645 // ServiceDeviceTask() on decoder_thread_ when processing needs to occur. 2008 // ServiceDeviceTask() on decoder_thread_ when processing needs to occur.
1646 // Other threads may notify this task to return early by writing to 2009 // Other threads may notify this task to return early by writing to
1647 // device_poll_interrupt_fd_. 2010 // device_poll_interrupt_fd_.
1648 struct pollfd pollfds[3]; 2011 struct pollfd pollfds[3];
1649 nfds_t nfds; 2012 nfds_t nfds;
1650 int mfc_pollfd = -1; 2013 int mfc_pollfd = -1;
1651 2014
1652 // Add device_poll_interrupt_fd_; 2015 // Add device_poll_interrupt_fd_;
1653 pollfds[0].fd = device_poll_interrupt_fd_; 2016 pollfds[0].fd = device_poll_interrupt_fd_;
1654 pollfds[0].events = POLLIN | POLLERR; 2017 pollfds[0].events = POLLIN | POLLERR;
1655 nfds = 1; 2018 nfds = 1;
1656 2019
1657 if (poll_fds & kPollMfc) { 2020 if (poll_fds & kPollMfc) {
1658 DVLOG(3) << "DevicePollTask(): adding MFC to poll() set"; 2021 DVLOG(3) << "DevicePollTask(): adding MFC to poll() set";
1659 pollfds[nfds].fd = mfc_fd_; 2022 pollfds[nfds].fd = mfc_fd_;
1660 pollfds[nfds].events = POLLIN | POLLOUT | POLLERR | POLLPRI; 2023 pollfds[nfds].events = POLLIN | POLLOUT | POLLERR | POLLPRI;
1661 mfc_pollfd = nfds; 2024 mfc_pollfd = nfds;
1662 nfds++; 2025 nfds++;
1663 } 2026 }
2027 // Add GSC fd, if we should poll on it.
2028 // GSC has to wait until both input and output buffers are queued.
2029 if (poll_fds & kPollGsc) {
2030 DVLOG(3) << "DevicePollTask(): adding GSC to poll() set";
2031 pollfds[nfds].fd = gsc_fd_;
2032 pollfds[nfds].events = POLLIN | POLLOUT | POLLERR;
2033 nfds++;
2034 }
1664 2035
1665 // Poll it! 2036 // Poll it!
1666 if (HANDLE_EINTR(poll(pollfds, nfds, -1)) == -1) { 2037 if (HANDLE_EINTR(poll(pollfds, nfds, -1)) == -1) {
1667 DPLOG(ERROR) << "DevicePollTask(): poll() failed"; 2038 DPLOG(ERROR) << "DevicePollTask(): poll() failed";
1668 NOTIFY_ERROR(PLATFORM_FAILURE); 2039 NOTIFY_ERROR(PLATFORM_FAILURE);
1669 return; 2040 return;
1670 } 2041 }
1671 2042
1672 bool mfc_event_pending = (mfc_pollfd != -1 && 2043 bool mfc_event_pending = (mfc_pollfd != -1 &&
1673 pollfds[mfc_pollfd].revents & POLLPRI); 2044 pollfds[mfc_pollfd].revents & POLLPRI);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1730 2101
1731 return true; 2102 return true;
1732 } 2103 }
1733 2104
1734 bool ExynosVideoDecodeAccelerator::CreateBuffersForFormat( 2105 bool ExynosVideoDecodeAccelerator::CreateBuffersForFormat(
1735 const struct v4l2_format& format) { 2106 const struct v4l2_format& format) {
1736 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 2107 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1737 CHECK_EQ(format.fmt.pix_mp.num_planes, 2); 2108 CHECK_EQ(format.fmt.pix_mp.num_planes, 2);
1738 frame_buffer_size_.SetSize( 2109 frame_buffer_size_.SetSize(
1739 format.fmt.pix_mp.width, format.fmt.pix_mp.height); 2110 format.fmt.pix_mp.width, format.fmt.pix_mp.height);
2111 mfc_output_buffer_size_[0] = format.fmt.pix_mp.plane_fmt[0].sizeimage;
2112 mfc_output_buffer_size_[1] = format.fmt.pix_mp.plane_fmt[1].sizeimage;
1740 mfc_output_buffer_pixelformat_ = format.fmt.pix_mp.pixelformat; 2113 mfc_output_buffer_pixelformat_ = format.fmt.pix_mp.pixelformat;
1741 DCHECK_EQ(mfc_output_buffer_pixelformat_, V4L2_PIX_FMT_NV12M); 2114 DCHECK_EQ(mfc_output_buffer_pixelformat_, V4L2_PIX_FMT_NV12MT_16X16);
1742 DVLOG(3) << "CreateBuffersForFormat(): new resolution: " 2115 DVLOG(3) << "CreateBuffersForFormat(): new resolution: "
1743 << frame_buffer_size_.ToString(); 2116 << frame_buffer_size_.ToString();
1744 2117
1745 if (!CreateMfcOutputBuffers()) 2118 if (!CreateMfcOutputBuffers() || !CreateGscInputBuffers() ||
2119 !CreateGscOutputBuffers())
1746 return false; 2120 return false;
1747 2121
1748 return true; 2122 return true;
1749 } 2123 }
1750 2124
1751 bool ExynosVideoDecodeAccelerator::CreateMfcInputBuffers() { 2125 bool ExynosVideoDecodeAccelerator::CreateMfcInputBuffers() {
1752 DVLOG(3) << "CreateMfcInputBuffers()"; 2126 DVLOG(3) << "CreateMfcInputBuffers()";
1753 // We always run this as we prepare to initialize. 2127 // We always run this as we prepare to initialize.
1754 DCHECK_EQ(decoder_state_, kUninitialized); 2128 DCHECK_EQ(decoder_state_, kUninitialized);
1755 DCHECK(!mfc_input_streamon_); 2129 DCHECK(!mfc_input_streamon_);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1826 // Output format setup in Initialize(). 2200 // Output format setup in Initialize().
1827 2201
1828 // Allocate the output buffers. 2202 // Allocate the output buffers.
1829 struct v4l2_requestbuffers reqbufs; 2203 struct v4l2_requestbuffers reqbufs;
1830 memset(&reqbufs, 0, sizeof(reqbufs)); 2204 memset(&reqbufs, 0, sizeof(reqbufs));
1831 reqbufs.count = mfc_output_dpb_size_ + kDpbOutputBufferExtraCount; 2205 reqbufs.count = mfc_output_dpb_size_ + kDpbOutputBufferExtraCount;
1832 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 2206 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1833 reqbufs.memory = V4L2_MEMORY_MMAP; 2207 reqbufs.memory = V4L2_MEMORY_MMAP;
1834 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_REQBUFS, &reqbufs); 2208 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_REQBUFS, &reqbufs);
1835 2209
1836 // Create DMABUFs from output buffers. 2210 // Fill our free-buffers list, and create DMABUFs from them.
1837 mfc_output_buffer_map_.resize(reqbufs.count); 2211 mfc_output_buffer_map_.resize(reqbufs.count);
1838 for (size_t i = 0; i < mfc_output_buffer_map_.size(); ++i) { 2212 for (size_t i = 0; i < mfc_output_buffer_map_.size(); ++i) {
1839 MfcOutputRecord& output_record = mfc_output_buffer_map_[i]; 2213 mfc_free_output_buffers_.push_back(i);
1840 for (size_t j = 0; j < arraysize(output_record.fds); ++j) { 2214
1841 // Export the DMABUF fd so we can export it as a texture. 2215 // Query for the MEMORY_MMAP pointer.
1842 struct v4l2_exportbuffer expbuf; 2216 struct v4l2_plane planes[2];
1843 memset(&expbuf, 0, sizeof(expbuf)); 2217 struct v4l2_buffer buffer;
1844 expbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 2218 memset(&buffer, 0, sizeof(buffer));
1845 expbuf.index = i; 2219 memset(planes, 0, sizeof(planes));
1846 expbuf.plane = j; 2220 buffer.index = i;
1847 expbuf.flags = O_CLOEXEC; 2221 buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1848 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_EXPBUF, &expbuf); 2222 buffer.memory = V4L2_MEMORY_MMAP;
1849 output_record.fds[j] = expbuf.fd; 2223 buffer.m.planes = planes;
2224 buffer.length = 2;
2225 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QUERYBUF, &buffer);
2226
2227 // Get their user memory for GSC input.
2228 for (int j = 0; j < 2; ++j) {
2229 void* address = mmap(NULL, buffer.m.planes[j].length,
2230 PROT_READ | PROT_WRITE, MAP_SHARED, mfc_fd_,
2231 buffer.m.planes[j].m.mem_offset);
2232 if (address == MAP_FAILED) {
2233 DPLOG(ERROR) << "CreateMfcInputBuffers(): mmap() failed";
2234 return false;
2235 }
2236 mfc_output_buffer_map_[i].address[j] = address;
2237 mfc_output_buffer_map_[i].length[j] = buffer.m.planes[j].length;
1850 } 2238 }
1851 } 2239 }
1852 2240
1853 DVLOG(3) << "CreateMfcOutputBuffers(): ProvidePictureBuffers(): " 2241 return true;
1854 << "buffer_count=" << mfc_output_buffer_map_.size() 2242 }
1855 << ", width=" << frame_buffer_size_.width() 2243
1856 << ", height=" << frame_buffer_size_.height(); 2244 bool ExynosVideoDecodeAccelerator::CreateGscInputBuffers() {
1857 child_message_loop_proxy_->PostTask(FROM_HERE, 2245 DVLOG(3) << "CreateGscInputBuffers()";
1858 base::Bind(&Client::ProvidePictureBuffers, 2246 DCHECK(decoder_state_ == kInitialized ||
1859 client_, 2247 decoder_state_ == kChangingResolution);
1860 mfc_output_buffer_map_.size(), 2248 DCHECK(!gsc_input_streamon_);
1861 frame_buffer_size_, 2249 DCHECK(gsc_input_buffer_map_.empty());
1862 GL_TEXTURE_EXTERNAL_OES)); 2250
2251 struct v4l2_format format;
2252 memset(&format, 0, sizeof(format));
2253 format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2254 format.fmt.pix_mp.width = frame_buffer_size_.width();
2255 format.fmt.pix_mp.height = frame_buffer_size_.height();
2256 format.fmt.pix_mp.pixelformat = mfc_output_buffer_pixelformat_;
2257 format.fmt.pix_mp.plane_fmt[0].sizeimage = mfc_output_buffer_size_[0];
2258 format.fmt.pix_mp.plane_fmt[1].sizeimage = mfc_output_buffer_size_[1];
2259 // NV12MT_16X16 is a tiled format for which bytesperline doesn't make too much
2260 // sense. Convention seems to be to assume 8bpp for these tiled formats.
2261 format.fmt.pix_mp.plane_fmt[0].bytesperline = frame_buffer_size_.width();
2262 format.fmt.pix_mp.plane_fmt[1].bytesperline = frame_buffer_size_.width();
2263 format.fmt.pix_mp.num_planes = 2;
2264 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_S_FMT, &format);
2265
2266 struct v4l2_control control;
2267 memset(&control, 0, sizeof(control));
2268 control.id = V4L2_CID_ROTATE;
2269 control.value = 0;
2270 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_S_CTRL, &control);
2271
2272 memset(&control, 0, sizeof(control));
2273 control.id = V4L2_CID_HFLIP;
2274 control.value = 0;
2275 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_S_CTRL, &control);
2276
2277 memset(&control, 0, sizeof(control));
2278 control.id = V4L2_CID_VFLIP;
2279 control.value = 0;
2280 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_S_CTRL, &control);
2281
2282 memset(&control, 0, sizeof(control));
2283 control.id = V4L2_CID_GLOBAL_ALPHA;
2284 control.value = 255;
2285 if (HANDLE_EINTR(ioctl(gsc_fd_, VIDIOC_S_CTRL, &control)) != 0) {
2286 memset(&control, 0, sizeof(control));
2287 control.id = V4L2_CID_ALPHA_COMPONENT;
2288 control.value = 255;
2289 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_S_CTRL, &control);
2290 }
2291
2292 struct v4l2_requestbuffers reqbufs;
2293 memset(&reqbufs, 0, sizeof(reqbufs));
2294 reqbufs.count = kGscInputBufferCount;
2295 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2296 reqbufs.memory = V4L2_MEMORY_USERPTR;
2297 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_REQBUFS, &reqbufs);
2298
2299 gsc_input_buffer_map_.resize(reqbufs.count);
2300 for (size_t i = 0; i < gsc_input_buffer_map_.size(); ++i) {
2301 gsc_free_input_buffers_.push_back(i);
2302 gsc_input_buffer_map_[i].mfc_output = -1;
2303 }
1863 2304
1864 return true; 2305 return true;
1865 } 2306 }
2307
2308 bool ExynosVideoDecodeAccelerator::CreateGscOutputBuffers() {
2309 DVLOG(3) << "CreateGscOutputBuffers()";
2310 DCHECK(decoder_state_ == kInitialized ||
2311 decoder_state_ == kChangingResolution);
2312 DCHECK(!gsc_output_streamon_);
2313 DCHECK(gsc_output_buffer_map_.empty());
2314
2315 // GSC outputs into the EGLImages we create from the textures we are
2316 // assigned. Assume RGBA8888 format.
2317 struct v4l2_format format;
2318 memset(&format, 0, sizeof(format));
2319 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2320 format.fmt.pix_mp.width = frame_buffer_size_.width();
2321 format.fmt.pix_mp.height = frame_buffer_size_.height();
2322 format.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_RGB32;
2323 format.fmt.pix_mp.plane_fmt[0].sizeimage =
2324 frame_buffer_size_.width() * frame_buffer_size_.height() * 4;
2325 format.fmt.pix_mp.plane_fmt[0].bytesperline = frame_buffer_size_.width() * 4;
2326 format.fmt.pix_mp.num_planes = 1;
2327 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_S_FMT, &format);
2328
2329 struct v4l2_requestbuffers reqbufs;
2330 memset(&reqbufs, 0, sizeof(reqbufs));
2331 reqbufs.count = mfc_output_dpb_size_ + kDpbOutputBufferExtraCount;
2332 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2333 reqbufs.memory = V4L2_MEMORY_DMABUF;
2334 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_REQBUFS, &reqbufs);
2335
2336 // We don't actually fill in the freelist or the map here. That happens once
2337 // we have actual usable buffers, after AssignPictureBuffers();
2338 gsc_output_buffer_map_.resize(reqbufs.count);
2339
2340 DVLOG(3) << "CreateGscOutputBuffers(): ProvidePictureBuffers(): "
2341 << "buffer_count=" << gsc_output_buffer_map_.size()
2342 << ", width=" << frame_buffer_size_.width()
2343 << ", height=" << frame_buffer_size_.height();
2344 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind(
2345 &Client::ProvidePictureBuffers, client_, gsc_output_buffer_map_.size(),
2346 gfx::Size(frame_buffer_size_.width(), frame_buffer_size_.height()),
2347 GL_TEXTURE_2D));
2348
2349 return true;
2350 }
1866 2351
1867 void ExynosVideoDecodeAccelerator::DestroyMfcInputBuffers() { 2352 void ExynosVideoDecodeAccelerator::DestroyMfcInputBuffers() {
1868 DVLOG(3) << "DestroyMfcInputBuffers()"; 2353 DVLOG(3) << "DestroyMfcInputBuffers()";
1869 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 2354 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
1870 DCHECK(!mfc_input_streamon_); 2355 DCHECK(!mfc_input_streamon_);
1871 2356
1872 for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) { 2357 for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) {
1873 if (mfc_input_buffer_map_[i].address != NULL) { 2358 if (mfc_input_buffer_map_[i].address != NULL) {
1874 munmap(mfc_input_buffer_map_[i].address, 2359 munmap(mfc_input_buffer_map_[i].address,
1875 mfc_input_buffer_map_[i].length); 2360 mfc_input_buffer_map_[i].length);
(...skipping 10 matching lines...) Expand all
1886 2371
1887 mfc_input_buffer_map_.clear(); 2372 mfc_input_buffer_map_.clear();
1888 mfc_free_input_buffers_.clear(); 2373 mfc_free_input_buffers_.clear();
1889 } 2374 }
1890 2375
1891 void ExynosVideoDecodeAccelerator::DestroyMfcOutputBuffers() { 2376 void ExynosVideoDecodeAccelerator::DestroyMfcOutputBuffers() {
1892 DVLOG(3) << "DestroyMfcOutputBuffers()"; 2377 DVLOG(3) << "DestroyMfcOutputBuffers()";
1893 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 2378 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
1894 DCHECK(!mfc_output_streamon_); 2379 DCHECK(!mfc_output_streamon_);
1895 2380
1896 if (mfc_output_buffer_map_.size() != 0) { 2381 for (size_t i = 0; i < mfc_output_buffer_map_.size(); ++i) {
1897 if (!make_context_current_.Run()) { 2382 if (mfc_output_buffer_map_[i].address[0] != NULL)
1898 DLOG(ERROR) << "DestroyMfcOutputBuffers(): " 2383 munmap(mfc_output_buffer_map_[i].address[0],
1899 << "could not make context current"; 2384 mfc_output_buffer_map_[i].length[0]);
1900 } else { 2385 if (mfc_output_buffer_map_[i].address[1] != NULL)
1901 size_t i = 0; 2386 munmap(mfc_output_buffer_map_[i].address[1],
1902 do { 2387 mfc_output_buffer_map_[i].length[1]);
1903 MfcOutputRecord& output_record = mfc_output_buffer_map_[i];
1904 for (size_t j = 0; j < arraysize(output_record.fds); ++j) {
1905 if (output_record.fds[j] != -1)
1906 HANDLE_EINTR(close(output_record.fds[j]));
1907 if (output_record.egl_image != EGL_NO_IMAGE_KHR)
1908 eglDestroyImageKHR(egl_display_, output_record.egl_image);
1909 if (output_record.egl_sync != EGL_NO_SYNC_KHR)
1910 eglDestroySyncKHR(egl_display_, output_record.egl_sync);
1911 }
1912 DVLOG(1) << "DestroyMfcOutputBuffers(): dismissing PictureBuffer id="
1913 << output_record.picture_id;
1914 child_message_loop_proxy_->PostTask(
1915 FROM_HERE,
1916 base::Bind(&Client::DismissPictureBuffer,
1917 client_,
1918 output_record.picture_id));
1919 i++;
1920 } while (i < mfc_output_buffer_map_.size());
1921 }
1922 } 2388 }
1923 2389
1924 struct v4l2_requestbuffers reqbufs; 2390 struct v4l2_requestbuffers reqbufs;
1925 memset(&reqbufs, 0, sizeof(reqbufs)); 2391 memset(&reqbufs, 0, sizeof(reqbufs));
1926 reqbufs.count = 0; 2392 reqbufs.count = 0;
1927 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 2393 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1928 reqbufs.memory = V4L2_MEMORY_MMAP; 2394 reqbufs.memory = V4L2_MEMORY_MMAP;
1929 if (ioctl(mfc_fd_, VIDIOC_REQBUFS, &reqbufs) != 0) 2395 if (ioctl(mfc_fd_, VIDIOC_REQBUFS, &reqbufs) != 0)
1930 DPLOG(ERROR) << "DestroyMfcOutputBuffers() ioctl() failed: VIDIOC_REQBUFS"; 2396 DPLOG(ERROR) << "DestroyMfcOutputBuffers() ioctl() failed: VIDIOC_REQBUFS";
1931 2397
1932 mfc_output_buffer_map_.clear(); 2398 mfc_output_buffer_map_.clear();
1933 while (!mfc_free_output_buffers_.empty()) 2399 mfc_free_output_buffers_.clear();
1934 mfc_free_output_buffers_.pop(); 2400 }
2401
2402 void ExynosVideoDecodeAccelerator::DestroyGscInputBuffers() {
2403 DVLOG(3) << "DestroyGscInputBuffers()";
2404 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
2405 DCHECK(!gsc_input_streamon_);
2406
2407 struct v4l2_requestbuffers reqbufs;
2408 memset(&reqbufs, 0, sizeof(reqbufs));
2409 reqbufs.count = 0;
2410 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2411 reqbufs.memory = V4L2_MEMORY_DMABUF;
2412 if (ioctl(gsc_fd_, VIDIOC_REQBUFS, &reqbufs) != 0)
2413 DPLOG(ERROR) << "DestroyGscInputBuffers(): ioctl() failed: VIDIOC_REQBUFS";
2414
2415 gsc_input_buffer_map_.clear();
2416 gsc_free_input_buffers_.clear();
2417 }
2418
2419 void ExynosVideoDecodeAccelerator::DestroyGscOutputBuffers() {
2420 DVLOG(3) << "DestroyGscOutputBuffers()";
2421 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
2422 DCHECK(!gsc_output_streamon_);
2423
2424 if (gsc_output_buffer_map_.size() != 0) {
2425 if (!make_context_current_.Run())
2426 DLOG(ERROR) << "DestroyGscOutputBuffers(): "
2427 << "could not make context current";
2428
2429 size_t i = 0;
2430 do {
2431 GscOutputRecord& output_record = gsc_output_buffer_map_[i];
2432 if (output_record.fd != -1)
2433 HANDLE_EINTR(close(output_record.fd));
2434 if (output_record.egl_image != EGL_NO_IMAGE_KHR)
2435 eglDestroyImageKHR(egl_display_, output_record.egl_image);
2436 if (output_record.egl_sync != EGL_NO_SYNC_KHR)
2437 eglDestroySyncKHR(egl_display_, output_record.egl_sync);
2438 if (client_) {
2439 DVLOG(1) << "DestroyGscOutputBuffers(): "
2440 << "dismissing PictureBuffer id=" << output_record.picture_id;
2441 client_->DismissPictureBuffer(output_record.picture_id);
2442 }
2443 ++i;
2444 } while (i < gsc_output_buffer_map_.size());
2445 }
2446
2447 struct v4l2_requestbuffers reqbufs;
2448 memset(&reqbufs, 0, sizeof(reqbufs));
2449 reqbufs.count = 0;
2450 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2451 reqbufs.memory = V4L2_MEMORY_DMABUF;
2452 if (ioctl(gsc_fd_, VIDIOC_REQBUFS, &reqbufs) != 0)
2453 DPLOG(ERROR) << "DestroyGscOutputBuffers(): ioctl() failed: VIDIOC_REQBUFS";
2454
2455 gsc_output_buffer_map_.clear();
2456 gsc_free_output_buffers_.clear();
1935 } 2457 }
1936 2458
1937 void ExynosVideoDecodeAccelerator::ResolutionChangeDestroyBuffers() { 2459 void ExynosVideoDecodeAccelerator::ResolutionChangeDestroyBuffers() {
1938 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 2460 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
1939 DVLOG(3) << "ResolutionChangeDestroyBuffers()"; 2461 DVLOG(3) << "ResolutionChangeDestroyBuffers()";
1940 2462
2463 DestroyGscInputBuffers();
2464 DestroyGscOutputBuffers();
1941 DestroyMfcOutputBuffers(); 2465 DestroyMfcOutputBuffers();
1942 2466
1943 // Finish resolution change on decoder thread. 2467 // Finish resolution change on decoder thread.
1944 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 2468 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
1945 &ExynosVideoDecodeAccelerator::FinishResolutionChange, 2469 &ExynosVideoDecodeAccelerator::FinishResolutionChange,
1946 base::Unretained(this))); 2470 base::Unretained(this)));
1947 } 2471 }
1948 2472
1949 void ExynosVideoDecodeAccelerator::SendPictureReady() { 2473 void ExynosVideoDecodeAccelerator::SendPictureReady() {
1950 DVLOG(3) << "SendPictureReady()";
1951 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 2474 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1952 bool resetting_or_flushing = 2475 bool resetting_or_flushing =
1953 (decoder_state_ == kResetting || decoder_flushing_); 2476 (decoder_state_ == kResetting || decoder_flushing_);
1954 while (pending_picture_ready_.size() > 0) { 2477 while (pending_picture_ready_.size() > 0) {
1955 bool cleared = pending_picture_ready_.front().cleared; 2478 bool cleared = pending_picture_ready_.front().cleared;
1956 const media::Picture& picture = pending_picture_ready_.front().picture; 2479 const media::Picture& picture = pending_picture_ready_.front().picture;
1957 if (cleared && picture_clearing_count_ == 0) { 2480 if (cleared && picture_clearing_count_ == 0) {
1958 // This picture is cleared. Post it to IO thread to reduce latency. This 2481 // This picture is cleared. Post it to IO thread to reduce latency. This
1959 // should be the case after all pictures are cleared at the beginning. 2482 // should be the case after all pictures are cleared at the beginning.
1960 io_message_loop_proxy_->PostTask( 2483 io_message_loop_proxy_->PostTask(
(...skipping 29 matching lines...) Expand all
1990 2513
1991 void ExynosVideoDecodeAccelerator::PictureCleared() { 2514 void ExynosVideoDecodeAccelerator::PictureCleared() {
1992 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_; 2515 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_;
1993 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 2516 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1994 DCHECK_GT(picture_clearing_count_, 0); 2517 DCHECK_GT(picture_clearing_count_, 0);
1995 picture_clearing_count_--; 2518 picture_clearing_count_--;
1996 SendPictureReady(); 2519 SendPictureReady();
1997 } 2520 }
1998 2521
1999 } // namespace content 2522 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/exynos_video_decode_accelerator.h ('k') | content/common/gpu/media/rendering_helper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698