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

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: Android build fix. 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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 493
492 void V4L2VideoDecodeAccelerator::DecodeTask( 494 void V4L2VideoDecodeAccelerator::DecodeTask(
493 const media::BitstreamBuffer& bitstream_buffer) { 495 const media::BitstreamBuffer& bitstream_buffer) {
494 DVLOG(3) << "DecodeTask(): input_id=" << bitstream_buffer.id(); 496 DVLOG(3) << "DecodeTask(): input_id=" << bitstream_buffer.id();
495 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 497 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
496 DCHECK_NE(decoder_state_, kUninitialized); 498 DCHECK_NE(decoder_state_, kUninitialized);
497 TRACE_EVENT1("Video Decoder", "V4L2VDA::DecodeTask", "input_id", 499 TRACE_EVENT1("Video Decoder", "V4L2VDA::DecodeTask", "input_id",
498 bitstream_buffer.id()); 500 bitstream_buffer.id());
499 501
500 scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef( 502 scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef(
501 io_client_, io_message_loop_proxy_, 503 io_client_, io_task_runner_,
502 new base::SharedMemory(bitstream_buffer.handle(), true), 504 new base::SharedMemory(bitstream_buffer.handle(), true),
503 bitstream_buffer.size(), bitstream_buffer.id())); 505 bitstream_buffer.size(), bitstream_buffer.id()));
504 if (!bitstream_record->shm->Map(bitstream_buffer.size())) { 506 if (!bitstream_record->shm->Map(bitstream_buffer.size())) {
505 LOG(ERROR) << "Decode(): could not map bitstream_buffer"; 507 LOG(ERROR) << "Decode(): could not map bitstream_buffer";
506 NOTIFY_ERROR(UNREADABLE_INPUT); 508 NOTIFY_ERROR(UNREADABLE_INPUT);
507 return; 509 return;
508 } 510 }
509 DVLOG(3) << "DecodeTask(): mapped at=" << bitstream_record->shm->memory(); 511 DVLOG(3) << "DecodeTask(): mapped at=" << bitstream_record->shm->memory();
510 512
511 if (decoder_state_ == kResetting || decoder_flushing_) { 513 if (decoder_state_ == kResetting || decoder_flushing_) {
(...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after
1268 1270
1269 void V4L2VideoDecodeAccelerator::FlushTask() { 1271 void V4L2VideoDecodeAccelerator::FlushTask() {
1270 DVLOG(3) << "FlushTask()"; 1272 DVLOG(3) << "FlushTask()";
1271 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1273 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1272 TRACE_EVENT0("Video Decoder", "V4L2VDA::FlushTask"); 1274 TRACE_EVENT0("Video Decoder", "V4L2VDA::FlushTask");
1273 1275
1274 // Flush outstanding buffers. 1276 // Flush outstanding buffers.
1275 if (decoder_state_ == kInitialized || decoder_state_ == kAfterReset) { 1277 if (decoder_state_ == kInitialized || decoder_state_ == kAfterReset) {
1276 // There's nothing in the pipe, so return done immediately. 1278 // There's nothing in the pipe, so return done immediately.
1277 DVLOG(3) << "FlushTask(): returning flush"; 1279 DVLOG(3) << "FlushTask(): returning flush";
1278 child_message_loop_proxy_->PostTask( 1280 child_task_runner_->PostTask(FROM_HERE,
1279 FROM_HERE, base::Bind(&Client::NotifyFlushDone, client_)); 1281 base::Bind(&Client::NotifyFlushDone, client_));
1280 return; 1282 return;
1281 } else if (decoder_state_ == kError) { 1283 } else if (decoder_state_ == kError) {
1282 DVLOG(2) << "FlushTask(): early out: kError state"; 1284 DVLOG(2) << "FlushTask(): early out: kError state";
1283 return; 1285 return;
1284 } 1286 }
1285 1287
1286 // We don't support stacked flushing. 1288 // We don't support stacked flushing.
1287 DCHECK(!decoder_flushing_); 1289 DCHECK(!decoder_flushing_);
1288 1290
1289 // Queue up an empty buffer -- this triggers the flush. 1291 // Queue up an empty buffer -- this triggers the flush.
1290 decoder_input_queue_.push( 1292 decoder_input_queue_.push(
1291 linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef( 1293 linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef(
1292 io_client_, io_message_loop_proxy_, NULL, 0, kFlushBufferId))); 1294 io_client_, io_task_runner_, NULL, 0, kFlushBufferId)));
1293 decoder_flushing_ = true; 1295 decoder_flushing_ = true;
1294 SendPictureReady(); // Send all pending PictureReady. 1296 SendPictureReady(); // Send all pending PictureReady.
1295 1297
1296 ScheduleDecodeBufferTaskIfNeeded(); 1298 ScheduleDecodeBufferTaskIfNeeded();
1297 } 1299 }
1298 1300
1299 void V4L2VideoDecodeAccelerator::NotifyFlushDoneIfNeeded() { 1301 void V4L2VideoDecodeAccelerator::NotifyFlushDoneIfNeeded() {
1300 if (!decoder_flushing_) 1302 if (!decoder_flushing_)
1301 return; 1303 return;
1302 1304
(...skipping 23 matching lines...) Expand all
1326 // when doing MSE. This should be harmless otherwise. 1328 // when doing MSE. This should be harmless otherwise.
1327 if (!StopDevicePoll(false)) 1329 if (!StopDevicePoll(false))
1328 return; 1330 return;
1329 1331
1330 if (!StartDevicePoll()) 1332 if (!StartDevicePoll())
1331 return; 1333 return;
1332 1334
1333 decoder_delay_bitstream_buffer_id_ = -1; 1335 decoder_delay_bitstream_buffer_id_ = -1;
1334 decoder_flushing_ = false; 1336 decoder_flushing_ = false;
1335 DVLOG(3) << "NotifyFlushDoneIfNeeded(): returning flush"; 1337 DVLOG(3) << "NotifyFlushDoneIfNeeded(): returning flush";
1336 child_message_loop_proxy_->PostTask( 1338 child_task_runner_->PostTask(FROM_HERE,
1337 FROM_HERE, base::Bind(&Client::NotifyFlushDone, client_)); 1339 base::Bind(&Client::NotifyFlushDone, client_));
1338 1340
1339 // While we were flushing, we early-outed DecodeBufferTask()s. 1341 // While we were flushing, we early-outed DecodeBufferTask()s.
1340 ScheduleDecodeBufferTaskIfNeeded(); 1342 ScheduleDecodeBufferTaskIfNeeded();
1341 } 1343 }
1342 1344
1343 void V4L2VideoDecodeAccelerator::ResetTask() { 1345 void V4L2VideoDecodeAccelerator::ResetTask() {
1344 DVLOG(3) << "ResetTask()"; 1346 DVLOG(3) << "ResetTask()";
1345 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1347 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1346 TRACE_EVENT0("Video Decoder", "V4L2VDA::ResetTask"); 1348 TRACE_EVENT0("Video Decoder", "V4L2VDA::ResetTask");
1347 1349
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1413 if (output_buffer_map_.empty()) { 1415 if (output_buffer_map_.empty()) {
1414 // We must have gotten Reset() before we had a chance to request buffers 1416 // We must have gotten Reset() before we had a chance to request buffers
1415 // from the client. 1417 // from the client.
1416 decoder_state_ = kInitialized; 1418 decoder_state_ = kInitialized;
1417 } else { 1419 } else {
1418 decoder_state_ = kAfterReset; 1420 decoder_state_ = kAfterReset;
1419 } 1421 }
1420 1422
1421 decoder_partial_frame_pending_ = false; 1423 decoder_partial_frame_pending_ = false;
1422 decoder_delay_bitstream_buffer_id_ = -1; 1424 decoder_delay_bitstream_buffer_id_ = -1;
1423 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( 1425 child_task_runner_->PostTask(FROM_HERE,
1424 &Client::NotifyResetDone, client_)); 1426 base::Bind(&Client::NotifyResetDone, client_));
1425 1427
1426 // While we were resetting, we early-outed DecodeBufferTask()s. 1428 // While we were resetting, we early-outed DecodeBufferTask()s.
1427 ScheduleDecodeBufferTaskIfNeeded(); 1429 ScheduleDecodeBufferTaskIfNeeded();
1428 } 1430 }
1429 1431
1430 void V4L2VideoDecodeAccelerator::DestroyTask() { 1432 void V4L2VideoDecodeAccelerator::DestroyTask() {
1431 DVLOG(3) << "DestroyTask()"; 1433 DVLOG(3) << "DestroyTask()";
1432 TRACE_EVENT0("Video Decoder", "V4L2VDA::DestroyTask"); 1434 TRACE_EVENT0("Video Decoder", "V4L2VDA::DestroyTask");
1433 1435
1434 // DestroyTask() should run regardless of decoder_state_. 1436 // DestroyTask() should run regardless of decoder_state_.
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1549 // Keep input queue. 1551 // Keep input queue.
1550 if (!StopDevicePoll(true)) 1552 if (!StopDevicePoll(true))
1551 return; 1553 return;
1552 1554
1553 decoder_state_ = kChangingResolution; 1555 decoder_state_ = kChangingResolution;
1554 DCHECK(resolution_change_pending_); 1556 DCHECK(resolution_change_pending_);
1555 resolution_change_pending_ = false; 1557 resolution_change_pending_ = false;
1556 1558
1557 // Post a task to clean up buffers on child thread. This will also ensure 1559 // Post a task to clean up buffers on child thread. This will also ensure
1558 // that we won't accept ReusePictureBuffer() anymore after that. 1560 // that we won't accept ReusePictureBuffer() anymore after that.
1559 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( 1561 child_task_runner_->PostTask(
1560 &V4L2VideoDecodeAccelerator::ResolutionChangeDestroyBuffers, 1562 FROM_HERE,
1561 weak_this_)); 1563 base::Bind(&V4L2VideoDecodeAccelerator::ResolutionChangeDestroyBuffers,
1564 weak_this_));
1562 } 1565 }
1563 1566
1564 void V4L2VideoDecodeAccelerator::FinishResolutionChange() { 1567 void V4L2VideoDecodeAccelerator::FinishResolutionChange() {
1565 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1568 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1566 DCHECK_EQ(decoder_state_, kChangingResolution); 1569 DCHECK_EQ(decoder_state_, kChangingResolution);
1567 DVLOG(3) << "FinishResolutionChange()"; 1570 DVLOG(3) << "FinishResolutionChange()";
1568 1571
1569 if (decoder_state_ == kError) { 1572 if (decoder_state_ == kError) {
1570 DVLOG(2) << "FinishResolutionChange(): early out: kError state"; 1573 DVLOG(2) << "FinishResolutionChange(): early out: kError state";
1571 return; 1574 return;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1617 // All processing should happen on ServiceDeviceTask(), since we shouldn't 1620 // All processing should happen on ServiceDeviceTask(), since we shouldn't
1618 // touch decoder state from this thread. 1621 // touch decoder state from this thread.
1619 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 1622 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
1620 &V4L2VideoDecodeAccelerator::ServiceDeviceTask, 1623 &V4L2VideoDecodeAccelerator::ServiceDeviceTask,
1621 base::Unretained(this), event_pending)); 1624 base::Unretained(this), event_pending));
1622 } 1625 }
1623 1626
1624 void V4L2VideoDecodeAccelerator::NotifyError(Error error) { 1627 void V4L2VideoDecodeAccelerator::NotifyError(Error error) {
1625 DVLOG(2) << "NotifyError()"; 1628 DVLOG(2) << "NotifyError()";
1626 1629
1627 if (!child_message_loop_proxy_->BelongsToCurrentThread()) { 1630 if (!child_task_runner_->BelongsToCurrentThread()) {
1628 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( 1631 child_task_runner_->PostTask(
1629 &V4L2VideoDecodeAccelerator::NotifyError, weak_this_, error)); 1632 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::NotifyError,
1633 weak_this_, error));
1630 return; 1634 return;
1631 } 1635 }
1632 1636
1633 if (client_) { 1637 if (client_) {
1634 client_->NotifyError(error); 1638 client_->NotifyError(error);
1635 client_ptr_factory_.reset(); 1639 client_ptr_factory_.reset();
1636 } 1640 }
1637 } 1641 }
1638 1642
1639 void V4L2VideoDecodeAccelerator::SetErrorState(Error error) { 1643 void V4L2VideoDecodeAccelerator::SetErrorState(Error error) {
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
1864 reqbufs.count = output_dpb_size_ + kDpbOutputBufferExtraCount; 1868 reqbufs.count = output_dpb_size_ + kDpbOutputBufferExtraCount;
1865 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1869 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1866 reqbufs.memory = V4L2_MEMORY_MMAP; 1870 reqbufs.memory = V4L2_MEMORY_MMAP;
1867 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs); 1871 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs);
1868 1872
1869 output_buffer_map_.resize(reqbufs.count); 1873 output_buffer_map_.resize(reqbufs.count);
1870 1874
1871 DVLOG(3) << "CreateOutputBuffers(): ProvidePictureBuffers(): " 1875 DVLOG(3) << "CreateOutputBuffers(): ProvidePictureBuffers(): "
1872 << "buffer_count=" << output_buffer_map_.size() 1876 << "buffer_count=" << output_buffer_map_.size()
1873 << ", coded_size=" << coded_size_.ToString(); 1877 << ", coded_size=" << coded_size_.ToString();
1874 child_message_loop_proxy_->PostTask(FROM_HERE, 1878 child_task_runner_->PostTask(
1875 base::Bind(&Client::ProvidePictureBuffers, 1879 FROM_HERE, base::Bind(&Client::ProvidePictureBuffers, client_,
1876 client_, 1880 output_buffer_map_.size(), coded_size_,
1877 output_buffer_map_.size(), 1881 device_->GetTextureTarget()));
1878 coded_size_,
1879 device_->GetTextureTarget()));
1880 1882
1881 // Wait for the client to call AssignPictureBuffers() on the Child thread. 1883 // Wait for the client to call AssignPictureBuffers() on the Child thread.
1882 // We do this, because if we continue decoding without finishing buffer 1884 // We do this, because if we continue decoding without finishing buffer
1883 // allocation, we may end up Resetting before AssignPictureBuffers arrives, 1885 // allocation, we may end up Resetting before AssignPictureBuffers arrives,
1884 // resulting in unnecessary complications and subtle bugs. 1886 // resulting in unnecessary complications and subtle bugs.
1885 // For example, if the client calls Decode(Input1), Reset(), Decode(Input2) 1887 // For example, if the client calls Decode(Input1), Reset(), Decode(Input2)
1886 // in a sequence, and Decode(Input1) results in us getting here and exiting 1888 // in a sequence, and Decode(Input1) results in us getting here and exiting
1887 // without waiting, we might end up running Reset{,Done}Task() before 1889 // without waiting, we might end up running Reset{,Done}Task() before
1888 // AssignPictureBuffers is scheduled, thus cleaning up and pushing buffers 1890 // AssignPictureBuffers is scheduled, thus cleaning up and pushing buffers
1889 // to the free_output_buffers_ map twice. If we somehow marked buffers as 1891 // to the free_output_buffers_ map twice. If we somehow marked buffers as
1890 // not ready, we'd need special handling for restarting the second Decode 1892 // not ready, we'd need special handling for restarting the second Decode
1891 // task and delaying it anyway. 1893 // task and delaying it anyway.
1892 // Waiting here is not very costly and makes reasoning about different 1894 // Waiting here is not very costly and makes reasoning about different
1893 // situations much simpler. 1895 // situations much simpler.
1894 pictures_assigned_.Wait(); 1896 pictures_assigned_.Wait();
1895 1897
1896 Enqueue(); 1898 Enqueue();
1897 return true; 1899 return true;
1898 } 1900 }
1899 1901
1900 void V4L2VideoDecodeAccelerator::DestroyInputBuffers() { 1902 void V4L2VideoDecodeAccelerator::DestroyInputBuffers() {
1901 DVLOG(3) << "DestroyInputBuffers()"; 1903 DVLOG(3) << "DestroyInputBuffers()";
1902 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 1904 DCHECK(child_task_runner_->BelongsToCurrentThread());
1903 DCHECK(!input_streamon_); 1905 DCHECK(!input_streamon_);
1904 1906
1905 for (size_t i = 0; i < input_buffer_map_.size(); ++i) { 1907 for (size_t i = 0; i < input_buffer_map_.size(); ++i) {
1906 if (input_buffer_map_[i].address != NULL) { 1908 if (input_buffer_map_[i].address != NULL) {
1907 device_->Munmap(input_buffer_map_[i].address, 1909 device_->Munmap(input_buffer_map_[i].address,
1908 input_buffer_map_[i].length); 1910 input_buffer_map_[i].length);
1909 } 1911 }
1910 } 1912 }
1911 1913
1912 struct v4l2_requestbuffers reqbufs; 1914 struct v4l2_requestbuffers reqbufs;
1913 memset(&reqbufs, 0, sizeof(reqbufs)); 1915 memset(&reqbufs, 0, sizeof(reqbufs));
1914 reqbufs.count = 0; 1916 reqbufs.count = 0;
1915 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1917 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1916 reqbufs.memory = V4L2_MEMORY_MMAP; 1918 reqbufs.memory = V4L2_MEMORY_MMAP;
1917 IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs); 1919 IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs);
1918 1920
1919 input_buffer_map_.clear(); 1921 input_buffer_map_.clear();
1920 free_input_buffers_.clear(); 1922 free_input_buffers_.clear();
1921 } 1923 }
1922 1924
1923 bool V4L2VideoDecodeAccelerator::DestroyOutputBuffers() { 1925 bool V4L2VideoDecodeAccelerator::DestroyOutputBuffers() {
1924 DVLOG(3) << "DestroyOutputBuffers()"; 1926 DVLOG(3) << "DestroyOutputBuffers()";
1925 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 1927 DCHECK(child_task_runner_->BelongsToCurrentThread());
1926 DCHECK(!output_streamon_); 1928 DCHECK(!output_streamon_);
1927 bool success = true; 1929 bool success = true;
1928 1930
1929 for (size_t i = 0; i < output_buffer_map_.size(); ++i) { 1931 for (size_t i = 0; i < output_buffer_map_.size(); ++i) {
1930 OutputRecord& output_record = output_buffer_map_[i]; 1932 OutputRecord& output_record = output_buffer_map_[i];
1931 1933
1932 if (output_record.egl_image != EGL_NO_IMAGE_KHR) { 1934 if (output_record.egl_image != EGL_NO_IMAGE_KHR) {
1933 if (device_->DestroyEGLImage(egl_display_, output_record.egl_image) != 1935 if (device_->DestroyEGLImage(egl_display_, output_record.egl_image) !=
1934 EGL_TRUE) { 1936 EGL_TRUE) {
1935 DVLOG(1) << __func__ << " DestroyEGLImage failed."; 1937 DVLOG(1) << __func__ << " DestroyEGLImage failed.";
1936 success = false; 1938 success = false;
1937 } 1939 }
1938 } 1940 }
1939 1941
1940 if (output_record.egl_sync != EGL_NO_SYNC_KHR) { 1942 if (output_record.egl_sync != EGL_NO_SYNC_KHR) {
1941 if (eglDestroySyncKHR(egl_display_, output_record.egl_sync) != EGL_TRUE) { 1943 if (eglDestroySyncKHR(egl_display_, output_record.egl_sync) != EGL_TRUE) {
1942 DVLOG(1) << __func__ << " eglDestroySyncKHR failed."; 1944 DVLOG(1) << __func__ << " eglDestroySyncKHR failed.";
1943 success = false; 1945 success = false;
1944 } 1946 }
1945 } 1947 }
1946 1948
1947 DVLOG(1) << "DestroyOutputBuffers(): dismissing PictureBuffer id=" 1949 DVLOG(1) << "DestroyOutputBuffers(): dismissing PictureBuffer id="
1948 << output_record.picture_id; 1950 << output_record.picture_id;
1949 child_message_loop_proxy_->PostTask( 1951 child_task_runner_->PostTask(
1950 FROM_HERE, 1952 FROM_HERE, base::Bind(&Client::DismissPictureBuffer, client_,
1951 base::Bind( 1953 output_record.picture_id));
1952 &Client::DismissPictureBuffer, client_, output_record.picture_id));
1953 } 1954 }
1954 1955
1955 struct v4l2_requestbuffers reqbufs; 1956 struct v4l2_requestbuffers reqbufs;
1956 memset(&reqbufs, 0, sizeof(reqbufs)); 1957 memset(&reqbufs, 0, sizeof(reqbufs));
1957 reqbufs.count = 0; 1958 reqbufs.count = 0;
1958 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1959 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1959 reqbufs.memory = V4L2_MEMORY_MMAP; 1960 reqbufs.memory = V4L2_MEMORY_MMAP;
1960 if (device_->Ioctl(VIDIOC_REQBUFS, &reqbufs) != 0) { 1961 if (device_->Ioctl(VIDIOC_REQBUFS, &reqbufs) != 0) {
1961 PLOG(ERROR) << "DestroyOutputBuffers() ioctl() failed: VIDIOC_REQBUFS"; 1962 PLOG(ERROR) << "DestroyOutputBuffers() ioctl() failed: VIDIOC_REQBUFS";
1962 success = false; 1963 success = false;
1963 } 1964 }
1964 1965
1965 output_buffer_map_.clear(); 1966 output_buffer_map_.clear();
1966 while (!free_output_buffers_.empty()) 1967 while (!free_output_buffers_.empty())
1967 free_output_buffers_.pop(); 1968 free_output_buffers_.pop();
1968 1969
1969 return success; 1970 return success;
1970 } 1971 }
1971 1972
1972 void V4L2VideoDecodeAccelerator::ResolutionChangeDestroyBuffers() { 1973 void V4L2VideoDecodeAccelerator::ResolutionChangeDestroyBuffers() {
1973 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 1974 DCHECK(child_task_runner_->BelongsToCurrentThread());
1974 DVLOG(3) << "ResolutionChangeDestroyBuffers()"; 1975 DVLOG(3) << "ResolutionChangeDestroyBuffers()";
1975 1976
1976 if (!DestroyOutputBuffers()) { 1977 if (!DestroyOutputBuffers()) {
1977 LOG(ERROR) << __func__ << " Failed destroying output buffers."; 1978 LOG(ERROR) << __func__ << " Failed destroying output buffers.";
1978 NOTIFY_ERROR(PLATFORM_FAILURE); 1979 NOTIFY_ERROR(PLATFORM_FAILURE);
1979 return; 1980 return;
1980 } 1981 }
1981 1982
1982 // Finish resolution change on decoder thread. 1983 // Finish resolution change on decoder thread.
1983 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 1984 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
1984 &V4L2VideoDecodeAccelerator::FinishResolutionChange, 1985 &V4L2VideoDecodeAccelerator::FinishResolutionChange,
1985 base::Unretained(this))); 1986 base::Unretained(this)));
1986 } 1987 }
1987 1988
1988 void V4L2VideoDecodeAccelerator::SendPictureReady() { 1989 void V4L2VideoDecodeAccelerator::SendPictureReady() {
1989 DVLOG(3) << "SendPictureReady()"; 1990 DVLOG(3) << "SendPictureReady()";
1990 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1991 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1991 bool resetting_or_flushing = 1992 bool resetting_or_flushing =
1992 (decoder_state_ == kResetting || decoder_flushing_); 1993 (decoder_state_ == kResetting || decoder_flushing_);
1993 while (pending_picture_ready_.size() > 0) { 1994 while (pending_picture_ready_.size() > 0) {
1994 bool cleared = pending_picture_ready_.front().cleared; 1995 bool cleared = pending_picture_ready_.front().cleared;
1995 const media::Picture& picture = pending_picture_ready_.front().picture; 1996 const media::Picture& picture = pending_picture_ready_.front().picture;
1996 if (cleared && picture_clearing_count_ == 0) { 1997 if (cleared && picture_clearing_count_ == 0) {
1997 // This picture is cleared. Post it to IO thread to reduce latency. This 1998 // This picture is cleared. Post it to IO thread to reduce latency. This
1998 // should be the case after all pictures are cleared at the beginning. 1999 // should be the case after all pictures are cleared at the beginning.
1999 io_message_loop_proxy_->PostTask( 2000 io_task_runner_->PostTask(
2000 FROM_HERE, base::Bind(&Client::PictureReady, io_client_, picture)); 2001 FROM_HERE, base::Bind(&Client::PictureReady, io_client_, picture));
2001 pending_picture_ready_.pop(); 2002 pending_picture_ready_.pop();
2002 } else if (!cleared || resetting_or_flushing) { 2003 } else if (!cleared || resetting_or_flushing) {
2003 DVLOG(3) << "SendPictureReady()" 2004 DVLOG(3) << "SendPictureReady()"
2004 << ". cleared=" << pending_picture_ready_.front().cleared 2005 << ". cleared=" << pending_picture_ready_.front().cleared
2005 << ", decoder_state_=" << decoder_state_ 2006 << ", decoder_state_=" << decoder_state_
2006 << ", decoder_flushing_=" << decoder_flushing_ 2007 << ", decoder_flushing_=" << decoder_flushing_
2007 << ", picture_clearing_count_=" << picture_clearing_count_; 2008 << ", picture_clearing_count_=" << picture_clearing_count_;
2008 // If the picture is not cleared, post it to the child thread because it 2009 // If the picture is not cleared, post it to the child thread because it
2009 // has to be cleared in the child thread. A picture only needs to be 2010 // has to be cleared in the child thread. A picture only needs to be
2010 // cleared once. If the decoder is resetting or flushing, send all 2011 // cleared once. If the decoder is resetting or flushing, send all
2011 // pictures to ensure PictureReady arrive before reset or flush done. 2012 // pictures to ensure PictureReady arrive before reset or flush done.
2012 child_message_loop_proxy_->PostTaskAndReply( 2013 child_task_runner_->PostTaskAndReply(
2013 FROM_HERE, 2014 FROM_HERE, base::Bind(&Client::PictureReady, client_, picture),
2014 base::Bind(&Client::PictureReady, client_, picture),
2015 // Unretained is safe. If Client::PictureReady gets to run, |this| is 2015 // Unretained is safe. If Client::PictureReady gets to run, |this| is
2016 // alive. Destroy() will wait the decode thread to finish. 2016 // alive. Destroy() will wait the decode thread to finish.
2017 base::Bind(&V4L2VideoDecodeAccelerator::PictureCleared, 2017 base::Bind(&V4L2VideoDecodeAccelerator::PictureCleared,
2018 base::Unretained(this))); 2018 base::Unretained(this)));
2019 picture_clearing_count_++; 2019 picture_clearing_count_++;
2020 pending_picture_ready_.pop(); 2020 pending_picture_ready_.pop();
2021 } else { 2021 } else {
2022 // This picture is cleared. But some pictures are about to be cleared on 2022 // This picture is cleared. But some pictures are about to be cleared on
2023 // the child thread. To preserve the order, do not send this until those 2023 // the child thread. To preserve the order, do not send this until those
2024 // pictures are cleared. 2024 // pictures are cleared.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2057 gfx::Size new_coded_size(base::checked_cast<int>(format.fmt.pix_mp.width), 2057 gfx::Size new_coded_size(base::checked_cast<int>(format.fmt.pix_mp.width),
2058 base::checked_cast<int>(format.fmt.pix_mp.height)); 2058 base::checked_cast<int>(format.fmt.pix_mp.height));
2059 if (coded_size_ != new_coded_size) { 2059 if (coded_size_ != new_coded_size) {
2060 DVLOG(3) << "IsResolutionChangeNecessary(): Resolution change detected"; 2060 DVLOG(3) << "IsResolutionChangeNecessary(): Resolution change detected";
2061 return true; 2061 return true;
2062 } 2062 }
2063 return false; 2063 return false;
2064 } 2064 }
2065 2065
2066 } // namespace content 2066 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698