Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(158)

Side by Side Diff: content/renderer/gpu/gpu_video_decode_accelerator_host.cc

Issue 7260008: Implement proper synchronization between HW video decode IPC and CommandBuffer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
scherkus (not reviewing) 2011/06/28 22:02:07 ok this is a bit of a nit but: RenderThread::curr
Ami GONE FROM CHROMIUM 2011/06/28 22:25:06 Oh boy. That's pretty exciting (and undocumented)
30 } 38 }
31 39
32 GpuVideoDecodeAcceleratorHost::~GpuVideoDecodeAcceleratorHost() {} 40 GpuVideoDecodeAcceleratorHost::~GpuVideoDecodeAcceleratorHost() {}
33 41
34 void GpuVideoDecodeAcceleratorHost::OnChannelConnected(int32 peer_pid) { 42 void GpuVideoDecodeAcceleratorHost::OnChannelConnected(int32 peer_pid) {
35 } 43 }
36 44
37 void GpuVideoDecodeAcceleratorHost::OnChannelError() { 45 void GpuVideoDecodeAcceleratorHost::OnChannelError() {
38 ipc_sender_ = NULL; 46 ipc_sender_ = NULL;
39 } 47 }
40 48
41 bool GpuVideoDecodeAcceleratorHost::OnMessageReceived(const IPC::Message& msg) { 49 bool GpuVideoDecodeAcceleratorHost::OnMessageReceived(const IPC::Message& msg) {
50 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
42 bool handled = true; 51 bool handled = true;
43 IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAcceleratorHost, msg) 52 IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAcceleratorHost, msg)
44 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed, 53 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed,
45 OnBitstreamBufferProcessed) 54 OnBitstreamBufferProcessed)
46 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers, 55 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers,
47 OnProvidePictureBuffer) 56 OnProvidePictureBuffer)
48 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_CreateDone, 57 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_CreateDone,
49 OnCreateDone) 58 OnCreateDone)
50 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_InitializeDone, 59 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_InitializeDone,
51 OnInitializeDone) 60 OnInitializeDone)
52 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_PictureReady, 61 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_PictureReady,
53 OnPictureReady) 62 OnPictureReady)
54 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_FlushDone, 63 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_FlushDone,
55 OnFlushDone) 64 OnFlushDone)
56 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_AbortDone, 65 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_AbortDone,
57 OnAbortDone) 66 OnAbortDone)
58 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_EndOfStream, 67 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_EndOfStream,
59 OnEndOfStream) 68 OnEndOfStream)
60 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ErrorNotification, 69 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ErrorNotification,
61 OnErrorNotification) 70 OnErrorNotification)
62 IPC_MESSAGE_UNHANDLED(handled = false) 71 IPC_MESSAGE_UNHANDLED(handled = false)
63 IPC_END_MESSAGE_MAP() 72 IPC_END_MESSAGE_MAP()
64 DCHECK(handled); 73 DCHECK(handled);
65 return handled; 74 return handled;
66 } 75 }
67 76
77 gpu::ReadWriteTokens GpuVideoDecodeAcceleratorHost::SyncTokens() {
78 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
79 // Note that the order below matters. InsertToken() must happen before
80 // Flush() and last_token_read() should be read before InsertToken().
81 int32 read = cmd_buffer_helper_->last_token_read();
82 int32 written = cmd_buffer_helper_->InsertToken();
83 cmd_buffer_helper_->Flush();
84 return gpu::ReadWriteTokens(read, written);
85 }
86
68 bool GpuVideoDecodeAcceleratorHost::GetConfigs( 87 bool GpuVideoDecodeAcceleratorHost::GetConfigs(
69 const std::vector<uint32>& requested_configs, 88 const std::vector<uint32>& requested_configs,
70 std::vector<uint32>* matched_configs) { 89 std::vector<uint32>* matched_configs) {
71 // TODO(vrk): Need to rethink GetConfigs. 90 // TODO(vrk): Need to rethink GetConfigs.
72 NOTIMPLEMENTED(); 91 NOTIMPLEMENTED();
73 return true; 92 return true;
74 } 93 }
75 94
76 bool GpuVideoDecodeAcceleratorHost::Initialize( 95 bool GpuVideoDecodeAcceleratorHost::Initialize(
77 const std::vector<uint32>& configs) { 96 const std::vector<uint32>& configs) {
97 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
78 router_->AddRoute(decoder_host_id_, this); 98 router_->AddRoute(decoder_host_id_, this);
79 99
80 // Temporarily save configs for after create is done and we're 100 // Temporarily save configs for after create is done and we're
81 // ready to initialize. 101 // ready to initialize.
82 configs_ = configs; 102 configs_ = configs;
83
84 if (!ipc_sender_->Send(new GpuChannelMsg_CreateVideoDecoder( 103 if (!ipc_sender_->Send(new GpuChannelMsg_CreateVideoDecoder(
85 decoder_id_, command_buffer_route_id_, configs))) { 104 decoder_host_id_, command_buffer_route_id_, configs))) {
86 LOG(ERROR) << "Send(GpuChannelMsg_CreateVideoDecoder) failed"; 105 LOG(ERROR) << "Send(GpuChannelMsg_CreateVideoDecoder) failed";
87 return false; 106 return false;
88 } 107 }
89 return true; 108 return true;
90 } 109 }
91 110
92 bool GpuVideoDecodeAcceleratorHost::Decode( 111 void GpuVideoDecodeAcceleratorHost::Decode(
93 const media::BitstreamBuffer& bitstream_buffer) { 112 const media::BitstreamBuffer& bitstream_buffer) {
113 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
94 if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_Decode( 114 if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_Decode(
95 decoder_id_, bitstream_buffer.id(), 115 decoder_id_, SyncTokens(), bitstream_buffer.handle(),
96 bitstream_buffer.handle(), bitstream_buffer.size()))) { 116 bitstream_buffer.id(), bitstream_buffer.size()))) {
97 DLOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_Decode) failed"; 117 DLOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_Decode) failed";
98 return false; 118 // TODO(fischman/vrk): signal error to client.
119 return;
99 } 120 }
100
101 return true;
102 } 121 }
103 122
104 void GpuVideoDecodeAcceleratorHost::AssignGLESBuffers( 123 void GpuVideoDecodeAcceleratorHost::AssignGLESBuffers(
105 const std::vector<media::GLESBuffer>& buffers) { 124 const std::vector<media::GLESBuffer>& buffers) {
125 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
106 // Rearrange data for IPC command. 126 // Rearrange data for IPC command.
107 std::vector<int32> buffer_ids; 127 std::vector<int32> buffer_ids;
108 std::vector<uint32> texture_ids; 128 std::vector<uint32> texture_ids;
109 std::vector<gfx::Size> sizes; 129 std::vector<gfx::Size> sizes;
110 for (uint32 i = 0; i < buffers.size(); i++) { 130 for (uint32 i = 0; i < buffers.size(); i++) {
111 const media::GLESBuffer& buffer = buffers[i]; 131 const media::GLESBuffer& buffer = buffers[i];
112 texture_ids.push_back(buffer.texture_id()); 132 texture_ids.push_back(buffer.texture_id());
113 buffer_ids.push_back(buffer.id()); 133 buffer_ids.push_back(buffer.id());
114 sizes.push_back(buffer.size()); 134 sizes.push_back(buffer.size());
115 } 135 }
116 if (!ipc_sender_->Send(new GpuChannelMsg_AssignTexturesToVideoDecoder( 136 if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_AssignTextures(
117 decoder_id_, buffer_ids, texture_ids, sizes))) { 137 decoder_id_, SyncTokens(), buffer_ids, texture_ids, sizes))) {
118 LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_AssignGLESBuffers) failed"; 138 LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_AssignGLESBuffers) failed";
119 } 139 }
120 } 140 }
121 141
122 void GpuVideoDecodeAcceleratorHost::AssignSysmemBuffers( 142 void GpuVideoDecodeAcceleratorHost::AssignSysmemBuffers(
123 const std::vector<media::SysmemBuffer>& buffers) { 143 const std::vector<media::SysmemBuffer>& buffers) {
144 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
124 // TODO(vrk): Implement. 145 // TODO(vrk): Implement.
125 NOTIMPLEMENTED(); 146 NOTIMPLEMENTED();
126 } 147 }
127 148
128 void GpuVideoDecodeAcceleratorHost::ReusePictureBuffer( 149 void GpuVideoDecodeAcceleratorHost::ReusePictureBuffer(
129 int32 picture_buffer_id) { 150 int32 picture_buffer_id) {
151 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
130 if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_ReusePictureBuffer( 152 if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_ReusePictureBuffer(
131 decoder_id_, picture_buffer_id))) { 153 decoder_id_, SyncTokens(), picture_buffer_id))) {
132 LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_ReusePictureBuffer) failed"; 154 LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_ReusePictureBuffer) failed";
133 } 155 }
134 } 156 }
135 157
136 bool GpuVideoDecodeAcceleratorHost::Flush() { 158 void GpuVideoDecodeAcceleratorHost::Flush() {
137 if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_Flush(decoder_id_))) { 159 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
160 if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_Flush(
161 decoder_id_, SyncTokens()))) {
138 LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_Flush) failed"; 162 LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_Flush) failed";
139 return false; 163 // TODO(fischman/vrk): signal error to client.
164 return;
140 } 165 }
141 return true;
142 } 166 }
143 167
144 bool GpuVideoDecodeAcceleratorHost::Abort() { 168 void GpuVideoDecodeAcceleratorHost::Abort() {
145 if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_Abort(decoder_id_))) { 169 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
170 if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_Abort(
171 decoder_id_, SyncTokens()))) {
146 LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_Abort) failed"; 172 LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_Abort) failed";
147 return false; 173 // TODO(fischman/vrk): signal error to client.
174 return;
148 } 175 }
149 return true;
150 } 176 }
151 177
152 void GpuVideoDecodeAcceleratorHost::OnBitstreamBufferProcessed( 178 void GpuVideoDecodeAcceleratorHost::OnBitstreamBufferProcessed(
153 int32 bitstream_buffer_id) { 179 int32 bitstream_buffer_id) {
180 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
154 client_->NotifyEndOfBitstreamBuffer(bitstream_buffer_id); 181 client_->NotifyEndOfBitstreamBuffer(bitstream_buffer_id);
155 } 182 }
156 183
157 void GpuVideoDecodeAcceleratorHost::OnProvidePictureBuffer( 184 void GpuVideoDecodeAcceleratorHost::OnProvidePictureBuffer(
158 uint32 num_requested_buffers, 185 uint32 num_requested_buffers,
159 const gfx::Size& buffer_size, 186 const gfx::Size& buffer_size,
160 int32 mem_type) { 187 int32 mem_type) {
188 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
161 media::VideoDecodeAccelerator::MemoryType converted_mem_type = 189 media::VideoDecodeAccelerator::MemoryType converted_mem_type =
162 static_cast<media::VideoDecodeAccelerator::MemoryType>(mem_type); 190 static_cast<media::VideoDecodeAccelerator::MemoryType>(mem_type);
163 client_->ProvidePictureBuffers( 191 client_->ProvidePictureBuffers(
164 num_requested_buffers, buffer_size, converted_mem_type); 192 num_requested_buffers, buffer_size, converted_mem_type);
165 } 193 }
166 194
167 void GpuVideoDecodeAcceleratorHost::OnDismissPictureBuffer( 195 void GpuVideoDecodeAcceleratorHost::OnDismissPictureBuffer(
168 int32 picture_buffer_id) { 196 int32 picture_buffer_id) {
197 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
169 client_->DismissPictureBuffer(picture_buffer_id); 198 client_->DismissPictureBuffer(picture_buffer_id);
170 } 199 }
171 200
172 void GpuVideoDecodeAcceleratorHost::OnCreateDone(int32 decoder_id) { 201 void GpuVideoDecodeAcceleratorHost::OnCreateDone(int32 decoder_id) {
202 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
173 decoder_id_ = decoder_id; 203 decoder_id_ = decoder_id;
174 if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_Initialize( 204 if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_Initialize(
175 decoder_id_, configs_))) { 205 decoder_id_, SyncTokens(), configs_))) {
176 LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_Initialize) failed"; 206 LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_Initialize) failed";
177 } 207 }
178 } 208 }
179 209
180 void GpuVideoDecodeAcceleratorHost::OnInitializeDone() { 210 void GpuVideoDecodeAcceleratorHost::OnInitializeDone() {
211 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
181 client_->NotifyInitializeDone(); 212 client_->NotifyInitializeDone();
182 } 213 }
183 214
184 void GpuVideoDecodeAcceleratorHost::OnPictureReady( 215 void GpuVideoDecodeAcceleratorHost::OnPictureReady(
185 int32 picture_buffer_id, int32 bitstream_buffer_id, 216 int32 picture_buffer_id, int32 bitstream_buffer_id,
186 const gfx::Size& visible_size, const gfx::Size& decoded_size) { 217 const gfx::Size& visible_size, const gfx::Size& decoded_size) {
218 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
187 media::Picture picture( 219 media::Picture picture(
188 picture_buffer_id, bitstream_buffer_id, visible_size, decoded_size); 220 picture_buffer_id, bitstream_buffer_id, visible_size, decoded_size);
189 client_->PictureReady(picture); 221 client_->PictureReady(picture);
190 } 222 }
191 223
192 void GpuVideoDecodeAcceleratorHost::OnFlushDone() { 224 void GpuVideoDecodeAcceleratorHost::OnFlushDone() {
225 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
193 client_->NotifyFlushDone(); 226 client_->NotifyFlushDone();
194 } 227 }
195 228
196 void GpuVideoDecodeAcceleratorHost::OnAbortDone() { 229 void GpuVideoDecodeAcceleratorHost::OnAbortDone() {
230 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
197 client_->NotifyAbortDone(); 231 client_->NotifyAbortDone();
198 } 232 }
199 233
200 void GpuVideoDecodeAcceleratorHost::OnEndOfStream() { 234 void GpuVideoDecodeAcceleratorHost::OnEndOfStream() {
235 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
201 client_->NotifyEndOfStream(); 236 client_->NotifyEndOfStream();
202 } 237 }
203 238
204 void GpuVideoDecodeAcceleratorHost::OnErrorNotification(uint32 error) { 239 void GpuVideoDecodeAcceleratorHost::OnErrorNotification(uint32 error) {
240 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
205 client_->NotifyError( 241 client_->NotifyError(
206 static_cast<media::VideoDecodeAccelerator::Error>(error)); 242 static_cast<media::VideoDecodeAccelerator::Error>(error));
207 } 243 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698