Index: content/common/gpu/client/gpu_video_decode_accelerator_host.cc |
diff --git a/content/common/gpu/client/gpu_video_decode_accelerator_host.cc b/content/common/gpu/client/gpu_video_decode_accelerator_host.cc |
index 1146258bac251799d8c2fddf66e1b270993e36a6..1da2709ae55284cd9c08027091155e8d82baad41 100644 |
--- a/content/common/gpu/client/gpu_video_decode_accelerator_host.cc |
+++ b/content/common/gpu/client/gpu_video_decode_accelerator_host.cc |
@@ -17,31 +17,33 @@ |
#include "content/public/common/sandbox_init.h" |
#endif // OS_WIN |
+#define NOTIFY_ERROR(error) \ |
+ PostNotifyError(error); \ |
+ DLOG(ERROR) |
+ |
using media::VideoDecodeAccelerator; |
namespace content { |
GpuVideoDecodeAcceleratorHost::GpuVideoDecodeAcceleratorHost( |
GpuChannelHost* channel, |
- int32 decoder_route_id, |
CommandBufferProxyImpl* impl) |
: channel_(channel), |
- decoder_route_id_(decoder_route_id), |
+ decoder_route_id_(-1), |
client_(NULL), |
- impl_(impl) { |
+ impl_(impl), |
+ weak_this_factory_(this) { |
DCHECK(channel_); |
- channel_->AddRoute(decoder_route_id, base::AsWeakPtr(this)); |
+ DCHECK(impl_); |
impl_->AddDeletionObserver(this); |
} |
-void GpuVideoDecodeAcceleratorHost::OnChannelError() { |
- DLOG(ERROR) << "GpuVideoDecodeAcceleratorHost::OnChannelError()"; |
- if (channel_) { |
+GpuVideoDecodeAcceleratorHost::~GpuVideoDecodeAcceleratorHost() { |
+ DCHECK(CalledOnValidThread()); |
+ |
+ if (channel_) |
channel_->RemoveRoute(decoder_route_id_); |
- channel_ = NULL; |
- } |
- // See OnErrorNotification for why this needs to be the last thing in this |
- // function. |
- OnErrorNotification(PLATFORM_FAILURE); |
+ if (impl_) |
+ impl_->RemoveDeletionObserver(this); |
} |
bool GpuVideoDecodeAcceleratorHost::OnMessageReceived(const IPC::Message& msg) { |
@@ -59,27 +61,49 @@ bool GpuVideoDecodeAcceleratorHost::OnMessageReceived(const IPC::Message& msg) { |
IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ResetDone, |
OnResetDone) |
IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ErrorNotification, |
- OnErrorNotification) |
+ OnNotifyError) |
IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_DismissPictureBuffer, |
OnDismissPictureBuffer) |
IPC_MESSAGE_UNHANDLED(handled = false) |
IPC_END_MESSAGE_MAP() |
DCHECK(handled); |
- // See OnErrorNotification for why |this| mustn't be used after |
- // OnErrorNotification might have been called above. |
+ // See OnNotifyError for why |this| mustn't be used after OnNotifyError might |
+ // have been called above. |
return handled; |
} |
+void GpuVideoDecodeAcceleratorHost::OnChannelError() { |
+ DCHECK(CalledOnValidThread()); |
+ if (channel_) { |
+ channel_->RemoveRoute(decoder_route_id_); |
+ channel_ = NULL; |
+ weak_this_factory_.InvalidateWeakPtrs(); |
+ } |
+ DLOG(ERROR) << "OnChannelError()"; |
Ami GONE FROM CHROMIUM
2014/03/18 23:53:19
ditto GVEAH
sheu
2014/03/19 20:38:24
Done.
|
+} |
+ |
bool GpuVideoDecodeAcceleratorHost::Initialize(media::VideoCodecProfile profile, |
Client* client) { |
+ DCHECK(CalledOnValidThread()); |
client_ = client; |
+ |
+ if (!impl_) |
+ return false; |
+ Send(new GpuCommandBufferMsg_CreateVideoDecoder( |
+ impl_->GetRouteID(), profile, &decoder_route_id_)); |
+ if (decoder_route_id_ < 0) { |
+ NOTIFY_ERROR(PLATFORM_FAILURE) |
+ << "Send(GpuCommandBufferMsg_CreateVideoDecoder()) failed"; |
+ return false; |
+ } |
+ |
+ channel_->AddRoute(decoder_route_id_, weak_this_factory_.GetWeakPtr()); |
return true; |
} |
void GpuVideoDecodeAcceleratorHost::Decode( |
const media::BitstreamBuffer& bitstream_buffer) { |
DCHECK(CalledOnValidThread()); |
- // Can happen if a decode task was posted before an error was delivered. |
if (!channel_) |
return; |
@@ -98,13 +122,17 @@ void GpuVideoDecodeAcceleratorHost::Decode( |
void GpuVideoDecodeAcceleratorHost::AssignPictureBuffers( |
const std::vector<media::PictureBuffer>& buffers) { |
DCHECK(CalledOnValidThread()); |
+ if (!channel_) |
+ return; |
// Rearrange data for IPC command. |
std::vector<int32> buffer_ids; |
std::vector<uint32> texture_ids; |
for (uint32 i = 0; i < buffers.size(); i++) { |
const media::PictureBuffer& buffer = buffers[i]; |
if (buffer.size() != picture_buffer_dimensions_) { |
- OnErrorNotification(INVALID_ARGUMENT); |
+ NOTIFY_ERROR(INVALID_ARGUMENT) << "buffer.size() invalid: expected " |
+ << picture_buffer_dimensions_.ToString() |
+ << ", got " << buffer.size().ToString(); |
return; |
} |
texture_ids.push_back(buffer.texture_id()); |
@@ -117,61 +145,57 @@ void GpuVideoDecodeAcceleratorHost::AssignPictureBuffers( |
void GpuVideoDecodeAcceleratorHost::ReusePictureBuffer( |
int32 picture_buffer_id) { |
DCHECK(CalledOnValidThread()); |
+ if (!channel_) |
+ return; |
Send(new AcceleratedVideoDecoderMsg_ReusePictureBuffer( |
decoder_route_id_, picture_buffer_id)); |
} |
void GpuVideoDecodeAcceleratorHost::Flush() { |
DCHECK(CalledOnValidThread()); |
+ if (!channel_) |
+ return; |
Send(new AcceleratedVideoDecoderMsg_Flush(decoder_route_id_)); |
} |
void GpuVideoDecodeAcceleratorHost::Reset() { |
DCHECK(CalledOnValidThread()); |
+ if (!channel_) |
+ return; |
Send(new AcceleratedVideoDecoderMsg_Reset(decoder_route_id_)); |
} |
void GpuVideoDecodeAcceleratorHost::Destroy() { |
DCHECK(CalledOnValidThread()); |
+ if (channel_) |
+ Send(new AcceleratedVideoDecoderMsg_Destroy(decoder_route_id_)); |
client_ = NULL; |
- Send(new AcceleratedVideoDecoderMsg_Destroy(decoder_route_id_)); |
delete this; |
} |
void GpuVideoDecodeAcceleratorHost::OnWillDeleteImpl() { |
+ DCHECK(CalledOnValidThread()); |
impl_ = NULL; |
// The CommandBufferProxyImpl is going away; error out this VDA. |
OnChannelError(); |
} |
-GpuVideoDecodeAcceleratorHost::~GpuVideoDecodeAcceleratorHost() { |
+void GpuVideoDecodeAcceleratorHost::PostNotifyError(Error error) { |
DCHECK(CalledOnValidThread()); |
- |
- if (channel_) |
- channel_->RemoveRoute(decoder_route_id_); |
- if (impl_) |
- impl_->RemoveDeletionObserver(this); |
+ DVLOG(2) << "PostNotifyError(): error=" << error; |
+ base::MessageLoopProxy::current()->PostTask( |
+ FROM_HERE, |
+ base::Bind(&GpuVideoDecodeAcceleratorHost::OnNotifyError, |
+ weak_this_factory_.GetWeakPtr(), |
+ error)); |
} |
void GpuVideoDecodeAcceleratorHost::Send(IPC::Message* message) { |
- // After OnChannelError is called, the client should no longer send |
- // messages to the gpu channel through this object. But queued posted tasks |
- // can still be draining, so we're forgiving and simply ignore them. |
- bool error = false; |
+ DCHECK(CalledOnValidThread()); |
uint32 message_type = message->type(); |
- if (!channel_) { |
- delete message; |
- DLOG(ERROR) << "Send(" << message_type << ") after error ignored"; |
- error = true; |
- } else if (!channel_->Send(message)) { |
- DLOG(ERROR) << "Send(" << message_type << ") failed"; |
- error = true; |
- } |
- // See OnErrorNotification for why this needs to be the last thing in this |
- // function. |
- if (error) |
- OnErrorNotification(PLATFORM_FAILURE); |
+ if (!channel_->Send(message)) |
+ NOTIFY_ERROR(PLATFORM_FAILURE) << "Send(" << message_type << ") failed"; |
} |
void GpuVideoDecodeAcceleratorHost::OnBitstreamBufferProcessed( |
@@ -221,7 +245,7 @@ void GpuVideoDecodeAcceleratorHost::OnResetDone() { |
client_->NotifyResetDone(); |
} |
-void GpuVideoDecodeAcceleratorHost::OnErrorNotification(uint32 error) { |
+void GpuVideoDecodeAcceleratorHost::OnNotifyError(uint32 error) { |
DCHECK(CalledOnValidThread()); |
if (!client_) |
return; |
@@ -230,8 +254,7 @@ void GpuVideoDecodeAcceleratorHost::OnErrorNotification(uint32 error) { |
// last thing done on this stack! |
media::VideoDecodeAccelerator::Client* client = NULL; |
std::swap(client, client_); |
- client->NotifyError( |
- static_cast<media::VideoDecodeAccelerator::Error>(error)); |
+ client->NotifyError(static_cast<media::VideoDecodeAccelerator::Error>(error)); |
} |
} // namespace content |