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

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

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

Powered by Google App Engine
This is Rietveld 408576698