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

Side by Side Diff: cc/video_layer_impl.cc

Issue 11269017: Plumb through cropped output size for VideoFrame (Closed) Base URL: https://git.chromium.org/git/chromium/src@git-svn
Patch Set: Found the windows failure, and fixed it. Thanks akalin@ Created 8 years, 1 month 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
« no previous file with comments | « cc/video_layer_impl.h ('k') | cc/yuv_video_draw_quad.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 The Chromium Authors. All rights reserved. 1 // Copyright 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 "config.h" 5 #include "config.h"
6 6
7 #include "cc/video_layer_impl.h" 7 #include "cc/video_layer_impl.h"
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "cc/io_surface_draw_quad.h" 10 #include "cc/io_surface_draw_quad.h"
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 } 149 }
150 150
151 m_webFrame = m_provider->getCurrentFrame(); 151 m_webFrame = m_provider->getCurrentFrame();
152 m_frame = m_unwrapper.Run(m_webFrame); 152 m_frame = m_unwrapper.Run(m_webFrame);
153 153
154 if (!m_frame) 154 if (!m_frame)
155 return; 155 return;
156 156
157 m_format = convertVFCFormatToGLenum(*m_frame); 157 m_format = convertVFCFormatToGLenum(*m_frame);
158 158
159 // If these fail, we'll have to add draw logic that handles offset bitmap/
160 // texture UVs. For now, just expect (0, 0) offset, since all our decoders
161 // so far don't offset.
162 DCHECK_EQ(m_frame->visible_rect().x(), 0);
163 DCHECK_EQ(m_frame->visible_rect().y(), 0);
164
159 if (m_format == GL_INVALID_VALUE) { 165 if (m_format == GL_INVALID_VALUE) {
160 m_provider->putCurrentFrame(m_webFrame); 166 m_provider->putCurrentFrame(m_webFrame);
161 m_frame = 0; 167 m_frame = 0;
162 return; 168 return;
163 } 169 }
164 170
165 // FIXME: If we're in software compositing mode, we do the YUV -> RGB 171 // FIXME: If we're in software compositing mode, we do the YUV -> RGB
166 // conversion here. That involves an extra copy of each frame to a bitmap. 172 // conversion here. That involves an extra copy of each frame to a bitmap.
167 // Obviously, this is suboptimal and should be addressed once ubercompositor 173 // Obviously, this is suboptimal and should be addressed once ubercompositor
168 // starts shaping up. 174 // starts shaping up.
(...skipping 27 matching lines...) Expand all
196 if (!m_frame) 202 if (!m_frame)
197 return; 203 return;
198 204
199 SharedQuadState* sharedQuadState = quadSink.useSharedQuadState(createSharedQ uadState()); 205 SharedQuadState* sharedQuadState = quadSink.useSharedQuadState(createSharedQ uadState());
200 appendDebugBorderQuad(quadSink, sharedQuadState, appendQuadsData); 206 appendDebugBorderQuad(quadSink, sharedQuadState, appendQuadsData);
201 207
202 // FIXME: When we pass quads out of process, we need to double-buffer, or 208 // FIXME: When we pass quads out of process, we need to double-buffer, or
203 // otherwise synchonize use of all textures in the quad. 209 // otherwise synchonize use of all textures in the quad.
204 210
205 gfx::Rect quadRect(gfx::Point(), contentBounds()); 211 gfx::Rect quadRect(gfx::Point(), contentBounds());
212 gfx::Rect visibleRect = m_frame->visible_rect();
213 gfx::Size codedSize = m_frame->coded_size();
214
215 // pixels for macroblocked formats.
216 const float texWidthScale =
217 static_cast<float>(visibleRect.width()) / codedSize.width();
218 const float texHeightScale =
219 static_cast<float>(visibleRect.height()) / codedSize.height();
206 220
207 switch (m_format) { 221 switch (m_format) {
208 case GL_LUMINANCE: { 222 case GL_LUMINANCE: {
209 // YUV software decoder. 223 // YUV software decoder.
210 const FramePlane& yPlane = m_framePlanes[media::VideoFrame::kYPlane]; 224 const FramePlane& yPlane = m_framePlanes[media::VideoFrame::kYPlane];
211 const FramePlane& uPlane = m_framePlanes[media::VideoFrame::kUPlane]; 225 const FramePlane& uPlane = m_framePlanes[media::VideoFrame::kUPlane];
212 const FramePlane& vPlane = m_framePlanes[media::VideoFrame::kVPlane]; 226 const FramePlane& vPlane = m_framePlanes[media::VideoFrame::kVPlane];
213 scoped_ptr<YUVVideoDrawQuad> yuvVideoQuad = YUVVideoDrawQuad::create(sha redQuadState, quadRect, yPlane, uPlane, vPlane); 227 gfx::SizeF texScale(texWidthScale, texHeightScale);
228 scoped_ptr<YUVVideoDrawQuad> yuvVideoQuad = YUVVideoDrawQuad::create(
229 sharedQuadState, quadRect, texScale, yPlane, uPlane, vPlane);
214 quadSink.append(yuvVideoQuad.PassAs<DrawQuad>(), appendQuadsData); 230 quadSink.append(yuvVideoQuad.PassAs<DrawQuad>(), appendQuadsData);
215 break; 231 break;
216 } 232 }
217 case GL_RGBA: { 233 case GL_RGBA: {
218 // RGBA software decoder. 234 // RGBA software decoder.
219 const FramePlane& plane = m_framePlanes[media::VideoFrame::kRGBPlane]; 235 const FramePlane& plane = m_framePlanes[media::VideoFrame::kRGBPlane];
220 bool premultipliedAlpha = true; 236 bool premultipliedAlpha = true;
221 float widthScaleFactor = static_cast<float>(plane.visibleSize.width()) / plane.size.width(); 237 gfx::RectF uvRect(0, 0, texWidthScale, texHeightScale);
222 gfx::RectF uvRect(widthScaleFactor, 1);
223 bool flipped = false; 238 bool flipped = false;
224 scoped_ptr<TextureDrawQuad> textureQuad = TextureDrawQuad::create(shared QuadState, quadRect, plane.resourceId, premultipliedAlpha, uvRect, flipped); 239 scoped_ptr<TextureDrawQuad> textureQuad = TextureDrawQuad::create(shared QuadState, quadRect, plane.resourceId, premultipliedAlpha, uvRect, flipped);
225 quadSink.append(textureQuad.PassAs<DrawQuad>(), appendQuadsData); 240 quadSink.append(textureQuad.PassAs<DrawQuad>(), appendQuadsData);
226 break; 241 break;
227 } 242 }
228 case GL_TEXTURE_2D: { 243 case GL_TEXTURE_2D: {
229 // NativeTexture hardware decoder. 244 // NativeTexture hardware decoder.
230 bool premultipliedAlpha = true; 245 bool premultipliedAlpha = true;
231 gfx::RectF uvRect(1, 1); 246 gfx::RectF uvRect(0, 0, texWidthScale, texHeightScale);
232 bool flipped = false; 247 bool flipped = false;
233 scoped_ptr<TextureDrawQuad> textureQuad = TextureDrawQuad::create(shared QuadState, quadRect, m_externalTextureResource, premultipliedAlpha, uvRect, flip ped); 248 scoped_ptr<TextureDrawQuad> textureQuad = TextureDrawQuad::create(shared QuadState, quadRect, m_externalTextureResource, premultipliedAlpha, uvRect, flip ped);
234 quadSink.append(textureQuad.PassAs<DrawQuad>(), appendQuadsData); 249 quadSink.append(textureQuad.PassAs<DrawQuad>(), appendQuadsData);
235 break; 250 break;
236 } 251 }
237 case GL_TEXTURE_RECTANGLE_ARB: { 252 case GL_TEXTURE_RECTANGLE_ARB: {
238 scoped_ptr<IOSurfaceDrawQuad> ioSurfaceQuad = IOSurfaceDrawQuad::create( sharedQuadState, quadRect, m_frame->data_size(), m_frame->texture_id(), IOSurfac eDrawQuad::Unflipped); 253 gfx::Size visibleSize(visibleRect.width(), visibleRect.height());
254 scoped_ptr<IOSurfaceDrawQuad> ioSurfaceQuad = IOSurfaceDrawQuad::create( sharedQuadState, quadRect, visibleSize, m_frame->texture_id(), IOSurfaceDrawQuad ::Unflipped);
239 quadSink.append(ioSurfaceQuad.PassAs<DrawQuad>(), appendQuadsData); 255 quadSink.append(ioSurfaceQuad.PassAs<DrawQuad>(), appendQuadsData);
240 break; 256 break;
241 } 257 }
242 case GL_TEXTURE_EXTERNAL_OES: { 258 case GL_TEXTURE_EXTERNAL_OES: {
243 // StreamTexture hardware decoder. 259 // StreamTexture hardware decoder.
244 scoped_ptr<StreamVideoDrawQuad> streamVideoQuad = StreamVideoDrawQuad::c reate(sharedQuadState, quadRect, m_frame->texture_id(), m_streamTextureMatrix); 260 WebKit::WebTransformationMatrix transform(m_streamTextureMatrix);
261 transform.scaleNonUniform(texWidthScale, texHeightScale);
262 scoped_ptr<StreamVideoDrawQuad> streamVideoQuad =
263 StreamVideoDrawQuad::create(sharedQuadState, quadRect,
264 m_frame->texture_id(),
265 transform);
245 quadSink.append(streamVideoQuad.PassAs<DrawQuad>(), appendQuadsData); 266 quadSink.append(streamVideoQuad.PassAs<DrawQuad>(), appendQuadsData);
246 break; 267 break;
247 } 268 }
248 default: 269 default:
249 NOTREACHED(); // Someone updated convertVFCFormatToGLenum above but upd ate this! 270 NOTREACHED(); // Someone updated convertVFCFormatToGLenum above but upd ate this!
250 break; 271 break;
251 } 272 }
252 } 273 }
253 274
254 void VideoLayerImpl::didDraw(ResourceProvider* resourceProvider) 275 void VideoLayerImpl::didDraw(ResourceProvider* resourceProvider)
(...skipping 13 matching lines...) Expand all
268 resourceProvider->deleteResource(m_externalTextureResource); 289 resourceProvider->deleteResource(m_externalTextureResource);
269 m_externalTextureResource = 0; 290 m_externalTextureResource = 0;
270 } 291 }
271 292
272 m_provider->putCurrentFrame(m_webFrame); 293 m_provider->putCurrentFrame(m_webFrame);
273 m_frame = 0; 294 m_frame = 0;
274 295
275 m_providerLock.Release(); 296 m_providerLock.Release();
276 } 297 }
277 298
278 static int videoFrameDimension(int originalDimension, size_t plane, int format) 299 static gfx::Size videoFrameDimension(media::VideoFrame* frame, int plane) {
279 { 300 gfx::Size dimensions = frame->coded_size();
280 if (format == media::VideoFrame::YV12 && plane != media::VideoFrame::kYPlane ) 301 switch (frame->format()) {
281 return originalDimension / 2; 302 case media::VideoFrame::YV12:
282 return originalDimension; 303 if (plane != media::VideoFrame::kYPlane) {
304 dimensions.set_width(dimensions.width() / 2);
305 dimensions.set_height(dimensions.height() / 2);
306 }
307 break;
308 case media::VideoFrame::YV16:
309 if (plane != media::VideoFrame::kYPlane) {
310 dimensions.set_width(dimensions.width() / 2);
311 }
312 break;
313 default:
314 break;
315 }
316 return dimensions;
283 } 317 }
284 318
285 static bool hasPaddingBytes(const media::VideoFrame& frame, size_t plane) 319 bool VideoLayerImpl::FramePlane::allocateData(
286 { 320 ResourceProvider* resourceProvider)
287 return frame.stride(plane) > videoFrameDimension(frame.data_size().width(), plane, frame.format());
288 }
289
290 gfx::Size computeVisibleSize(const media::VideoFrame& frame, size_t plane)
291 {
292 int visibleWidth = videoFrameDimension(frame.data_size().width(), plane, fra me.format());
293 int originalWidth = visibleWidth;
294 int visibleHeight = videoFrameDimension(frame.data_size().height(), plane, f rame.format());
295
296 // When there are dead pixels at the edge of the texture, decrease
297 // the frame width by 1 to prevent the rightmost pixels from
298 // interpolating with the dead pixels.
299 if (hasPaddingBytes(frame, plane))
300 --visibleWidth;
301
302 // In YV12, every 2x2 square of Y values corresponds to one U and
303 // one V value. If we decrease the width of the UV plane, we must decrease t he
304 // width of the Y texture by 2 for proper alignment. This must happen
305 // always, even if Y's texture does not have padding bytes.
306 if (plane == media::VideoFrame::kYPlane && frame.format() == media::VideoFra me::YV12) {
307 if (hasPaddingBytes(frame, media::VideoFrame::kUPlane))
308 visibleWidth = originalWidth - 2;
309 }
310
311 return gfx::Size(visibleWidth, visibleHeight);
312 }
313
314 bool VideoLayerImpl::FramePlane::allocateData(ResourceProvider* resourceProvider )
315 { 321 {
316 if (resourceId) 322 if (resourceId)
317 return true; 323 return true;
318 324
319 resourceId = resourceProvider->createResource(Renderer::ImplPool, size, form at, ResourceProvider::TextureUsageAny); 325 resourceId = resourceProvider->createResource(Renderer::ImplPool, size, form at, ResourceProvider::TextureUsageAny);
320 return resourceId; 326 return resourceId;
321 } 327 }
322 328
323 void VideoLayerImpl::FramePlane::freeData(ResourceProvider* resourceProvider) 329 void VideoLayerImpl::FramePlane::freeData(ResourceProvider* resourceProvider)
324 { 330 {
325 if (!resourceId) 331 if (!resourceId)
326 return; 332 return;
327 333
328 resourceProvider->deleteResource(resourceId); 334 resourceProvider->deleteResource(resourceId);
329 resourceId = 0; 335 resourceId = 0;
330 } 336 }
331 337
332 bool VideoLayerImpl::allocatePlaneData(ResourceProvider* resourceProvider) 338 bool VideoLayerImpl::allocatePlaneData(ResourceProvider* resourceProvider)
333 { 339 {
334 const int maxTextureSize = resourceProvider->maxTextureSize(); 340 const int maxTextureSize = resourceProvider->maxTextureSize();
335 const size_t planeCount = numPlanes(); 341 const size_t planeCount = numPlanes();
336 for (size_t planeIndex = 0; planeIndex < planeCount; ++planeIndex) { 342 for (unsigned planeIdx = 0; planeIdx < planeCount; ++planeIdx) {
337 VideoLayerImpl::FramePlane& plane = m_framePlanes[planeIndex]; 343 VideoLayerImpl::FramePlane& plane = m_framePlanes[planeIdx];
338 344
339 gfx::Size requiredTextureSize(m_frame->stride(planeIndex), videoFrameDim ension(m_frame->data_size().height(), planeIndex, m_frame->format())); 345 gfx::Size requiredTextureSize = videoFrameDimension(m_frame, planeIdx);
340 // FIXME: Remove the test against maxTextureSize when tiled layers are i mplemented. 346 // FIXME: Remove the test against maxTextureSize when tiled layers are
341 if (requiredTextureSize.IsEmpty() || requiredTextureSize.width() > maxTe xtureSize || requiredTextureSize.height() > maxTextureSize) 347 // implemented.
348 if (requiredTextureSize.IsEmpty() ||
349 requiredTextureSize.width() > maxTextureSize ||
350 requiredTextureSize.height() > maxTextureSize)
342 return false; 351 return false;
343 352
344 if (plane.size != requiredTextureSize || plane.format != m_format) { 353 if (plane.size != requiredTextureSize || plane.format != m_format) {
345 plane.freeData(resourceProvider); 354 plane.freeData(resourceProvider);
346 plane.size = requiredTextureSize; 355 plane.size = requiredTextureSize;
347 plane.format = m_format; 356 plane.format = m_format;
348 } 357 }
349 358
350 if (!plane.resourceId) { 359 if (!plane.allocateData(resourceProvider))
351 if (!plane.allocateData(resourceProvider)) 360 return false;
352 return false;
353 plane.visibleSize = computeVisibleSize(*m_frame, planeIndex);
354 }
355 } 361 }
356 return true; 362 return true;
357 } 363 }
358 364
359 bool VideoLayerImpl::copyPlaneData(ResourceProvider* resourceProvider) 365 bool VideoLayerImpl::copyPlaneData(ResourceProvider* resourceProvider)
360 { 366 {
361 const size_t planeCount = numPlanes(); 367 const size_t planeCount = numPlanes();
362 if (!planeCount) 368 if (!planeCount)
363 return true; 369 return true;
364 370
365 if (m_convertYUV) { 371 if (m_convertYUV) {
366 if (!m_videoRenderer) 372 if (!m_videoRenderer)
367 m_videoRenderer.reset(new media::SkCanvasVideoRenderer); 373 m_videoRenderer.reset(new media::SkCanvasVideoRenderer);
368 VideoLayerImpl::FramePlane& plane = m_framePlanes[media::VideoFrame::kRG BPlane]; 374 VideoLayerImpl::FramePlane& plane = m_framePlanes[media::VideoFrame::kRG BPlane];
369 ResourceProvider::ScopedWriteLockSoftware lock(resourceProvider, plane.r esourceId); 375 ResourceProvider::ScopedWriteLockSoftware lock(resourceProvider, plane.r esourceId);
370 m_videoRenderer->Paint(m_frame, lock.skCanvas(), gfx::Rect(plane.size), 0xFF); 376 m_videoRenderer->Paint(m_frame, lock.skCanvas(), m_frame->visible_rect() , 0xFF);
371 return true; 377 return true;
372 } 378 }
373 379
374 for (size_t planeIndex = 0; planeIndex < planeCount; ++planeIndex) { 380 for (size_t planeIndex = 0; planeIndex < planeCount; ++planeIndex) {
375 VideoLayerImpl::FramePlane& plane = m_framePlanes[planeIndex]; 381 VideoLayerImpl::FramePlane& plane = m_framePlanes[planeIndex];
382 // Only non-FormatNativeTexture planes should need upload.
383 DCHECK_EQ(plane.format, GL_LUMINANCE);
376 const uint8_t* softwarePlanePixels = m_frame->data(planeIndex); 384 const uint8_t* softwarePlanePixels = m_frame->data(planeIndex);
377 gfx::Rect planeRect(gfx::Point(), plane.size); 385 gfx::Rect planeRect(gfx::Point(), plane.size);
378 resourceProvider->setPixels(plane.resourceId, softwarePlanePixels, plane Rect, planeRect, gfx::Vector2d()); 386 resourceProvider->setPixels(plane.resourceId, softwarePlanePixels, plane Rect, planeRect, gfx::Vector2d());
379 } 387 }
380 return true; 388 return true;
381 } 389 }
382 390
383 void VideoLayerImpl::freePlaneData(ResourceProvider* resourceProvider) 391 void VideoLayerImpl::freePlaneData(ResourceProvider* resourceProvider)
384 { 392 {
385 for (size_t i = 0; i < media::VideoFrame::kMaxPlanes; ++i) 393 for (size_t i = 0; i < media::VideoFrame::kMaxPlanes; ++i)
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 str->append("video layer\n"); 432 str->append("video layer\n");
425 LayerImpl::dumpLayerProperties(str, indent); 433 LayerImpl::dumpLayerProperties(str, indent);
426 } 434 }
427 435
428 const char* VideoLayerImpl::layerTypeAsString() const 436 const char* VideoLayerImpl::layerTypeAsString() const
429 { 437 {
430 return "VideoLayer"; 438 return "VideoLayer";
431 } 439 }
432 440
433 } // namespace cc 441 } // namespace cc
OLDNEW
« no previous file with comments | « cc/video_layer_impl.h ('k') | cc/yuv_video_draw_quad.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698