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

Side by Side Diff: chrome/gpu/gpu_video_decoder.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/gpu/gpu_video_decoder.h" 5 #include "chrome/gpu/gpu_video_decoder.h"
6 6
7 #include "chrome/common/gpu_messages.h" 7 #include "chrome/common/gpu_messages.h"
8 #include "chrome/gpu/gpu_channel.h" 8 #include "chrome/gpu/gpu_channel.h"
9 #include "chrome/gpu/media/fake_gl_video_decode_engine.h"
9 #include "media/base/data_buffer.h" 10 #include "media/base/data_buffer.h"
10 #include "media/base/video_frame.h" 11 #include "media/base/video_frame.h"
11 12
12 void GpuVideoDecoder::OnChannelConnected(int32 peer_pid) { 13 void GpuVideoDecoder::OnChannelConnected(int32 peer_pid) {
13 } 14 }
14 15
15 void GpuVideoDecoder::OnChannelError() { 16 void GpuVideoDecoder::OnChannelError() {
16 } 17 }
17 18
18 void GpuVideoDecoder::OnMessageReceived(const IPC::Message& msg) { 19 void GpuVideoDecoder::OnMessageReceived(const IPC::Message& msg) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 return true; 72 return true;
72 } 73 }
73 74
74 void GpuVideoDecoder::CreateVideoFrameOnTransferBuffer() { 75 void GpuVideoDecoder::CreateVideoFrameOnTransferBuffer() {
75 const base::TimeDelta kZero; 76 const base::TimeDelta kZero;
76 uint8* data[media::VideoFrame::kMaxPlanes]; 77 uint8* data[media::VideoFrame::kMaxPlanes];
77 int32 strides[media::VideoFrame::kMaxPlanes]; 78 int32 strides[media::VideoFrame::kMaxPlanes];
78 memset(data, 0, sizeof(data)); 79 memset(data, 0, sizeof(data));
79 memset(strides, 0, sizeof(strides)); 80 memset(strides, 0, sizeof(strides));
80 data[0] = static_cast<uint8*>(output_transfer_buffer_->memory()); 81 data[0] = static_cast<uint8*>(output_transfer_buffer_->memory());
81 data[1] = data[0] + config_.width_ * config_.height_; 82 data[1] = data[0] + config_.width * config_.height;
82 data[2] = data[1] + config_.width_ * config_.height_ / 4; 83 data[2] = data[1] + config_.width * config_.height / 4;
83 strides[0] = config_.width_; 84 strides[0] = config_.width;
84 strides[1] = strides[2] = config_.width_ >> 1; 85 strides[1] = strides[2] = config_.width >> 1;
85 media::VideoFrame:: CreateFrameExternal( 86 media::VideoFrame:: CreateFrameExternal(
86 media::VideoFrame::TYPE_SYSTEM_MEMORY, 87 media::VideoFrame::TYPE_SYSTEM_MEMORY,
87 media::VideoFrame::YV12, 88 media::VideoFrame::YV12,
88 config_.width_, config_.height_, 3, 89 config_.width, config_.height, 3,
89 data, strides, 90 data, strides,
90 kZero, kZero, 91 kZero, kZero,
91 NULL, 92 NULL,
92 &frame_); 93 &frame_);
93 } 94 }
94 95
95 void GpuVideoDecoder::OnInitializeComplete(const VideoCodecInfo& info) { 96 void GpuVideoDecoder::OnInitializeComplete(const VideoCodecInfo& info) {
96 info_ = info; 97 info_ = info;
97 GpuVideoDecoderInitDoneParam param; 98 GpuVideoDecoderInitDoneParam param;
98 param.success_ = false; 99 param.success = false;
99 param.input_buffer_handle_ = base::SharedMemory::NULLHandle(); 100 param.input_buffer_handle = base::SharedMemory::NULLHandle();
100 param.output_buffer_handle_ = base::SharedMemory::NULLHandle(); 101 param.output_buffer_handle = base::SharedMemory::NULLHandle();
101 102
102 if (!info.success_) { 103 if (!info.success) {
103 SendInitializeDone(param); 104 SendInitializeDone(param);
104 return; 105 return;
105 } 106 }
106 107
107 // Translate surface type. 108 // Translate surface type.
108 switch (info.stream_info_.surface_type_) { 109 param.surface_type = static_cast<GpuVideoDecoderInitDoneParam::SurfaceType>(
109 case VideoFrame::TYPE_SYSTEM_MEMORY: 110 info.stream_info.surface_type);
110 param.surface_type_ =
111 GpuVideoDecoderInitDoneParam::SurfaceTypeSystemMemory;
112 break;
113 default:
114 NOTREACHED();
115 }
116 111
117 // Translate surface format. 112 // Translate surface format.
118 switch (info.stream_info_.surface_format_) { 113 switch (info.stream_info.surface_format) {
119 case VideoFrame::YV12: 114 case VideoFrame::YV12:
120 param.format_ = GpuVideoDecoderInitDoneParam::SurfaceFormat_YV12; 115 param.format = GpuVideoDecoderInitDoneParam::SurfaceFormat_YV12;
121 break; 116 break;
117 case VideoFrame::RGBA:
118 param.format = GpuVideoDecoderInitDoneParam::SurfaceFormat_RGBA;
122 default: 119 default:
123 NOTREACHED(); 120 NOTREACHED();
124 } 121 }
125 122
126 // TODO(jiesun): Check the assumption of input size < original size. 123 // TODO(jiesun): Check the assumption of input size < original size.
127 param.input_buffer_size_ = config_.width_ * config_.height_ * 3 / 2; 124 param.input_buffer_size = config_.width * config_.height * 3 / 2;
128 if (!CreateInputTransferBuffer(param.input_buffer_size_, 125 if (!CreateInputTransferBuffer(param.input_buffer_size,
129 &param.input_buffer_handle_)) { 126 &param.input_buffer_handle)) {
130 SendInitializeDone(param); 127 SendInitializeDone(param);
131 return; 128 return;
132 } 129 }
133 130
134 if (info.stream_info_.surface_type_ == VideoFrame::TYPE_SYSTEM_MEMORY) { 131 if (info.stream_info.surface_type == VideoFrame::TYPE_SYSTEM_MEMORY) {
135 // TODO(jiesun): Allocate this according to the surface format. 132 // TODO(jiesun): Allocate this according to the surface format.
136 // The format actually could change during streaming, we need to 133 // The format actually could change during streaming, we need to
137 // notify GpuVideoDecoderHost side when this happened and renegotiate 134 // notify GpuVideoDecoderHost side when this happened and renegotiate
138 // the transfer buffer. 135 // the transfer buffer.
139 136 switch (info.stream_info.surface_format) {
140 switch (info.stream_info_.surface_format_) {
141 case VideoFrame::YV12: 137 case VideoFrame::YV12:
142 // TODO(jiesun): take stride into account. 138 // TODO(jiesun): take stride into account.
143 param.output_buffer_size_ = 139 param.output_buffer_size =
144 config_.width_ * config_.height_ * 3 / 2; 140 config_.width * config_.height * 3 / 2;
145 break; 141 break;
146 default: 142 default:
147 NOTREACHED(); 143 NOTREACHED();
148 } 144 }
149 145
150 if (!CreateOutputTransferBuffer(param.output_buffer_size_, 146 if (!CreateOutputTransferBuffer(param.output_buffer_size,
151 &param.output_buffer_handle_)) { 147 &param.output_buffer_handle)) {
152 SendInitializeDone(param); 148 SendInitializeDone(param);
153 return; 149 return;
154 } 150 }
155
156 CreateVideoFrameOnTransferBuffer(); 151 CreateVideoFrameOnTransferBuffer();
157 } 152 }
158 153
159 param.success_ = true; 154 param.success = true;
160 155
161 SendInitializeDone(param); 156 SendInitializeDone(param);
162 } 157 }
163 158
164 void GpuVideoDecoder::OnUninitializeComplete() { 159 void GpuVideoDecoder::OnUninitializeComplete() {
165 SendUninitializeDone(); 160 SendUninitializeDone();
166 } 161 }
167 162
168 void GpuVideoDecoder::OnFlushComplete() { 163 void GpuVideoDecoder::OnFlushComplete() {
169 SendFlushDone(); 164 SendFlushDone();
(...skipping 10 matching lines...) Expand all
180 void GpuVideoDecoder::OnFormatChange(VideoStreamInfo stream_info) { 175 void GpuVideoDecoder::OnFormatChange(VideoStreamInfo stream_info) {
181 NOTIMPLEMENTED(); 176 NOTIMPLEMENTED();
182 } 177 }
183 178
184 void GpuVideoDecoder::ProduceVideoSample(scoped_refptr<Buffer> buffer) { 179 void GpuVideoDecoder::ProduceVideoSample(scoped_refptr<Buffer> buffer) {
185 SendEmptyBufferDone(); 180 SendEmptyBufferDone();
186 } 181 }
187 182
188 void GpuVideoDecoder::ConsumeVideoFrame(scoped_refptr<VideoFrame> frame) { 183 void GpuVideoDecoder::ConsumeVideoFrame(scoped_refptr<VideoFrame> frame) {
189 GpuVideoDecoderOutputBufferParam output_param; 184 GpuVideoDecoderOutputBufferParam output_param;
190 output_param.timestamp_ = frame->GetTimestamp().InMicroseconds(); 185 output_param.timestamp = frame->GetTimestamp().InMicroseconds();
191 output_param.duration_ = frame->GetDuration().InMicroseconds(); 186 output_param.duration = frame->GetDuration().InMicroseconds();
192 output_param.flags_ = frame->IsEndOfStream() ? 187 output_param.flags = frame->IsEndOfStream() ?
193 GpuVideoDecoderOutputBufferParam::kFlagsEndOfStream : 0; 188 GpuVideoDecoderOutputBufferParam::kFlagsEndOfStream : 0;
189 // TODO(hclam): We should have the conversion between VideoFrame and the
190 // IPC transport param done in GpuVideoDecodeContext.
191 // This is a hack to pass texture back as a param.
192 output_param.texture = frame->gl_texture(media::VideoFrame::kRGBPlane);
194 SendFillBufferDone(output_param); 193 SendFillBufferDone(output_param);
195 } 194 }
196 195
197 GpuVideoDecoder::GpuVideoDecoder( 196 GpuVideoDecoder::GpuVideoDecoder(
198 const GpuVideoDecoderInfoParam* param, 197 const GpuVideoDecoderInfoParam* param,
199 GpuChannel* channel, 198 GpuChannel* channel,
200 base::ProcessHandle handle, 199 base::ProcessHandle handle,
201 gpu::gles2::GLES2Decoder* decoder) 200 gpu::gles2::GLES2Decoder* decoder)
202 : decoder_host_route_id_(param->decoder_host_route_id), 201 : decoder_host_route_id_(param->decoder_host_route_id),
203 output_transfer_buffer_busy_(false), 202 output_transfer_buffer_busy_(false),
204 pending_output_requests_(0), 203 pending_output_requests_(0),
205 channel_(channel), 204 channel_(channel),
206 renderer_handle_(handle), 205 renderer_handle_(handle),
207 gles2_decoder_(decoder) { 206 gles2_decoder_(decoder) {
208 memset(&config_, 0, sizeof(config_)); 207 memset(&config_, 0, sizeof(config_));
209 memset(&info_, 0, sizeof(info_)); 208 memset(&info_, 0, sizeof(info_));
210 #if defined(OS_WIN) && defined(ENABLE_GPU_DECODER) 209
211 // TODO(jiesun): find a better way to determine which GpuVideoDecoder 210 // TODO(jiesun): find a better way to determine which VideoDecodeEngine
212 // to return on current platform. 211 // to return on current platform.
213 decode_engine_.reset(new GpuVideoDecoderMFT()); 212 decode_engine_.reset(new FakeGlVideoDecodeEngine());
214 #else
215 #endif
216 } 213 }
217 214
218 void GpuVideoDecoder::OnInitialize(const GpuVideoDecoderInitParam& param) { 215 void GpuVideoDecoder::OnInitialize(const GpuVideoDecoderInitParam& param) {
216 // TODO(hclam): Initialize the VideoDecodeContext first.
217
219 // TODO(jiesun): codec id should come from |param|. 218 // TODO(jiesun): codec id should come from |param|.
220 config_.codec_ = media::kCodecH264; 219 config_.codec = media::kCodecH264;
221 config_.width_ = param.width_; 220 config_.width = param.width;
222 config_.height_ = param.height_; 221 config_.height = param.height;
223 config_.opaque_context_ = NULL; 222 config_.opaque_context = NULL;
224 decode_engine_->Initialize(NULL, this, config_); 223 decode_engine_->Initialize(NULL, this, config_);
225 } 224 }
226 225
227 void GpuVideoDecoder::OnUninitialize() { 226 void GpuVideoDecoder::OnUninitialize() {
228 decode_engine_->Uninitialize(); 227 decode_engine_->Uninitialize();
229 } 228 }
230 229
231 void GpuVideoDecoder::OnFlush() { 230 void GpuVideoDecoder::OnFlush() {
232 // TODO(jiesun): this is wrong?? 231 // TODO(jiesun): this is wrong??
233 output_transfer_buffer_busy_ = false; 232 output_transfer_buffer_busy_ = false;
234 pending_output_requests_ = 0; 233 pending_output_requests_ = 0;
235 234
236 decode_engine_->Flush(); 235 decode_engine_->Flush();
237 } 236 }
238 237
239 void GpuVideoDecoder::OnEmptyThisBuffer( 238 void GpuVideoDecoder::OnEmptyThisBuffer(
240 const GpuVideoDecoderInputBufferParam& buffer) { 239 const GpuVideoDecoderInputBufferParam& buffer) {
241 DCHECK(input_transfer_buffer_->memory()); 240 DCHECK(input_transfer_buffer_->memory());
242 241
243 uint8* src = static_cast<uint8*>(input_transfer_buffer_->memory()); 242 uint8* src = static_cast<uint8*>(input_transfer_buffer_->memory());
244 243
245 scoped_refptr<Buffer> input_buffer; 244 scoped_refptr<Buffer> input_buffer;
246 uint8* dst = buffer.size_ ? new uint8[buffer.size_] : NULL; 245 uint8* dst = buffer.size ? new uint8[buffer.size] : NULL;
247 input_buffer = new media::DataBuffer(dst, buffer.size_); 246 input_buffer = new media::DataBuffer(dst, buffer.size);
248 memcpy(dst, src, buffer.size_); 247 memcpy(dst, src, buffer.size);
249 SendEmptyBufferACK(); 248 SendEmptyBufferACK();
250 249
251 decode_engine_->ConsumeVideoSample(input_buffer); 250 decode_engine_->ConsumeVideoSample(input_buffer);
252 } 251 }
252
253 void GpuVideoDecoder::OnFillThisBuffer( 253 void GpuVideoDecoder::OnFillThisBuffer(
254 const GpuVideoDecoderOutputBufferParam& frame) { 254 const GpuVideoDecoderOutputBufferParam& param) {
255 if (info_.stream_info_.surface_type_ == VideoFrame::TYPE_SYSTEM_MEMORY) { 255 // Switch context before calling to the decode engine.
256 // TODO(hclam): This is temporary to allow FakeGlVideoDecodeEngine to issue
257 // GL commands correctly.
258 bool ret = gles2_decoder_->MakeCurrent();
259 DCHECK(ret) << "Failed to switch context";
260
261 if (info_.stream_info.surface_type == VideoFrame::TYPE_SYSTEM_MEMORY) {
256 pending_output_requests_++; 262 pending_output_requests_++;
257 if (!output_transfer_buffer_busy_) { 263 if (!output_transfer_buffer_busy_) {
258 output_transfer_buffer_busy_ = true; 264 output_transfer_buffer_busy_ = true;
259 decode_engine_->ProduceVideoFrame(frame_); 265 decode_engine_->ProduceVideoFrame(frame_);
260 } 266 }
261 } else { 267 } else {
262 decode_engine_->ProduceVideoFrame(frame_); 268 // TODO(hclam): I need to rethink how to delegate calls to
269 // VideoDecodeEngine, I may need to create a GpuVideoDecodeContext that
270 // provides a method for me to make calls to VideoDecodeEngine with the
271 // correct VideoFrame.
272 DCHECK_EQ(VideoFrame::TYPE_GL_TEXTURE, info_.stream_info.surface_type);
273
274 scoped_refptr<media::VideoFrame> frame;
275 VideoFrame::GlTexture textures[3] = { param.texture, 0, 0 };
276
277 media::VideoFrame:: CreateFrameGlTexture(
278 media::VideoFrame::RGBA, config_.width, config_.height, textures,
279 base::TimeDelta(), base::TimeDelta(), &frame);
280 decode_engine_->ProduceVideoFrame(frame);
263 } 281 }
264 } 282 }
265 283
266 void GpuVideoDecoder::OnFillThisBufferDoneACK() { 284 void GpuVideoDecoder::OnFillThisBufferDoneACK() {
267 if (info_.stream_info_.surface_type_ == VideoFrame::TYPE_SYSTEM_MEMORY) { 285 if (info_.stream_info.surface_type == VideoFrame::TYPE_SYSTEM_MEMORY) {
268 output_transfer_buffer_busy_ = false; 286 output_transfer_buffer_busy_ = false;
269 pending_output_requests_--; 287 pending_output_requests_--;
270 if (pending_output_requests_) { 288 if (pending_output_requests_) {
271 output_transfer_buffer_busy_ = true; 289 output_transfer_buffer_busy_ = true;
272 decode_engine_->ProduceVideoFrame(frame_); 290 decode_engine_->ProduceVideoFrame(frame_);
273 } 291 }
274 } 292 }
275 } 293 }
276 294
277 void GpuVideoDecoder::SendInitializeDone( 295 void GpuVideoDecoder::SendInitializeDone(
(...skipping 24 matching lines...) Expand all
302 } 320 }
303 321
304 void GpuVideoDecoder::SendEmptyBufferACK() { 322 void GpuVideoDecoder::SendEmptyBufferACK() {
305 if (!channel_->Send( 323 if (!channel_->Send(
306 new GpuVideoDecoderHostMsg_EmptyThisBufferACK(route_id()))) { 324 new GpuVideoDecoderHostMsg_EmptyThisBufferACK(route_id()))) {
307 LOG(ERROR) << "GpuVideoDecoderMsg_EmptyThisBufferACK failed"; 325 LOG(ERROR) << "GpuVideoDecoderMsg_EmptyThisBufferACK failed";
308 } 326 }
309 } 327 }
310 328
311 void GpuVideoDecoder::SendFillBufferDone( 329 void GpuVideoDecoder::SendFillBufferDone(
312 const GpuVideoDecoderOutputBufferParam& frame) { 330 const GpuVideoDecoderOutputBufferParam& param) {
313 if (!channel_->Send( 331 if (!channel_->Send(
314 new GpuVideoDecoderHostMsg_FillThisBufferDone(route_id(), frame))) { 332 new GpuVideoDecoderHostMsg_FillThisBufferDone(route_id(), param))) {
315 LOG(ERROR) << "GpuVideoDecoderMsg_FillThisBufferDone failed"; 333 LOG(ERROR) << "GpuVideoDecoderMsg_FillThisBufferDone failed";
316 } 334 }
317 } 335 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698