video_frame.cc revision 3240926e260ce088908e02ac07a6cf7b0c0cbf44
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/video_frame.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <algorithm> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/callback_helpers.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/aligned_memory.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_piece.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/limits.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/video_util.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::CreateFrame( 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoFrame::Format format, 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& coded_size, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& visible_rect, 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& natural_size, 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta timestamp) { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsValidConfig(format, coded_size, visible_rect, natural_size)); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<VideoFrame> frame(new VideoFrame( 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) format, coded_size, visible_rect, natural_size, timestamp)); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (format) { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case VideoFrame::RGB32: 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame->AllocateRGB(4u); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case VideoFrame::YV12: 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case VideoFrame::YV12A: 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case VideoFrame::YV16: 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame->AllocateYUV(); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(FATAL) << "Unsupported frame format: " << format; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return frame; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 463240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochstd::string VideoFrame::FormatToString(VideoFrame::Format format) { 473240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch switch (format) { 483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch case VideoFrame::INVALID: 493240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return "INVALID"; 503240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch case VideoFrame::RGB32: 513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return "RGB32"; 523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch case VideoFrame::YV12: 533240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return "YV12"; 543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch case VideoFrame::YV16: 553240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return "YV16"; 563240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch case VideoFrame::EMPTY: 573240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return "EMPTY"; 583240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch case VideoFrame::I420: 593240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return "I420"; 603240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch case VideoFrame::NATIVE_TEXTURE: 613240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return "NATIVE_TEXTURE"; 623240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#if defined(GOOGLE_TV) 633240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch case VideoFrame::HOLE: 643240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return "HOLE"; 653240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#endif 663240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch case VideoFrame::YV12A: 673240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return "YV12A"; 683240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 693240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch NOTREACHED() << "Invalid videoframe format provided: " << format; 703240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return ""; 713240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch} 723240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 733240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// static 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VideoFrame::IsValidConfig(VideoFrame::Format format, 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& coded_size, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& visible_rect, 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& natural_size) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (format != VideoFrame::INVALID && 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !coded_size.IsEmpty() && 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coded_size.GetArea() <= limits::kMaxCanvas && 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coded_size.width() <= limits::kMaxDimension && 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coded_size.height() <= limits::kMaxDimension && 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !visible_rect.IsEmpty() && 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visible_rect.x() >= 0 && visible_rect.y() >= 0 && 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visible_rect.right() <= coded_size.width() && 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visible_rect.bottom() <= coded_size.height() && 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !natural_size.IsEmpty() && 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) natural_size.GetArea() <= limits::kMaxCanvas && 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) natural_size.width() <= limits::kMaxDimension && 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) natural_size.height() <= limits::kMaxDimension); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::WrapNativeTexture( 95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const scoped_refptr<MailboxHolder>& mailbox_holder, 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 texture_target, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& coded_size, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& visible_rect, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& natural_size, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta timestamp, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ReadPixelsCB& read_pixels_cb, 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Closure& no_longer_needed_cb) { 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<VideoFrame> frame(new VideoFrame( 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NATIVE_TEXTURE, coded_size, visible_rect, natural_size, timestamp)); 105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch frame->texture_mailbox_holder_ = mailbox_holder; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame->texture_target_ = texture_target; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame->read_pixels_cb_ = read_pixels_cb; 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frame->no_longer_needed_cb_ = no_longer_needed_cb; 109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return frame; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void VideoFrame::ReadPixelsFromNativeTexture(const SkBitmap& pixels) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(format_, NATIVE_TEXTURE); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!read_pixels_cb_.is_null()) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_pixels_cb_.Run(pixels); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::WrapExternalYuvData( 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Format format, 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Size& coded_size, 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Rect& visible_rect, 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Size& natural_size, 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32 y_stride, int32 u_stride, int32 v_stride, 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint8* y_data, uint8* u_data, uint8* v_data, 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta timestamp, 128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::SharedMemoryHandle shm_handle, 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Closure& no_longer_needed_cb) { 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(format == YV12 || format == YV16 || format == I420) << format; 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<VideoFrame> frame(new VideoFrame( 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) format, coded_size, visible_rect, natural_size, timestamp)); 133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch frame->shared_memory_handle_ = shm_handle; 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frame->strides_[kYPlane] = y_stride; 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frame->strides_[kUPlane] = u_stride; 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frame->strides_[kVPlane] = v_stride; 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frame->data_[kYPlane] = y_data; 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frame->data_[kUPlane] = u_data; 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frame->data_[kVPlane] = v_data; 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frame->no_longer_needed_cb_ = no_longer_needed_cb; 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return frame; 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::CreateEmptyFrame() { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new VideoFrame( 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoFrame::EMPTY, gfx::Size(), gfx::Rect(), gfx::Size(), 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta()); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::CreateColorFrame( 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& size, 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8 y, uint8 u, uint8 v, 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta timestamp) { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsValidConfig(VideoFrame::YV12, size, gfx::Rect(size), size)); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<VideoFrame> frame = VideoFrame::CreateFrame( 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoFrame::YV12, size, gfx::Rect(size), size, timestamp); 159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FillYUV(frame.get(), y, u, v); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return frame; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::CreateBlackFrame(const gfx::Size& size) { 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8 kBlackY = 0x00; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8 kBlackUV = 0x80; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeDelta kZero; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CreateColorFrame(size, kBlackY, kBlackUV, kBlackUV, kZero); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(GOOGLE_TV) 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This block and other blocks wrapped around #if defined(GOOGLE_TV) is not 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// maintained by the general compositor team. Please contact the following 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// people instead: 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// wonsik@chromium.org 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ycheo@chromium.org 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::CreateHoleFrame( 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Size& size) { 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(IsValidConfig(VideoFrame::HOLE, size, gfx::Rect(size), size)); 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<VideoFrame> frame(new VideoFrame( 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VideoFrame::HOLE, size, gfx::Rect(size), size, base::TimeDelta())); 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return frame; 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t VideoFrame::NumPlanes(Format format) { 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (format) { 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case VideoFrame::NATIVE_TEXTURE: 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(GOOGLE_TV) 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case VideoFrame::HOLE: 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case VideoFrame::RGB32: 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 1; 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case VideoFrame::YV12: 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case VideoFrame::YV16: 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 3; 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case VideoFrame::YV12A: 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return 4; 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case VideoFrame::EMPTY: 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case VideoFrame::I420: 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case VideoFrame::INVALID: 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED() << "Unsupported video frame format: " << format; 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline size_t RoundUp(size_t value, size_t alignment) { 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that |alignment| is a power of 2. 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK((alignment + (alignment - 1)) == (alignment | (alignment - 1))); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ((value + (alignment - 1)) & ~(alignment-1)); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Release data allocated by AllocateRGB() or AllocateYUV(). 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static void ReleaseData(uint8* data) { 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(data); 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AlignedFree(data); 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoFrame::AllocateRGB(size_t bytes_per_pixel) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Round up to align at least at a 16-byte boundary for each row. 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is sufficient for MMX and SSE2 reads (movq/movdqa). 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t bytes_per_row = RoundUp(coded_size_.width(), 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kFrameSizeAlignment) * bytes_per_pixel; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t aligned_height = RoundUp(coded_size_.height(), kFrameSizeAlignment); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strides_[VideoFrame::kRGBPlane] = bytes_per_row; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_[VideoFrame::kRGBPlane] = reinterpret_cast<uint8*>( 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AlignedAlloc(bytes_per_row * aligned_height + kFrameSizePadding, 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kFrameAddressAlignment)); 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) no_longer_needed_cb_ = base::Bind(&ReleaseData, data_[VideoFrame::kRGBPlane]); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!(reinterpret_cast<intptr_t>(data_[VideoFrame::kRGBPlane]) & 7)); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPILE_ASSERT(0 == VideoFrame::kRGBPlane, RGB_data_must_be_index_0); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoFrame::AllocateYUV() { 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(format_ == VideoFrame::YV12 || format_ == VideoFrame::YV16 || 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) format_ == VideoFrame::YV12A); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Align Y rows at least at 16 byte boundaries. The stride for both 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // YV12 and YV16 is 1/2 of the stride of Y. For YV12, every row of bytes for 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // U and V applies to two rows of Y (one byte of UV for 4 bytes of Y), so in 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the case of YV12 the strides are identical for the same width surface, but 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the number of bytes allocated for YV12 is 1/2 the amount for U & V as 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // YV16. We also round the height of the surface allocated to be an even 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // number to avoid any potential of faulting by code that attempts to access 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the Y values of the final row, but assumes that the last row of U & V 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // applies to a full two rows of Y. YV12A is the same as YV12, but with an 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // additional alpha plane that has the same size and alignment as the Y plane. 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t y_stride = RoundUp(row_bytes(VideoFrame::kYPlane), 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kFrameSizeAlignment); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t uv_stride = RoundUp(row_bytes(VideoFrame::kUPlane), 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kFrameSizeAlignment); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The *2 here is because some formats (e.g. h264) allow interlaced coding, 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and then the size needs to be a multiple of two macroblocks (vertically). 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See libavcodec/utils.c:avcodec_align_dimensions2(). 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t y_height = RoundUp(coded_size_.height(), kFrameSizeAlignment * 2); 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size_t uv_height = (format_ == VideoFrame::YV12 || 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) format_ == VideoFrame::YV12A) ? 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) y_height / 2 : y_height; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t y_bytes = y_height * y_stride; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t uv_bytes = uv_height * uv_stride; 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size_t a_bytes = format_ == VideoFrame::YV12A ? y_bytes : 0; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The extra line of UV being allocated is because h264 chroma MC 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // overreads by one line in some cases, see libavcodec/utils.c: 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // avcodec_align_dimensions2() and libavcodec/x86/h264_chromamc.asm: 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // put_h264_chroma_mc4_ssse3(). 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8* data = reinterpret_cast<uint8*>( 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AlignedAlloc( 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) y_bytes + (uv_bytes * 2 + uv_stride) + a_bytes + kFrameSizePadding, 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kFrameAddressAlignment)); 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) no_longer_needed_cb_ = base::Bind(&ReleaseData, data); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPILE_ASSERT(0 == VideoFrame::kYPlane, y_plane_data_must_be_index_0); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_[VideoFrame::kYPlane] = data; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_[VideoFrame::kUPlane] = data + y_bytes; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_[VideoFrame::kVPlane] = data + y_bytes + uv_bytes; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strides_[VideoFrame::kYPlane] = y_stride; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strides_[VideoFrame::kUPlane] = uv_stride; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strides_[VideoFrame::kVPlane] = uv_stride; 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (format_ == YV12A) { 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) data_[VideoFrame::kAPlane] = data + y_bytes + (2 * uv_bytes); 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) strides_[VideoFrame::kAPlane] = y_stride; 288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VideoFrame::VideoFrame(VideoFrame::Format format, 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& coded_size, 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& visible_rect, 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& natural_size, 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta timestamp) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : format_(format), 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coded_size_(coded_size), 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visible_rect_(visible_rect), 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) natural_size_(natural_size), 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) texture_target_(0), 301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch shared_memory_handle_(base::SharedMemory::NULLHandle()), 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timestamp_(timestamp) { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&strides_, 0, sizeof(strides_)); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&data_, 0, sizeof(data_)); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VideoFrame::~VideoFrame() { 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!no_longer_needed_cb_.is_null()) 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ResetAndReturn(&no_longer_needed_cb_).Run(); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VideoFrame::IsValidPlane(size_t plane) const { 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (plane < NumPlanes(format_)); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int VideoFrame::stride(size_t plane) const { 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsValidPlane(plane)); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return strides_[plane]; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int VideoFrame::row_bytes(size_t plane) const { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsValidPlane(plane)); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int width = coded_size_.width(); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (format_) { 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 32bpp. 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case RGB32: 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return width * 4; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Planar, 8bpp. 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case YV12: 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case YV16: 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case YV12A: 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (plane == kYPlane || plane == kAPlane) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return width; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return RoundUp(width, 2) / 2; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Intentionally leave out non-production formats. 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unsupported video frame format: " << format_; 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int VideoFrame::rows(size_t plane) const { 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsValidPlane(plane)); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int height = coded_size_.height(); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (format_) { 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case RGB32: 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case YV16: 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return height; 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case YV12: 355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case YV12A: 356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (plane == kYPlane || plane == kAPlane) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return height; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return RoundUp(height, 2) / 2; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Intentionally leave out non-production formats. 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unsupported video frame format: " << format_; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint8* VideoFrame::data(size_t plane) const { 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsValidPlane(plane)); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return data_[plane]; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 374eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst scoped_refptr<VideoFrame::MailboxHolder>& VideoFrame::texture_mailbox() 375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const { 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(format_, NATIVE_TEXTURE); 377eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return texture_mailbox_holder_; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32 VideoFrame::texture_target() const { 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(format_, NATIVE_TEXTURE); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return texture_target_; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbase::SharedMemoryHandle VideoFrame::shared_memory_handle() const { 386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return shared_memory_handle_; 387eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 388eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VideoFrame::IsEndOfStream() const { 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return format_ == VideoFrame::EMPTY; 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoFrame::HashFrameForTesting(base::MD5Context* context) { 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int plane = 0; plane < kMaxPlanes; ++plane) { 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValidPlane(plane)) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int row = 0; row < rows(plane); ++row) { 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::MD5Update(context, base::StringPiece( 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<char*>(data(plane) + stride(plane) * row), 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_bytes(plane))); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochVideoFrame::MailboxHolder::MailboxHolder( 406eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const gpu::Mailbox& mailbox, 407eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch unsigned sync_point, 408eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const TextureNoLongerNeededCallback& release_callback) 409eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : mailbox_(mailbox), 410eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch sync_point_(sync_point), 411eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch release_callback_(release_callback) {} 412eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 413eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochVideoFrame::MailboxHolder::~MailboxHolder() { 414eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!release_callback_.is_null()) 415eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch release_callback_.Run(sync_point_); 416eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 417eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace media 419