OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "content/renderer/gpu/gpu_video_decode_accelerator_host.h" | 5 #include "content/renderer/gpu/gpu_video_decode_accelerator_host.h" |
6 | 6 |
| 7 #include "base/bind.h" |
7 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/message_loop.h" |
8 #include "base/shared_memory.h" | 10 #include "base/shared_memory.h" |
9 #include "base/task.h" | 11 #include "base/task.h" |
10 #include "content/common/gpu/gpu_messages.h" | 12 #include "content/common/gpu/gpu_messages.h" |
11 #include "content/common/view_messages.h" | 13 #include "content/common/view_messages.h" |
12 #include "content/renderer/render_thread.h" | 14 #include "content/renderer/render_thread.h" |
| 15 #include "gpu/command_buffer/client/cmd_buffer_helper.h" |
| 16 #include "gpu/command_buffer/common/command_buffer.h" |
13 #include "ipc/ipc_message_macros.h" | 17 #include "ipc/ipc_message_macros.h" |
14 #include "ipc/ipc_message_utils.h" | 18 #include "ipc/ipc_message_utils.h" |
| 19 #include "ipc/ipc_platform_file.h" |
15 | 20 |
16 using media::VideoDecodeAccelerator; | 21 using media::VideoDecodeAccelerator; |
17 | 22 |
18 GpuVideoDecodeAcceleratorHost::GpuVideoDecodeAcceleratorHost( | 23 GpuVideoDecodeAcceleratorHost::GpuVideoDecodeAcceleratorHost( |
19 MessageRouter* router, | 24 MessageRouter* router, |
20 IPC::Message::Sender* ipc_sender, | 25 IPC::Message::Sender* ipc_sender, |
21 int32 decoder_host_id, | 26 int32 decoder_host_id, |
22 uint32 command_buffer_route_id, | 27 int32 command_buffer_route_id, |
| 28 gpu::CommandBufferHelper* cmd_buffer_helper, |
23 VideoDecodeAccelerator::Client* client) | 29 VideoDecodeAccelerator::Client* client) |
24 : router_(router), | 30 : router_(router), |
25 ipc_sender_(ipc_sender), | 31 ipc_sender_(ipc_sender), |
26 decoder_host_id_(decoder_host_id), | 32 decoder_host_id_(decoder_host_id), |
27 decoder_id_(0), | 33 decoder_id_(-1), |
28 command_buffer_route_id_(command_buffer_route_id), | 34 command_buffer_route_id_(command_buffer_route_id), |
| 35 cmd_buffer_helper_(cmd_buffer_helper), |
29 client_(client) { | 36 client_(client) { |
| 37 DCHECK(RenderThread::current()); |
| 38 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current()); |
30 } | 39 } |
31 | 40 |
32 GpuVideoDecodeAcceleratorHost::~GpuVideoDecodeAcceleratorHost() {} | 41 GpuVideoDecodeAcceleratorHost::~GpuVideoDecodeAcceleratorHost() {} |
33 | 42 |
34 void GpuVideoDecodeAcceleratorHost::OnChannelConnected(int32 peer_pid) { | 43 void GpuVideoDecodeAcceleratorHost::OnChannelConnected(int32 peer_pid) { |
35 } | 44 } |
36 | 45 |
37 void GpuVideoDecodeAcceleratorHost::OnChannelError() { | 46 void GpuVideoDecodeAcceleratorHost::OnChannelError() { |
38 ipc_sender_ = NULL; | 47 ipc_sender_ = NULL; |
39 } | 48 } |
40 | 49 |
41 bool GpuVideoDecodeAcceleratorHost::OnMessageReceived(const IPC::Message& msg) { | 50 bool GpuVideoDecodeAcceleratorHost::OnMessageReceived(const IPC::Message& msg) { |
| 51 DCHECK(CalledOnValidThread()); |
42 bool handled = true; | 52 bool handled = true; |
43 IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAcceleratorHost, msg) | 53 IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAcceleratorHost, msg) |
44 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed, | 54 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed, |
45 OnBitstreamBufferProcessed) | 55 OnBitstreamBufferProcessed) |
46 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers, | 56 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers, |
47 OnProvidePictureBuffer) | 57 OnProvidePictureBuffer) |
48 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_CreateDone, | 58 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_CreateDone, |
49 OnCreateDone) | 59 OnCreateDone) |
50 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_InitializeDone, | 60 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_InitializeDone, |
51 OnInitializeDone) | 61 OnInitializeDone) |
52 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_PictureReady, | 62 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_PictureReady, |
53 OnPictureReady) | 63 OnPictureReady) |
54 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_FlushDone, | 64 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_FlushDone, |
55 OnFlushDone) | 65 OnFlushDone) |
56 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_AbortDone, | 66 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_AbortDone, |
57 OnAbortDone) | 67 OnAbortDone) |
58 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_EndOfStream, | 68 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_EndOfStream, |
59 OnEndOfStream) | 69 OnEndOfStream) |
60 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ErrorNotification, | 70 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ErrorNotification, |
61 OnErrorNotification) | 71 OnErrorNotification) |
62 IPC_MESSAGE_UNHANDLED(handled = false) | 72 IPC_MESSAGE_UNHANDLED(handled = false) |
63 IPC_END_MESSAGE_MAP() | 73 IPC_END_MESSAGE_MAP() |
64 DCHECK(handled); | 74 DCHECK(handled); |
65 return handled; | 75 return handled; |
66 } | 76 } |
67 | 77 |
| 78 gpu::ReadWriteTokens GpuVideoDecodeAcceleratorHost::SyncTokens() { |
| 79 DCHECK(CalledOnValidThread()); |
| 80 // Note that the order below matters. InsertToken() must happen before |
| 81 // Flush() and last_token_read() should be read before InsertToken(). |
| 82 int32 read = cmd_buffer_helper_->last_token_read(); |
| 83 int32 written = cmd_buffer_helper_->InsertToken(); |
| 84 cmd_buffer_helper_->Flush(); |
| 85 return gpu::ReadWriteTokens(read, written); |
| 86 } |
| 87 |
68 bool GpuVideoDecodeAcceleratorHost::GetConfigs( | 88 bool GpuVideoDecodeAcceleratorHost::GetConfigs( |
69 const std::vector<uint32>& requested_configs, | 89 const std::vector<uint32>& requested_configs, |
70 std::vector<uint32>* matched_configs) { | 90 std::vector<uint32>* matched_configs) { |
71 // TODO(vrk): Need to rethink GetConfigs. | 91 // TODO(vrk): Need to rethink GetConfigs. |
72 NOTIMPLEMENTED(); | 92 NOTIMPLEMENTED(); |
73 return true; | 93 return true; |
74 } | 94 } |
75 | 95 |
76 bool GpuVideoDecodeAcceleratorHost::Initialize( | 96 bool GpuVideoDecodeAcceleratorHost::Initialize( |
77 const std::vector<uint32>& configs) { | 97 const std::vector<uint32>& configs) { |
| 98 DCHECK(CalledOnValidThread()); |
78 router_->AddRoute(decoder_host_id_, this); | 99 router_->AddRoute(decoder_host_id_, this); |
79 | 100 |
80 // Temporarily save configs for after create is done and we're | 101 // Temporarily save configs for after create is done and we're |
81 // ready to initialize. | 102 // ready to initialize. |
82 configs_ = configs; | 103 configs_ = configs; |
83 | |
84 if (!ipc_sender_->Send(new GpuChannelMsg_CreateVideoDecoder( | 104 if (!ipc_sender_->Send(new GpuChannelMsg_CreateVideoDecoder( |
85 decoder_id_, command_buffer_route_id_, configs))) { | 105 decoder_host_id_, command_buffer_route_id_, configs))) { |
86 LOG(ERROR) << "Send(GpuChannelMsg_CreateVideoDecoder) failed"; | 106 LOG(ERROR) << "Send(GpuChannelMsg_CreateVideoDecoder) failed"; |
87 return false; | 107 return false; |
88 } | 108 } |
89 return true; | 109 return true; |
90 } | 110 } |
91 | 111 |
92 bool GpuVideoDecodeAcceleratorHost::Decode( | 112 void GpuVideoDecodeAcceleratorHost::Decode( |
93 const media::BitstreamBuffer& bitstream_buffer) { | 113 const media::BitstreamBuffer& bitstream_buffer) { |
| 114 DCHECK(CalledOnValidThread()); |
94 if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_Decode( | 115 if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_Decode( |
95 decoder_id_, bitstream_buffer.id(), | 116 decoder_id_, SyncTokens(), bitstream_buffer.handle(), |
96 bitstream_buffer.handle(), bitstream_buffer.size()))) { | 117 bitstream_buffer.id(), bitstream_buffer.size()))) { |
97 DLOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_Decode) failed"; | 118 DLOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_Decode) failed"; |
98 return false; | 119 // TODO(fischman/vrk): signal error to client. |
| 120 return; |
99 } | 121 } |
100 | |
101 return true; | |
102 } | 122 } |
103 | 123 |
104 void GpuVideoDecodeAcceleratorHost::AssignGLESBuffers( | 124 void GpuVideoDecodeAcceleratorHost::AssignGLESBuffers( |
105 const std::vector<media::GLESBuffer>& buffers) { | 125 const std::vector<media::GLESBuffer>& buffers) { |
| 126 DCHECK(CalledOnValidThread()); |
106 // Rearrange data for IPC command. | 127 // Rearrange data for IPC command. |
107 std::vector<int32> buffer_ids; | 128 std::vector<int32> buffer_ids; |
108 std::vector<uint32> texture_ids; | 129 std::vector<uint32> texture_ids; |
109 std::vector<gfx::Size> sizes; | 130 std::vector<gfx::Size> sizes; |
110 for (uint32 i = 0; i < buffers.size(); i++) { | 131 for (uint32 i = 0; i < buffers.size(); i++) { |
111 const media::GLESBuffer& buffer = buffers[i]; | 132 const media::GLESBuffer& buffer = buffers[i]; |
112 texture_ids.push_back(buffer.texture_id()); | 133 texture_ids.push_back(buffer.texture_id()); |
113 buffer_ids.push_back(buffer.id()); | 134 buffer_ids.push_back(buffer.id()); |
114 sizes.push_back(buffer.size()); | 135 sizes.push_back(buffer.size()); |
115 } | 136 } |
116 if (!ipc_sender_->Send(new GpuChannelMsg_AssignTexturesToVideoDecoder( | 137 if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_AssignTextures( |
117 decoder_id_, buffer_ids, texture_ids, sizes))) { | 138 decoder_id_, SyncTokens(), buffer_ids, texture_ids, sizes))) { |
118 LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_AssignGLESBuffers) failed"; | 139 LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_AssignGLESBuffers) failed"; |
119 } | 140 } |
120 } | 141 } |
121 | 142 |
122 void GpuVideoDecodeAcceleratorHost::AssignSysmemBuffers( | 143 void GpuVideoDecodeAcceleratorHost::AssignSysmemBuffers( |
123 const std::vector<media::SysmemBuffer>& buffers) { | 144 const std::vector<media::SysmemBuffer>& buffers) { |
| 145 DCHECK(CalledOnValidThread()); |
124 // TODO(vrk): Implement. | 146 // TODO(vrk): Implement. |
125 NOTIMPLEMENTED(); | 147 NOTIMPLEMENTED(); |
126 } | 148 } |
127 | 149 |
128 void GpuVideoDecodeAcceleratorHost::ReusePictureBuffer( | 150 void GpuVideoDecodeAcceleratorHost::ReusePictureBuffer( |
129 int32 picture_buffer_id) { | 151 int32 picture_buffer_id) { |
| 152 DCHECK(CalledOnValidThread()); |
130 if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_ReusePictureBuffer( | 153 if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_ReusePictureBuffer( |
131 decoder_id_, picture_buffer_id))) { | 154 decoder_id_, SyncTokens(), picture_buffer_id))) { |
132 LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_ReusePictureBuffer) failed"; | 155 LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_ReusePictureBuffer) failed"; |
133 } | 156 } |
134 } | 157 } |
135 | 158 |
136 bool GpuVideoDecodeAcceleratorHost::Flush() { | 159 void GpuVideoDecodeAcceleratorHost::Flush() { |
137 if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_Flush(decoder_id_))) { | 160 DCHECK(CalledOnValidThread()); |
| 161 if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_Flush( |
| 162 decoder_id_, SyncTokens()))) { |
138 LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_Flush) failed"; | 163 LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_Flush) failed"; |
139 return false; | 164 // TODO(fischman/vrk): signal error to client. |
| 165 return; |
140 } | 166 } |
141 return true; | |
142 } | 167 } |
143 | 168 |
144 bool GpuVideoDecodeAcceleratorHost::Abort() { | 169 void GpuVideoDecodeAcceleratorHost::Abort() { |
145 if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_Abort(decoder_id_))) { | 170 DCHECK(CalledOnValidThread()); |
| 171 if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_Abort( |
| 172 decoder_id_, SyncTokens()))) { |
146 LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_Abort) failed"; | 173 LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_Abort) failed"; |
147 return false; | 174 // TODO(fischman/vrk): signal error to client. |
| 175 return; |
148 } | 176 } |
149 return true; | |
150 } | 177 } |
151 | 178 |
152 void GpuVideoDecodeAcceleratorHost::OnBitstreamBufferProcessed( | 179 void GpuVideoDecodeAcceleratorHost::OnBitstreamBufferProcessed( |
153 int32 bitstream_buffer_id) { | 180 int32 bitstream_buffer_id) { |
| 181 DCHECK(CalledOnValidThread()); |
154 client_->NotifyEndOfBitstreamBuffer(bitstream_buffer_id); | 182 client_->NotifyEndOfBitstreamBuffer(bitstream_buffer_id); |
155 } | 183 } |
156 | 184 |
157 void GpuVideoDecodeAcceleratorHost::OnProvidePictureBuffer( | 185 void GpuVideoDecodeAcceleratorHost::OnProvidePictureBuffer( |
158 uint32 num_requested_buffers, | 186 uint32 num_requested_buffers, |
159 const gfx::Size& buffer_size, | 187 const gfx::Size& buffer_size, |
160 int32 mem_type) { | 188 int32 mem_type) { |
| 189 DCHECK(CalledOnValidThread()); |
161 media::VideoDecodeAccelerator::MemoryType converted_mem_type = | 190 media::VideoDecodeAccelerator::MemoryType converted_mem_type = |
162 static_cast<media::VideoDecodeAccelerator::MemoryType>(mem_type); | 191 static_cast<media::VideoDecodeAccelerator::MemoryType>(mem_type); |
163 client_->ProvidePictureBuffers( | 192 client_->ProvidePictureBuffers( |
164 num_requested_buffers, buffer_size, converted_mem_type); | 193 num_requested_buffers, buffer_size, converted_mem_type); |
165 } | 194 } |
166 | 195 |
167 void GpuVideoDecodeAcceleratorHost::OnDismissPictureBuffer( | 196 void GpuVideoDecodeAcceleratorHost::OnDismissPictureBuffer( |
168 int32 picture_buffer_id) { | 197 int32 picture_buffer_id) { |
| 198 DCHECK(CalledOnValidThread()); |
169 client_->DismissPictureBuffer(picture_buffer_id); | 199 client_->DismissPictureBuffer(picture_buffer_id); |
170 } | 200 } |
171 | 201 |
172 void GpuVideoDecodeAcceleratorHost::OnCreateDone(int32 decoder_id) { | 202 void GpuVideoDecodeAcceleratorHost::OnCreateDone(int32 decoder_id) { |
| 203 DCHECK(CalledOnValidThread()); |
173 decoder_id_ = decoder_id; | 204 decoder_id_ = decoder_id; |
174 if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_Initialize( | 205 if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_Initialize( |
175 decoder_id_, configs_))) { | 206 decoder_id_, SyncTokens(), configs_))) { |
176 LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_Initialize) failed"; | 207 LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_Initialize) failed"; |
177 } | 208 } |
178 } | 209 } |
179 | 210 |
180 void GpuVideoDecodeAcceleratorHost::OnInitializeDone() { | 211 void GpuVideoDecodeAcceleratorHost::OnInitializeDone() { |
| 212 DCHECK(CalledOnValidThread()); |
181 client_->NotifyInitializeDone(); | 213 client_->NotifyInitializeDone(); |
182 } | 214 } |
183 | 215 |
184 void GpuVideoDecodeAcceleratorHost::OnPictureReady( | 216 void GpuVideoDecodeAcceleratorHost::OnPictureReady( |
185 int32 picture_buffer_id, int32 bitstream_buffer_id, | 217 int32 picture_buffer_id, int32 bitstream_buffer_id, |
186 const gfx::Size& visible_size, const gfx::Size& decoded_size) { | 218 const gfx::Size& visible_size, const gfx::Size& decoded_size) { |
| 219 DCHECK(CalledOnValidThread()); |
187 media::Picture picture( | 220 media::Picture picture( |
188 picture_buffer_id, bitstream_buffer_id, visible_size, decoded_size); | 221 picture_buffer_id, bitstream_buffer_id, visible_size, decoded_size); |
189 client_->PictureReady(picture); | 222 client_->PictureReady(picture); |
190 } | 223 } |
191 | 224 |
192 void GpuVideoDecodeAcceleratorHost::OnFlushDone() { | 225 void GpuVideoDecodeAcceleratorHost::OnFlushDone() { |
| 226 DCHECK(CalledOnValidThread()); |
193 client_->NotifyFlushDone(); | 227 client_->NotifyFlushDone(); |
194 } | 228 } |
195 | 229 |
196 void GpuVideoDecodeAcceleratorHost::OnAbortDone() { | 230 void GpuVideoDecodeAcceleratorHost::OnAbortDone() { |
| 231 DCHECK(CalledOnValidThread()); |
197 client_->NotifyAbortDone(); | 232 client_->NotifyAbortDone(); |
198 } | 233 } |
199 | 234 |
200 void GpuVideoDecodeAcceleratorHost::OnEndOfStream() { | 235 void GpuVideoDecodeAcceleratorHost::OnEndOfStream() { |
| 236 DCHECK(CalledOnValidThread()); |
201 client_->NotifyEndOfStream(); | 237 client_->NotifyEndOfStream(); |
202 } | 238 } |
203 | 239 |
204 void GpuVideoDecodeAcceleratorHost::OnErrorNotification(uint32 error) { | 240 void GpuVideoDecodeAcceleratorHost::OnErrorNotification(uint32 error) { |
| 241 DCHECK(CalledOnValidThread()); |
205 client_->NotifyError( | 242 client_->NotifyError( |
206 static_cast<media::VideoDecodeAccelerator::Error>(error)); | 243 static_cast<media::VideoDecodeAccelerator::Error>(error)); |
207 } | 244 } |
OLD | NEW |