15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/client/gpu_video_decode_accelerator_host.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
99ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/client/gpu_channel_host.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_messages.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/view_messages.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message_macros.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message_utils.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/sandbox_init.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // OS_WIN
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using media::VideoDecodeAccelerator;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuVideoDecodeAcceleratorHost::GpuVideoDecodeAcceleratorHost(
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GpuChannelHost* channel,
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CommandBufferProxyImpl* impl)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : channel_(channel),
27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      decoder_route_id_(MSG_ROUTING_NONE),
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      client_(NULL),
29c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      impl_(impl),
30c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      weak_this_factory_(this) {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(channel_);
32c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(impl_);
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  impl_->AddDeletionObserver(this);
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochGpuVideoDecodeAcceleratorHost::~GpuVideoDecodeAcceleratorHost() {
37c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(CalledOnValidThread());
38c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
39c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (channel_ && decoder_route_id_ != MSG_ROUTING_NONE)
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    channel_->RemoveRoute(decoder_route_id_);
41c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (impl_)
42c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    impl_->RemoveDeletionObserver(this);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuVideoDecodeAcceleratorHost::OnMessageReceived(const IPC::Message& msg) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handled = true;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAcceleratorHost, msg)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnBitstreamBufferProcessed)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnProvidePictureBuffer)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_PictureReady,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnPictureReady)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_FlushDone,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnFlushDone)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ResetDone,
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnResetDone)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ErrorNotification,
60c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                        OnNotifyError)
61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_DismissPictureBuffer,
62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                        OnDismissPictureBuffer)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(handled);
66c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // See OnNotifyError for why |this| mustn't be used after OnNotifyError might
67c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // have been called above.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return handled;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid GpuVideoDecodeAcceleratorHost::OnChannelError() {
72c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(CalledOnValidThread());
73c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (channel_) {
74c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if (decoder_route_id_ != MSG_ROUTING_NONE)
75c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      channel_->RemoveRoute(decoder_route_id_);
76c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    channel_ = NULL;
77c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DLOG(ERROR) << "OnChannelError()";
790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  PostNotifyError(PLATFORM_FAILURE);
80c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
81c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool GpuVideoDecodeAcceleratorHost::Initialize(media::VideoCodecProfile profile,
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                               Client* client) {
84c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(CalledOnValidThread());
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  client_ = client;
86c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
87c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!impl_)
88c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return false;
89c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
90c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  int32 route_id = channel_->GenerateRouteID();
91c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  channel_->AddRoute(route_id, weak_this_factory_.GetWeakPtr());
92c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
93c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  bool succeeded = false;
94c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  Send(new GpuCommandBufferMsg_CreateVideoDecoder(
95c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      impl_->GetRouteID(), profile, route_id, &succeeded));
96c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
97c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!succeeded) {
980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    DLOG(ERROR) << "Send(GpuCommandBufferMsg_CreateVideoDecoder()) failed";
990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    PostNotifyError(PLATFORM_FAILURE);
100c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    channel_->RemoveRoute(route_id);
101c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return false;
102c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
103c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  decoder_route_id_ = route_id;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuVideoDecodeAcceleratorHost::Decode(
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const media::BitstreamBuffer& bitstream_buffer) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!channel_)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::SharedMemoryHandle handle = channel_->ShareToGpuProcess(
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      bitstream_buffer.handle());
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!base::SharedMemory::IsHandleValid(handle)) {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "Failed to duplicate buffer handler";
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new AcceleratedVideoDecoderMsg_Decode(
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      decoder_route_id_, handle, bitstream_buffer.id(),
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bitstream_buffer.size()));
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuVideoDecodeAcceleratorHost::AssignPictureBuffers(
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<media::PictureBuffer>& buffers) {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!channel_)
129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Rearrange data for IPC command.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<int32> buffer_ids;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<uint32> texture_ids;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (uint32 i = 0; i < buffers.size(); i++) {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const media::PictureBuffer& buffer = buffers[i];
13568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (buffer.size() != picture_buffer_dimensions_) {
1360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      DLOG(ERROR) << "buffer.size() invalid: expected "
1370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                  << picture_buffer_dimensions_.ToString()
1380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                  << ", got " << buffer.size().ToString();
1390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      PostNotifyError(INVALID_ARGUMENT);
14068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      return;
14168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    texture_ids.push_back(buffer.texture_id());
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buffer_ids.push_back(buffer.id());
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new AcceleratedVideoDecoderMsg_AssignPictureBuffers(
14668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      decoder_route_id_, buffer_ids, texture_ids));
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuVideoDecodeAcceleratorHost::ReusePictureBuffer(
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32 picture_buffer_id) {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
152c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!channel_)
153c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new AcceleratedVideoDecoderMsg_ReusePictureBuffer(
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      decoder_route_id_, picture_buffer_id));
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuVideoDecodeAcceleratorHost::Flush() {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
160c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!channel_)
161c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new AcceleratedVideoDecoderMsg_Flush(decoder_route_id_));
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuVideoDecodeAcceleratorHost::Reset() {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
167c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!channel_)
168c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new AcceleratedVideoDecoderMsg_Reset(decoder_route_id_));
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuVideoDecodeAcceleratorHost::Destroy() {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
174c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (channel_)
175c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    Send(new AcceleratedVideoDecoderMsg_Destroy(decoder_route_id_));
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_ = NULL;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete this;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GpuVideoDecodeAcceleratorHost::OnWillDeleteImpl() {
181c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(CalledOnValidThread());
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  impl_ = NULL;
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The CommandBufferProxyImpl is going away; error out this VDA.
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  OnChannelError();
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
188c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid GpuVideoDecodeAcceleratorHost::PostNotifyError(Error error) {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
190c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DVLOG(2) << "PostNotifyError(): error=" << error;
191c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  base::MessageLoopProxy::current()->PostTask(
192c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      FROM_HERE,
193c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      base::Bind(&GpuVideoDecodeAcceleratorHost::OnNotifyError,
194c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                 weak_this_factory_.GetWeakPtr(),
195c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                 error));
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuVideoDecodeAcceleratorHost::Send(IPC::Message* message) {
199c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(CalledOnValidThread());
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 message_type = message->type();
2010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!channel_->Send(message)) {
2020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    DLOG(ERROR) << "Send(" << message_type << ") failed";
2030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    PostNotifyError(PLATFORM_FAILURE);
2040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuVideoDecodeAcceleratorHost::OnBitstreamBufferProcessed(
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32 bitstream_buffer_id) {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (client_)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    client_->NotifyEndOfBitstreamBuffer(bitstream_buffer_id);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuVideoDecodeAcceleratorHost::OnProvidePictureBuffer(
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 num_requested_buffers,
21668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const gfx::Size& dimensions,
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 texture_target) {
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
21968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  picture_buffer_dimensions_ = dimensions;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (client_) {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    client_->ProvidePictureBuffers(
22268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        num_requested_buffers, dimensions, texture_target);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuVideoDecodeAcceleratorHost::OnDismissPictureBuffer(
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32 picture_buffer_id) {
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (client_)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    client_->DismissPictureBuffer(picture_buffer_id);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuVideoDecodeAcceleratorHost::OnPictureReady(
23403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    int32 picture_buffer_id,
23503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    int32 bitstream_buffer_id,
23603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const gfx::Rect& visible_rect) {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!client_)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
24003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  media::Picture picture(picture_buffer_id, bitstream_buffer_id, visible_rect);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_->PictureReady(picture);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuVideoDecodeAcceleratorHost::OnFlushDone() {
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (client_)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    client_->NotifyFlushDone();
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuVideoDecodeAcceleratorHost::OnResetDone() {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (client_)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    client_->NotifyResetDone();
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
256c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid GpuVideoDecodeAcceleratorHost::OnNotifyError(uint32 error) {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!client_)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
260c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  weak_this_factory_.InvalidateWeakPtrs();
2613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Client::NotifyError() may Destroy() |this|, so calling it needs to be the
2633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // last thing done on this stack!
2643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  media::VideoDecodeAccelerator::Client* client = NULL;
2653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::swap(client, client_);
266c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  client->NotifyError(static_cast<media::VideoDecodeAccelerator::Error>(error));
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
270