video_frame.cc revision a02191e04bc25c4935f804f2c080ae28663d096d
1c3aae25116e66c177579b0b79182b09340b19753Chris Lattner// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2ea61c358720aa6c7a159d51658b34276316aa841Misha Brukman// Use of this source code is governed by a BSD-style license that can be 36fbcc26f1460eaee4e0eb8b426fc1ff0c7af11beJohn Criswell// found in the LICENSE file. 46fbcc26f1460eaee4e0eb8b426fc1ff0c7af11beJohn Criswell 57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner#include "media/base/video_frame.h" 67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner 7ea61c358720aa6c7a159d51658b34276316aa841Misha Brukman#include <algorithm> 86fbcc26f1460eaee4e0eb8b426fc1ff0c7af11beJohn Criswell 9ea61c358720aa6c7a159d51658b34276316aa841Misha Brukman#include "base/bind.h" 10c3aae25116e66c177579b0b79182b09340b19753Chris Lattner#include "base/callback_helpers.h" 11c3aae25116e66c177579b0b79182b09340b19753Chris Lattner#include "base/logging.h" 12ea61c358720aa6c7a159d51658b34276316aa841Misha Brukman#include "base/memory/aligned_memory.h" 13cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattner#include "base/strings/string_piece.h" 14cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattner#include "gpu/command_buffer/common/mailbox_holder.h" 15cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattner#include "media/base/limits.h" 16cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattner#include "media/base/video_util.h" 17cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattner#include "third_party/skia/include/core/SkBitmap.h" 18c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene 194b84086e89d86fb16f562166d9fea8df37db6be7Dan Gohmannamespace media { 20255f89faee13dc491cb64fbeae3c763e7e2ea4e6Chandler Carruth 21444b4bf5c84c80833ff283244de0885124091a13Nadav Rotemstatic inline size_t RoundUp(size_t value, size_t alignment) { 22583bd47f777fe3eb8305872fa0eadab31e833dffJim Laskey // Check that |alignment| is a power of 2. 23c76909abfec876c6b751d693ebd3df07df686aa0Dan Gohman DCHECK((alignment + (alignment - 1)) == (alignment | (alignment - 1))); 2498a366d547772010e94609e4584489b3e5ce0043Bill Wendling return ((value + (alignment - 1)) & ~(alignment - 1)); 25acaf09dbe4a6781163857db1321bbd5795e7d410Dan Gohman} 26322812e603705e1c2037313633e72f689524b163Evan Cheng 27eb19e40efbd3cae80c908a30cdf4d33450733c45Chris Lattner// static 28255f89faee13dc491cb64fbeae3c763e7e2ea4e6Chandler Carruthscoped_refptr<VideoFrame> VideoFrame::CreateFrame( 29d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke VideoFrame::Format format, 30d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke const gfx::Size& coded_size, 31fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman const gfx::Rect& visible_rect, 32fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman const gfx::Size& natural_size, 33b4e6a5df5dada0cd919cc6e2717eb3118db9cc45Bill Wendling base::TimeDelta timestamp) { 34b4e6a5df5dada0cd919cc6e2717eb3118db9cc45Bill Wendling // Since we're creating a new YUV frame (and allocating memory for it 3531441b7e95e0840e1ae144e5db6f791d6a36bc60Evan Cheng // ourselves), we can pad the requested |coded_size| if necessary if the 36b4e6a5df5dada0cd919cc6e2717eb3118db9cc45Bill Wendling // request does not line up on sample boundaries. 37bfdf7f38523bd38ae0538861a2bfd8bdc46e5c33Dale Johannesen gfx::Size new_coded_size(coded_size); 38b4e6a5df5dada0cd919cc6e2717eb3118db9cc45Bill Wendling switch (format) { 39ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman case VideoFrame::YV12: 40fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman case VideoFrame::YV12A: 418e4018e2de52c534405d7155c7009d0b35afb861Cedric Venet case VideoFrame::I420: 428e4018e2de52c534405d7155c7009d0b35afb861Cedric Venet case VideoFrame::YV12J: 437309be6735666143bd9835b275dc8501617a2591Gabor Greif new_coded_size.set_height((new_coded_size.height() + 1) / 2 * 2); 44fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman // Fallthrough. 45fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman case VideoFrame::YV16: 46c7f6b8c5d40e17bf43fd3a1549d7d89c9da735e1Gabor Greif new_coded_size.set_width((new_coded_size.width() + 1) / 2 * 2); 47fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman break; 48fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman default: 49fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman LOG(FATAL) << "Only YUV formats supported: " << format; 50c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif return NULL; 51c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif } 52f3841fcbd587c31aa9842b3f33bd57de40c9f443Gabor Greif DCHECK(IsValidConfig(format, new_coded_size, visible_rect, natural_size)); 53c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif scoped_refptr<VideoFrame> frame(new VideoFrame( 54fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman format, new_coded_size, visible_rect, natural_size, timestamp, false)); 5550bee42b54cd9aec5f49566307df2b0cf23afcf6Craig Topper frame->AllocateYUV(); 56fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman return frame; 57fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman} 58fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman 59fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman// static 60c3aae25116e66c177579b0b79182b09340b19753Chris Lattnerstd::string VideoFrame::FormatToString(VideoFrame::Format format) { 61bfdf7f38523bd38ae0538861a2bfd8bdc46e5c33Dale Johannesen switch (format) { 62bfdf7f38523bd38ae0538861a2bfd8bdc46e5c33Dale Johannesen case VideoFrame::UNKNOWN: 63bfcb3051899b7141a946d769fcf6e8a8453bc530Evan Cheng return "UNKNOWN"; 64bfcb3051899b7141a946d769fcf6e8a8453bc530Evan Cheng case VideoFrame::YV12: 65bfcb3051899b7141a946d769fcf6e8a8453bc530Evan Cheng return "YV12"; 66fdb42fa5fe794cc2c89e2ed7f57a89ed24d9952aDale Johannesen case VideoFrame::YV16: 67fdb42fa5fe794cc2c89e2ed7f57a89ed24d9952aDale Johannesen return "YV16"; 68fdb42fa5fe794cc2c89e2ed7f57a89ed24d9952aDale Johannesen case VideoFrame::I420: 69fdb42fa5fe794cc2c89e2ed7f57a89ed24d9952aDale Johannesen return "I420"; 70fdb42fa5fe794cc2c89e2ed7f57a89ed24d9952aDale Johannesen case VideoFrame::NATIVE_TEXTURE: 71fdb42fa5fe794cc2c89e2ed7f57a89ed24d9952aDale Johannesen return "NATIVE_TEXTURE"; 72bfdf7f38523bd38ae0538861a2bfd8bdc46e5c33Dale Johannesen#if defined(VIDEO_HOLE) 73bfcb3051899b7141a946d769fcf6e8a8453bc530Evan Cheng case VideoFrame::HOLE: 74fdb42fa5fe794cc2c89e2ed7f57a89ed24d9952aDale Johannesen return "HOLE"; 75d4c6c3a7c3140ce487a805138b6f53f82ff6b783Devang Patel#endif // defined(VIDEO_HOLE) 76bfdf7f38523bd38ae0538861a2bfd8bdc46e5c33Dale Johannesen case VideoFrame::YV12A: 77001d3dc976d7cda8a3dd8c7fd4020b0b96033f4eCraig Topper return "YV12A"; 78001d3dc976d7cda8a3dd8c7fd4020b0b96033f4eCraig Topper case VideoFrame::YV12J: 79bfdf7f38523bd38ae0538861a2bfd8bdc46e5c33Dale Johannesen return "YV12J"; 80bfdf7f38523bd38ae0538861a2bfd8bdc46e5c33Dale Johannesen } 81bfdf7f38523bd38ae0538861a2bfd8bdc46e5c33Dale Johannesen NOTREACHED() << "Invalid videoframe format provided: " << format; 82fdb42fa5fe794cc2c89e2ed7f57a89ed24d9952aDale Johannesen return ""; 83fdb42fa5fe794cc2c89e2ed7f57a89ed24d9952aDale Johannesen} 84fdb42fa5fe794cc2c89e2ed7f57a89ed24d9952aDale Johannesen 85fdb42fa5fe794cc2c89e2ed7f57a89ed24d9952aDale Johannesen// static 86bfcb3051899b7141a946d769fcf6e8a8453bc530Evan Chengbool VideoFrame::IsValidConfig(VideoFrame::Format format, 87d4c6c3a7c3140ce487a805138b6f53f82ff6b783Devang Patel const gfx::Size& coded_size, 88bfdf7f38523bd38ae0538861a2bfd8bdc46e5c33Dale Johannesen const gfx::Rect& visible_rect, 89bfcb3051899b7141a946d769fcf6e8a8453bc530Evan Cheng const gfx::Size& natural_size) { 90bfdf7f38523bd38ae0538861a2bfd8bdc46e5c33Dale Johannesen // Check maximum limits for all formats. 91d4c6c3a7c3140ce487a805138b6f53f82ff6b783Devang Patel if (coded_size.GetArea() > limits::kMaxCanvas || 92bfcb3051899b7141a946d769fcf6e8a8453bc530Evan Cheng coded_size.width() > limits::kMaxDimension || 93fdb42fa5fe794cc2c89e2ed7f57a89ed24d9952aDale Johannesen coded_size.height() > limits::kMaxDimension || 94bfcb3051899b7141a946d769fcf6e8a8453bc530Evan Cheng visible_rect.x() < 0 || visible_rect.y() < 0 || 95bfcb3051899b7141a946d769fcf6e8a8453bc530Evan Cheng visible_rect.right() > coded_size.width() || 96bfcb3051899b7141a946d769fcf6e8a8453bc530Evan Cheng visible_rect.bottom() > coded_size.height() || 97fdb42fa5fe794cc2c89e2ed7f57a89ed24d9952aDale Johannesen natural_size.GetArea() > limits::kMaxCanvas || 98bfdf7f38523bd38ae0538861a2bfd8bdc46e5c33Dale Johannesen natural_size.width() > limits::kMaxDimension || 99bfcb3051899b7141a946d769fcf6e8a8453bc530Evan Cheng natural_size.height() > limits::kMaxDimension) 10022a54c1cd711afccd4558374918d12a939e1cca5Benjamin Kramer return false; 10122a54c1cd711afccd4558374918d12a939e1cca5Benjamin Kramer 10222a54c1cd711afccd4558374918d12a939e1cca5Benjamin Kramer // Check format-specific width/height requirements. 10322a54c1cd711afccd4558374918d12a939e1cca5Benjamin Kramer switch (format) { 10422a54c1cd711afccd4558374918d12a939e1cca5Benjamin Kramer case VideoFrame::UNKNOWN: 10522a54c1cd711afccd4558374918d12a939e1cca5Benjamin Kramer return (coded_size.IsEmpty() && visible_rect.IsEmpty() && 106bfdf7f38523bd38ae0538861a2bfd8bdc46e5c33Dale Johannesen natural_size.IsEmpty()); 107bfcb3051899b7141a946d769fcf6e8a8453bc530Evan Cheng case VideoFrame::YV12: 108bfcb3051899b7141a946d769fcf6e8a8453bc530Evan Cheng case VideoFrame::YV12J: 109bfcb3051899b7141a946d769fcf6e8a8453bc530Evan Cheng case VideoFrame::I420: 110bfcb3051899b7141a946d769fcf6e8a8453bc530Evan Cheng case VideoFrame::YV12A: 111fdb42fa5fe794cc2c89e2ed7f57a89ed24d9952aDale Johannesen // YUV formats have width/height requirements due to chroma subsampling. 112fdb42fa5fe794cc2c89e2ed7f57a89ed24d9952aDale Johannesen if (static_cast<size_t>(coded_size.height()) < 113bfdf7f38523bd38ae0538861a2bfd8bdc46e5c33Dale Johannesen RoundUp(visible_rect.bottom(), 2)) 114bfdf7f38523bd38ae0538861a2bfd8bdc46e5c33Dale Johannesen return false; 115cf495bc2e505e52ad018da55bed11c7b8bc97db5David Greene // Fallthrough. 116cf495bc2e505e52ad018da55bed11c7b8bc97db5David Greene case VideoFrame::YV16: 117cf495bc2e505e52ad018da55bed11c7b8bc97db5David Greene if (static_cast<size_t>(coded_size.width()) < 118cf495bc2e505e52ad018da55bed11c7b8bc97db5David Greene RoundUp(visible_rect.right(), 2)) 119c3aae25116e66c177579b0b79182b09340b19753Chris Lattner return false; 120c3aae25116e66c177579b0b79182b09340b19753Chris Lattner break; 121c3aae25116e66c177579b0b79182b09340b19753Chris Lattner case VideoFrame::NATIVE_TEXTURE: 122c3aae25116e66c177579b0b79182b09340b19753Chris Lattner#if defined(VIDEO_HOLE) 123c3aae25116e66c177579b0b79182b09340b19753Chris Lattner case VideoFrame::HOLE: 124c3aae25116e66c177579b0b79182b09340b19753Chris Lattner#endif // defined(VIDEO_HOLE) 125c3aae25116e66c177579b0b79182b09340b19753Chris Lattner // NATIVE_TEXTURE and HOLE have no software-allocated buffers and are 126c3aae25116e66c177579b0b79182b09340b19753Chris Lattner // allowed to skip the below check and be empty. 127c3aae25116e66c177579b0b79182b09340b19753Chris Lattner return true; 128c3aae25116e66c177579b0b79182b09340b19753Chris Lattner } 129cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattner 130cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattner // Check that software-allocated buffer formats are not empty. 13150d2b1ac029d63500ea9b9347561b1454fa6ed6aDan Gohman return (!coded_size.IsEmpty() && !visible_rect.IsEmpty() && 132d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman !natural_size.IsEmpty()); 133ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman} 1347c3234c6be0dc0bdf4b5d6f848cd728a77f349d7Dan Gohman 135512063dd0f91a76b9dd904dfff72a52b4d09e89fChris Lattner// static 1360508d047fefef36d4f943ee13c82c18cf3a943abDevang Patelscoped_refptr<VideoFrame> VideoFrame::WrapNativeTexture( 137cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattner scoped_ptr<gpu::MailboxHolder> mailbox_holder, 138f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman const ReleaseMailboxCB& mailbox_holder_release_cb, 139f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman const gfx::Size& coded_size, 140f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman const gfx::Rect& visible_rect, 141f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman const gfx::Size& natural_size, 142f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman base::TimeDelta timestamp, 143cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattner const ReadPixelsCB& read_pixels_cb) { 144213a16c637926bfc38ba373d3aba6778e181e3ecChris Lattner scoped_refptr<VideoFrame> frame(new VideoFrame(NATIVE_TEXTURE, 145fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman coded_size, 146fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman visible_rect, 147f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman natural_size, 148f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman timestamp, 149f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman false)); 150f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman frame->mailbox_holder_ = mailbox_holder.Pass(); 151f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman frame->mailbox_holder_release_cb_ = mailbox_holder_release_cb; 152f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman frame->read_pixels_cb_ = read_pixels_cb; 153f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman 154f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman return frame; 155691ef2ba066dda14ae4ac0ad645054fbc967785aAndrew Lenharth} 156213a16c637926bfc38ba373d3aba6778e181e3ecChris Lattner 157d23b33435ae722ff5aa5ab97135a4f31041959e2Bob Wilsonvoid VideoFrame::ReadPixelsFromNativeTexture(const SkBitmap& pixels) { 158583bd47f777fe3eb8305872fa0eadab31e833dffJim Laskey DCHECK_EQ(format_, NATIVE_TEXTURE); 159213a16c637926bfc38ba373d3aba6778e181e3ecChris Lattner if (!read_pixels_cb_.is_null()) 160f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman read_pixels_cb_.Run(pixels); 161f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman} 162f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman 163e8be6c63915e0389f1eef6b53c64300d13b2ce99Dan Gohman// static 164e8be6c63915e0389f1eef6b53c64300d13b2ce99Dan Gohmanscoped_refptr<VideoFrame> VideoFrame::WrapExternalPackedMemory( 165e8be6c63915e0389f1eef6b53c64300d13b2ce99Dan Gohman Format format, 166e8be6c63915e0389f1eef6b53c64300d13b2ce99Dan Gohman const gfx::Size& coded_size, 167b4e6a5df5dada0cd919cc6e2717eb3118db9cc45Bill Wendling const gfx::Rect& visible_rect, 168b4e6a5df5dada0cd919cc6e2717eb3118db9cc45Bill Wendling const gfx::Size& natural_size, 169b4e6a5df5dada0cd919cc6e2717eb3118db9cc45Bill Wendling uint8* data, 170819309efec6f11ba752bd7cbfe186495745f020bDaniel Dunbar size_t data_size, 171bfdf7f38523bd38ae0538861a2bfd8bdc46e5c33Dale Johannesen base::SharedMemoryHandle handle, 172bfdf7f38523bd38ae0538861a2bfd8bdc46e5c33Dale Johannesen base::TimeDelta timestamp, 173bfdf7f38523bd38ae0538861a2bfd8bdc46e5c33Dale Johannesen const base::Closure& no_longer_needed_cb) { 174bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen if (!IsValidConfig(format, coded_size, visible_rect, natural_size)) 175bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen return NULL; 176bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen if (data_size < AllocationSize(format, coded_size)) 177bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen return NULL; 178bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen 179bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen switch (format) { 180bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen case I420: { 181bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen scoped_refptr<VideoFrame> frame(new VideoFrame( 182bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen format, coded_size, visible_rect, natural_size, timestamp, false)); 183bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen frame->shared_memory_handle_ = handle; 184bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen frame->strides_[kYPlane] = coded_size.width(); 185bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen frame->strides_[kUPlane] = coded_size.width() / 2; 186bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen frame->strides_[kVPlane] = coded_size.width() / 2; 187bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen frame->data_[kYPlane] = data; 188bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen frame->data_[kUPlane] = data + coded_size.GetArea(); 189bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen frame->data_[kVPlane] = data + (coded_size.GetArea() * 5 / 4); 190bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen frame->no_longer_needed_cb_ = no_longer_needed_cb; 191bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen return frame; 192bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen } 193bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen default: 194bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen NOTIMPLEMENTED(); 195bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen return NULL; 196bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen } 197bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen} 198bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen 199bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen// static 200bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesenscoped_refptr<VideoFrame> VideoFrame::WrapExternalYuvData( 201bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen Format format, 202bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen const gfx::Size& coded_size, 203bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen const gfx::Rect& visible_rect, 204bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen const gfx::Size& natural_size, 205bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen int32 y_stride, 206bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen int32 u_stride, 207bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen int32 v_stride, 208bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen uint8* y_data, 209bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen uint8* u_data, 210bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen uint8* v_data, 211bc7d448f242b1bbc1031fb87cd69c285ff9aaffaJakob Stoklund Olesen base::TimeDelta timestamp, 212c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene const base::Closure& no_longer_needed_cb) { 213c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene if (!IsValidConfig(format, coded_size, visible_rect, natural_size)) 214c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene return NULL; 215c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif 216c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif scoped_refptr<VideoFrame> frame(new VideoFrame( 217c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene format, coded_size, visible_rect, natural_size, timestamp, false)); 218c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene frame->strides_[kYPlane] = y_stride; 219001d3dc976d7cda8a3dd8c7fd4020b0b96033f4eCraig Topper frame->strides_[kUPlane] = u_stride; 220001d3dc976d7cda8a3dd8c7fd4020b0b96033f4eCraig Topper frame->strides_[kVPlane] = v_stride; 221819309efec6f11ba752bd7cbfe186495745f020bDaniel Dunbar frame->data_[kYPlane] = y_data; 222cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattner frame->data_[kUPlane] = u_data; 2230508d047fefef36d4f943ee13c82c18cf3a943abDevang Patel frame->data_[kVPlane] = v_data; 224cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattner frame->no_longer_needed_cb_ = no_longer_needed_cb; 225cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattner return frame; 2267c3234c6be0dc0bdf4b5d6f848cd728a77f349d7Dan Gohman} 2277c3234c6be0dc0bdf4b5d6f848cd728a77f349d7Dan Gohman 2287c3234c6be0dc0bdf4b5d6f848cd728a77f349d7Dan Gohman// static 229de6e783b2490447866b592cd39855e6f4d25efffChris Lattnerscoped_refptr<VideoFrame> VideoFrame::WrapVideoFrame( 2307c3234c6be0dc0bdf4b5d6f848cd728a77f349d7Dan Gohman const scoped_refptr<VideoFrame>& frame, 2317c3234c6be0dc0bdf4b5d6f848cd728a77f349d7Dan Gohman const gfx::Rect& visible_rect, 232f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman const gfx::Size& natural_size, 233f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman const base::Closure& no_longer_needed_cb) { 2347c3234c6be0dc0bdf4b5d6f848cd728a77f349d7Dan Gohman // NATIVE_TEXTURE frames need mailbox info propagated, and there's no support 235f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman // for that here yet, see http://crbug/362521. 2367c3234c6be0dc0bdf4b5d6f848cd728a77f349d7Dan Gohman CHECK(frame->format() != NATIVE_TEXTURE); 23750d2b1ac029d63500ea9b9347561b1454fa6ed6aDan Gohman 238d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman DCHECK(frame->visible_rect().Contains(visible_rect)); 239ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman scoped_refptr<VideoFrame> wrapped_frame(new VideoFrame( 240d1474d09cbe5fdeec8ba0d6c6b52f316f3422532Owen Anderson frame->format(), frame->coded_size(), visible_rect, natural_size, 241cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattner frame->timestamp(), frame->end_of_stream())); 242ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey 2431080b9ee534579c67f7c99364cc6fa11edbcd919Chris Lattner for (size_t i = 0; i < NumPlanes(frame->format()); ++i) { 244462dc7f4960e5074ddf4769ec8b2ef1ba7a4d2c8Dan Gohman wrapped_frame->strides_[i] = frame->stride(i); 2450b12aef49087b57d276ed760a83525d1e2602144Dan Gohman wrapped_frame->data_[i] = frame->data(i); 246fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel } 247ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey 248ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey wrapped_frame->no_longer_needed_cb_ = no_longer_needed_cb; 249ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey return wrapped_frame; 2501080b9ee534579c67f7c99364cc6fa11edbcd919Chris Lattner} 251ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey 252ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey// static 253ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskeyscoped_refptr<VideoFrame> VideoFrame::CreateEOSFrame() { 254fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel return new VideoFrame(VideoFrame::UNKNOWN, 255ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey gfx::Size(), 256ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey gfx::Rect(), 257ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey gfx::Size(), 258fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel kNoTimestamp(), 259ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey true); 260ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey} 261ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey 262fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel// static 263ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskeyscoped_refptr<VideoFrame> VideoFrame::CreateColorFrame( 264ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey const gfx::Size& size, 265ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey uint8 y, uint8 u, uint8 v, 2661080b9ee534579c67f7c99364cc6fa11edbcd919Chris Lattner base::TimeDelta timestamp) { 267c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene scoped_refptr<VideoFrame> frame = VideoFrame::CreateFrame( 268c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene VideoFrame::YV12, size, gfx::Rect(size), size, timestamp); 269c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene FillYUV(frame.get(), y, u, v); 270c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene return frame; 271fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman} 272b80e2be8894db9f843f32ebaffb9b7fd6b57d206Chris Lattner 273b80e2be8894db9f843f32ebaffb9b7fd6b57d206Chris Lattner// static 274fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohmanscoped_refptr<VideoFrame> VideoFrame::CreateBlackFrame(const gfx::Size& size) { 275b80e2be8894db9f843f32ebaffb9b7fd6b57d206Chris Lattner const uint8 kBlackY = 0x00; 276b80e2be8894db9f843f32ebaffb9b7fd6b57d206Chris Lattner const uint8 kBlackUV = 0x80; 277fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman const base::TimeDelta kZero; 2780e5f1306b059b62d7725f324e087efbc8e7a782dDan Gohman return CreateColorFrame(size, kBlackY, kBlackUV, kBlackUV, kZero); 2790e5f1306b059b62d7725f324e087efbc8e7a782dDan Gohman} 280fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 281c3aae25116e66c177579b0b79182b09340b19753Chris Lattner#if defined(VIDEO_HOLE) 282cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattner// This block and other blocks wrapped around #if defined(VIDEO_HOLE) is not 283475871a144eb604ddaf37503397ba0941442e5fbDan Gohman// maintained by the general compositor team. Please contact the following 284cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattner// people instead: 285c3aae25116e66c177579b0b79182b09340b19753Chris Lattner// 286c3aae25116e66c177579b0b79182b09340b19753Chris Lattner// wonsik@chromium.org 287f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman// ycheo@chromium.org 288f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman 289f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman// static 290cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattnerscoped_refptr<VideoFrame> VideoFrame::CreateHoleFrame( 291c3aae25116e66c177579b0b79182b09340b19753Chris Lattner const gfx::Size& size) { 292cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattner DCHECK(IsValidConfig(VideoFrame::HOLE, size, gfx::Rect(size), size)); 293475871a144eb604ddaf37503397ba0941442e5fbDan Gohman scoped_refptr<VideoFrame> frame(new VideoFrame( 294825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson VideoFrame::HOLE, size, gfx::Rect(size), size, base::TimeDelta(), false)); 295acaf09dbe4a6781163857db1321bbd5795e7d410Dan Gohman return frame; 296cf495bc2e505e52ad018da55bed11c7b8bc97db5David Greene} 297cf495bc2e505e52ad018da55bed11c7b8bc97db5David Greene#endif // defined(VIDEO_HOLE) 298cf495bc2e505e52ad018da55bed11c7b8bc97db5David Greene 299cf495bc2e505e52ad018da55bed11c7b8bc97db5David Greene// static 300cf495bc2e505e52ad018da55bed11c7b8bc97db5David Greenesize_t VideoFrame::NumPlanes(Format format) { 301cf495bc2e505e52ad018da55bed11c7b8bc97db5David Greene switch (format) { 302acaf09dbe4a6781163857db1321bbd5795e7d410Dan Gohman case VideoFrame::NATIVE_TEXTURE: 303cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattner#if defined(VIDEO_HOLE) 3041d4d41411190dd9e62764e56713753d4155764ddNate Begeman case VideoFrame::HOLE: 30525cf2275ff7de3de3bc0e508abaf457413d74725Duncan Sands#endif // defined(VIDEO_HOLE) 30625cf2275ff7de3de3bc0e508abaf457413d74725Duncan Sands return 0; 30725cf2275ff7de3de3bc0e508abaf457413d74725Duncan Sands case VideoFrame::YV12: 30898a366d547772010e94609e4584489b3e5ce0043Bill Wendling case VideoFrame::YV16: 30998a366d547772010e94609e4584489b3e5ce0043Bill Wendling case VideoFrame::I420: 31025cf2275ff7de3de3bc0e508abaf457413d74725Duncan Sands case VideoFrame::YV12J: 31101d029b82cb08367d81aa10cdc94d05360466649Chris Lattner return 3; 31225cf2275ff7de3de3bc0e508abaf457413d74725Duncan Sands case VideoFrame::YV12A: 31325cf2275ff7de3de3bc0e508abaf457413d74725Duncan Sands return 4; 31401d029b82cb08367d81aa10cdc94d05360466649Chris Lattner case VideoFrame::UNKNOWN: 31501d029b82cb08367d81aa10cdc94d05360466649Chris Lattner break; 31601d029b82cb08367d81aa10cdc94d05360466649Chris Lattner } 31725cf2275ff7de3de3bc0e508abaf457413d74725Duncan Sands NOTREACHED() << "Unsupported video frame format: " << format; 31825cf2275ff7de3de3bc0e508abaf457413d74725Duncan Sands return 0; 319c3aae25116e66c177579b0b79182b09340b19753Chris Lattner} 320c3aae25116e66c177579b0b79182b09340b19753Chris Lattner 321c3aae25116e66c177579b0b79182b09340b19753Chris Lattner 322cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattner// static 323c3aae25116e66c177579b0b79182b09340b19753Chris Lattnersize_t VideoFrame::AllocationSize(Format format, const gfx::Size& coded_size) { 324c3aae25116e66c177579b0b79182b09340b19753Chris Lattner size_t total = 0; 325975716af1b9a09274df6c2d92683449015bd8564Dan Gohman for (size_t i = 0; i < NumPlanes(format); ++i) 326c3aae25116e66c177579b0b79182b09340b19753Chris Lattner total += PlaneAllocationSize(format, i, coded_size); 3275c22c8074404797f1313b1334757254fb5c6487aEli Friedman return total; 3285c22c8074404797f1313b1334757254fb5c6487aEli Friedman} 3295c22c8074404797f1313b1334757254fb5c6487aEli Friedman 3305c22c8074404797f1313b1334757254fb5c6487aEli Friedman// static 3315c22c8074404797f1313b1334757254fb5c6487aEli Friedmangfx::Size VideoFrame::PlaneSize(Format format, 3325c22c8074404797f1313b1334757254fb5c6487aEli Friedman size_t plane, 3335c22c8074404797f1313b1334757254fb5c6487aEli Friedman const gfx::Size& coded_size) { 3345c22c8074404797f1313b1334757254fb5c6487aEli Friedman const int width = RoundUp(coded_size.width(), 2); 3355c22c8074404797f1313b1334757254fb5c6487aEli Friedman const int height = RoundUp(coded_size.height(), 2); 3365c22c8074404797f1313b1334757254fb5c6487aEli Friedman switch (format) { 3375c22c8074404797f1313b1334757254fb5c6487aEli Friedman case VideoFrame::YV12: 3385c22c8074404797f1313b1334757254fb5c6487aEli Friedman case VideoFrame::YV12J: 3395c22c8074404797f1313b1334757254fb5c6487aEli Friedman case VideoFrame::I420: { 340d1fc96499b7619356c7542200d32da898b79f7c1Chris Lattner switch (plane) { 341190a418bf6b49a4ef1c1980229a2f0d516e8a2cdChris Lattner case VideoFrame::kYPlane: 342190a418bf6b49a4ef1c1980229a2f0d516e8a2cdChris Lattner return gfx::Size(width, height); 343130a6471b90f66e99b1f9f42877fdf611c330ac6Evan Cheng case VideoFrame::kUPlane: 344130a6471b90f66e99b1f9f42877fdf611c330ac6Evan Cheng case VideoFrame::kVPlane: 345130a6471b90f66e99b1f9f42877fdf611c330ac6Evan Cheng return gfx::Size(width / 2, height / 2); 346130a6471b90f66e99b1f9f42877fdf611c330ac6Evan Cheng default: 347130a6471b90f66e99b1f9f42877fdf611c330ac6Evan Cheng break; 34870046e920fa37989a041af663ada2b2b646e258fChris Lattner } 34970046e920fa37989a041af663ada2b2b646e258fChris Lattner } 350e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson case VideoFrame::YV12A: { 351e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson switch (plane) { 352e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson case VideoFrame::kYPlane: 353e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson case VideoFrame::kAPlane: 354e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson return gfx::Size(width, height); 355fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel case VideoFrame::kUPlane: 3561b1a49714ef26225a42199cf2930529f31868322Chris Lattner case VideoFrame::kVPlane: 35770046e920fa37989a041af663ada2b2b646e258fChris Lattner return gfx::Size(width / 2, height / 2); 35870046e920fa37989a041af663ada2b2b646e258fChris Lattner default: 359e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson break; 360e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson } 361e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson } 362475871a144eb604ddaf37503397ba0941442e5fbDan Gohman case VideoFrame::YV16: { 363e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson switch (plane) { 364cbea3045ce0bdd061c494a831d0ce2d5834211ccChris Lattner case VideoFrame::kYPlane: 365cbea3045ce0bdd061c494a831d0ce2d5834211ccChris Lattner return gfx::Size(width, height); 366e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson case VideoFrame::kUPlane: 3676394b099e836f56a937cdcc7332c9487b504ca68Dan Gohman case VideoFrame::kVPlane: 3686394b099e836f56a937cdcc7332c9487b504ca68Dan Gohman return gfx::Size(width / 2, height); 369e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson default: 3704fbd796a1251a27e6590765a0a34876f436a0af9Dan Gohman break; 3714fbd796a1251a27e6590765a0a34876f436a0af9Dan Gohman } 3720a406ae0d940d92c51ee145b48ff7a483a366849Dale Johannesen } 3730a406ae0d940d92c51ee145b48ff7a483a366849Dale Johannesen case VideoFrame::UNKNOWN: 374e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson case VideoFrame::NATIVE_TEXTURE: 375e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson#if defined(VIDEO_HOLE) 376e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson case VideoFrame::HOLE: 377e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson#endif // defined(VIDEO_HOLE) 378c9f8f416800784ca6453222b307bc44ad24739b0Chris Lattner break; 379c9f8f416800784ca6453222b307bc44ad24739b0Chris Lattner } 380e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson NOTREACHED() << "Unsupported video frame format/plane: " 381f04afdbb48568ef09f11fd10ac03426101f2dbf8Dale Johannesen << format << "/" << plane; 382f04afdbb48568ef09f11fd10ac03426101f2dbf8Dale Johannesen return gfx::Size(); 383e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson} 3844fbd796a1251a27e6590765a0a34876f436a0af9Dan Gohman 3854fbd796a1251a27e6590765a0a34876f436a0af9Dan Gohmansize_t VideoFrame::PlaneAllocationSize(Format format, 3860d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel size_t plane, 3872a4ed82ce2ba4a02f2a02eb4ed8ce5186f3f93daChris Lattner const gfx::Size& coded_size) { 3882a4ed82ce2ba4a02f2a02eb4ed8ce5186f3f93daChris Lattner // VideoFrame formats are (so far) all YUV and 1 byte per sample. 3890d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel return PlaneSize(format, plane, coded_size).GetArea(); 3902a4ed82ce2ba4a02f2a02eb4ed8ce5186f3f93daChris Lattner} 3912a4ed82ce2ba4a02f2a02eb4ed8ce5186f3f93daChris Lattner 3920d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel// Release data allocated by AllocateYUV(). 393cbea3045ce0bdd061c494a831d0ce2d5834211ccChris Lattnerstatic void ReleaseData(uint8* data) { 394e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson DCHECK(data); 395e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson base::AlignedFree(data); 396c9f8f416800784ca6453222b307bc44ad24739b0Chris Lattner} 397c9f8f416800784ca6453222b307bc44ad24739b0Chris Lattner 398e50ed30282bb5b4a9ed952580523f2dda16215acOwen Andersonvoid VideoFrame::AllocateYUV() { 399f5a5546f435a261c93078defb41ed18d9cafd7d3Chris Lattner DCHECK(format_ == VideoFrame::YV12 || format_ == VideoFrame::YV16 || 400e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson format_ == VideoFrame::YV12A || format_ == VideoFrame::I420 || 401f5a5546f435a261c93078defb41ed18d9cafd7d3Chris Lattner format_ == VideoFrame::YV12J); 402c9f8f416800784ca6453222b307bc44ad24739b0Chris Lattner // Align Y rows at least at 16 byte boundaries. The stride for both 40346510a73e977273ec67747eb34cbdb43f815e451Dan Gohman // YV12 and YV16 is 1/2 of the stride of Y. For YV12, every row of bytes for 404f5a5546f435a261c93078defb41ed18d9cafd7d3Chris Lattner // U and V applies to two rows of Y (one byte of UV for 4 bytes of Y), so in 405f5a5546f435a261c93078defb41ed18d9cafd7d3Chris Lattner // the case of YV12 the strides are identical for the same width surface, but 40646510a73e977273ec67747eb34cbdb43f815e451Dan Gohman // the number of bytes allocated for YV12 is 1/2 the amount for U & V as 407f5a5546f435a261c93078defb41ed18d9cafd7d3Chris Lattner // YV16. We also round the height of the surface allocated to be an even 408f5a5546f435a261c93078defb41ed18d9cafd7d3Chris Lattner // number to avoid any potential of faulting by code that attempts to access 409f5a5546f435a261c93078defb41ed18d9cafd7d3Chris Lattner // the Y values of the final row, but assumes that the last row of U & V 410c9f8f416800784ca6453222b307bc44ad24739b0Chris Lattner // applies to a full two rows of Y. YV12A is the same as YV12, but with an 411e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson // additional alpha plane that has the same size and alignment as the Y plane. 412f5a5546f435a261c93078defb41ed18d9cafd7d3Chris Lattner 413f5a5546f435a261c93078defb41ed18d9cafd7d3Chris Lattner size_t y_stride = RoundUp(row_bytes(VideoFrame::kYPlane), 414475871a144eb604ddaf37503397ba0941442e5fbDan Gohman kFrameSizeAlignment); 415e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson size_t uv_stride = RoundUp(row_bytes(VideoFrame::kUPlane), 416f5a5546f435a261c93078defb41ed18d9cafd7d3Chris Lattner kFrameSizeAlignment); 417f5a5546f435a261c93078defb41ed18d9cafd7d3Chris Lattner // The *2 here is because some formats (e.g. h264) allow interlaced coding, 418d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng // and then the size needs to be a multiple of two macroblocks (vertically). 41974500bdba3eae36a1a8a17d8bad0b971b9c212ecJakob Stoklund Olesen // See libavcodec/utils.c:avcodec_align_dimensions2(). 42074500bdba3eae36a1a8a17d8bad0b971b9c212ecJakob Stoklund Olesen size_t y_height = RoundUp(coded_size_.height(), kFrameSizeAlignment * 2); 4218ad9b43e690e8773cf836b30e8da26bc71e18844Dale Johannesen size_t uv_height = 4228ad9b43e690e8773cf836b30e8da26bc71e18844Dale Johannesen (format_ == VideoFrame::YV12 || format_ == VideoFrame::YV12A || 423475871a144eb604ddaf37503397ba0941442e5fbDan Gohman format_ == VideoFrame::I420) 424e8c17335c53f0f37262ee342f46b0d00ac0c1493Dale Johannesen ? y_height / 2 425e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson : y_height; 426e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson size_t y_bytes = y_height * y_stride; 427e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson size_t uv_bytes = uv_height * uv_stride; 4281af2231da64a14d638406d133c7912bfc1c8a9ceChris Lattner size_t a_bytes = format_ == VideoFrame::YV12A ? y_bytes : 0; 429e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson 430e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson // The extra line of UV being allocated is because h264 chroma MC 4319cf37e8b48732fccd4c301ed51aafed7074bd84eJakob Stoklund Olesen // overreads by one line in some cases, see libavcodec/utils.c: 4327561d480953e0a2faa4af9be0a00b1180097c4bdChris Lattner // avcodec_align_dimensions2() and libavcodec/x86/h264_chromamc.asm: 43346510a73e977273ec67747eb34cbdb43f815e451Dan Gohman // put_h264_chroma_mc4_ssse3(). 4346c7ccaa3fd1d6e96d0bf922554b09d2b17c3b0e3Michael Liao uint8* data = reinterpret_cast<uint8*>( 4356c7ccaa3fd1d6e96d0bf922554b09d2b17c3b0e3Michael Liao base::AlignedAlloc( 4366c7ccaa3fd1d6e96d0bf922554b09d2b17c3b0e3Michael Liao y_bytes + (uv_bytes * 2 + uv_stride) + a_bytes + kFrameSizePadding, 4376c7ccaa3fd1d6e96d0bf922554b09d2b17c3b0e3Michael Liao kFrameAddressAlignment)); 4386c7ccaa3fd1d6e96d0bf922554b09d2b17c3b0e3Michael Liao no_longer_needed_cb_ = base::Bind(&ReleaseData, data); 4396c7ccaa3fd1d6e96d0bf922554b09d2b17c3b0e3Michael Liao COMPILE_ASSERT(0 == VideoFrame::kYPlane, y_plane_data_must_be_index_0); 4406c7ccaa3fd1d6e96d0bf922554b09d2b17c3b0e3Michael Liao data_[VideoFrame::kYPlane] = data; 441c3aae25116e66c177579b0b79182b09340b19753Chris Lattner data_[VideoFrame::kUPlane] = data + y_bytes; 4420f502f6f44f2756f5cb7b17d8f1d8eae000d51b4Dale Johannesen data_[VideoFrame::kVPlane] = data + y_bytes + uv_bytes; 443825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson strides_[VideoFrame::kYPlane] = y_stride; 4440f502f6f44f2756f5cb7b17d8f1d8eae000d51b4Dale Johannesen strides_[VideoFrame::kUPlane] = uv_stride; 4450f502f6f44f2756f5cb7b17d8f1d8eae000d51b4Dale Johannesen strides_[VideoFrame::kVPlane] = uv_stride; 446cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattner if (format_ == YV12A) { 447e3f1026683c38f6605ccaf698b7082f1b0a0f8c8Chris Lattner data_[VideoFrame::kAPlane] = data + y_bytes + (2 * uv_bytes); 44829d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner strides_[VideoFrame::kAPlane] = y_stride; 44929d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner } 4500f502f6f44f2756f5cb7b17d8f1d8eae000d51b4Dale Johannesen} 45129d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner 452f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris LattnerVideoFrame::VideoFrame(VideoFrame::Format format, 45329d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner const gfx::Size& coded_size, 45429d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner const gfx::Rect& visible_rect, 4550f502f6f44f2756f5cb7b17d8f1d8eae000d51b4Dale Johannesen const gfx::Size& natural_size, 45666a48bbc3565b40ea0e6f2d58cf5e3a8e64802efEvan Cheng base::TimeDelta timestamp, 457475871a144eb604ddaf37503397ba0941442e5fbDan Gohman bool end_of_stream) 4580f502f6f44f2756f5cb7b17d8f1d8eae000d51b4Dale Johannesen : format_(format), 45929d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner coded_size_(coded_size), 460f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner visible_rect_(visible_rect), 46129d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner natural_size_(natural_size), 46229d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner shared_memory_handle_(base::SharedMemory::NULLHandle()), 4630f502f6f44f2756f5cb7b17d8f1d8eae000d51b4Dale Johannesen timestamp_(timestamp), 464fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel end_of_stream_(end_of_stream) { 465e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson DCHECK(IsValidConfig(format_, coded_size_, visible_rect_, natural_size_)); 466825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 4670f502f6f44f2756f5cb7b17d8f1d8eae000d51b4Dale Johannesen memset(&strides_, 0, sizeof(strides_)); 468fc1665793e62eb4f26d24b8a19eecf59cd872e2aDan Gohman memset(&data_, 0, sizeof(data_)); 4690f502f6f44f2756f5cb7b17d8f1d8eae000d51b4Dale Johannesen} 470fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 471e3f1026683c38f6605ccaf698b7082f1b0a0f8c8Chris LattnerVideoFrame::~VideoFrame() { 47229d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner if (!mailbox_holder_release_cb_.is_null()) { 47329d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner base::ResetAndReturn(&mailbox_holder_release_cb_) 474e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson .Run(mailbox_holder_.Pass()); 47529d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner } 476f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner if (!no_longer_needed_cb_.is_null()) 47729d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner base::ResetAndReturn(&no_longer_needed_cb_).Run(); 47829d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner} 4790f502f6f44f2756f5cb7b17d8f1d8eae000d51b4Dale Johannesen 48018c2f13e0f9d0e5d6227cf6d1881e9ee3d1b6109Chris Lattnerbool VideoFrame::IsValidPlane(size_t plane) const { 481475871a144eb604ddaf37503397ba0941442e5fbDan Gohman return (plane < NumPlanes(format_)); 482cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattner} 48377cdf30742284a173fe818417eb482224cdee8d4Mon P Wang 48477cdf30742284a173fe818417eb482224cdee8d4Mon P Wangint VideoFrame::stride(size_t plane) const { 485e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson DCHECK(IsValidPlane(plane)); 4860f502f6f44f2756f5cb7b17d8f1d8eae000d51b4Dale Johannesen return strides_[plane]; 4870f502f6f44f2756f5cb7b17d8f1d8eae000d51b4Dale Johannesen} 4886154f6c9292179fab6346ae8336f2ad790b52028Owen Anderson 4899008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begemanint VideoFrame::row_bytes(size_t plane) const { 4909008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman DCHECK(IsValidPlane(plane)); 4915a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman int width = coded_size_.width(); 4929008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman switch (format_) { 4936154f6c9292179fab6346ae8336f2ad790b52028Owen Anderson // Planar, 8bpp. 4949008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman case YV12A: 49577cdf30742284a173fe818417eb482224cdee8d4Mon P Wang if (plane == kAPlane) 496a3c42f3d4e5d14c8f4fb9bb123e7759c425d041bNadav Rotem return width; 497a3c42f3d4e5d14c8f4fb9bb123e7759c425d041bNadav Rotem // Fallthrough. 498a3c42f3d4e5d14c8f4fb9bb123e7759c425d041bNadav Rotem case YV12: 499a3c42f3d4e5d14c8f4fb9bb123e7759c425d041bNadav Rotem case YV16: 5003a66a68b0cc81193abfc074b1d360a4950151d38Duncan Sands case I420: 5013a66a68b0cc81193abfc074b1d360a4950151d38Duncan Sands case YV12J: 5023a66a68b0cc81193abfc074b1d360a4950151d38Duncan Sands if (plane == kYPlane) 5033a66a68b0cc81193abfc074b1d360a4950151d38Duncan Sands return width; 5043a66a68b0cc81193abfc074b1d360a4950151d38Duncan Sands return RoundUp(width, 2) / 2; 5053a66a68b0cc81193abfc074b1d360a4950151d38Duncan Sands 5063a66a68b0cc81193abfc074b1d360a4950151d38Duncan Sands default: 5073a66a68b0cc81193abfc074b1d360a4950151d38Duncan Sands break; 5081ccae666f596d5aeca5c9942995763600b622062Chris Lattner } 5091ccae666f596d5aeca5c9942995763600b622062Chris Lattner 510e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson // Intentionally leave out non-production formats. 511fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel NOTREACHED() << "Unsupported video frame format: " << format_; 5124c2454623841f05c6c665659b34c214950d12d7eBob Wilson return 0; 513e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson} 5144c2454623841f05c6c665659b34c214950d12d7eBob Wilson 5156a5b6d7633c96c72ca7d5f8ba0c855e4690ada04Chris Lattnerint VideoFrame::rows(size_t plane) const { 51629d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner DCHECK(IsValidPlane(plane)); 517e8d7230f480654cdb8ff1c3d0a38e1e9ab0bd55fDale Johannesen int height = coded_size_.height(); 518475871a144eb604ddaf37503397ba0941442e5fbDan Gohman switch (format_) { 519f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner case YV16: 520475871a144eb604ddaf37503397ba0941442e5fbDan Gohman return height; 521b494ccf02ce17318d3f2a7b2d674bec60781fc73Chris Lattner 5226a5b6d7633c96c72ca7d5f8ba0c855e4690ada04Chris Lattner case YV12A: 5231ccae666f596d5aeca5c9942995763600b622062Chris Lattner if (plane == kAPlane) 5240f8d9c04d9feef86cee35cf5fecfb348a6b3de50Bill Wendling return height; 52529d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner // Fallthrough. 526e8d7230f480654cdb8ff1c3d0a38e1e9ab0bd55fDale Johannesen case YV12: 527475871a144eb604ddaf37503397ba0941442e5fbDan Gohman case I420: 52829d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner if (plane == kYPlane) 529f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner return height; 530475871a144eb604ddaf37503397ba0941442e5fbDan Gohman return RoundUp(height, 2) / 2; 5310f8d9c04d9feef86cee35cf5fecfb348a6b3de50Bill Wendling 5320f8d9c04d9feef86cee35cf5fecfb348a6b3de50Bill Wendling default: 5330f8d9c04d9feef86cee35cf5fecfb348a6b3de50Bill Wendling break; 53429d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner } 535b494ccf02ce17318d3f2a7b2d674bec60781fc73Chris Lattner 53629d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner // Intentionally leave out non-production formats. 5370f8d9c04d9feef86cee35cf5fecfb348a6b3de50Bill Wendling NOTREACHED() << "Unsupported video frame format: " << format_; 5380f8d9c04d9feef86cee35cf5fecfb348a6b3de50Bill Wendling return 0; 539e8d7230f480654cdb8ff1c3d0a38e1e9ab0bd55fDale Johannesen} 540e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson 541b494ccf02ce17318d3f2a7b2d674bec60781fc73Chris Lattneruint8* VideoFrame::data(size_t plane) const { 542e8d7230f480654cdb8ff1c3d0a38e1e9ab0bd55fDale Johannesen DCHECK(IsValidPlane(plane)); 543e8d7230f480654cdb8ff1c3d0a38e1e9ab0bd55fDale Johannesen return data_[plane]; 544b300d2aa3ef08b5074449e2c05804717f488f4e4Dale Johannesen} 545b300d2aa3ef08b5074449e2c05804717f488f4e4Dale Johannesen 546e50ed30282bb5b4a9ed952580523f2dda16215acOwen Andersongpu::MailboxHolder* VideoFrame::mailbox_holder() const { 547b494ccf02ce17318d3f2a7b2d674bec60781fc73Chris Lattner DCHECK_EQ(format_, NATIVE_TEXTURE); 548b300d2aa3ef08b5074449e2c05804717f488f4e4Dale Johannesen return mailbox_holder_.get(); 549b300d2aa3ef08b5074449e2c05804717f488f4e4Dale Johannesen} 550c3aae25116e66c177579b0b79182b09340b19753Chris Lattner 551cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattnerbase::SharedMemoryHandle VideoFrame::shared_memory_handle() const { 552e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson return shared_memory_handle_; 553e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson} 554e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson 555e50ed30282bb5b4a9ed952580523f2dda16215acOwen Andersonvoid VideoFrame::HashFrameForTesting(base::MD5Context* context) { 5567ade28cd62f5188951387e1056a46001388a21f9Bill Wendling for (int plane = 0; plane < kMaxPlanes; ++plane) { 557e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson if (!IsValidPlane(plane)) 5587ade28cd62f5188951387e1056a46001388a21f9Bill Wendling break; 559e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson for (int row = 0; row < rows(plane); ++row) { 5607ade28cd62f5188951387e1056a46001388a21f9Bill Wendling base::MD5Update(context, base::StringPiece( 5617ade28cd62f5188951387e1056a46001388a21f9Bill Wendling reinterpret_cast<char*>(data(plane) + stride(plane) * row), 562e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson row_bytes(plane))); 5637ade28cd62f5188951387e1056a46001388a21f9Bill Wendling } 564e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson } 5657ade28cd62f5188951387e1056a46001388a21f9Bill Wendling} 5667ade28cd62f5188951387e1056a46001388a21f9Bill Wendling 567e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson} // namespace media 5687ade28cd62f5188951387e1056a46001388a21f9Bill Wendling