Index: content/common/gpu/media/v4l2_video_decode_accelerator.cc |
diff --git a/content/common/gpu/media/v4l2_video_decode_accelerator.cc b/content/common/gpu/media/v4l2_video_decode_accelerator.cc |
index 68baaa85c845c91dda916e544ddd9e15e27431a3..bbb51d4ea990ae2f6b6480a1494895f54ddc7125 100644 |
--- a/content/common/gpu/media/v4l2_video_decode_accelerator.cc |
+++ b/content/common/gpu/media/v4l2_video_decode_accelerator.cc |
@@ -282,6 +282,11 @@ bool V4L2VideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, |
decoder_h264_parser_.reset(new media::H264Parser()); |
} |
+ if (!StartDevicePoll()) { |
+ NOTIFY_ERROR(PLATFORM_FAILURE); |
+ return false; |
+ } |
+ |
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.
|
if (!decoder_thread_.Start()) { |
DLOG(ERROR) << "Initialize(): decoder thread failed to start"; |
NOTIFY_ERROR(PLATFORM_FAILURE); |
@@ -709,7 +714,6 @@ bool V4L2VideoDecodeAccelerator::DecodeBufferInitial( |
DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
DCHECK_NE(decoder_state_, kUninitialized); |
DCHECK_NE(decoder_state_, kDecoding); |
- DCHECK(!device_poll_thread_.IsRunning()); |
// Initial decode. We haven't been able to get output stream format info yet. |
// Get it, and start decoding. |
@@ -755,10 +759,6 @@ bool V4L2VideoDecodeAccelerator::DecodeBufferInitial( |
*endpos = size; |
} |
- // StartDevicePoll will raise the error if there is one. |
- if (!StartDevicePoll()) |
- return false; |
- |
decoder_state_ = kDecoding; |
ScheduleDecodeBufferTaskIfNeeded(); |
return true; |
@@ -885,8 +885,6 @@ void V4L2VideoDecodeAccelerator::ServiceDeviceTask(bool event_pending) { |
DVLOG(3) << "ServiceDeviceTask()"; |
DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
DCHECK_NE(decoder_state_, kUninitialized); |
- DCHECK_NE(decoder_state_, kInitialized); |
- DCHECK_NE(decoder_state_, kAfterReset); |
TRACE_EVENT0("Video Decoder", "V4L2VDA::ServiceDeviceTask"); |
if (decoder_state_ == kResetting) { |
@@ -1284,11 +1282,15 @@ void V4L2VideoDecodeAccelerator::NotifyFlushDoneIfNeeded() { |
// transitioning to next chunk. |
// For now, do the streamoff-streamon cycle to satisfy Exynos and not freeze |
// when doing MSE. This should be harmless otherwise. |
- if (!StopDevicePoll(false)) |
+ if (!StopDevicePoll(false)) { |
+ NOTIFY_ERROR(PLATFORM_FAILURE); |
return; |
+ } |
- if (!StartDevicePoll()) |
+ if (!StartDevicePoll()) { |
+ NOTIFY_ERROR(PLATFORM_FAILURE); |
return; |
+ } |
decoder_delay_bitstream_buffer_id_ = -1; |
decoder_flushing_ = false; |
@@ -1322,8 +1324,10 @@ void V4L2VideoDecodeAccelerator::ResetTask() { |
// We stop streaming and clear buffer tracking info (not preserving inputs). |
// StopDevicePoll() unconditionally does _not_ destroy buffers, however. |
- if (!StopDevicePoll(false)) |
+ if (!StopDevicePoll(false)) { |
+ NOTIFY_ERROR(PLATFORM_FAILURE); |
return; |
+ } |
decoder_current_bitstream_buffer_.reset(); |
while (!decoder_input_queue_.empty()) |
@@ -1353,6 +1357,11 @@ void V4L2VideoDecodeAccelerator::ResetDoneTask() { |
return; |
} |
+ if (!StartDevicePoll()) { |
+ NOTIFY_ERROR(PLATFORM_FAILURE); |
+ return; |
+ } |
+ |
// We might have received a resolution change event while we were waiting |
// for the reset to finish. The codec will not post another event if the |
// resolution after reset remains the same as the one to which were just |
@@ -1407,13 +1416,13 @@ void V4L2VideoDecodeAccelerator::DestroyTask() { |
bool V4L2VideoDecodeAccelerator::StartDevicePoll() { |
DVLOG(3) << "StartDevicePoll()"; |
- DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
DCHECK(!device_poll_thread_.IsRunning()); |
+ if (decoder_thread_.IsRunning()) |
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
// Start up the device poll thread and schedule its first DevicePollTask(). |
if (!device_poll_thread_.Start()) { |
DLOG(ERROR) << "StartDevicePoll(): Device thread failed to start"; |
- 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
|
return false; |
} |
device_poll_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
@@ -1432,13 +1441,11 @@ bool V4L2VideoDecodeAccelerator::StopDevicePoll(bool keep_input_state) { |
// Signal the DevicePollTask() to stop, and stop the device poll thread. |
if (!device_->SetDevicePollInterrupt()) { |
DPLOG(ERROR) << "SetDevicePollInterrupt(): failed"; |
- NOTIFY_ERROR(PLATFORM_FAILURE); |
return false; |
} |
device_poll_thread_.Stop(); |
// Clear the interrupt now, to be sure. |
if (!device_->ClearDevicePollInterrupt()) { |
- NOTIFY_ERROR(PLATFORM_FAILURE); |
return false; |
} |
@@ -1495,7 +1502,8 @@ bool V4L2VideoDecodeAccelerator::StopDevicePoll(bool keep_input_state) { |
void V4L2VideoDecodeAccelerator::StartResolutionChangeIfNeeded() { |
DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
- DCHECK_EQ(decoder_state_, kDecoding); |
+ DCHECK_NE(decoder_state_, kUninitialized); |
+ DCHECK_NE(decoder_state_, kResetting); |
if (!resolution_change_pending_) |
return; |
@@ -1503,8 +1511,10 @@ void V4L2VideoDecodeAccelerator::StartResolutionChangeIfNeeded() { |
DVLOG(3) << "No more work, initiate resolution change"; |
// Keep input queue. |
- if (!StopDevicePoll(true)) |
+ if (!StopDevicePoll(true)) { |
+ NOTIFY_ERROR(PLATFORM_FAILURE); |
return; |
+ } |
decoder_state_ = kChangingResolution; |
DCHECK(resolution_change_pending_); |
@@ -1550,8 +1560,10 @@ void V4L2VideoDecodeAccelerator::FinishResolutionChange() { |
return; |
} |
- if (!StartDevicePoll()) |
+ if (!StartDevicePoll()) { |
+ NOTIFY_ERROR(PLATFORM_FAILURE); |
return; |
+ } |
Enqueue(); |
ScheduleDecodeBufferTaskIfNeeded(); |