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

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

Issue 1135943005: Revert of content/common: Remove use of MessageLoopProxy and deprecated MessageLoop APIs (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 months 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <dlfcn.h> 5 #include <dlfcn.h>
6 #include <errno.h> 6 #include <errno.h>
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <linux/videodev2.h> 8 #include <linux/videodev2.h>
9 #include <poll.h> 9 #include <poll.h>
10 #include <sys/eventfd.h> 10 #include <sys/eventfd.h>
11 #include <sys/ioctl.h> 11 #include <sys/ioctl.h>
12 #include <sys/mman.h> 12 #include <sys/mman.h>
13 13
14 #include "base/bind.h" 14 #include "base/bind.h"
15 #include "base/command_line.h" 15 #include "base/command_line.h"
16 #include "base/memory/shared_memory.h" 16 #include "base/memory/shared_memory.h"
17 #include "base/message_loop/message_loop.h" 17 #include "base/message_loop/message_loop.h"
18 #include "base/message_loop/message_loop_proxy.h"
18 #include "base/numerics/safe_conversions.h" 19 #include "base/numerics/safe_conversions.h"
19 #include "base/trace_event/trace_event.h" 20 #include "base/trace_event/trace_event.h"
20 #include "content/common/gpu/media/v4l2_video_decode_accelerator.h" 21 #include "content/common/gpu/media/v4l2_video_decode_accelerator.h"
21 #include "media/base/media_switches.h" 22 #include "media/base/media_switches.h"
22 #include "media/filters/h264_parser.h" 23 #include "media/filters/h264_parser.h"
23 #include "ui/gfx/geometry/rect.h" 24 #include "ui/gfx/geometry/rect.h"
24 #include "ui/gl/scoped_binders.h" 25 #include "ui/gl/scoped_binders.h"
25 26
26 #define NOTIFY_ERROR(x) \ 27 #define NOTIFY_ERROR(x) \
27 do { \ 28 do { \
(...skipping 29 matching lines...) Expand all
57 // TODO(posciak): remove once we update linux-headers. 58 // TODO(posciak): remove once we update linux-headers.
58 #ifndef V4L2_EVENT_RESOLUTION_CHANGE 59 #ifndef V4L2_EVENT_RESOLUTION_CHANGE
59 #define V4L2_EVENT_RESOLUTION_CHANGE 5 60 #define V4L2_EVENT_RESOLUTION_CHANGE 5
60 #endif 61 #endif
61 62
62 } // anonymous namespace 63 } // anonymous namespace
63 64
64 struct V4L2VideoDecodeAccelerator::BitstreamBufferRef { 65 struct V4L2VideoDecodeAccelerator::BitstreamBufferRef {
65 BitstreamBufferRef( 66 BitstreamBufferRef(
66 base::WeakPtr<Client>& client, 67 base::WeakPtr<Client>& client,
67 scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner, 68 scoped_refptr<base::MessageLoopProxy>& client_message_loop_proxy,
68 base::SharedMemory* shm, 69 base::SharedMemory* shm,
69 size_t size, 70 size_t size,
70 int32 input_id); 71 int32 input_id);
71 ~BitstreamBufferRef(); 72 ~BitstreamBufferRef();
72 const base::WeakPtr<Client> client; 73 const base::WeakPtr<Client> client;
73 const scoped_refptr<base::SingleThreadTaskRunner> client_task_runner; 74 const scoped_refptr<base::MessageLoopProxy> client_message_loop_proxy;
74 const scoped_ptr<base::SharedMemory> shm; 75 const scoped_ptr<base::SharedMemory> shm;
75 const size_t size; 76 const size_t size;
76 size_t bytes_used; 77 size_t bytes_used;
77 const int32 input_id; 78 const int32 input_id;
78 }; 79 };
79 80
80 struct V4L2VideoDecodeAccelerator::EGLSyncKHRRef { 81 struct V4L2VideoDecodeAccelerator::EGLSyncKHRRef {
81 EGLSyncKHRRef(EGLDisplay egl_display, EGLSyncKHR egl_sync); 82 EGLSyncKHRRef(EGLDisplay egl_display, EGLSyncKHR egl_sync);
82 ~EGLSyncKHRRef(); 83 ~EGLSyncKHRRef();
83 EGLDisplay const egl_display; 84 EGLDisplay const egl_display;
84 EGLSyncKHR egl_sync; 85 EGLSyncKHR egl_sync;
85 }; 86 };
86 87
87 struct V4L2VideoDecodeAccelerator::PictureRecord { 88 struct V4L2VideoDecodeAccelerator::PictureRecord {
88 PictureRecord(bool cleared, const media::Picture& picture); 89 PictureRecord(bool cleared, const media::Picture& picture);
89 ~PictureRecord(); 90 ~PictureRecord();
90 bool cleared; // Whether the texture is cleared and safe to render from. 91 bool cleared; // Whether the texture is cleared and safe to render from.
91 media::Picture picture; // The decoded picture. 92 media::Picture picture; // The decoded picture.
92 }; 93 };
93 94
94 V4L2VideoDecodeAccelerator::BitstreamBufferRef::BitstreamBufferRef( 95 V4L2VideoDecodeAccelerator::BitstreamBufferRef::BitstreamBufferRef(
95 base::WeakPtr<Client>& client, 96 base::WeakPtr<Client>& client,
96 scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner, 97 scoped_refptr<base::MessageLoopProxy>& client_message_loop_proxy,
97 base::SharedMemory* shm, 98 base::SharedMemory* shm, size_t size, int32 input_id)
98 size_t size,
99 int32 input_id)
100 : client(client), 99 : client(client),
101 client_task_runner(client_task_runner), 100 client_message_loop_proxy(client_message_loop_proxy),
102 shm(shm), 101 shm(shm),
103 size(size), 102 size(size),
104 bytes_used(0), 103 bytes_used(0),
105 input_id(input_id) { 104 input_id(input_id) {
106 } 105 }
107 106
108 V4L2VideoDecodeAccelerator::BitstreamBufferRef::~BitstreamBufferRef() { 107 V4L2VideoDecodeAccelerator::BitstreamBufferRef::~BitstreamBufferRef() {
109 if (input_id >= 0) { 108 if (input_id >= 0) {
110 client_task_runner->PostTask( 109 client_message_loop_proxy->PostTask(FROM_HERE, base::Bind(
111 FROM_HERE, 110 &Client::NotifyEndOfBitstreamBuffer, client, input_id));
112 base::Bind(&Client::NotifyEndOfBitstreamBuffer, client, input_id));
113 } 111 }
114 } 112 }
115 113
116 V4L2VideoDecodeAccelerator::EGLSyncKHRRef::EGLSyncKHRRef( 114 V4L2VideoDecodeAccelerator::EGLSyncKHRRef::EGLSyncKHRRef(
117 EGLDisplay egl_display, EGLSyncKHR egl_sync) 115 EGLDisplay egl_display, EGLSyncKHR egl_sync)
118 : egl_display(egl_display), 116 : egl_display(egl_display),
119 egl_sync(egl_sync) { 117 egl_sync(egl_sync) {
120 } 118 }
121 119
122 V4L2VideoDecodeAccelerator::EGLSyncKHRRef::~EGLSyncKHRRef() { 120 V4L2VideoDecodeAccelerator::EGLSyncKHRRef::~EGLSyncKHRRef() {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 : cleared(cleared), picture(picture) {} 153 : cleared(cleared), picture(picture) {}
156 154
157 V4L2VideoDecodeAccelerator::PictureRecord::~PictureRecord() {} 155 V4L2VideoDecodeAccelerator::PictureRecord::~PictureRecord() {}
158 156
159 V4L2VideoDecodeAccelerator::V4L2VideoDecodeAccelerator( 157 V4L2VideoDecodeAccelerator::V4L2VideoDecodeAccelerator(
160 EGLDisplay egl_display, 158 EGLDisplay egl_display,
161 EGLContext egl_context, 159 EGLContext egl_context,
162 const base::WeakPtr<Client>& io_client, 160 const base::WeakPtr<Client>& io_client,
163 const base::Callback<bool(void)>& make_context_current, 161 const base::Callback<bool(void)>& make_context_current,
164 const scoped_refptr<V4L2Device>& device, 162 const scoped_refptr<V4L2Device>& device,
165 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) 163 const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy)
166 : child_task_runner_(base::ThreadTaskRunnerHandle::Get()), 164 : child_message_loop_proxy_(base::MessageLoopProxy::current()),
167 io_task_runner_(io_task_runner), 165 io_message_loop_proxy_(io_message_loop_proxy),
168 io_client_(io_client), 166 io_client_(io_client),
169 decoder_thread_("V4L2DecoderThread"), 167 decoder_thread_("V4L2DecoderThread"),
170 decoder_state_(kUninitialized), 168 decoder_state_(kUninitialized),
171 device_(device), 169 device_(device),
172 decoder_delay_bitstream_buffer_id_(-1), 170 decoder_delay_bitstream_buffer_id_(-1),
173 decoder_current_input_buffer_(-1), 171 decoder_current_input_buffer_(-1),
174 decoder_decode_buffer_tasks_scheduled_(0), 172 decoder_decode_buffer_tasks_scheduled_(0),
175 decoder_frames_at_client_(0), 173 decoder_frames_at_client_(0),
176 decoder_flushing_(false), 174 decoder_flushing_(false),
177 resolution_change_pending_(false), 175 resolution_change_pending_(false),
(...skipping 26 matching lines...) Expand all
204 202
205 // These maps have members that should be manually destroyed, e.g. file 203 // These maps have members that should be manually destroyed, e.g. file
206 // descriptors, mmap() segments, etc. 204 // descriptors, mmap() segments, etc.
207 DCHECK(input_buffer_map_.empty()); 205 DCHECK(input_buffer_map_.empty());
208 DCHECK(output_buffer_map_.empty()); 206 DCHECK(output_buffer_map_.empty());
209 } 207 }
210 208
211 bool V4L2VideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, 209 bool V4L2VideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile,
212 Client* client) { 210 Client* client) {
213 DVLOG(3) << "Initialize()"; 211 DVLOG(3) << "Initialize()";
214 DCHECK(child_task_runner_->BelongsToCurrentThread()); 212 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
215 DCHECK_EQ(decoder_state_, kUninitialized); 213 DCHECK_EQ(decoder_state_, kUninitialized);
216 214
217 client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client)); 215 client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client));
218 client_ = client_ptr_factory_->GetWeakPtr(); 216 client_ = client_ptr_factory_->GetWeakPtr();
219 217
220 switch (profile) { 218 switch (profile) {
221 case media::H264PROFILE_BASELINE: 219 case media::H264PROFILE_BASELINE:
222 DVLOG(2) << "Initialize(): profile H264PROFILE_BASELINE"; 220 DVLOG(2) << "Initialize(): profile H264PROFILE_BASELINE";
223 break; 221 break;
224 case media::H264PROFILE_MAIN: 222 case media::H264PROFILE_MAIN:
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 base::IgnoreResult(&V4L2VideoDecodeAccelerator::StartDevicePoll), 300 base::IgnoreResult(&V4L2VideoDecodeAccelerator::StartDevicePoll),
303 base::Unretained(this))); 301 base::Unretained(this)));
304 302
305 return true; 303 return true;
306 } 304 }
307 305
308 void V4L2VideoDecodeAccelerator::Decode( 306 void V4L2VideoDecodeAccelerator::Decode(
309 const media::BitstreamBuffer& bitstream_buffer) { 307 const media::BitstreamBuffer& bitstream_buffer) {
310 DVLOG(1) << "Decode(): input_id=" << bitstream_buffer.id() 308 DVLOG(1) << "Decode(): input_id=" << bitstream_buffer.id()
311 << ", size=" << bitstream_buffer.size(); 309 << ", size=" << bitstream_buffer.size();
312 DCHECK(io_task_runner_->BelongsToCurrentThread()); 310 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
313 311
314 // DecodeTask() will take care of running a DecodeBufferTask(). 312 // DecodeTask() will take care of running a DecodeBufferTask().
315 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 313 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
316 &V4L2VideoDecodeAccelerator::DecodeTask, base::Unretained(this), 314 &V4L2VideoDecodeAccelerator::DecodeTask, base::Unretained(this),
317 bitstream_buffer)); 315 bitstream_buffer));
318 } 316 }
319 317
320 void V4L2VideoDecodeAccelerator::AssignPictureBuffers( 318 void V4L2VideoDecodeAccelerator::AssignPictureBuffers(
321 const std::vector<media::PictureBuffer>& buffers) { 319 const std::vector<media::PictureBuffer>& buffers) {
322 DVLOG(3) << "AssignPictureBuffers(): buffer_count=" << buffers.size(); 320 DVLOG(3) << "AssignPictureBuffers(): buffer_count=" << buffers.size();
323 DCHECK(child_task_runner_->BelongsToCurrentThread()); 321 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
324 322
325 if (buffers.size() != output_buffer_map_.size()) { 323 if (buffers.size() != output_buffer_map_.size()) {
326 LOG(ERROR) << "AssignPictureBuffers(): Failed to provide requested picture" 324 LOG(ERROR) << "AssignPictureBuffers(): Failed to provide requested picture"
327 " buffers. (Got " << buffers.size() 325 " buffers. (Got " << buffers.size()
328 << ", requested " << output_buffer_map_.size() << ")"; 326 << ", requested " << output_buffer_map_.size() << ")";
329 NOTIFY_ERROR(INVALID_ARGUMENT); 327 NOTIFY_ERROR(INVALID_ARGUMENT);
330 return; 328 return;
331 } 329 }
332 330
333 if (!make_context_current_.Run()) { 331 if (!make_context_current_.Run()) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 DVLOG(3) << "AssignPictureBuffers(): buffer[" << i 372 DVLOG(3) << "AssignPictureBuffers(): buffer[" << i
375 << "]: picture_id=" << output_record.picture_id; 373 << "]: picture_id=" << output_record.picture_id;
376 } 374 }
377 375
378 pictures_assigned_.Signal(); 376 pictures_assigned_.Signal();
379 } 377 }
380 378
381 void V4L2VideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) { 379 void V4L2VideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) {
382 DVLOG(3) << "ReusePictureBuffer(): picture_buffer_id=" << picture_buffer_id; 380 DVLOG(3) << "ReusePictureBuffer(): picture_buffer_id=" << picture_buffer_id;
383 // Must be run on child thread, as we'll insert a sync in the EGL context. 381 // Must be run on child thread, as we'll insert a sync in the EGL context.
384 DCHECK(child_task_runner_->BelongsToCurrentThread()); 382 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
385 383
386 if (!make_context_current_.Run()) { 384 if (!make_context_current_.Run()) {
387 LOG(ERROR) << "ReusePictureBuffer(): could not make context current"; 385 LOG(ERROR) << "ReusePictureBuffer(): could not make context current";
388 NOTIFY_ERROR(PLATFORM_FAILURE); 386 NOTIFY_ERROR(PLATFORM_FAILURE);
389 return; 387 return;
390 } 388 }
391 389
392 EGLSyncKHR egl_sync = EGL_NO_SYNC_KHR; 390 EGLSyncKHR egl_sync = EGL_NO_SYNC_KHR;
393 // TODO(posciak): crbug.com/450898. 391 // TODO(posciak): crbug.com/450898.
394 #if defined(ARCH_CPU_ARMEL) 392 #if defined(ARCH_CPU_ARMEL)
395 egl_sync = eglCreateSyncKHR(egl_display_, EGL_SYNC_FENCE_KHR, NULL); 393 egl_sync = eglCreateSyncKHR(egl_display_, EGL_SYNC_FENCE_KHR, NULL);
396 if (egl_sync == EGL_NO_SYNC_KHR) { 394 if (egl_sync == EGL_NO_SYNC_KHR) {
397 LOG(ERROR) << "ReusePictureBuffer(): eglCreateSyncKHR() failed"; 395 LOG(ERROR) << "ReusePictureBuffer(): eglCreateSyncKHR() failed";
398 NOTIFY_ERROR(PLATFORM_FAILURE); 396 NOTIFY_ERROR(PLATFORM_FAILURE);
399 return; 397 return;
400 } 398 }
401 #endif 399 #endif
402 400
403 scoped_ptr<EGLSyncKHRRef> egl_sync_ref(new EGLSyncKHRRef( 401 scoped_ptr<EGLSyncKHRRef> egl_sync_ref(new EGLSyncKHRRef(
404 egl_display_, egl_sync)); 402 egl_display_, egl_sync));
405 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 403 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
406 &V4L2VideoDecodeAccelerator::ReusePictureBufferTask, 404 &V4L2VideoDecodeAccelerator::ReusePictureBufferTask,
407 base::Unretained(this), picture_buffer_id, base::Passed(&egl_sync_ref))); 405 base::Unretained(this), picture_buffer_id, base::Passed(&egl_sync_ref)));
408 } 406 }
409 407
410 void V4L2VideoDecodeAccelerator::Flush() { 408 void V4L2VideoDecodeAccelerator::Flush() {
411 DVLOG(3) << "Flush()"; 409 DVLOG(3) << "Flush()";
412 DCHECK(child_task_runner_->BelongsToCurrentThread()); 410 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
413 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 411 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
414 &V4L2VideoDecodeAccelerator::FlushTask, base::Unretained(this))); 412 &V4L2VideoDecodeAccelerator::FlushTask, base::Unretained(this)));
415 } 413 }
416 414
417 void V4L2VideoDecodeAccelerator::Reset() { 415 void V4L2VideoDecodeAccelerator::Reset() {
418 DVLOG(3) << "Reset()"; 416 DVLOG(3) << "Reset()";
419 DCHECK(child_task_runner_->BelongsToCurrentThread()); 417 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
420 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 418 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
421 &V4L2VideoDecodeAccelerator::ResetTask, base::Unretained(this))); 419 &V4L2VideoDecodeAccelerator::ResetTask, base::Unretained(this)));
422 } 420 }
423 421
424 void V4L2VideoDecodeAccelerator::Destroy() { 422 void V4L2VideoDecodeAccelerator::Destroy() {
425 DVLOG(3) << "Destroy()"; 423 DVLOG(3) << "Destroy()";
426 DCHECK(child_task_runner_->BelongsToCurrentThread()); 424 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
427 425
428 // We're destroying; cancel all callbacks. 426 // We're destroying; cancel all callbacks.
429 client_ptr_factory_.reset(); 427 client_ptr_factory_.reset();
430 weak_this_factory_.InvalidateWeakPtrs(); 428 weak_this_factory_.InvalidateWeakPtrs();
431 429
432 // If the decoder thread is running, destroy using posted task. 430 // If the decoder thread is running, destroy using posted task.
433 if (decoder_thread_.IsRunning()) { 431 if (decoder_thread_.IsRunning()) {
434 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 432 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
435 &V4L2VideoDecodeAccelerator::DestroyTask, base::Unretained(this))); 433 &V4L2VideoDecodeAccelerator::DestroyTask, base::Unretained(this)));
436 pictures_assigned_.Signal(); 434 pictures_assigned_.Signal();
(...skipping 24 matching lines...) Expand all
461 459
462 void V4L2VideoDecodeAccelerator::DecodeTask( 460 void V4L2VideoDecodeAccelerator::DecodeTask(
463 const media::BitstreamBuffer& bitstream_buffer) { 461 const media::BitstreamBuffer& bitstream_buffer) {
464 DVLOG(3) << "DecodeTask(): input_id=" << bitstream_buffer.id(); 462 DVLOG(3) << "DecodeTask(): input_id=" << bitstream_buffer.id();
465 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 463 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
466 DCHECK_NE(decoder_state_, kUninitialized); 464 DCHECK_NE(decoder_state_, kUninitialized);
467 TRACE_EVENT1("Video Decoder", "V4L2VDA::DecodeTask", "input_id", 465 TRACE_EVENT1("Video Decoder", "V4L2VDA::DecodeTask", "input_id",
468 bitstream_buffer.id()); 466 bitstream_buffer.id());
469 467
470 scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef( 468 scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef(
471 io_client_, io_task_runner_, 469 io_client_, io_message_loop_proxy_,
472 new base::SharedMemory(bitstream_buffer.handle(), true), 470 new base::SharedMemory(bitstream_buffer.handle(), true),
473 bitstream_buffer.size(), bitstream_buffer.id())); 471 bitstream_buffer.size(), bitstream_buffer.id()));
474 if (!bitstream_record->shm->Map(bitstream_buffer.size())) { 472 if (!bitstream_record->shm->Map(bitstream_buffer.size())) {
475 LOG(ERROR) << "Decode(): could not map bitstream_buffer"; 473 LOG(ERROR) << "Decode(): could not map bitstream_buffer";
476 NOTIFY_ERROR(UNREADABLE_INPUT); 474 NOTIFY_ERROR(UNREADABLE_INPUT);
477 return; 475 return;
478 } 476 }
479 DVLOG(3) << "DecodeTask(): mapped at=" << bitstream_record->shm->memory(); 477 DVLOG(3) << "DecodeTask(): mapped at=" << bitstream_record->shm->memory();
480 478
481 if (decoder_state_ == kResetting || decoder_flushing_) { 479 if (decoder_state_ == kResetting || decoder_flushing_) {
(...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after
1238 1236
1239 void V4L2VideoDecodeAccelerator::FlushTask() { 1237 void V4L2VideoDecodeAccelerator::FlushTask() {
1240 DVLOG(3) << "FlushTask()"; 1238 DVLOG(3) << "FlushTask()";
1241 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1239 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1242 TRACE_EVENT0("Video Decoder", "V4L2VDA::FlushTask"); 1240 TRACE_EVENT0("Video Decoder", "V4L2VDA::FlushTask");
1243 1241
1244 // Flush outstanding buffers. 1242 // Flush outstanding buffers.
1245 if (decoder_state_ == kInitialized || decoder_state_ == kAfterReset) { 1243 if (decoder_state_ == kInitialized || decoder_state_ == kAfterReset) {
1246 // There's nothing in the pipe, so return done immediately. 1244 // There's nothing in the pipe, so return done immediately.
1247 DVLOG(3) << "FlushTask(): returning flush"; 1245 DVLOG(3) << "FlushTask(): returning flush";
1248 child_task_runner_->PostTask(FROM_HERE, 1246 child_message_loop_proxy_->PostTask(
1249 base::Bind(&Client::NotifyFlushDone, client_)); 1247 FROM_HERE, base::Bind(&Client::NotifyFlushDone, client_));
1250 return; 1248 return;
1251 } else if (decoder_state_ == kError) { 1249 } else if (decoder_state_ == kError) {
1252 DVLOG(2) << "FlushTask(): early out: kError state"; 1250 DVLOG(2) << "FlushTask(): early out: kError state";
1253 return; 1251 return;
1254 } 1252 }
1255 1253
1256 // We don't support stacked flushing. 1254 // We don't support stacked flushing.
1257 DCHECK(!decoder_flushing_); 1255 DCHECK(!decoder_flushing_);
1258 1256
1259 // Queue up an empty buffer -- this triggers the flush. 1257 // Queue up an empty buffer -- this triggers the flush.
1260 decoder_input_queue_.push( 1258 decoder_input_queue_.push(
1261 linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef( 1259 linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef(
1262 io_client_, io_task_runner_, NULL, 0, kFlushBufferId))); 1260 io_client_, io_message_loop_proxy_, NULL, 0, kFlushBufferId)));
1263 decoder_flushing_ = true; 1261 decoder_flushing_ = true;
1264 SendPictureReady(); // Send all pending PictureReady. 1262 SendPictureReady(); // Send all pending PictureReady.
1265 1263
1266 ScheduleDecodeBufferTaskIfNeeded(); 1264 ScheduleDecodeBufferTaskIfNeeded();
1267 } 1265 }
1268 1266
1269 void V4L2VideoDecodeAccelerator::NotifyFlushDoneIfNeeded() { 1267 void V4L2VideoDecodeAccelerator::NotifyFlushDoneIfNeeded() {
1270 if (!decoder_flushing_) 1268 if (!decoder_flushing_)
1271 return; 1269 return;
1272 1270
(...skipping 23 matching lines...) Expand all
1296 // when doing MSE. This should be harmless otherwise. 1294 // when doing MSE. This should be harmless otherwise.
1297 if (!StopDevicePoll(false)) 1295 if (!StopDevicePoll(false))
1298 return; 1296 return;
1299 1297
1300 if (!StartDevicePoll()) 1298 if (!StartDevicePoll())
1301 return; 1299 return;
1302 1300
1303 decoder_delay_bitstream_buffer_id_ = -1; 1301 decoder_delay_bitstream_buffer_id_ = -1;
1304 decoder_flushing_ = false; 1302 decoder_flushing_ = false;
1305 DVLOG(3) << "NotifyFlushDoneIfNeeded(): returning flush"; 1303 DVLOG(3) << "NotifyFlushDoneIfNeeded(): returning flush";
1306 child_task_runner_->PostTask(FROM_HERE, 1304 child_message_loop_proxy_->PostTask(
1307 base::Bind(&Client::NotifyFlushDone, client_)); 1305 FROM_HERE, base::Bind(&Client::NotifyFlushDone, client_));
1308 1306
1309 // While we were flushing, we early-outed DecodeBufferTask()s. 1307 // While we were flushing, we early-outed DecodeBufferTask()s.
1310 ScheduleDecodeBufferTaskIfNeeded(); 1308 ScheduleDecodeBufferTaskIfNeeded();
1311 } 1309 }
1312 1310
1313 void V4L2VideoDecodeAccelerator::ResetTask() { 1311 void V4L2VideoDecodeAccelerator::ResetTask() {
1314 DVLOG(3) << "ResetTask()"; 1312 DVLOG(3) << "ResetTask()";
1315 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1313 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1316 TRACE_EVENT0("Video Decoder", "V4L2VDA::ResetTask"); 1314 TRACE_EVENT0("Video Decoder", "V4L2VDA::ResetTask");
1317 1315
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1383 if (output_buffer_map_.empty()) { 1381 if (output_buffer_map_.empty()) {
1384 // We must have gotten Reset() before we had a chance to request buffers 1382 // We must have gotten Reset() before we had a chance to request buffers
1385 // from the client. 1383 // from the client.
1386 decoder_state_ = kInitialized; 1384 decoder_state_ = kInitialized;
1387 } else { 1385 } else {
1388 decoder_state_ = kAfterReset; 1386 decoder_state_ = kAfterReset;
1389 } 1387 }
1390 1388
1391 decoder_partial_frame_pending_ = false; 1389 decoder_partial_frame_pending_ = false;
1392 decoder_delay_bitstream_buffer_id_ = -1; 1390 decoder_delay_bitstream_buffer_id_ = -1;
1393 child_task_runner_->PostTask(FROM_HERE, 1391 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind(
1394 base::Bind(&Client::NotifyResetDone, client_)); 1392 &Client::NotifyResetDone, client_));
1395 1393
1396 // While we were resetting, we early-outed DecodeBufferTask()s. 1394 // While we were resetting, we early-outed DecodeBufferTask()s.
1397 ScheduleDecodeBufferTaskIfNeeded(); 1395 ScheduleDecodeBufferTaskIfNeeded();
1398 } 1396 }
1399 1397
1400 void V4L2VideoDecodeAccelerator::DestroyTask() { 1398 void V4L2VideoDecodeAccelerator::DestroyTask() {
1401 DVLOG(3) << "DestroyTask()"; 1399 DVLOG(3) << "DestroyTask()";
1402 TRACE_EVENT0("Video Decoder", "V4L2VDA::DestroyTask"); 1400 TRACE_EVENT0("Video Decoder", "V4L2VDA::DestroyTask");
1403 1401
1404 // DestroyTask() should run regardless of decoder_state_. 1402 // DestroyTask() should run regardless of decoder_state_.
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1519 // Keep input queue. 1517 // Keep input queue.
1520 if (!StopDevicePoll(true)) 1518 if (!StopDevicePoll(true))
1521 return; 1519 return;
1522 1520
1523 decoder_state_ = kChangingResolution; 1521 decoder_state_ = kChangingResolution;
1524 DCHECK(resolution_change_pending_); 1522 DCHECK(resolution_change_pending_);
1525 resolution_change_pending_ = false; 1523 resolution_change_pending_ = false;
1526 1524
1527 // Post a task to clean up buffers on child thread. This will also ensure 1525 // Post a task to clean up buffers on child thread. This will also ensure
1528 // that we won't accept ReusePictureBuffer() anymore after that. 1526 // that we won't accept ReusePictureBuffer() anymore after that.
1529 child_task_runner_->PostTask( 1527 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind(
1530 FROM_HERE, 1528 &V4L2VideoDecodeAccelerator::ResolutionChangeDestroyBuffers,
1531 base::Bind(&V4L2VideoDecodeAccelerator::ResolutionChangeDestroyBuffers, 1529 weak_this_));
1532 weak_this_));
1533 } 1530 }
1534 1531
1535 void V4L2VideoDecodeAccelerator::FinishResolutionChange() { 1532 void V4L2VideoDecodeAccelerator::FinishResolutionChange() {
1536 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1533 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1537 DCHECK_EQ(decoder_state_, kChangingResolution); 1534 DCHECK_EQ(decoder_state_, kChangingResolution);
1538 DVLOG(3) << "FinishResolutionChange()"; 1535 DVLOG(3) << "FinishResolutionChange()";
1539 1536
1540 if (decoder_state_ == kError) { 1537 if (decoder_state_ == kError) {
1541 DVLOG(2) << "FinishResolutionChange(): early out: kError state"; 1538 DVLOG(2) << "FinishResolutionChange(): early out: kError state";
1542 return; 1539 return;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1588 // All processing should happen on ServiceDeviceTask(), since we shouldn't 1585 // All processing should happen on ServiceDeviceTask(), since we shouldn't
1589 // touch decoder state from this thread. 1586 // touch decoder state from this thread.
1590 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 1587 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
1591 &V4L2VideoDecodeAccelerator::ServiceDeviceTask, 1588 &V4L2VideoDecodeAccelerator::ServiceDeviceTask,
1592 base::Unretained(this), event_pending)); 1589 base::Unretained(this), event_pending));
1593 } 1590 }
1594 1591
1595 void V4L2VideoDecodeAccelerator::NotifyError(Error error) { 1592 void V4L2VideoDecodeAccelerator::NotifyError(Error error) {
1596 DVLOG(2) << "NotifyError()"; 1593 DVLOG(2) << "NotifyError()";
1597 1594
1598 if (!child_task_runner_->BelongsToCurrentThread()) { 1595 if (!child_message_loop_proxy_->BelongsToCurrentThread()) {
1599 child_task_runner_->PostTask( 1596 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind(
1600 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::NotifyError, 1597 &V4L2VideoDecodeAccelerator::NotifyError, weak_this_, error));
1601 weak_this_, error));
1602 return; 1598 return;
1603 } 1599 }
1604 1600
1605 if (client_) { 1601 if (client_) {
1606 client_->NotifyError(error); 1602 client_->NotifyError(error);
1607 client_ptr_factory_.reset(); 1603 client_ptr_factory_.reset();
1608 } 1604 }
1609 } 1605 }
1610 1606
1611 void V4L2VideoDecodeAccelerator::SetErrorState(Error error) { 1607 void V4L2VideoDecodeAccelerator::SetErrorState(Error error) {
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
1838 reqbufs.count = output_dpb_size_ + kDpbOutputBufferExtraCount; 1834 reqbufs.count = output_dpb_size_ + kDpbOutputBufferExtraCount;
1839 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1835 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1840 reqbufs.memory = V4L2_MEMORY_MMAP; 1836 reqbufs.memory = V4L2_MEMORY_MMAP;
1841 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs); 1837 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs);
1842 1838
1843 output_buffer_map_.resize(reqbufs.count); 1839 output_buffer_map_.resize(reqbufs.count);
1844 1840
1845 DVLOG(3) << "CreateOutputBuffers(): ProvidePictureBuffers(): " 1841 DVLOG(3) << "CreateOutputBuffers(): ProvidePictureBuffers(): "
1846 << "buffer_count=" << output_buffer_map_.size() 1842 << "buffer_count=" << output_buffer_map_.size()
1847 << ", coded_size=" << coded_size_.ToString(); 1843 << ", coded_size=" << coded_size_.ToString();
1848 child_task_runner_->PostTask( 1844 child_message_loop_proxy_->PostTask(FROM_HERE,
1849 FROM_HERE, base::Bind(&Client::ProvidePictureBuffers, client_, 1845 base::Bind(&Client::ProvidePictureBuffers,
1850 output_buffer_map_.size(), coded_size_, 1846 client_,
1851 device_->GetTextureTarget())); 1847 output_buffer_map_.size(),
1848 coded_size_,
1849 device_->GetTextureTarget()));
1852 1850
1853 // Wait for the client to call AssignPictureBuffers() on the Child thread. 1851 // Wait for the client to call AssignPictureBuffers() on the Child thread.
1854 // We do this, because if we continue decoding without finishing buffer 1852 // We do this, because if we continue decoding without finishing buffer
1855 // allocation, we may end up Resetting before AssignPictureBuffers arrives, 1853 // allocation, we may end up Resetting before AssignPictureBuffers arrives,
1856 // resulting in unnecessary complications and subtle bugs. 1854 // resulting in unnecessary complications and subtle bugs.
1857 // For example, if the client calls Decode(Input1), Reset(), Decode(Input2) 1855 // For example, if the client calls Decode(Input1), Reset(), Decode(Input2)
1858 // in a sequence, and Decode(Input1) results in us getting here and exiting 1856 // in a sequence, and Decode(Input1) results in us getting here and exiting
1859 // without waiting, we might end up running Reset{,Done}Task() before 1857 // without waiting, we might end up running Reset{,Done}Task() before
1860 // AssignPictureBuffers is scheduled, thus cleaning up and pushing buffers 1858 // AssignPictureBuffers is scheduled, thus cleaning up and pushing buffers
1861 // to the free_output_buffers_ map twice. If we somehow marked buffers as 1859 // to the free_output_buffers_ map twice. If we somehow marked buffers as
1862 // not ready, we'd need special handling for restarting the second Decode 1860 // not ready, we'd need special handling for restarting the second Decode
1863 // task and delaying it anyway. 1861 // task and delaying it anyway.
1864 // Waiting here is not very costly and makes reasoning about different 1862 // Waiting here is not very costly and makes reasoning about different
1865 // situations much simpler. 1863 // situations much simpler.
1866 pictures_assigned_.Wait(); 1864 pictures_assigned_.Wait();
1867 1865
1868 Enqueue(); 1866 Enqueue();
1869 return true; 1867 return true;
1870 } 1868 }
1871 1869
1872 void V4L2VideoDecodeAccelerator::DestroyInputBuffers() { 1870 void V4L2VideoDecodeAccelerator::DestroyInputBuffers() {
1873 DVLOG(3) << "DestroyInputBuffers()"; 1871 DVLOG(3) << "DestroyInputBuffers()";
1874 DCHECK(child_task_runner_->BelongsToCurrentThread()); 1872 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
1875 DCHECK(!input_streamon_); 1873 DCHECK(!input_streamon_);
1876 1874
1877 for (size_t i = 0; i < input_buffer_map_.size(); ++i) { 1875 for (size_t i = 0; i < input_buffer_map_.size(); ++i) {
1878 if (input_buffer_map_[i].address != NULL) { 1876 if (input_buffer_map_[i].address != NULL) {
1879 device_->Munmap(input_buffer_map_[i].address, 1877 device_->Munmap(input_buffer_map_[i].address,
1880 input_buffer_map_[i].length); 1878 input_buffer_map_[i].length);
1881 } 1879 }
1882 } 1880 }
1883 1881
1884 struct v4l2_requestbuffers reqbufs; 1882 struct v4l2_requestbuffers reqbufs;
1885 memset(&reqbufs, 0, sizeof(reqbufs)); 1883 memset(&reqbufs, 0, sizeof(reqbufs));
1886 reqbufs.count = 0; 1884 reqbufs.count = 0;
1887 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1885 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1888 reqbufs.memory = V4L2_MEMORY_MMAP; 1886 reqbufs.memory = V4L2_MEMORY_MMAP;
1889 IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs); 1887 IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs);
1890 1888
1891 input_buffer_map_.clear(); 1889 input_buffer_map_.clear();
1892 free_input_buffers_.clear(); 1890 free_input_buffers_.clear();
1893 } 1891 }
1894 1892
1895 bool V4L2VideoDecodeAccelerator::DestroyOutputBuffers() { 1893 bool V4L2VideoDecodeAccelerator::DestroyOutputBuffers() {
1896 DVLOG(3) << "DestroyOutputBuffers()"; 1894 DVLOG(3) << "DestroyOutputBuffers()";
1897 DCHECK(child_task_runner_->BelongsToCurrentThread()); 1895 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
1898 DCHECK(!output_streamon_); 1896 DCHECK(!output_streamon_);
1899 bool success = true; 1897 bool success = true;
1900 1898
1901 for (size_t i = 0; i < output_buffer_map_.size(); ++i) { 1899 for (size_t i = 0; i < output_buffer_map_.size(); ++i) {
1902 OutputRecord& output_record = output_buffer_map_[i]; 1900 OutputRecord& output_record = output_buffer_map_[i];
1903 1901
1904 if (output_record.egl_image != EGL_NO_IMAGE_KHR) { 1902 if (output_record.egl_image != EGL_NO_IMAGE_KHR) {
1905 if (device_->DestroyEGLImage(egl_display_, output_record.egl_image) != 1903 if (device_->DestroyEGLImage(egl_display_, output_record.egl_image) !=
1906 EGL_TRUE) { 1904 EGL_TRUE) {
1907 DVLOG(1) << __func__ << " DestroyEGLImage failed."; 1905 DVLOG(1) << __func__ << " DestroyEGLImage failed.";
1908 success = false; 1906 success = false;
1909 } 1907 }
1910 } 1908 }
1911 1909
1912 if (output_record.egl_sync != EGL_NO_SYNC_KHR) { 1910 if (output_record.egl_sync != EGL_NO_SYNC_KHR) {
1913 if (eglDestroySyncKHR(egl_display_, output_record.egl_sync) != EGL_TRUE) { 1911 if (eglDestroySyncKHR(egl_display_, output_record.egl_sync) != EGL_TRUE) {
1914 DVLOG(1) << __func__ << " eglDestroySyncKHR failed."; 1912 DVLOG(1) << __func__ << " eglDestroySyncKHR failed.";
1915 success = false; 1913 success = false;
1916 } 1914 }
1917 } 1915 }
1918 1916
1919 DVLOG(1) << "DestroyOutputBuffers(): dismissing PictureBuffer id=" 1917 DVLOG(1) << "DestroyOutputBuffers(): dismissing PictureBuffer id="
1920 << output_record.picture_id; 1918 << output_record.picture_id;
1921 child_task_runner_->PostTask( 1919 child_message_loop_proxy_->PostTask(
1922 FROM_HERE, base::Bind(&Client::DismissPictureBuffer, client_, 1920 FROM_HERE,
1923 output_record.picture_id)); 1921 base::Bind(
1922 &Client::DismissPictureBuffer, client_, output_record.picture_id));
1924 } 1923 }
1925 1924
1926 struct v4l2_requestbuffers reqbufs; 1925 struct v4l2_requestbuffers reqbufs;
1927 memset(&reqbufs, 0, sizeof(reqbufs)); 1926 memset(&reqbufs, 0, sizeof(reqbufs));
1928 reqbufs.count = 0; 1927 reqbufs.count = 0;
1929 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1928 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1930 reqbufs.memory = V4L2_MEMORY_MMAP; 1929 reqbufs.memory = V4L2_MEMORY_MMAP;
1931 if (device_->Ioctl(VIDIOC_REQBUFS, &reqbufs) != 0) { 1930 if (device_->Ioctl(VIDIOC_REQBUFS, &reqbufs) != 0) {
1932 PLOG(ERROR) << "DestroyOutputBuffers() ioctl() failed: VIDIOC_REQBUFS"; 1931 PLOG(ERROR) << "DestroyOutputBuffers() ioctl() failed: VIDIOC_REQBUFS";
1933 success = false; 1932 success = false;
1934 } 1933 }
1935 1934
1936 output_buffer_map_.clear(); 1935 output_buffer_map_.clear();
1937 while (!free_output_buffers_.empty()) 1936 while (!free_output_buffers_.empty())
1938 free_output_buffers_.pop(); 1937 free_output_buffers_.pop();
1939 1938
1940 return success; 1939 return success;
1941 } 1940 }
1942 1941
1943 void V4L2VideoDecodeAccelerator::ResolutionChangeDestroyBuffers() { 1942 void V4L2VideoDecodeAccelerator::ResolutionChangeDestroyBuffers() {
1944 DCHECK(child_task_runner_->BelongsToCurrentThread()); 1943 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
1945 DVLOG(3) << "ResolutionChangeDestroyBuffers()"; 1944 DVLOG(3) << "ResolutionChangeDestroyBuffers()";
1946 1945
1947 if (!DestroyOutputBuffers()) { 1946 if (!DestroyOutputBuffers()) {
1948 LOG(ERROR) << __func__ << " Failed destroying output buffers."; 1947 LOG(ERROR) << __func__ << " Failed destroying output buffers.";
1949 NOTIFY_ERROR(PLATFORM_FAILURE); 1948 NOTIFY_ERROR(PLATFORM_FAILURE);
1950 return; 1949 return;
1951 } 1950 }
1952 1951
1953 // Finish resolution change on decoder thread. 1952 // Finish resolution change on decoder thread.
1954 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 1953 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
1955 &V4L2VideoDecodeAccelerator::FinishResolutionChange, 1954 &V4L2VideoDecodeAccelerator::FinishResolutionChange,
1956 base::Unretained(this))); 1955 base::Unretained(this)));
1957 } 1956 }
1958 1957
1959 void V4L2VideoDecodeAccelerator::SendPictureReady() { 1958 void V4L2VideoDecodeAccelerator::SendPictureReady() {
1960 DVLOG(3) << "SendPictureReady()"; 1959 DVLOG(3) << "SendPictureReady()";
1961 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1960 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1962 bool resetting_or_flushing = 1961 bool resetting_or_flushing =
1963 (decoder_state_ == kResetting || decoder_flushing_); 1962 (decoder_state_ == kResetting || decoder_flushing_);
1964 while (pending_picture_ready_.size() > 0) { 1963 while (pending_picture_ready_.size() > 0) {
1965 bool cleared = pending_picture_ready_.front().cleared; 1964 bool cleared = pending_picture_ready_.front().cleared;
1966 const media::Picture& picture = pending_picture_ready_.front().picture; 1965 const media::Picture& picture = pending_picture_ready_.front().picture;
1967 if (cleared && picture_clearing_count_ == 0) { 1966 if (cleared && picture_clearing_count_ == 0) {
1968 // This picture is cleared. Post it to IO thread to reduce latency. This 1967 // This picture is cleared. Post it to IO thread to reduce latency. This
1969 // should be the case after all pictures are cleared at the beginning. 1968 // should be the case after all pictures are cleared at the beginning.
1970 io_task_runner_->PostTask( 1969 io_message_loop_proxy_->PostTask(
1971 FROM_HERE, base::Bind(&Client::PictureReady, io_client_, picture)); 1970 FROM_HERE, base::Bind(&Client::PictureReady, io_client_, picture));
1972 pending_picture_ready_.pop(); 1971 pending_picture_ready_.pop();
1973 } else if (!cleared || resetting_or_flushing) { 1972 } else if (!cleared || resetting_or_flushing) {
1974 DVLOG(3) << "SendPictureReady()" 1973 DVLOG(3) << "SendPictureReady()"
1975 << ". cleared=" << pending_picture_ready_.front().cleared 1974 << ". cleared=" << pending_picture_ready_.front().cleared
1976 << ", decoder_state_=" << decoder_state_ 1975 << ", decoder_state_=" << decoder_state_
1977 << ", decoder_flushing_=" << decoder_flushing_ 1976 << ", decoder_flushing_=" << decoder_flushing_
1978 << ", picture_clearing_count_=" << picture_clearing_count_; 1977 << ", picture_clearing_count_=" << picture_clearing_count_;
1979 // If the picture is not cleared, post it to the child thread because it 1978 // If the picture is not cleared, post it to the child thread because it
1980 // has to be cleared in the child thread. A picture only needs to be 1979 // has to be cleared in the child thread. A picture only needs to be
1981 // cleared once. If the decoder is resetting or flushing, send all 1980 // cleared once. If the decoder is resetting or flushing, send all
1982 // pictures to ensure PictureReady arrive before reset or flush done. 1981 // pictures to ensure PictureReady arrive before reset or flush done.
1983 child_task_runner_->PostTaskAndReply( 1982 child_message_loop_proxy_->PostTaskAndReply(
1984 FROM_HERE, base::Bind(&Client::PictureReady, client_, picture), 1983 FROM_HERE,
1984 base::Bind(&Client::PictureReady, client_, picture),
1985 // Unretained is safe. If Client::PictureReady gets to run, |this| is 1985 // Unretained is safe. If Client::PictureReady gets to run, |this| is
1986 // alive. Destroy() will wait the decode thread to finish. 1986 // alive. Destroy() will wait the decode thread to finish.
1987 base::Bind(&V4L2VideoDecodeAccelerator::PictureCleared, 1987 base::Bind(&V4L2VideoDecodeAccelerator::PictureCleared,
1988 base::Unretained(this))); 1988 base::Unretained(this)));
1989 picture_clearing_count_++; 1989 picture_clearing_count_++;
1990 pending_picture_ready_.pop(); 1990 pending_picture_ready_.pop();
1991 } else { 1991 } else {
1992 // This picture is cleared. But some pictures are about to be cleared on 1992 // This picture is cleared. But some pictures are about to be cleared on
1993 // the child thread. To preserve the order, do not send this until those 1993 // the child thread. To preserve the order, do not send this until those
1994 // pictures are cleared. 1994 // pictures are cleared.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2027 gfx::Size new_coded_size(base::checked_cast<int>(format.fmt.pix_mp.width), 2027 gfx::Size new_coded_size(base::checked_cast<int>(format.fmt.pix_mp.width),
2028 base::checked_cast<int>(format.fmt.pix_mp.height)); 2028 base::checked_cast<int>(format.fmt.pix_mp.height));
2029 if (coded_size_ != new_coded_size) { 2029 if (coded_size_ != new_coded_size) {
2030 DVLOG(3) << "IsResolutionChangeNecessary(): Resolution change detected"; 2030 DVLOG(3) << "IsResolutionChangeNecessary(): Resolution change detected";
2031 return true; 2031 return true;
2032 } 2032 }
2033 return false; 2033 return false;
2034 } 2034 }
2035 2035
2036 } // namespace content 2036 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/v4l2_video_decode_accelerator.h ('k') | content/common/gpu/media/v4l2_video_encode_accelerator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698