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/common/gpu/media/gpu_video_decode_accelerator.h" | 5 #include "content/common/gpu/media/gpu_video_decode_accelerator.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/stl_util-inl.h" | 11 #include "base/stl_util-inl.h" |
12 #include "gpu/command_buffer/common/command_buffer.h" | 12 #include "gpu/command_buffer/common/command_buffer.h" |
13 #include "ipc/ipc_message_macros.h" | 13 #include "ipc/ipc_message_macros.h" |
14 #include "ipc/ipc_message_utils.h" | 14 #include "ipc/ipc_message_utils.h" |
15 #include "content/common/gpu/gpu_channel.h" | 15 #include "content/common/gpu/gpu_channel.h" |
16 #include "content/common/gpu/gpu_command_buffer_stub.h" | 16 #include "content/common/gpu/gpu_command_buffer_stub.h" |
17 #include "content/common/gpu/gpu_messages.h" | 17 #include "content/common/gpu/gpu_messages.h" |
18 #include "content/common/gpu/media/gpu_video_service.h" | 18 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) |
| 19 #include "content/common/gpu/media/omx_video_decode_accelerator.h" |
| 20 #include "ui/gfx/gl/gl_surface_egl.h" |
| 21 #endif |
19 #include "ui/gfx/size.h" | 22 #include "ui/gfx/size.h" |
20 | 23 |
21 GpuVideoDecodeAccelerator::GpuVideoDecodeAccelerator( | 24 GpuVideoDecodeAccelerator::GpuVideoDecodeAccelerator( |
22 IPC::Message::Sender* sender, | 25 IPC::Message::Sender* sender, |
23 int32 host_route_id, | 26 int32 host_route_id, |
24 int32 decoder_route_id, | |
25 GpuCommandBufferStub* stub) | 27 GpuCommandBufferStub* stub) |
26 : sender_(sender), | 28 : sender_(sender), |
27 host_route_id_(host_route_id), | 29 host_route_id_(host_route_id), |
28 decoder_route_id_(decoder_route_id), | |
29 stub_(stub), | 30 stub_(stub), |
30 video_decode_accelerator_(NULL) { | 31 video_decode_accelerator_(NULL) { |
| 32 // stub_ owns and will always outlive this object. |
31 stub_->AddSetTokenCallback(base::Bind( | 33 stub_->AddSetTokenCallback(base::Bind( |
32 &GpuVideoDecodeAccelerator::OnSetToken, this)); | 34 &GpuVideoDecodeAccelerator::OnSetToken, base::Unretained(this))); |
33 } | 35 } |
34 | 36 |
35 GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() { | 37 GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() { |
36 STLDeleteElements(&deferred_messages_); | 38 STLDeleteElements(&deferred_messages_); |
| 39 // TODO(fischman/vrk): We need to synchronously wait for the OMX decoder |
| 40 // to finish shutting down. |
37 } | 41 } |
38 | 42 |
39 void GpuVideoDecodeAccelerator::OnSetToken(int32 token) { | 43 void GpuVideoDecodeAccelerator::OnSetToken(int32 token) { |
40 // Note: this always retries all deferred messages on every token arrival. | 44 // Note: this always retries all deferred messages on every token arrival. |
41 // There's an optimization to be done here by only trying messages which are | 45 // There's an optimization to be done here by only trying messages which are |
42 // waiting for tokens which are earlier than |token|. | 46 // waiting for tokens which are earlier than |token|. |
43 std::vector<IPC::Message*> deferred_messages_copy; | 47 std::vector<IPC::Message*> deferred_messages_copy; |
44 std::swap(deferred_messages_copy, deferred_messages_); | 48 std::swap(deferred_messages_copy, deferred_messages_); |
45 for (size_t i = 0; i < deferred_messages_copy.size(); ++i) | 49 for (size_t i = 0; i < deferred_messages_copy.size(); ++i) |
46 OnMessageReceived(*deferred_messages_copy[i]); | 50 OnMessageReceived(*deferred_messages_copy[i]); |
47 STLDeleteElements(&deferred_messages_copy); | 51 STLDeleteElements(&deferred_messages_copy); |
48 } | 52 } |
49 | 53 |
50 bool GpuVideoDecodeAccelerator::DeferMessageIfNeeded( | 54 bool GpuVideoDecodeAccelerator::DeferMessageIfNeeded( |
51 const IPC::Message& msg, bool* deferred) { | 55 const IPC::Message& msg, bool* deferred) { |
52 // Only consider deferring for message types that need it. | 56 // Only consider deferring for message types that need it. |
53 switch (msg.type()) { | 57 switch (msg.type()) { |
54 case AcceleratedVideoDecoderMsg_GetConfigs::ID: | 58 case AcceleratedVideoDecoderMsg_GetConfigs::ID: |
55 case AcceleratedVideoDecoderMsg_Initialize::ID: | |
56 case AcceleratedVideoDecoderMsg_Decode::ID: | 59 case AcceleratedVideoDecoderMsg_Decode::ID: |
57 case AcceleratedVideoDecoderMsg_AssignTextures::ID: | 60 case AcceleratedVideoDecoderMsg_AssignGLESBuffers::ID: |
58 case AcceleratedVideoDecoderMsg_AssignSysmemBuffers::ID: | 61 case AcceleratedVideoDecoderMsg_AssignSysmemBuffers::ID: |
59 case AcceleratedVideoDecoderMsg_ReusePictureBuffer::ID: | 62 case AcceleratedVideoDecoderMsg_ReusePictureBuffer::ID: |
60 case AcceleratedVideoDecoderMsg_Flush::ID: | 63 case AcceleratedVideoDecoderMsg_Flush::ID: |
61 case AcceleratedVideoDecoderMsg_Abort::ID: | 64 case AcceleratedVideoDecoderMsg_Abort::ID: |
62 break; | 65 break; |
63 default: | 66 default: |
64 return false; | 67 return false; |
65 } | 68 } |
66 | 69 |
67 gpu::ReadWriteTokens tokens; | 70 gpu::ReadWriteTokens tokens; |
(...skipping 12 matching lines...) Expand all Loading... |
80 bool GpuVideoDecodeAccelerator::OnMessageReceived(const IPC::Message& msg) { | 83 bool GpuVideoDecodeAccelerator::OnMessageReceived(const IPC::Message& msg) { |
81 bool deferred = false; | 84 bool deferred = false; |
82 if (!DeferMessageIfNeeded(msg, &deferred)) | 85 if (!DeferMessageIfNeeded(msg, &deferred)) |
83 return false; | 86 return false; |
84 if (deferred) | 87 if (deferred) |
85 return true; | 88 return true; |
86 | 89 |
87 bool handled = true; | 90 bool handled = true; |
88 IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAccelerator, msg) | 91 IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAccelerator, msg) |
89 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_GetConfigs, OnGetConfigs) | 92 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_GetConfigs, OnGetConfigs) |
90 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Initialize, OnInitialize) | |
91 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Decode, OnDecode) | 93 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Decode, OnDecode) |
92 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_AssignTextures, | 94 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_AssignGLESBuffers, |
93 OnAssignTextures) | 95 OnAssignGLESBuffers) |
94 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_AssignSysmemBuffers, | 96 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_AssignSysmemBuffers, |
95 OnAssignSysmemBuffers) | 97 OnAssignSysmemBuffers) |
96 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_ReusePictureBuffer, | 98 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_ReusePictureBuffer, |
97 OnReusePictureBuffer) | 99 OnReusePictureBuffer) |
98 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Flush, OnFlush) | 100 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Flush, OnFlush) |
99 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Abort, OnAbort) | 101 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Abort, OnAbort) |
100 IPC_MESSAGE_UNHANDLED(handled = false) | 102 IPC_MESSAGE_UNHANDLED(handled = false) |
101 IPC_END_MESSAGE_MAP() | 103 IPC_END_MESSAGE_MAP() |
102 return handled; | 104 return handled; |
103 } | 105 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 void GpuVideoDecodeAccelerator::OnGetConfigs( | 161 void GpuVideoDecodeAccelerator::OnGetConfigs( |
160 const gpu::ReadWriteTokens& /* tokens */, | 162 const gpu::ReadWriteTokens& /* tokens */, |
161 const std::vector<uint32>& requested, std::vector<uint32>* matched) { | 163 const std::vector<uint32>& requested, std::vector<uint32>* matched) { |
162 // TODO(fischman,vrk): this is borked; can't have a VDA before calling | 164 // TODO(fischman,vrk): this is borked; can't have a VDA before calling |
163 // Initialize, but can't call Initialize until we have some configs! | 165 // Initialize, but can't call Initialize until we have some configs! |
164 if (!video_decode_accelerator_.get()) | 166 if (!video_decode_accelerator_.get()) |
165 return; | 167 return; |
166 video_decode_accelerator_->GetConfigs(requested, matched); | 168 video_decode_accelerator_->GetConfigs(requested, matched); |
167 } | 169 } |
168 | 170 |
169 void GpuVideoDecodeAccelerator::OnInitialize( | 171 void GpuVideoDecodeAccelerator::Initialize(const std::vector<uint32>& configs) { |
170 const gpu::ReadWriteTokens& /* tokens */, | |
171 const std::vector<uint32>& configs) { | |
172 DCHECK(!video_decode_accelerator_.get()); | 172 DCHECK(!video_decode_accelerator_.get()); |
173 GpuVideoService::GetInstance()->InitializeVideoDecoder(decoder_route_id_); | 173 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) |
174 DCHECK(video_decode_accelerator_.get()); | 174 DCHECK(stub_ && stub_->scheduler()); |
| 175 OmxVideoDecodeAccelerator* omx_decoder = new OmxVideoDecodeAccelerator(this); |
| 176 omx_decoder->SetEglState( |
| 177 gfx::GLSurfaceEGL::GetDisplay(), |
| 178 stub_->scheduler()->decoder()->GetGLContext()->GetHandle()); |
| 179 video_decode_accelerator_.reset(omx_decoder); |
175 video_decode_accelerator_->Initialize(configs); | 180 video_decode_accelerator_->Initialize(configs); |
| 181 #else |
| 182 NOTIMPLEMENTED() << "HW video decode acceleration not available."; |
| 183 #endif // defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) |
176 } | 184 } |
177 | 185 |
178 void GpuVideoDecodeAccelerator::OnDecode( | 186 void GpuVideoDecodeAccelerator::OnDecode( |
179 const gpu::ReadWriteTokens&, /* tokens */ | 187 const gpu::ReadWriteTokens&, /* tokens */ |
180 base::SharedMemoryHandle handle, int32 id, int32 size) { | 188 base::SharedMemoryHandle handle, int32 id, int32 size) { |
181 DCHECK(video_decode_accelerator_.get()); | 189 DCHECK(video_decode_accelerator_.get()); |
182 video_decode_accelerator_->Decode(media::BitstreamBuffer(id, handle, size)); | 190 video_decode_accelerator_->Decode(media::BitstreamBuffer(id, handle, size)); |
183 } | 191 } |
184 | 192 |
185 void GpuVideoDecodeAccelerator::AssignGLESBuffers( | 193 void GpuVideoDecodeAccelerator::OnAssignGLESBuffers( |
186 const std::vector<media::GLESBuffer>& buffers) { | 194 const gpu::ReadWriteTokens& /* tokens */, |
187 // TODO(fischman,vrk): it's wonky that we handle the AssignTextures message by | 195 const std::vector<int32>& buffer_ids, |
188 // handing its contents to GpuVideoService which then turns around and calls | 196 const std::vector<uint32>& texture_ids, |
189 // this (public) method. Instead we should make GpuVideoService vend the | 197 const std::vector<gfx::Size>& sizes) { |
190 // translation method we need and use it directly. | 198 DCHECK(stub_ && stub_->scheduler()); // Ensure already Initialize()'d. |
191 DCHECK(video_decode_accelerator_.get()); | 199 gpu::gles2::GLES2Decoder* command_decoder = stub_->scheduler()->decoder(); |
| 200 |
| 201 std::vector<media::GLESBuffer> buffers; |
| 202 for (uint32 i = 0; i < buffer_ids.size(); ++i) { |
| 203 uint32 service_texture_id; |
| 204 if (!command_decoder->GetServiceTextureId( |
| 205 texture_ids[i], &service_texture_id)) { |
| 206 // TODO(vrk): Send an error for invalid GLES buffers. |
| 207 LOG(DFATAL) << "Failed to translate texture!"; |
| 208 return; |
| 209 } |
| 210 buffers.push_back(media::GLESBuffer( |
| 211 buffer_ids[i], sizes[i], service_texture_id)); |
| 212 } |
192 video_decode_accelerator_->AssignGLESBuffers(buffers); | 213 video_decode_accelerator_->AssignGLESBuffers(buffers); |
193 } | 214 } |
194 | 215 |
195 void GpuVideoDecodeAccelerator::OnAssignTextures( | |
196 const gpu::ReadWriteTokens& /* tokens */, | |
197 const std::vector<int32>& buffer_ids, | |
198 const std::vector<uint32>& texture_ids, | |
199 const std::vector<gfx::Size>& sizes) { | |
200 GpuVideoService* service = GpuVideoService::GetInstance(); | |
201 service->AssignTexturesToDecoder( | |
202 decoder_route_id_, buffer_ids, texture_ids, sizes); | |
203 } | |
204 | |
205 void GpuVideoDecodeAccelerator::OnAssignSysmemBuffers( | 216 void GpuVideoDecodeAccelerator::OnAssignSysmemBuffers( |
206 const gpu::ReadWriteTokens& /* tokens */, | 217 const gpu::ReadWriteTokens& /* tokens */, |
207 const std::vector<int32> buffer_ids, | 218 const std::vector<int32> buffer_ids, |
208 const std::vector<base::SharedMemoryHandle> data, | 219 const std::vector<base::SharedMemoryHandle> data, |
209 const std::vector<gfx::Size> sizes) { | 220 const std::vector<gfx::Size> sizes) { |
210 // TODO(vrk): Implement. | 221 // TODO(vrk): Implement. |
211 NOTIMPLEMENTED(); | 222 NOTIMPLEMENTED(); |
212 } | 223 } |
213 | 224 |
214 void GpuVideoDecodeAccelerator::OnReusePictureBuffer( | 225 void GpuVideoDecodeAccelerator::OnReusePictureBuffer( |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 | 263 |
253 void GpuVideoDecodeAccelerator::NotifyAbortDone() { | 264 void GpuVideoDecodeAccelerator::NotifyAbortDone() { |
254 if (!Send(new AcceleratedVideoDecoderHostMsg_AbortDone(host_route_id_))) | 265 if (!Send(new AcceleratedVideoDecoderHostMsg_AbortDone(host_route_id_))) |
255 LOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_AbortDone) failed"; | 266 LOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_AbortDone) failed"; |
256 } | 267 } |
257 | 268 |
258 bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) { | 269 bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) { |
259 DCHECK(sender_); | 270 DCHECK(sender_); |
260 return sender_->Send(message); | 271 return sender_->Send(message); |
261 } | 272 } |
OLD | NEW |