video_frame.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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)
21effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochstatic inline size_t RoundUp(size_t value, size_t alignment) {
22effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Check that |alignment| is a power of 2.
23effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK((alignment + (alignment - 1)) == (alignment | (alignment - 1)));
24effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return ((value + (alignment - 1)) & ~(alignment - 1));
25effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
26effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Rounds up |coded_size| if necessary for |format|.
28116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic gfx::Size AdjustCodedSize(VideoFrame::Format format,
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 const gfx::Size& coded_size) {
30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  gfx::Size new_coded_size(coded_size);
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (format) {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case VideoFrame::YV12:
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case VideoFrame::YV12A:
34ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    case VideoFrame::I420:
35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case VideoFrame::YV12J:
36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      new_coded_size.set_height(RoundUp(new_coded_size.height(), 2));
37effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // Fallthrough.
38effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case VideoFrame::YV16:
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      new_coded_size.set_width(RoundUp(new_coded_size.width(), 2));
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    default:
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      break;
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return new_coded_size;
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// static
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdochscoped_refptr<VideoFrame> VideoFrame::CreateFrame(
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    VideoFrame::Format format,
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const gfx::Size& coded_size,
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const gfx::Rect& visible_rect,
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const gfx::Size& natural_size,
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::TimeDelta timestamp) {
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(format != VideoFrame::UNKNOWN &&
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch         format != VideoFrame::NV12 &&
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch         format != VideoFrame::NATIVE_TEXTURE);
5746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(VIDEO_HOLE)
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(format != VideoFrame::HOLE);
5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif  // defined(VIDEO_HOLE)
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Since we're creating a new YUV frame (and allocating memory for it
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // ourselves), we can pad the requested |coded_size| if necessary if the
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // request does not line up on sample boundaries.
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  gfx::Size new_coded_size = AdjustCodedSize(format, coded_size);
65effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK(IsValidConfig(format, new_coded_size, visible_rect, natural_size));
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<VideoFrame> frame(
685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      new VideoFrame(format,
695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     new_coded_size,
705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     visible_rect,
715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     natural_size,
725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     scoped_ptr<gpu::MailboxHolder>(),
735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     timestamp,
745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     false));
75effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  frame->AllocateYUV();
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return frame;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
803240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochstd::string VideoFrame::FormatToString(VideoFrame::Format format) {
813240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  switch (format) {
820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    case VideoFrame::UNKNOWN:
830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      return "UNKNOWN";
843240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    case VideoFrame::YV12:
853240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      return "YV12";
863240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    case VideoFrame::YV16:
873240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      return "YV16";
883240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    case VideoFrame::I420:
893240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      return "I420";
903240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    case VideoFrame::NATIVE_TEXTURE:
913240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      return "NATIVE_TEXTURE";
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(VIDEO_HOLE)
933240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    case VideoFrame::HOLE:
943240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      return "HOLE";
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif  // defined(VIDEO_HOLE)
963240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    case VideoFrame::YV12A:
973240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      return "YV12A";
98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case VideoFrame::YV12J:
99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return "YV12J";
100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case VideoFrame::NV12:
101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return "NV12";
10246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV24:
10346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      return "YV24";
1043240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  }
1053240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  NOTREACHED() << "Invalid videoframe format provided: " << format;
1063240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  return "";
1073240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
1083240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1093240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// static
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VideoFrame::IsValidConfig(VideoFrame::Format format,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const gfx::Size& coded_size,
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const gfx::Rect& visible_rect,
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const gfx::Size& natural_size) {
114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Check maximum limits for all formats.
115effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (coded_size.GetArea() > limits::kMaxCanvas ||
116effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      coded_size.width() > limits::kMaxDimension ||
117effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      coded_size.height() > limits::kMaxDimension ||
118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      visible_rect.x() < 0 || visible_rect.y() < 0 ||
119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      visible_rect.right() > coded_size.width() ||
120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      visible_rect.bottom() > coded_size.height() ||
121effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      natural_size.GetArea() > limits::kMaxCanvas ||
122effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      natural_size.width() > limits::kMaxDimension ||
123effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      natural_size.height() > limits::kMaxDimension)
124effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return false;
125effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
126effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Check format-specific width/height requirements.
127effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  switch (format) {
128effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case VideoFrame::UNKNOWN:
129effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return (coded_size.IsEmpty() && visible_rect.IsEmpty() &&
130effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch              natural_size.IsEmpty());
13146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV24:
13246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
133effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case VideoFrame::YV12:
134effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case VideoFrame::YV12J:
135effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case VideoFrame::I420:
136effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case VideoFrame::YV12A:
137010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case VideoFrame::NV12:
13846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      // Subsampled YUV formats have width/height requirements.
139effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      if (static_cast<size_t>(coded_size.height()) <
140effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          RoundUp(visible_rect.bottom(), 2))
141effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        return false;
142effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // Fallthrough.
143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case VideoFrame::YV16:
144effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      if (static_cast<size_t>(coded_size.width()) <
145effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          RoundUp(visible_rect.right(), 2))
146effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        return false;
147effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      break;
148effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case VideoFrame::NATIVE_TEXTURE:
149effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#if defined(VIDEO_HOLE)
150effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case VideoFrame::HOLE:
151effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#endif  // defined(VIDEO_HOLE)
152effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      // NATIVE_TEXTURE and HOLE have no software-allocated buffers and are
153effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      // allowed to skip the below check and be empty.
154effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return true;
155effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
156effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
157effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Check that software-allocated buffer formats are not empty.
158effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return (!coded_size.IsEmpty() && !visible_rect.IsEmpty() &&
159effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          !natural_size.IsEmpty());
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::WrapNativeTexture(
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<gpu::MailboxHolder> mailbox_holder,
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const ReleaseMailboxCB& mailbox_holder_release_cb,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Size& coded_size,
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& visible_rect,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Size& natural_size,
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::TimeDelta timestamp,
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const ReadPixelsCB& read_pixels_cb) {
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<VideoFrame> frame(new VideoFrame(NATIVE_TEXTURE,
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                 coded_size,
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                 visible_rect,
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                 natural_size,
1755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                                 mailbox_holder.Pass(),
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                 timestamp,
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                 false));
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  frame->mailbox_holder_release_cb_ = mailbox_holder_release_cb;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  frame->read_pixels_cb_ = read_pixels_cb;
180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return frame;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void VideoFrame::ReadPixelsFromNativeTexture(const SkBitmap& pixels) {
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(format_, NATIVE_TEXTURE);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!read_pixels_cb_.is_null())
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    read_pixels_cb_.Run(pixels);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::WrapExternalPackedMemory(
192ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    Format format,
193ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    const gfx::Size& coded_size,
194ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    const gfx::Rect& visible_rect,
195ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    const gfx::Size& natural_size,
196ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    uint8* data,
197424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    size_t data_size,
198ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    base::SharedMemoryHandle handle,
199ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    base::TimeDelta timestamp,
200ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    const base::Closure& no_longer_needed_cb) {
201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  gfx::Size new_coded_size = AdjustCodedSize(format, coded_size);
202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!IsValidConfig(format, new_coded_size, visible_rect, natural_size))
204effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return NULL;
205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (data_size < AllocationSize(format, new_coded_size))
206424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return NULL;
207424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
208ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  switch (format) {
20946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::I420: {
2105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      scoped_refptr<VideoFrame> frame(
2115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          new VideoFrame(format,
212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                         new_coded_size,
2135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                         visible_rect,
2145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                         natural_size,
2155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                         scoped_ptr<gpu::MailboxHolder>(),
2165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                         timestamp,
2175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                         false));
218ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      frame->shared_memory_handle_ = handle;
219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      frame->strides_[kYPlane] = new_coded_size.width();
220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      frame->strides_[kUPlane] = new_coded_size.width() / 2;
221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      frame->strides_[kVPlane] = new_coded_size.width() / 2;
222ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      frame->data_[kYPlane] = data;
223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      frame->data_[kUPlane] = data + new_coded_size.GetArea();
224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      frame->data_[kVPlane] = data + (new_coded_size.GetArea() * 5 / 4);
225ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      frame->no_longer_needed_cb_ = no_longer_needed_cb;
226ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      return frame;
227ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
228ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    default:
229ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      NOTIMPLEMENTED();
230ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      return NULL;
231ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
232ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
233ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
234010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#if defined(OS_POSIX)
235010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// static
236010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::WrapExternalDmabufs(
237010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    Format format,
238010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const gfx::Size& coded_size,
239010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const gfx::Rect& visible_rect,
240010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const gfx::Size& natural_size,
241010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const std::vector<int> dmabuf_fds,
242010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    base::TimeDelta timestamp,
243010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const base::Closure& no_longer_needed_cb) {
244010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!IsValidConfig(format, coded_size, visible_rect, natural_size))
245010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return NULL;
246010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
247010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (dmabuf_fds.size() != NumPlanes(format)) {
248010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    LOG(FATAL) << "Not enough dmabuf fds provided!";
249010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return NULL;
250010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
251010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
252010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scoped_refptr<VideoFrame> frame(
253010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      new VideoFrame(format,
254010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                     coded_size,
255010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                     visible_rect,
256010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                     natural_size,
257010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                     scoped_ptr<gpu::MailboxHolder>(),
258010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                     timestamp,
259010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                     false));
260010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
261010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (size_t i = 0; i < dmabuf_fds.size(); ++i) {
262010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    int duped_fd = HANDLE_EINTR(dup(dmabuf_fds[i]));
263010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (duped_fd == -1) {
264010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      // The already-duped in previous iterations fds will be closed when
265010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      // the partially-created frame drops out of scope here.
266010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      DLOG(ERROR) << "Failed duplicating a dmabuf fd";
267010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return NULL;
268010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
270010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    frame->dmabuf_fds_[i].reset(duped_fd);
271010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // Data is accessible only via fds.
272010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    frame->data_[i] = NULL;
273010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    frame->strides_[i] = 0;
274010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
275010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
276010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  frame->no_longer_needed_cb_ = no_longer_needed_cb;
277010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return frame;
278010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
279010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#endif
280010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
281ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// static
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::WrapExternalYuvData(
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Format format,
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Size& coded_size,
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Rect& visible_rect,
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Size& natural_size,
287ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    int32 y_stride,
288ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    int32 u_stride,
289ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    int32 v_stride,
290ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    uint8* y_data,
291ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    uint8* u_data,
292ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    uint8* v_data,
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::TimeDelta timestamp,
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Closure& no_longer_needed_cb) {
295116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  gfx::Size new_coded_size = AdjustCodedSize(format, coded_size);
296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  CHECK(IsValidConfig(format, new_coded_size, visible_rect, natural_size));
297effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
2985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<VideoFrame> frame(
2995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      new VideoFrame(format,
300116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                     new_coded_size,
3015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     visible_rect,
3025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     natural_size,
3035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     scoped_ptr<gpu::MailboxHolder>(),
3045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     timestamp,
3055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     false));
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frame->strides_[kYPlane] = y_stride;
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frame->strides_[kUPlane] = u_stride;
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frame->strides_[kVPlane] = v_stride;
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frame->data_[kYPlane] = y_data;
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frame->data_[kUPlane] = u_data;
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frame->data_[kVPlane] = v_data;
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frame->no_longer_needed_cb_ = no_longer_needed_cb;
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return frame;
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
317a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::WrapVideoFrame(
318a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const scoped_refptr<VideoFrame>& frame,
319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const gfx::Rect& visible_rect,
320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const gfx::Size& natural_size,
321a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const base::Closure& no_longer_needed_cb) {
322a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // NATIVE_TEXTURE frames need mailbox info propagated, and there's no support
323a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // for that here yet, see http://crbug/362521.
324116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  CHECK_NE(frame->format(), NATIVE_TEXTURE);
325a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(frame->visible_rect().Contains(visible_rect));
3275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<VideoFrame> wrapped_frame(
3285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      new VideoFrame(frame->format(),
3295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     frame->coded_size(),
3305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     visible_rect,
3315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     natural_size,
3325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     scoped_ptr<gpu::MailboxHolder>(),
3335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     frame->timestamp(),
3345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     frame->end_of_stream()));
335a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
336a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  for (size_t i = 0; i < NumPlanes(frame->format()); ++i) {
337a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    wrapped_frame->strides_[i] = frame->stride(i);
338a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    wrapped_frame->data_[i] = frame->data(i);
339a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
340a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
341a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  wrapped_frame->no_longer_needed_cb_ = no_longer_needed_cb;
342a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return wrapped_frame;
343a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
344a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
345a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// static
346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::CreateEOSFrame() {
347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return new VideoFrame(VideoFrame::UNKNOWN,
348f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        gfx::Size(),
349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        gfx::Rect(),
350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        gfx::Size(),
3515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                        scoped_ptr<gpu::MailboxHolder>(),
352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        kNoTimestamp(),
353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        true);
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::CreateColorFrame(
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Size& size,
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8 y, uint8 u, uint8 v,
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::TimeDelta timestamp) {
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<VideoFrame> frame = VideoFrame::CreateFrame(
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      VideoFrame::YV12, size, gfx::Rect(size), size, timestamp);
363868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FillYUV(frame.get(), y, u, v);
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return frame;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::CreateBlackFrame(const gfx::Size& size) {
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const uint8 kBlackY = 0x00;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const uint8 kBlackUV = 0x80;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::TimeDelta kZero;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CreateColorFrame(size, kBlackY, kBlackUV, kBlackUV, kZero);
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// static
376116680a4aac90f2aa7413d9095a592090648e557Ben Murdochscoped_refptr<VideoFrame> VideoFrame::CreateTransparentFrame(
377116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const gfx::Size& size) {
378116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const uint8 kBlackY = 0x00;
379116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const uint8 kBlackUV = 0x00;
380116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const uint8 kTransparentA = 0x00;
381116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const base::TimeDelta kZero;
382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<VideoFrame> frame = VideoFrame::CreateFrame(
383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      VideoFrame::YV12A, size, gfx::Rect(size), size, kZero);
384116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  FillYUVA(frame, kBlackY, kBlackUV, kBlackUV, kTransparentA);
385116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return frame;
386116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
387116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(VIDEO_HOLE)
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This block and other blocks wrapped around #if defined(VIDEO_HOLE) is not
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// maintained by the general compositor team. Please contact the following
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// people instead:
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// wonsik@chromium.org
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ycheo@chromium.org
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::CreateHoleFrame(
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Size& size) {
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsValidConfig(VideoFrame::HOLE, size, gfx::Rect(size), size));
4005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<VideoFrame> frame(
4015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      new VideoFrame(VideoFrame::HOLE,
4025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     size,
4035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     gfx::Rect(size),
4045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     size,
4055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     scoped_ptr<gpu::MailboxHolder>(),
4065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     base::TimeDelta(),
4075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     false));
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return frame;
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif  // defined(VIDEO_HOLE)
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t VideoFrame::NumPlanes(Format format) {
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (format) {
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case VideoFrame::NATIVE_TEXTURE:
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(VIDEO_HOLE)
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case VideoFrame::HOLE:
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif  // defined(VIDEO_HOLE)
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return 0;
420010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case VideoFrame::NV12:
421010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return 2;
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case VideoFrame::YV12:
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case VideoFrame::YV16:
424ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    case VideoFrame::I420:
425a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case VideoFrame::YV12J:
42646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV24:
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return 3;
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case VideoFrame::YV12A:
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return 4;
4300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    case VideoFrame::UNKNOWN:
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NOTREACHED() << "Unsupported video frame format: " << format;
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return 0;
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
437424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
438424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// static
439424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)size_t VideoFrame::AllocationSize(Format format, const gfx::Size& coded_size) {
440f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  size_t total = 0;
441f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (size_t i = 0; i < NumPlanes(format); ++i)
442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    total += PlaneAllocationSize(format, i, coded_size);
443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return total;
444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
445f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
446f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// static
447effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochgfx::Size VideoFrame::PlaneSize(Format format,
448effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                size_t plane,
449effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                const gfx::Size& coded_size) {
45046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Align to multiple-of-two size overall. This ensures that non-subsampled
45146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // planes can be addressed by pixel with the same scaling as the subsampled
45246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // planes.
453effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const int width = RoundUp(coded_size.width(), 2);
454effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const int height = RoundUp(coded_size.height(), 2);
455424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  switch (format) {
45646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV24:
45746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      switch (plane) {
45846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case VideoFrame::kYPlane:
45946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case VideoFrame::kUPlane:
46046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case VideoFrame::kVPlane:
46146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return gfx::Size(width, height);
46246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        default:
46346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          break;
46446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      }
46546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
466424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    case VideoFrame::YV12:
467a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case VideoFrame::YV12J:
46846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::I420:
469f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      switch (plane) {
470f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        case VideoFrame::kYPlane:
471effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          return gfx::Size(width, height);
472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        case VideoFrame::kUPlane:
473f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        case VideoFrame::kVPlane:
474effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          return gfx::Size(width / 2, height / 2);
475f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        default:
476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          break;
477f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
47846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
47946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV12A:
480f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      switch (plane) {
481f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        case VideoFrame::kYPlane:
482f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        case VideoFrame::kAPlane:
483effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          return gfx::Size(width, height);
484f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        case VideoFrame::kUPlane:
485f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        case VideoFrame::kVPlane:
486effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          return gfx::Size(width / 2, height / 2);
487f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        default:
488f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          break;
489f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
49046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
49146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV16:
492f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      switch (plane) {
493f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        case VideoFrame::kYPlane:
494effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          return gfx::Size(width, height);
495f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        case VideoFrame::kUPlane:
496f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        case VideoFrame::kVPlane:
497effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          return gfx::Size(width / 2, height);
498f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        default:
499f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          break;
500f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
50146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
50246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::NV12:
503010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      switch (plane) {
504010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        case VideoFrame::kYPlane:
505010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          return gfx::Size(width, height);
506010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        case VideoFrame::kUVPlane:
507010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          return gfx::Size(width, height / 2);
508010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        default:
509010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          break;
510010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      }
51146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
5120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    case VideoFrame::UNKNOWN:
513424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    case VideoFrame::NATIVE_TEXTURE:
5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(VIDEO_HOLE)
515424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    case VideoFrame::HOLE:
5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif  // defined(VIDEO_HOLE)
517424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      break;
518424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
519f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  NOTREACHED() << "Unsupported video frame format/plane: "
520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)               << format << "/" << plane;
521effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return gfx::Size();
522effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
523effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
524effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochsize_t VideoFrame::PlaneAllocationSize(Format format,
525effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                       size_t plane,
526effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                       const gfx::Size& coded_size) {
527effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // VideoFrame formats are (so far) all YUV and 1 byte per sample.
528effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return PlaneSize(format, plane, coded_size).GetArea();
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
531010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// static
532010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)int VideoFrame::PlaneHorizontalBitsPerPixel(Format format, size_t plane) {
533010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  switch (format) {
53446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV24:
53546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      switch (plane) {
53646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kYPlane:
53746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kUPlane:
53846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kVPlane:
53946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return 8;
54046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        default:
54146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          break;
54246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      }
54346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
544010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case VideoFrame::YV12:
545010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case VideoFrame::YV16:
546010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case VideoFrame::I420:
54746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV12J:
548010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      switch (plane) {
549010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        case kYPlane:
550010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          return 8;
551010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        case kUPlane:
552010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        case kVPlane:
553010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          return 2;
554010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        default:
555010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          break;
556010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      }
55746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
55846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV12A:
55946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      switch (plane) {
56046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kYPlane:
56146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kAPlane:
56246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return 8;
56346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kUPlane:
56446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kVPlane:
56546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return 2;
56646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        default:
56746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          break;
56846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      }
56946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
57046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::NV12:
571010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      switch (plane) {
572010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        case kYPlane:
573010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          return 8;
574010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        case kUVPlane:
575010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          return 4;
576010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        default:
577010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          break;
578010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      }
57946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
58046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::UNKNOWN:
58146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(VIDEO_HOLE)
58246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::HOLE:
58346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif  // defined(VIDEO_HOLE)
58446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::NATIVE_TEXTURE:
585010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      break;
586010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
58746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  NOTREACHED() << "Unsupported video frame format/plane: "
58846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)               << format << "/" << plane;
589010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return 0;
590010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
591010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
592f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Release data allocated by AllocateYUV().
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static void ReleaseData(uint8* data) {
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(data);
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::AlignedFree(data);
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoFrame::AllocateYUV() {
599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(format_ == VideoFrame::YV12 || format_ == VideoFrame::YV16 ||
600a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)         format_ == VideoFrame::YV12A || format_ == VideoFrame::I420 ||
60146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)         format_ == VideoFrame::YV12J || format_ == VideoFrame::YV24);
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Align Y rows at least at 16 byte boundaries.  The stride for both
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // YV12 and YV16 is 1/2 of the stride of Y.  For YV12, every row of bytes for
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // U and V applies to two rows of Y (one byte of UV for 4 bytes of Y), so in
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the case of YV12 the strides are identical for the same width surface, but
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the number of bytes allocated for YV12 is 1/2 the amount for U & V as
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // YV16. We also round the height of the surface allocated to be an even
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // number to avoid any potential of faulting by code that attempts to access
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the Y values of the final row, but assumes that the last row of U & V
610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // applies to a full two rows of Y. YV12A is the same as YV12, but with an
611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // additional alpha plane that has the same size and alignment as the Y plane.
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t y_stride = RoundUp(row_bytes(VideoFrame::kYPlane),
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            kFrameSizeAlignment);
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t uv_stride = RoundUp(row_bytes(VideoFrame::kUPlane),
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             kFrameSizeAlignment);
61646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The *2 here is because some formats (e.g. h264) allow interlaced coding,
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and then the size needs to be a multiple of two macroblocks (vertically).
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See libavcodec/utils.c:avcodec_align_dimensions2().
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t y_height = RoundUp(coded_size_.height(), kFrameSizeAlignment * 2);
621ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  size_t uv_height =
622ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      (format_ == VideoFrame::YV12 || format_ == VideoFrame::YV12A ||
623ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch       format_ == VideoFrame::I420)
624ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          ? y_height / 2
625ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          : y_height;
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t y_bytes = y_height * y_stride;
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t uv_bytes = uv_height * uv_stride;
628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  size_t a_bytes = format_ == VideoFrame::YV12A ? y_bytes : 0;
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The extra line of UV being allocated is because h264 chroma MC
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // overreads by one line in some cases, see libavcodec/utils.c:
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // avcodec_align_dimensions2() and libavcodec/x86/h264_chromamc.asm:
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // put_h264_chroma_mc4_ssse3().
634116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const size_t data_size =
635116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      y_bytes + (uv_bytes * 2 + uv_stride) + a_bytes + kFrameSizePadding;
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint8* data = reinterpret_cast<uint8*>(
637116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::AlignedAlloc(data_size, kFrameAddressAlignment));
638116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // FFmpeg expects the initialize allocation to be zero-initialized.  Failure
639116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // to do so can lead to unitialized value usage.  See http://crbug.com/390941
640116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  memset(data, 0, data_size);
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  no_longer_needed_cb_ = base::Bind(&ReleaseData, data);
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(0 == VideoFrame::kYPlane, y_plane_data_must_be_index_0);
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_[VideoFrame::kYPlane] = data;
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_[VideoFrame::kUPlane] = data + y_bytes;
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_[VideoFrame::kVPlane] = data + y_bytes + uv_bytes;
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  strides_[VideoFrame::kYPlane] = y_stride;
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  strides_[VideoFrame::kUPlane] = uv_stride;
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  strides_[VideoFrame::kVPlane] = uv_stride;
649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (format_ == YV12A) {
650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    data_[VideoFrame::kAPlane] = data + y_bytes + (2 * uv_bytes);
651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    strides_[VideoFrame::kAPlane] = y_stride;
652c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VideoFrame::VideoFrame(VideoFrame::Format format,
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const gfx::Size& coded_size,
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const gfx::Rect& visible_rect,
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const gfx::Size& natural_size,
6595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                       scoped_ptr<gpu::MailboxHolder> mailbox_holder,
660f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       base::TimeDelta timestamp,
661f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       bool end_of_stream)
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : format_(format),
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      coded_size_(coded_size),
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      visible_rect_(visible_rect),
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      natural_size_(natural_size),
6665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      mailbox_holder_(mailbox_holder.Pass()),
667eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      shared_memory_handle_(base::SharedMemory::NULLHandle()),
668f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      timestamp_(timestamp),
669f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      end_of_stream_(end_of_stream) {
670effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK(IsValidConfig(format_, coded_size_, visible_rect_, natural_size_));
671effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(&strides_, 0, sizeof(strides_));
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(&data_, 0, sizeof(data_));
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VideoFrame::~VideoFrame() {
6775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!mailbox_holder_release_cb_.is_null()) {
6785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    std::vector<uint32> release_sync_points;
6795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    {
6805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      base::AutoLock locker(release_sync_point_lock_);
6815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      release_sync_points_.swap(release_sync_points);
6825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    }
6835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    base::ResetAndReturn(&mailbox_holder_release_cb_).Run(release_sync_points);
6845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!no_longer_needed_cb_.is_null())
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::ResetAndReturn(&no_longer_needed_cb_).Run();
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VideoFrame::IsValidPlane(size_t plane) const {
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (plane < NumPlanes(format_));
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int VideoFrame::stride(size_t plane) const {
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsValidPlane(plane));
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return strides_[plane];
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int VideoFrame::row_bytes(size_t plane) const {
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsValidPlane(plane));
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int width = coded_size_.width();
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (format_) {
70246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV24:
70346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      switch (plane) {
70446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kYPlane:
70546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kUPlane:
70646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kVPlane:
70746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return width;
70846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        default:
70946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          break;
71046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      }
711010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      break;
71246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV12:
71346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV16:
71446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::I420:
71546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV12J:
71646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      switch (plane) {
71746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kYPlane:
71846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return width;
71946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kUPlane:
72046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kVPlane:
72146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return RoundUp(width, 2) / 2;
72246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        default:
72346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          break;
72446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      }
725010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      break;
72646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV12A:
72746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      switch (plane) {
72846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kYPlane:
72946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kAPlane:
73046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return width;
73146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kUPlane:
73246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kVPlane:
73346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return RoundUp(width, 2) / 2;
73446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        default:
73546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          break;
73646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      }
73746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
73846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::NV12:
73946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      switch (plane) {
74046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kYPlane:
74146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kUVPlane:
74246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return width;
74346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        default:
74446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          break;
74546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      }
74646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
74746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::UNKNOWN:
74846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(VIDEO_HOLE)
74946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::HOLE:
75046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif  // defined(VIDEO_HOLE)
75146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::NATIVE_TEXTURE:
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
75446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  NOTREACHED() << "Unsupported video frame format/plane: "
75546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)               << format_ << "/" << plane;
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int VideoFrame::rows(size_t plane) const {
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsValidPlane(plane));
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int height = coded_size_.height();
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (format_) {
76346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV24:
76446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV16:
76546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      switch (plane) {
76646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kYPlane:
76746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kUPlane:
76846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kVPlane:
76946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return height;
77046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        default:
77146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          break;
77246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      }
773010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      break;
77446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV12:
77546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV12J:
77646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::I420:
77746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      switch (plane) {
77846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kYPlane:
77946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return height;
78046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kUPlane:
78146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kVPlane:
78246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return RoundUp(height, 2) / 2;
78346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        default:
78446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          break;
78546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      }
786010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      break;
78746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV12A:
78846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      switch (plane) {
78946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kYPlane:
79046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kAPlane:
79146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return height;
79246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kUPlane:
79346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kVPlane:
79446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return RoundUp(height, 2) / 2;
79546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        default:
79646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          break;
79746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      }
79846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
79946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::NV12:
80046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      switch (plane) {
80146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kYPlane:
80246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return height;
80346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kUVPlane:
80446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return RoundUp(height, 2) / 2;
80546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        default:
80646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          break;
80746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      }
80846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
80946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::UNKNOWN:
81046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(VIDEO_HOLE)
81146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::HOLE:
81246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif  // defined(VIDEO_HOLE)
81346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::NATIVE_TEXTURE:
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
81646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  NOTREACHED() << "Unsupported video frame format/plane: "
81746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)               << format_ << "/" << plane;
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint8* VideoFrame::data(size_t plane) const {
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsValidPlane(plane));
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return data_[plane];
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuconst gpu::MailboxHolder* VideoFrame::mailbox_holder() const {
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(format_, NATIVE_TEXTURE);
8285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return mailbox_holder_.get();
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
831eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbase::SharedMemoryHandle VideoFrame::shared_memory_handle() const {
832eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return shared_memory_handle_;
833eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
834eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
8355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid VideoFrame::AppendReleaseSyncPoint(uint32 sync_point) {
8365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  DCHECK_EQ(format_, NATIVE_TEXTURE);
8375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!sync_point)
8385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return;
8395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  base::AutoLock locker(release_sync_point_lock_);
8405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  release_sync_points_.push_back(sync_point);
8415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
8425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
843010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#if defined(OS_POSIX)
844010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)int VideoFrame::dmabuf_fd(size_t plane) const {
845010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return dmabuf_fds_[plane].get();
846010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
847010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#endif
848010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoFrame::HashFrameForTesting(base::MD5Context* context) {
8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int plane = 0; plane < kMaxPlanes; ++plane) {
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!IsValidPlane(plane))
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int row = 0; row < rows(plane); ++row) {
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::MD5Update(context, base::StringPiece(
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          reinterpret_cast<char*>(data(plane) + stride(plane) * row),
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          row_bytes(plane)));
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
862