Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 <libdrm/drm_fourcc.h> | 8 #include <libdrm/drm_fourcc.h> |
| 9 #include <linux/videodev2.h> | 9 #include <linux/videodev2.h> |
| 10 #include <poll.h> | 10 #include <poll.h> |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 275 memset(&sub, 0, sizeof(sub)); | 275 memset(&sub, 0, sizeof(sub)); |
| 276 sub.type = V4L2_EVENT_RESOLUTION_CHANGE; | 276 sub.type = V4L2_EVENT_RESOLUTION_CHANGE; |
| 277 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_SUBSCRIBE_EVENT, &sub); | 277 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_SUBSCRIBE_EVENT, &sub); |
| 278 | 278 |
| 279 // Initialize format-specific bits. | 279 // Initialize format-specific bits. |
| 280 if (video_profile_ >= media::H264PROFILE_MIN && | 280 if (video_profile_ >= media::H264PROFILE_MIN && |
| 281 video_profile_ <= media::H264PROFILE_MAX) { | 281 video_profile_ <= media::H264PROFILE_MAX) { |
| 282 decoder_h264_parser_.reset(new media::H264Parser()); | 282 decoder_h264_parser_.reset(new media::H264Parser()); |
| 283 } | 283 } |
| 284 | 284 |
| 285 if (!StartDevicePoll()) { | |
| 286 NOTIFY_ERROR(PLATFORM_FAILURE); | |
| 287 return false; | |
| 288 } | |
| 289 | |
|
shivdasp
2014/03/12 12:12:27
It seems there is a race condition here. The Devic
sheu
2014/03/12 20:51:21
You're completely correct here. Thanks. Fixed.
| |
| 285 if (!decoder_thread_.Start()) { | 290 if (!decoder_thread_.Start()) { |
| 286 DLOG(ERROR) << "Initialize(): decoder thread failed to start"; | 291 DLOG(ERROR) << "Initialize(): decoder thread failed to start"; |
| 287 NOTIFY_ERROR(PLATFORM_FAILURE); | 292 NOTIFY_ERROR(PLATFORM_FAILURE); |
| 288 return false; | 293 return false; |
| 289 } | 294 } |
| 290 | 295 |
| 291 SetDecoderState(kInitialized); | 296 SetDecoderState(kInitialized); |
| 292 | 297 |
| 293 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 298 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
| 294 &Client::NotifyInitializeDone, client_)); | 299 &Client::NotifyInitializeDone, client_)); |
| (...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 702 base::Unretained(this))); | 707 base::Unretained(this))); |
| 703 } | 708 } |
| 704 } | 709 } |
| 705 | 710 |
| 706 bool V4L2VideoDecodeAccelerator::DecodeBufferInitial( | 711 bool V4L2VideoDecodeAccelerator::DecodeBufferInitial( |
| 707 const void* data, size_t size, size_t* endpos) { | 712 const void* data, size_t size, size_t* endpos) { |
| 708 DVLOG(3) << "DecodeBufferInitial(): data=" << data << ", size=" << size; | 713 DVLOG(3) << "DecodeBufferInitial(): data=" << data << ", size=" << size; |
| 709 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 714 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
| 710 DCHECK_NE(decoder_state_, kUninitialized); | 715 DCHECK_NE(decoder_state_, kUninitialized); |
| 711 DCHECK_NE(decoder_state_, kDecoding); | 716 DCHECK_NE(decoder_state_, kDecoding); |
| 712 DCHECK(!device_poll_thread_.IsRunning()); | |
| 713 // Initial decode. We haven't been able to get output stream format info yet. | 717 // Initial decode. We haven't been able to get output stream format info yet. |
| 714 // Get it, and start decoding. | 718 // Get it, and start decoding. |
| 715 | 719 |
| 716 // Copy in and send to HW. | 720 // Copy in and send to HW. |
| 717 if (!AppendToInputFrame(data, size)) | 721 if (!AppendToInputFrame(data, size)) |
| 718 return false; | 722 return false; |
| 719 | 723 |
| 720 // If we only have a partial frame, don't flush and process yet. | 724 // If we only have a partial frame, don't flush and process yet. |
| 721 if (decoder_partial_frame_pending_) | 725 if (decoder_partial_frame_pending_) |
| 722 return true; | 726 return true; |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 748 | 752 |
| 749 // We expect to process the initial buffer once during stream init to | 753 // We expect to process the initial buffer once during stream init to |
| 750 // configure stream parameters, but will not consume the steam data on that | 754 // configure stream parameters, but will not consume the steam data on that |
| 751 // iteration. Subsequent iterations (including after reset) do not require | 755 // iteration. Subsequent iterations (including after reset) do not require |
| 752 // the stream init step. | 756 // the stream init step. |
| 753 *endpos = 0; | 757 *endpos = 0; |
| 754 } else { | 758 } else { |
| 755 *endpos = size; | 759 *endpos = size; |
| 756 } | 760 } |
| 757 | 761 |
| 758 // StartDevicePoll will raise the error if there is one. | |
| 759 if (!StartDevicePoll()) | |
| 760 return false; | |
| 761 | |
| 762 decoder_state_ = kDecoding; | 762 decoder_state_ = kDecoding; |
| 763 ScheduleDecodeBufferTaskIfNeeded(); | 763 ScheduleDecodeBufferTaskIfNeeded(); |
| 764 return true; | 764 return true; |
| 765 } | 765 } |
| 766 | 766 |
| 767 bool V4L2VideoDecodeAccelerator::DecodeBufferContinue( | 767 bool V4L2VideoDecodeAccelerator::DecodeBufferContinue( |
| 768 const void* data, size_t size) { | 768 const void* data, size_t size) { |
| 769 DVLOG(3) << "DecodeBufferContinue(): data=" << data << ", size=" << size; | 769 DVLOG(3) << "DecodeBufferContinue(): data=" << data << ", size=" << size; |
| 770 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 770 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
| 771 DCHECK_EQ(decoder_state_, kDecoding); | 771 DCHECK_EQ(decoder_state_, kDecoding); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 878 // Enqueue once since there's new available input for it. | 878 // Enqueue once since there's new available input for it. |
| 879 Enqueue(); | 879 Enqueue(); |
| 880 | 880 |
| 881 return (decoder_state_ != kError); | 881 return (decoder_state_ != kError); |
| 882 } | 882 } |
| 883 | 883 |
| 884 void V4L2VideoDecodeAccelerator::ServiceDeviceTask(bool event_pending) { | 884 void V4L2VideoDecodeAccelerator::ServiceDeviceTask(bool event_pending) { |
| 885 DVLOG(3) << "ServiceDeviceTask()"; | 885 DVLOG(3) << "ServiceDeviceTask()"; |
| 886 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 886 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
| 887 DCHECK_NE(decoder_state_, kUninitialized); | 887 DCHECK_NE(decoder_state_, kUninitialized); |
| 888 DCHECK_NE(decoder_state_, kInitialized); | |
| 889 DCHECK_NE(decoder_state_, kAfterReset); | |
| 890 TRACE_EVENT0("Video Decoder", "V4L2VDA::ServiceDeviceTask"); | 888 TRACE_EVENT0("Video Decoder", "V4L2VDA::ServiceDeviceTask"); |
| 891 | 889 |
| 892 if (decoder_state_ == kResetting) { | 890 if (decoder_state_ == kResetting) { |
| 893 DVLOG(2) << "ServiceDeviceTask(): early out: kResetting state"; | 891 DVLOG(2) << "ServiceDeviceTask(): early out: kResetting state"; |
| 894 return; | 892 return; |
| 895 } else if (decoder_state_ == kError) { | 893 } else if (decoder_state_ == kError) { |
| 896 DVLOG(2) << "ServiceDeviceTask(): early out: kError state"; | 894 DVLOG(2) << "ServiceDeviceTask(): early out: kError state"; |
| 897 return; | 895 return; |
| 898 } else if (decoder_state_ == kChangingResolution) { | 896 } else if (decoder_state_ == kChangingResolution) { |
| 899 DVLOG(2) << "ServiceDeviceTask(): early out: kChangingResolution state"; | 897 DVLOG(2) << "ServiceDeviceTask(): early out: kChangingResolution state"; |
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1277 | 1275 |
| 1278 // TODO(posciak): crbug.com/270039. Exynos requires a streamoff-streamon | 1276 // TODO(posciak): crbug.com/270039. Exynos requires a streamoff-streamon |
| 1279 // sequence after flush to continue, even if we are not resetting. This would | 1277 // sequence after flush to continue, even if we are not resetting. This would |
| 1280 // make sense, because we don't really want to resume from a non-resume point | 1278 // make sense, because we don't really want to resume from a non-resume point |
| 1281 // (e.g. not from an IDR) if we are flushed. | 1279 // (e.g. not from an IDR) if we are flushed. |
| 1282 // MSE player however triggers a Flush() on chunk end, but never Reset(). One | 1280 // MSE player however triggers a Flush() on chunk end, but never Reset(). One |
| 1283 // could argue either way, or even say that Flush() is not needed/harmful when | 1281 // could argue either way, or even say that Flush() is not needed/harmful when |
| 1284 // transitioning to next chunk. | 1282 // transitioning to next chunk. |
| 1285 // For now, do the streamoff-streamon cycle to satisfy Exynos and not freeze | 1283 // For now, do the streamoff-streamon cycle to satisfy Exynos and not freeze |
| 1286 // when doing MSE. This should be harmless otherwise. | 1284 // when doing MSE. This should be harmless otherwise. |
| 1287 if (!StopDevicePoll(false)) | 1285 if (!StopDevicePoll(false)) { |
| 1286 NOTIFY_ERROR(PLATFORM_FAILURE); | |
| 1288 return; | 1287 return; |
| 1288 } | |
| 1289 | 1289 |
| 1290 if (!StartDevicePoll()) | 1290 if (!StartDevicePoll()) { |
| 1291 NOTIFY_ERROR(PLATFORM_FAILURE); | |
| 1291 return; | 1292 return; |
| 1293 } | |
| 1292 | 1294 |
| 1293 decoder_delay_bitstream_buffer_id_ = -1; | 1295 decoder_delay_bitstream_buffer_id_ = -1; |
| 1294 decoder_flushing_ = false; | 1296 decoder_flushing_ = false; |
| 1295 DVLOG(3) << "NotifyFlushDoneIfNeeded(): returning flush"; | 1297 DVLOG(3) << "NotifyFlushDoneIfNeeded(): returning flush"; |
| 1296 child_message_loop_proxy_->PostTask( | 1298 child_message_loop_proxy_->PostTask( |
| 1297 FROM_HERE, base::Bind(&Client::NotifyFlushDone, client_)); | 1299 FROM_HERE, base::Bind(&Client::NotifyFlushDone, client_)); |
| 1298 | 1300 |
| 1299 // While we were flushing, we early-outed DecodeBufferTask()s. | 1301 // While we were flushing, we early-outed DecodeBufferTask()s. |
| 1300 ScheduleDecodeBufferTaskIfNeeded(); | 1302 ScheduleDecodeBufferTaskIfNeeded(); |
| 1301 } | 1303 } |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1315 // because input pipe is already stopped if we are changing resolution. | 1317 // because input pipe is already stopped if we are changing resolution. |
| 1316 // We will come back here after we are done with the resolution change. | 1318 // We will come back here after we are done with the resolution change. |
| 1317 DCHECK(!resolution_change_reset_pending_); | 1319 DCHECK(!resolution_change_reset_pending_); |
| 1318 if (resolution_change_pending_ || decoder_state_ == kChangingResolution) { | 1320 if (resolution_change_pending_ || decoder_state_ == kChangingResolution) { |
| 1319 resolution_change_reset_pending_ = true; | 1321 resolution_change_reset_pending_ = true; |
| 1320 return; | 1322 return; |
| 1321 } | 1323 } |
| 1322 | 1324 |
| 1323 // We stop streaming and clear buffer tracking info (not preserving inputs). | 1325 // We stop streaming and clear buffer tracking info (not preserving inputs). |
| 1324 // StopDevicePoll() unconditionally does _not_ destroy buffers, however. | 1326 // StopDevicePoll() unconditionally does _not_ destroy buffers, however. |
| 1325 if (!StopDevicePoll(false)) | 1327 if (!StopDevicePoll(false)) { |
| 1328 NOTIFY_ERROR(PLATFORM_FAILURE); | |
| 1326 return; | 1329 return; |
| 1330 } | |
| 1327 | 1331 |
| 1328 decoder_current_bitstream_buffer_.reset(); | 1332 decoder_current_bitstream_buffer_.reset(); |
| 1329 while (!decoder_input_queue_.empty()) | 1333 while (!decoder_input_queue_.empty()) |
| 1330 decoder_input_queue_.pop(); | 1334 decoder_input_queue_.pop(); |
| 1331 | 1335 |
| 1332 decoder_current_input_buffer_ = -1; | 1336 decoder_current_input_buffer_ = -1; |
| 1333 | 1337 |
| 1334 // If we were flushing, we'll never return any more BitstreamBuffers or | 1338 // If we were flushing, we'll never return any more BitstreamBuffers or |
| 1335 // PictureBuffers; they have all been dropped and returned by now. | 1339 // PictureBuffers; they have all been dropped and returned by now. |
| 1336 NotifyFlushDoneIfNeeded(); | 1340 NotifyFlushDoneIfNeeded(); |
| 1337 | 1341 |
| 1338 // Mark that we're resetting, then enqueue a ResetDoneTask(). All intervening | 1342 // Mark that we're resetting, then enqueue a ResetDoneTask(). All intervening |
| 1339 // jobs will early-out in the kResetting state. | 1343 // jobs will early-out in the kResetting state. |
| 1340 decoder_state_ = kResetting; | 1344 decoder_state_ = kResetting; |
| 1341 SendPictureReady(); // Send all pending PictureReady. | 1345 SendPictureReady(); // Send all pending PictureReady. |
| 1342 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 1346 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
| 1343 &V4L2VideoDecodeAccelerator::ResetDoneTask, base::Unretained(this))); | 1347 &V4L2VideoDecodeAccelerator::ResetDoneTask, base::Unretained(this))); |
| 1344 } | 1348 } |
| 1345 | 1349 |
| 1346 void V4L2VideoDecodeAccelerator::ResetDoneTask() { | 1350 void V4L2VideoDecodeAccelerator::ResetDoneTask() { |
| 1347 DVLOG(3) << "ResetDoneTask()"; | 1351 DVLOG(3) << "ResetDoneTask()"; |
| 1348 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1352 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
| 1349 TRACE_EVENT0("Video Decoder", "V4L2VDA::ResetDoneTask"); | 1353 TRACE_EVENT0("Video Decoder", "V4L2VDA::ResetDoneTask"); |
| 1350 | 1354 |
| 1351 if (decoder_state_ == kError) { | 1355 if (decoder_state_ == kError) { |
| 1352 DVLOG(2) << "ResetDoneTask(): early out: kError state"; | 1356 DVLOG(2) << "ResetDoneTask(): early out: kError state"; |
| 1353 return; | 1357 return; |
| 1354 } | 1358 } |
| 1355 | 1359 |
| 1360 if (!StartDevicePoll()) { | |
| 1361 NOTIFY_ERROR(PLATFORM_FAILURE); | |
| 1362 return; | |
| 1363 } | |
| 1364 | |
| 1356 // We might have received a resolution change event while we were waiting | 1365 // We might have received a resolution change event while we were waiting |
| 1357 // for the reset to finish. The codec will not post another event if the | 1366 // for the reset to finish. The codec will not post another event if the |
| 1358 // resolution after reset remains the same as the one to which were just | 1367 // resolution after reset remains the same as the one to which were just |
| 1359 // about to switch, so preserve the event across reset so we can address | 1368 // about to switch, so preserve the event across reset so we can address |
| 1360 // it after resuming. | 1369 // it after resuming. |
| 1361 | 1370 |
| 1362 // Reset format-specific bits. | 1371 // Reset format-specific bits. |
| 1363 if (video_profile_ >= media::H264PROFILE_MIN && | 1372 if (video_profile_ >= media::H264PROFILE_MIN && |
| 1364 video_profile_ <= media::H264PROFILE_MAX) { | 1373 video_profile_ <= media::H264PROFILE_MAX) { |
| 1365 decoder_h264_parser_.reset(new media::H264Parser()); | 1374 decoder_h264_parser_.reset(new media::H264Parser()); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1400 while (!decoder_input_queue_.empty()) | 1409 while (!decoder_input_queue_.empty()) |
| 1401 decoder_input_queue_.pop(); | 1410 decoder_input_queue_.pop(); |
| 1402 decoder_flushing_ = false; | 1411 decoder_flushing_ = false; |
| 1403 | 1412 |
| 1404 // Set our state to kError. Just in case. | 1413 // Set our state to kError. Just in case. |
| 1405 decoder_state_ = kError; | 1414 decoder_state_ = kError; |
| 1406 } | 1415 } |
| 1407 | 1416 |
| 1408 bool V4L2VideoDecodeAccelerator::StartDevicePoll() { | 1417 bool V4L2VideoDecodeAccelerator::StartDevicePoll() { |
| 1409 DVLOG(3) << "StartDevicePoll()"; | 1418 DVLOG(3) << "StartDevicePoll()"; |
| 1410 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | |
| 1411 DCHECK(!device_poll_thread_.IsRunning()); | 1419 DCHECK(!device_poll_thread_.IsRunning()); |
| 1420 if (decoder_thread_.IsRunning()) | |
| 1421 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | |
| 1412 | 1422 |
| 1413 // Start up the device poll thread and schedule its first DevicePollTask(). | 1423 // Start up the device poll thread and schedule its first DevicePollTask(). |
| 1414 if (!device_poll_thread_.Start()) { | 1424 if (!device_poll_thread_.Start()) { |
| 1415 DLOG(ERROR) << "StartDevicePoll(): Device thread failed to start"; | 1425 DLOG(ERROR) << "StartDevicePoll(): Device thread failed to start"; |
| 1416 NOTIFY_ERROR(PLATFORM_FAILURE); | |
|
Pawel Osciak
2014/03/09 02:34:50
Could you instead just:
if (state != kUninitializ
sheu
2014/03/10 19:38:42
Not sure what you mean here. We should error out
Pawel Osciak
2014/03/11 00:07:44
Sorry, should have been more precise. The issue he
sheu
2014/03/12 20:51:21
I'd be more inclined to check in the macro, but ev
| |
| 1417 return false; | 1426 return false; |
| 1418 } | 1427 } |
| 1419 device_poll_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 1428 device_poll_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
| 1420 &V4L2VideoDecodeAccelerator::DevicePollTask, | 1429 &V4L2VideoDecodeAccelerator::DevicePollTask, |
| 1421 base::Unretained(this), | 1430 base::Unretained(this), |
| 1422 0)); | 1431 0)); |
| 1423 | 1432 |
| 1424 return true; | 1433 return true; |
| 1425 } | 1434 } |
| 1426 | 1435 |
| 1427 bool V4L2VideoDecodeAccelerator::StopDevicePoll(bool keep_input_state) { | 1436 bool V4L2VideoDecodeAccelerator::StopDevicePoll(bool keep_input_state) { |
| 1428 DVLOG(3) << "StopDevicePoll()"; | 1437 DVLOG(3) << "StopDevicePoll()"; |
| 1429 if (decoder_thread_.IsRunning()) | 1438 if (decoder_thread_.IsRunning()) |
| 1430 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1439 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
| 1431 | 1440 |
| 1432 // Signal the DevicePollTask() to stop, and stop the device poll thread. | 1441 // Signal the DevicePollTask() to stop, and stop the device poll thread. |
| 1433 if (!device_->SetDevicePollInterrupt()) { | 1442 if (!device_->SetDevicePollInterrupt()) { |
| 1434 DPLOG(ERROR) << "SetDevicePollInterrupt(): failed"; | 1443 DPLOG(ERROR) << "SetDevicePollInterrupt(): failed"; |
| 1435 NOTIFY_ERROR(PLATFORM_FAILURE); | |
| 1436 return false; | 1444 return false; |
| 1437 } | 1445 } |
| 1438 device_poll_thread_.Stop(); | 1446 device_poll_thread_.Stop(); |
| 1439 // Clear the interrupt now, to be sure. | 1447 // Clear the interrupt now, to be sure. |
| 1440 if (!device_->ClearDevicePollInterrupt()) { | 1448 if (!device_->ClearDevicePollInterrupt()) { |
| 1441 NOTIFY_ERROR(PLATFORM_FAILURE); | |
| 1442 return false; | 1449 return false; |
| 1443 } | 1450 } |
| 1444 | 1451 |
| 1445 // Stop streaming. | 1452 // Stop streaming. |
| 1446 if (!keep_input_state) { | 1453 if (!keep_input_state) { |
| 1447 if (input_streamon_) { | 1454 if (input_streamon_) { |
| 1448 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; | 1455 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; |
| 1449 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_STREAMOFF, &type); | 1456 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_STREAMOFF, &type); |
| 1450 } | 1457 } |
| 1451 input_streamon_ = false; | 1458 input_streamon_ = false; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1488 } | 1495 } |
| 1489 } | 1496 } |
| 1490 output_buffer_queued_count_ = 0; | 1497 output_buffer_queued_count_ = 0; |
| 1491 | 1498 |
| 1492 DVLOG(3) << "StopDevicePoll(): device poll stopped"; | 1499 DVLOG(3) << "StopDevicePoll(): device poll stopped"; |
| 1493 return true; | 1500 return true; |
| 1494 } | 1501 } |
| 1495 | 1502 |
| 1496 void V4L2VideoDecodeAccelerator::StartResolutionChangeIfNeeded() { | 1503 void V4L2VideoDecodeAccelerator::StartResolutionChangeIfNeeded() { |
| 1497 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1504 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
| 1498 DCHECK_EQ(decoder_state_, kDecoding); | 1505 DCHECK_NE(decoder_state_, kUninitialized); |
| 1506 DCHECK_NE(decoder_state_, kResetting); | |
| 1499 | 1507 |
| 1500 if (!resolution_change_pending_) | 1508 if (!resolution_change_pending_) |
| 1501 return; | 1509 return; |
| 1502 | 1510 |
| 1503 DVLOG(3) << "No more work, initiate resolution change"; | 1511 DVLOG(3) << "No more work, initiate resolution change"; |
| 1504 | 1512 |
| 1505 // Keep input queue. | 1513 // Keep input queue. |
| 1506 if (!StopDevicePoll(true)) | 1514 if (!StopDevicePoll(true)) { |
| 1515 NOTIFY_ERROR(PLATFORM_FAILURE); | |
| 1507 return; | 1516 return; |
| 1517 } | |
| 1508 | 1518 |
| 1509 decoder_state_ = kChangingResolution; | 1519 decoder_state_ = kChangingResolution; |
| 1510 DCHECK(resolution_change_pending_); | 1520 DCHECK(resolution_change_pending_); |
| 1511 resolution_change_pending_ = false; | 1521 resolution_change_pending_ = false; |
| 1512 | 1522 |
| 1513 // Post a task to clean up buffers on child thread. This will also ensure | 1523 // Post a task to clean up buffers on child thread. This will also ensure |
| 1514 // that we won't accept ReusePictureBuffer() anymore after that. | 1524 // that we won't accept ReusePictureBuffer() anymore after that. |
| 1515 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 1525 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
| 1516 &V4L2VideoDecodeAccelerator::ResolutionChangeDestroyBuffers, | 1526 &V4L2VideoDecodeAccelerator::ResolutionChangeDestroyBuffers, |
| 1517 weak_this_)); | 1527 weak_this_)); |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 1543 } | 1553 } |
| 1544 | 1554 |
| 1545 decoder_state_ = kDecoding; | 1555 decoder_state_ = kDecoding; |
| 1546 | 1556 |
| 1547 if (resolution_change_reset_pending_) { | 1557 if (resolution_change_reset_pending_) { |
| 1548 resolution_change_reset_pending_ = false; | 1558 resolution_change_reset_pending_ = false; |
| 1549 ResetTask(); | 1559 ResetTask(); |
| 1550 return; | 1560 return; |
| 1551 } | 1561 } |
| 1552 | 1562 |
| 1553 if (!StartDevicePoll()) | 1563 if (!StartDevicePoll()) { |
| 1564 NOTIFY_ERROR(PLATFORM_FAILURE); | |
| 1554 return; | 1565 return; |
| 1566 } | |
| 1555 | 1567 |
| 1556 Enqueue(); | 1568 Enqueue(); |
| 1557 ScheduleDecodeBufferTaskIfNeeded(); | 1569 ScheduleDecodeBufferTaskIfNeeded(); |
| 1558 } | 1570 } |
| 1559 | 1571 |
| 1560 void V4L2VideoDecodeAccelerator::DevicePollTask(bool poll_device) { | 1572 void V4L2VideoDecodeAccelerator::DevicePollTask(bool poll_device) { |
| 1561 DVLOG(3) << "DevicePollTask()"; | 1573 DVLOG(3) << "DevicePollTask()"; |
| 1562 DCHECK_EQ(device_poll_thread_.message_loop(), base::MessageLoop::current()); | 1574 DCHECK_EQ(device_poll_thread_.message_loop(), base::MessageLoop::current()); |
| 1563 TRACE_EVENT0("Video Decoder", "V4L2VDA::DevicePollTask"); | 1575 TRACE_EVENT0("Video Decoder", "V4L2VDA::DevicePollTask"); |
| 1564 | 1576 |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1919 | 1931 |
| 1920 void V4L2VideoDecodeAccelerator::PictureCleared() { | 1932 void V4L2VideoDecodeAccelerator::PictureCleared() { |
| 1921 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_; | 1933 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_; |
| 1922 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1934 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
| 1923 DCHECK_GT(picture_clearing_count_, 0); | 1935 DCHECK_GT(picture_clearing_count_, 0); |
| 1924 picture_clearing_count_--; | 1936 picture_clearing_count_--; |
| 1925 SendPictureReady(); | 1937 SendPictureReady(); |
| 1926 } | 1938 } |
| 1927 | 1939 |
| 1928 } // namespace content | 1940 } // namespace content |
| OLD | NEW |