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

Side by Side Diff: chrome/renderer/gpu_video_decoder_host.cc

Issue 3335014: Added FakeGlVideoDecodeEngine to exercise the IPC protocol for hardware video decoding (Closed)
Patch Set: compile man... Created 10 years, 3 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
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "chrome/renderer/gpu_video_decoder_host.h" 5 #include "chrome/renderer/gpu_video_decoder_host.h"
6 6
7 #include "chrome/common/gpu_messages.h" 7 #include "chrome/common/gpu_messages.h"
8 #include "chrome/renderer/gpu_video_service_host.h" 8 #include "chrome/renderer/gpu_video_service_host.h"
9 #include "chrome/renderer/render_thread.h" 9 #include "chrome/renderer/render_thread.h"
10 10
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 } 99 }
100 100
101 void GpuVideoDecoderHost::FillThisBuffer(scoped_refptr<VideoFrame> frame) { 101 void GpuVideoDecoderHost::FillThisBuffer(scoped_refptr<VideoFrame> frame) {
102 DCHECK_NE(state_, kStateUninitialized); 102 DCHECK_NE(state_, kStateUninitialized);
103 103
104 // Depends on who provides buffer. client could return buffer to 104 // Depends on who provides buffer. client could return buffer to
105 // us while flushing. 105 // us while flushing.
106 if (state_ == kStateError) 106 if (state_ == kStateError)
107 return; 107 return;
108 108
109 // TODO(hclam): We should keep an IDMap to convert between a frame a buffer
110 // ID so that we can signal GpuVideoDecoder in GPU process to use the buffer.
111 // This eliminates one conversion step.
109 GpuVideoDecoderOutputBufferParam param; 112 GpuVideoDecoderOutputBufferParam param;
113
114 // TODO(hclam): This is a hack to pass the texture id to the hardware video
115 // decoder. We should have created a mapping between VideoFrame and buffer id
116 // and we pass the buffer id to the GPU process.
117 param.texture = frame->gl_texture(VideoFrame::kRGBPlane);
110 if (!channel_host_ || !channel_host_->Send( 118 if (!channel_host_ || !channel_host_->Send(
111 new GpuVideoDecoderMsg_FillThisBuffer(route_id(), param))) { 119 new GpuVideoDecoderMsg_FillThisBuffer(route_id(), param))) {
112 LOG(ERROR) << "GpuVideoDecoderMsg_FillThisBuffer failed"; 120 LOG(ERROR) << "GpuVideoDecoderMsg_FillThisBuffer failed";
113 } 121 }
114 } 122 }
115 123
116 bool GpuVideoDecoderHost::Flush() { 124 bool GpuVideoDecoderHost::Flush() {
117 state_ = kStateFlushing; 125 state_ = kStateFlushing;
118 if (!channel_host_ || !channel_host_->Send( 126 if (!channel_host_ || !channel_host_->Send(
119 new GpuVideoDecoderMsg_Flush(route_id()))) { 127 new GpuVideoDecoderMsg_Flush(route_id()))) {
120 LOG(ERROR) << "GpuVideoDecoderMsg_Flush failed"; 128 LOG(ERROR) << "GpuVideoDecoderMsg_Flush failed";
121 return false; 129 return false;
122 } 130 }
123 input_buffer_queue_.clear(); 131 input_buffer_queue_.clear();
124 // TODO(jiesun): because GpuVideoDeocder/GpuVideoDecoder are asynchronously. 132 // TODO(jiesun): because GpuVideoDeocder/GpuVideoDecoder are asynchronously.
125 // We need a way to make flush logic more clear. but I think ring buffer 133 // We need a way to make flush logic more clear. but I think ring buffer
126 // should make the busy flag obsolete, therefore I will leave it for now. 134 // should make the busy flag obsolete, therefore I will leave it for now.
127 input_buffer_busy_ = false; 135 input_buffer_busy_ = false;
128 return true; 136 return true;
129 } 137 }
130 138
131 void GpuVideoDecoderHost::OnInitializeDone( 139 void GpuVideoDecoderHost::OnInitializeDone(
132 const GpuVideoDecoderInitDoneParam& param) { 140 const GpuVideoDecoderInitDoneParam& param) {
133 done_param_ = param; 141 done_param_ = param;
134 bool success = false; 142 bool success = false;
135 143
136 do { 144 do {
137 if (!param.success_) 145 if (!param.success)
138 break; 146 break;
139 147
140 if (!base::SharedMemory::IsHandleValid(param.input_buffer_handle_)) 148 if (!base::SharedMemory::IsHandleValid(param.input_buffer_handle))
141 break; 149 break;
142 input_transfer_buffer_.reset( 150 input_transfer_buffer_.reset(
143 new base::SharedMemory(param.input_buffer_handle_, false)); 151 new base::SharedMemory(param.input_buffer_handle, false));
144 if (!input_transfer_buffer_->Map(param.input_buffer_size_)) 152 if (!input_transfer_buffer_->Map(param.input_buffer_size))
145 break; 153 break;
146 154
147 if (!base::SharedMemory::IsHandleValid(param.output_buffer_handle_)) 155 if (!base::SharedMemory::IsHandleValid(param.output_buffer_handle))
148 break; 156 break;
149 output_transfer_buffer_.reset( 157 output_transfer_buffer_.reset(
150 new base::SharedMemory(param.output_buffer_handle_, false)); 158 new base::SharedMemory(param.output_buffer_handle, false));
151 if (!output_transfer_buffer_->Map(param.output_buffer_size_)) 159 if (!output_transfer_buffer_->Map(param.output_buffer_size))
152 break; 160 break;
153 161
154 success = true; 162 success = true;
155 } while (0); 163 } while (0);
156 164
157 state_ = success ? kStateNormal : kStateError; 165 state_ = success ? kStateNormal : kStateError;
158 event_handler_->OnInitializeDone(success, param); 166 event_handler_->OnInitializeDone(success, param);
159 } 167 }
160 168
161 void GpuVideoDecoderHost::OnUninitializeDone() { 169 void GpuVideoDecoderHost::OnUninitializeDone() {
(...skipping 10 matching lines...) Expand all
172 180
173 void GpuVideoDecoderHost::OnEmptyThisBufferDone() { 181 void GpuVideoDecoderHost::OnEmptyThisBufferDone() {
174 scoped_refptr<Buffer> buffer; 182 scoped_refptr<Buffer> buffer;
175 event_handler_->OnEmptyBufferDone(buffer); 183 event_handler_->OnEmptyBufferDone(buffer);
176 } 184 }
177 185
178 void GpuVideoDecoderHost::OnFillThisBufferDone( 186 void GpuVideoDecoderHost::OnFillThisBufferDone(
179 const GpuVideoDecoderOutputBufferParam& param) { 187 const GpuVideoDecoderOutputBufferParam& param) {
180 scoped_refptr<VideoFrame> frame; 188 scoped_refptr<VideoFrame> frame;
181 189
182 if (param.flags_ & GpuVideoDecoderOutputBufferParam::kFlagsEndOfStream) { 190 if (param.flags & GpuVideoDecoderOutputBufferParam::kFlagsEndOfStream) {
183 VideoFrame::CreateEmptyFrame(&frame); 191 VideoFrame::CreateEmptyFrame(&frame);
184 } else { 192 } else if (done_param_.surface_type ==
193 GpuVideoDecoderInitDoneParam::SurfaceTypeSystemMemory) {
185 VideoFrame::CreateFrame(VideoFrame::YV12, 194 VideoFrame::CreateFrame(VideoFrame::YV12,
186 init_param_.width_, 195 init_param_.width,
187 init_param_.height_, 196 init_param_.height,
188 base::TimeDelta::FromMicroseconds(param.timestamp_), 197 base::TimeDelta::FromMicroseconds(param.timestamp),
189 base::TimeDelta::FromMicroseconds(param.duration_), 198 base::TimeDelta::FromMicroseconds(param.duration),
190 &frame); 199 &frame);
191
192 uint8* src = static_cast<uint8*>(output_transfer_buffer_->memory()); 200 uint8* src = static_cast<uint8*>(output_transfer_buffer_->memory());
193 uint8* data0 = frame->data(0); 201 uint8* data0 = frame->data(0);
194 uint8* data1 = frame->data(1); 202 uint8* data1 = frame->data(1);
195 uint8* data2 = frame->data(2); 203 uint8* data2 = frame->data(2);
196 int32 size = init_param_.width_ * init_param_.height_; 204 int32 size = init_param_.width * init_param_.height;
197 memcpy(data0, src, size); 205 memcpy(data0, src, size);
198 memcpy(data1, src + size, size / 4); 206 memcpy(data1, src + size, size / 4);
199 memcpy(data2, src + size + size / 4, size / 4); 207 memcpy(data2, src + size + size / 4, size / 4);
208 } else if (done_param_.surface_type ==
209 GpuVideoDecoderInitDoneParam::SurfaceTypeGlTexture) {
210 // TODO(hclam): The logic in buffer allocation is pretty much around
211 // using shared memory for output buffer which needs to be adjusted. For
212 // now we have to add this hack to get the texture id.
213 VideoFrame::GlTexture textures[3] = { param.texture, 0, 0 };
214 media::VideoFrame::CreateFrameGlTexture(
215 media::VideoFrame::RGBA, init_param_.width, init_param_.height,
216 textures,
217 base::TimeDelta::FromMicroseconds(param.timestamp),
218 base::TimeDelta::FromMicroseconds(param.duration),
219 &frame);
200 } 220 }
201 221
202 event_handler_->OnFillBufferDone(frame); 222 event_handler_->OnFillBufferDone(frame);
203 if (!channel_host_ || !channel_host_->Send( 223 if (!channel_host_ || !channel_host_->Send(
204 new GpuVideoDecoderMsg_FillThisBufferDoneACK(route_id()))) { 224 new GpuVideoDecoderMsg_FillThisBufferDoneACK(route_id()))) {
205 LOG(ERROR) << "GpuVideoDecoderMsg_FillThisBufferDoneACK failed"; 225 LOG(ERROR) << "GpuVideoDecoderMsg_FillThisBufferDoneACK failed";
206 } 226 }
207 } 227 }
208 228
209 void GpuVideoDecoderHost::OnEmptyThisBufferACK() { 229 void GpuVideoDecoderHost::OnEmptyThisBufferACK() {
210 input_buffer_busy_ = false; 230 input_buffer_busy_ = false;
211 SendInputBufferToGpu(); 231 SendInputBufferToGpu();
212 } 232 }
213 233
214 void GpuVideoDecoderHost::SendInputBufferToGpu() { 234 void GpuVideoDecoderHost::SendInputBufferToGpu() {
215 if (input_buffer_busy_) return; 235 if (input_buffer_busy_) return;
216 if (input_buffer_queue_.empty()) return; 236 if (input_buffer_queue_.empty()) return;
217 237
218 input_buffer_busy_ = true; 238 input_buffer_busy_ = true;
219 239
220 scoped_refptr<Buffer> buffer; 240 scoped_refptr<Buffer> buffer;
221 buffer = input_buffer_queue_.front(); 241 buffer = input_buffer_queue_.front();
222 input_buffer_queue_.pop_front(); 242 input_buffer_queue_.pop_front();
223 243
224 // Send input data to GPU process. 244 // Send input data to GPU process.
225 GpuVideoDecoderInputBufferParam param; 245 GpuVideoDecoderInputBufferParam param;
226 param.offset_ = 0; 246 param.offset = 0;
227 param.size_ = buffer->GetDataSize(); 247 param.size = buffer->GetDataSize();
228 param.timestamp_ = buffer->GetTimestamp().InMicroseconds(); 248 param.timestamp = buffer->GetTimestamp().InMicroseconds();
229 memcpy(input_transfer_buffer_->memory(), buffer->GetData(), param.size_); 249 memcpy(input_transfer_buffer_->memory(), buffer->GetData(), param.size);
230 if (!channel_host_ || !channel_host_->Send( 250 if (!channel_host_ || !channel_host_->Send(
231 new GpuVideoDecoderMsg_EmptyThisBuffer(route_id(), param))) { 251 new GpuVideoDecoderMsg_EmptyThisBuffer(route_id(), param))) {
232 LOG(ERROR) << "GpuVideoDecoderMsg_EmptyThisBuffer failed"; 252 LOG(ERROR) << "GpuVideoDecoderMsg_EmptyThisBuffer failed";
233 } 253 }
234 } 254 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698