video_frame.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "gpu/command_buffer/common/mailbox_holder.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/limits.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/video_util.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::CreateFrame( 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoFrame::Format format, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& coded_size, 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& visible_rect, 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& natural_size, 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta timestamp) { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsValidConfig(format, coded_size, visible_rect, natural_size)); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<VideoFrame> frame(new VideoFrame( 30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) format, coded_size, visible_rect, natural_size, timestamp, false)); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (format) { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case VideoFrame::YV12: 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case VideoFrame::YV12A: 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case VideoFrame::YV16: 35ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case VideoFrame::I420: 36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case VideoFrame::YV12J: 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) { 480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) case VideoFrame::UNKNOWN: 490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return "UNKNOWN"; 503240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch case VideoFrame::YV12: 513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return "YV12"; 523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch case VideoFrame::YV16: 533240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return "YV16"; 543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch case VideoFrame::I420: 553240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return "I420"; 563240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch case VideoFrame::NATIVE_TEXTURE: 573240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return "NATIVE_TEXTURE"; 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(VIDEO_HOLE) 593240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch case VideoFrame::HOLE: 603240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return "HOLE"; 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif // defined(VIDEO_HOLE) 623240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch case VideoFrame::YV12A: 633240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return "YV12A"; 64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case VideoFrame::YV12J: 65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return "YV12J"; 66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case VideoFrame::HISTOGRAM_MAX: 67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return "HISTOGRAM_MAX"; 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) { 780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return (format != VideoFrame::UNKNOWN && 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( 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<gpu::MailboxHolder> mailbox_holder, 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ReleaseMailboxCB& mailbox_holder_release_cb, 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, 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ReadPixelsCB& read_pixels_cb) { 102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<VideoFrame> frame(new VideoFrame(NATIVE_TEXTURE, 103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) coded_size, 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) visible_rect, 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) natural_size, 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) timestamp, 107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) false)); 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) frame->mailbox_holder_ = mailbox_holder.Pass(); 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) frame->mailbox_holder_release_cb_ = mailbox_holder_release_cb; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame->read_pixels_cb_ = read_pixels_cb; 111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return frame; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void VideoFrame::ReadPixelsFromNativeTexture(const SkBitmap& pixels) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(format_, NATIVE_TEXTURE); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!read_pixels_cb_.is_null()) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_pixels_cb_.Run(pixels); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::WrapExternalPackedMemory( 123ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch Format format, 124ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const gfx::Size& coded_size, 125ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const gfx::Rect& visible_rect, 126ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const gfx::Size& natural_size, 127ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch uint8* data, 128424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) size_t data_size, 129ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::SharedMemoryHandle handle, 130ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::TimeDelta timestamp, 131ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const base::Closure& no_longer_needed_cb) { 132424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (data_size < AllocationSize(format, coded_size)) 133424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return NULL; 134424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 135ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch switch (format) { 136ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case I420: { 137ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch scoped_refptr<VideoFrame> frame(new VideoFrame( 138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) format, coded_size, visible_rect, natural_size, timestamp, false)); 139ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch frame->shared_memory_handle_ = handle; 140ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch frame->strides_[kYPlane] = coded_size.width(); 141ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch frame->strides_[kUPlane] = coded_size.width() / 2; 142ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch frame->strides_[kVPlane] = coded_size.width() / 2; 143ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch frame->data_[kYPlane] = data; 144ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch frame->data_[kUPlane] = data + coded_size.GetArea(); 145ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch frame->data_[kVPlane] = data + (coded_size.GetArea() * 5 / 4); 146ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch frame->no_longer_needed_cb_ = no_longer_needed_cb; 147ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return frame; 148ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 149ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch default: 150ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch NOTIMPLEMENTED(); 151ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return NULL; 152ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 153ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 154ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 155ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// static 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::WrapExternalYuvData( 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Format format, 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Size& coded_size, 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Rect& visible_rect, 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Size& natural_size, 161ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int32 y_stride, 162ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int32 u_stride, 163ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int32 v_stride, 164ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch uint8* y_data, 165ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch uint8* u_data, 166ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch uint8* v_data, 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta timestamp, 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Closure& no_longer_needed_cb) { 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(format == YV12 || format == YV16 || format == I420) << format; 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<VideoFrame> frame(new VideoFrame( 171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) format, coded_size, visible_rect, natural_size, timestamp, false)); 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frame->strides_[kYPlane] = y_stride; 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frame->strides_[kUPlane] = u_stride; 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frame->strides_[kVPlane] = v_stride; 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frame->data_[kYPlane] = y_data; 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frame->data_[kUPlane] = u_data; 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frame->data_[kVPlane] = v_data; 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frame->no_longer_needed_cb_ = no_longer_needed_cb; 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return frame; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 183a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::WrapVideoFrame( 184a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const scoped_refptr<VideoFrame>& frame, 185a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::Closure& no_longer_needed_cb) { 186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_refptr<VideoFrame> wrapped_frame(new VideoFrame( 187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) frame->format(), frame->coded_size(), frame->visible_rect(), 188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) frame->natural_size(), frame->GetTimestamp(), frame->end_of_stream())); 189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (size_t i = 0; i < NumPlanes(frame->format()); ++i) { 191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) wrapped_frame->strides_[i] = frame->stride(i); 192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) wrapped_frame->data_[i] = frame->data(i); 193a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 194a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 195a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) wrapped_frame->no_longer_needed_cb_ = no_longer_needed_cb; 196a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return wrapped_frame; 197a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 198a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 199a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// static 200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::CreateEOSFrame() { 201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return new VideoFrame(VideoFrame::UNKNOWN, 202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Size(), 203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Rect(), 204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Size(), 205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) kNoTimestamp(), 206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) true); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::CreateColorFrame( 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& size, 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8 y, uint8 u, uint8 v, 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta timestamp) { 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsValidConfig(VideoFrame::YV12, size, gfx::Rect(size), size)); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<VideoFrame> frame = VideoFrame::CreateFrame( 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoFrame::YV12, size, gfx::Rect(size), size, timestamp); 217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FillYUV(frame.get(), y, u, v); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return frame; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::CreateBlackFrame(const gfx::Size& size) { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8 kBlackY = 0x00; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8 kBlackUV = 0x80; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeDelta kZero; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CreateColorFrame(size, kBlackY, kBlackUV, kBlackUV, kZero); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(VIDEO_HOLE) 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This block and other blocks wrapped around #if defined(VIDEO_HOLE) is not 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// maintained by the general compositor team. Please contact the following 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// people instead: 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// wonsik@chromium.org 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ycheo@chromium.org 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::CreateHoleFrame( 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Size& size) { 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(IsValidConfig(VideoFrame::HOLE, size, gfx::Rect(size), size)); 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<VideoFrame> frame(new VideoFrame( 242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) VideoFrame::HOLE, size, gfx::Rect(size), size, base::TimeDelta(), false)); 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return frame; 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif // defined(VIDEO_HOLE) 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t VideoFrame::NumPlanes(Format format) { 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (format) { 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case VideoFrame::NATIVE_TEXTURE: 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(VIDEO_HOLE) 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case VideoFrame::HOLE: 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif // defined(VIDEO_HOLE) 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case VideoFrame::YV12: 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case VideoFrame::YV16: 257ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case VideoFrame::I420: 258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case VideoFrame::YV12J: 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 3; 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case VideoFrame::YV12A: 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return 4; 2620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) case VideoFrame::UNKNOWN: 263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case VideoFrame::HISTOGRAM_MAX: 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED() << "Unsupported video frame format: " << format; 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline size_t RoundUp(size_t value, size_t alignment) { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that |alignment| is a power of 2. 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK((alignment + (alignment - 1)) == (alignment | (alignment - 1))); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ((value + (alignment - 1)) & ~(alignment-1)); 274424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 275424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 276424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// static 277424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)size_t VideoFrame::AllocationSize(Format format, const gfx::Size& coded_size) { 278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) size_t total = 0; 279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (size_t i = 0; i < NumPlanes(format); ++i) 280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) total += PlaneAllocationSize(format, i, coded_size); 281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return total; 282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// static 285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)size_t VideoFrame::PlaneAllocationSize(Format format, 286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) size_t plane, 287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const gfx::Size& coded_size) { 288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const size_t area = 289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RoundUp(coded_size.width(), 2) * RoundUp(coded_size.height(), 2); 290424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) switch (format) { 291424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case VideoFrame::YV12: 292a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case VideoFrame::YV12J: 293424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case VideoFrame::I420: { 294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) switch (plane) { 295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case VideoFrame::kYPlane: 296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return area; 297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case VideoFrame::kUPlane: 298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case VideoFrame::kVPlane: 299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return area / 4; 300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) default: 301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) break; 302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 303424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 304424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case VideoFrame::YV12A: { 305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) switch (plane) { 306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case VideoFrame::kYPlane: 307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case VideoFrame::kAPlane: 308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return area; 309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case VideoFrame::kUPlane: 310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case VideoFrame::kVPlane: 311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return area / 4; 312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) default: 313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) break; 314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 315424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 316424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case VideoFrame::YV16: { 317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) switch (plane) { 318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case VideoFrame::kYPlane: 319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return area; 320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case VideoFrame::kUPlane: 321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case VideoFrame::kVPlane: 322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return area / 2; 323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) default: 324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) break; 325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 326424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 3270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) case VideoFrame::UNKNOWN: 328424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case VideoFrame::NATIVE_TEXTURE: 329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case VideoFrame::HISTOGRAM_MAX: 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(VIDEO_HOLE) 331424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case VideoFrame::HOLE: 3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif // defined(VIDEO_HOLE) 333424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 334424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) NOTREACHED() << "Unsupported video frame format/plane: " 336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << format << "/" << plane; 337424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return 0; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Release data allocated by AllocateYUV(). 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static void ReleaseData(uint8* data) { 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(data); 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AlignedFree(data); 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoFrame::AllocateYUV() { 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(format_ == VideoFrame::YV12 || format_ == VideoFrame::YV16 || 348a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) format_ == VideoFrame::YV12A || format_ == VideoFrame::I420 || 349a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) format_ == VideoFrame::YV12J); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Align Y rows at least at 16 byte boundaries. The stride for both 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // YV12 and YV16 is 1/2 of the stride of Y. For YV12, every row of bytes for 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // U and V applies to two rows of Y (one byte of UV for 4 bytes of Y), so in 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the case of YV12 the strides are identical for the same width surface, but 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the number of bytes allocated for YV12 is 1/2 the amount for U & V as 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // YV16. We also round the height of the surface allocated to be an even 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // number to avoid any potential of faulting by code that attempts to access 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the Y values of the final row, but assumes that the last row of U & V 358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // applies to a full two rows of Y. YV12A is the same as YV12, but with an 359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // additional alpha plane that has the same size and alignment as the Y plane. 360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t y_stride = RoundUp(row_bytes(VideoFrame::kYPlane), 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kFrameSizeAlignment); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t uv_stride = RoundUp(row_bytes(VideoFrame::kUPlane), 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kFrameSizeAlignment); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The *2 here is because some formats (e.g. h264) allow interlaced coding, 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and then the size needs to be a multiple of two macroblocks (vertically). 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See libavcodec/utils.c:avcodec_align_dimensions2(). 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t y_height = RoundUp(coded_size_.height(), kFrameSizeAlignment * 2); 369ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch size_t uv_height = 370ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch (format_ == VideoFrame::YV12 || format_ == VideoFrame::YV12A || 371ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch format_ == VideoFrame::I420) 372ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ? y_height / 2 373ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : y_height; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t y_bytes = y_height * y_stride; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t uv_bytes = uv_height * uv_stride; 376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size_t a_bytes = format_ == VideoFrame::YV12A ? y_bytes : 0; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The extra line of UV being allocated is because h264 chroma MC 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // overreads by one line in some cases, see libavcodec/utils.c: 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // avcodec_align_dimensions2() and libavcodec/x86/h264_chromamc.asm: 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // put_h264_chroma_mc4_ssse3(). 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8* data = reinterpret_cast<uint8*>( 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AlignedAlloc( 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) y_bytes + (uv_bytes * 2 + uv_stride) + a_bytes + kFrameSizePadding, 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kFrameAddressAlignment)); 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) no_longer_needed_cb_ = base::Bind(&ReleaseData, data); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPILE_ASSERT(0 == VideoFrame::kYPlane, y_plane_data_must_be_index_0); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_[VideoFrame::kYPlane] = data; 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_[VideoFrame::kUPlane] = data + y_bytes; 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_[VideoFrame::kVPlane] = data + y_bytes + uv_bytes; 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strides_[VideoFrame::kYPlane] = y_stride; 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strides_[VideoFrame::kUPlane] = uv_stride; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strides_[VideoFrame::kVPlane] = uv_stride; 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (format_ == YV12A) { 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) data_[VideoFrame::kAPlane] = data + y_bytes + (2 * uv_bytes); 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) strides_[VideoFrame::kAPlane] = y_stride; 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VideoFrame::VideoFrame(VideoFrame::Format format, 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& coded_size, 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& visible_rect, 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& natural_size, 404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::TimeDelta timestamp, 405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool end_of_stream) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : format_(format), 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coded_size_(coded_size), 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visible_rect_(visible_rect), 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) natural_size_(natural_size), 410eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch shared_memory_handle_(base::SharedMemory::NULLHandle()), 411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) timestamp_(timestamp), 412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) end_of_stream_(end_of_stream) { 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&strides_, 0, sizeof(strides_)); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&data_, 0, sizeof(data_)); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VideoFrame::~VideoFrame() { 4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!mailbox_holder_release_cb_.is_null()) { 4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ResetAndReturn(&mailbox_holder_release_cb_) 4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .Run(mailbox_holder_.Pass()); 4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!no_longer_needed_cb_.is_null()) 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ResetAndReturn(&no_longer_needed_cb_).Run(); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VideoFrame::IsValidPlane(size_t plane) const { 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (plane < NumPlanes(format_)); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int VideoFrame::stride(size_t plane) const { 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsValidPlane(plane)); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return strides_[plane]; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int VideoFrame::row_bytes(size_t plane) const { 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsValidPlane(plane)); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int width = coded_size_.width(); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (format_) { 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Planar, 8bpp. 440ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case YV12A: 441ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (plane == kAPlane) 442ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return width; 443ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Fallthrough. 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case YV12: 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case YV16: 446ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case I420: 447a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case YV12J: 448ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (plane == kYPlane) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return width; 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return RoundUp(width, 2) / 2; 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Intentionally leave out non-production formats. 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unsupported video frame format: " << format_; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int VideoFrame::rows(size_t plane) const { 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsValidPlane(plane)); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int height = coded_size_.height(); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (format_) { 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case YV16: 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return height; 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case YV12A: 469ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (plane == kAPlane) 470ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return height; 471ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Fallthrough. 472ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case YV12: 473ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case I420: 474ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (plane == kYPlane) 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return height; 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return RoundUp(height, 2) / 2; 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Intentionally leave out non-production formats. 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unsupported video frame format: " << format_; 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint8* VideoFrame::data(size_t plane) const { 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsValidPlane(plane)); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return data_[plane]; 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)gpu::MailboxHolder* VideoFrame::mailbox_holder() const { 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(format_, NATIVE_TEXTURE); 4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return mailbox_holder_.get(); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 497eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbase::SharedMemoryHandle VideoFrame::shared_memory_handle() const { 498eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return shared_memory_handle_; 499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 500eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoFrame::HashFrameForTesting(base::MD5Context* context) { 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int plane = 0; plane < kMaxPlanes; ++plane) { 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValidPlane(plane)) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int row = 0; row < rows(plane); ++row) { 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::MD5Update(context, base::StringPiece( 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<char*>(data(plane) + stride(plane) * row), 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_bytes(plane))); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace media 514