video_frame.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
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
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::CreateFrame(
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VideoFrame::Format format,
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Size& coded_size,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& visible_rect,
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Size& natural_size,
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::TimeDelta timestamp) {
34effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Since we're creating a new YUV frame (and allocating memory for it
35effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // ourselves), we can pad the requested |coded_size| if necessary if the
36effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // request does not line up on sample boundaries.
37effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  gfx::Size new_coded_size(coded_size);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (format) {
3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV24:
4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case VideoFrame::YV12:
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case VideoFrame::YV12A:
43ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    case VideoFrame::I420:
44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case VideoFrame::YV12J:
45effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      new_coded_size.set_height((new_coded_size.height() + 1) / 2 * 2);
46effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // Fallthrough.
47effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case VideoFrame::YV16:
48effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      new_coded_size.set_width((new_coded_size.width() + 1) / 2 * 2);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::UNKNOWN:
5146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::NV12:
5246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(VIDEO_HOLE)
5346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::HOLE:
5446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif  // defined(VIDEO_HOLE)
5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::NATIVE_TEXTURE:
56effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      LOG(FATAL) << "Only YUV formats supported: " << format;
57effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return NULL;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK(IsValidConfig(format, new_coded_size, visible_rect, natural_size));
605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<VideoFrame> frame(
615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      new VideoFrame(format,
625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     new_coded_size,
635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     visible_rect,
645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     natural_size,
655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     scoped_ptr<gpu::MailboxHolder>(),
665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     timestamp,
675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     false));
68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  frame->AllocateYUV();
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return frame;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
733240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochstd::string VideoFrame::FormatToString(VideoFrame::Format format) {
743240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  switch (format) {
750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    case VideoFrame::UNKNOWN:
760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      return "UNKNOWN";
773240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    case VideoFrame::YV12:
783240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      return "YV12";
793240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    case VideoFrame::YV16:
803240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      return "YV16";
813240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    case VideoFrame::I420:
823240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      return "I420";
833240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    case VideoFrame::NATIVE_TEXTURE:
843240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      return "NATIVE_TEXTURE";
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(VIDEO_HOLE)
863240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    case VideoFrame::HOLE:
873240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      return "HOLE";
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif  // defined(VIDEO_HOLE)
893240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    case VideoFrame::YV12A:
903240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      return "YV12A";
91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case VideoFrame::YV12J:
92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return "YV12J";
93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case VideoFrame::NV12:
94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return "NV12";
9546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV24:
9646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      return "YV24";
973240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  }
983240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  NOTREACHED() << "Invalid videoframe format provided: " << format;
993240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  return "";
1003240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
1013240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1023240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// static
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VideoFrame::IsValidConfig(VideoFrame::Format format,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const gfx::Size& coded_size,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const gfx::Rect& visible_rect,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const gfx::Size& natural_size) {
107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Check maximum limits for all formats.
108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (coded_size.GetArea() > limits::kMaxCanvas ||
109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      coded_size.width() > limits::kMaxDimension ||
110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      coded_size.height() > limits::kMaxDimension ||
111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      visible_rect.x() < 0 || visible_rect.y() < 0 ||
112effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      visible_rect.right() > coded_size.width() ||
113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      visible_rect.bottom() > coded_size.height() ||
114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      natural_size.GetArea() > limits::kMaxCanvas ||
115effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      natural_size.width() > limits::kMaxDimension ||
116effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      natural_size.height() > limits::kMaxDimension)
117effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return false;
118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Check format-specific width/height requirements.
120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  switch (format) {
121effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case VideoFrame::UNKNOWN:
122effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return (coded_size.IsEmpty() && visible_rect.IsEmpty() &&
123effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch              natural_size.IsEmpty());
12446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV24:
12546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
126effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case VideoFrame::YV12:
127effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case VideoFrame::YV12J:
128effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case VideoFrame::I420:
129effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case VideoFrame::YV12A:
130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case VideoFrame::NV12:
13146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      // Subsampled YUV formats have width/height requirements.
132effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      if (static_cast<size_t>(coded_size.height()) <
133effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          RoundUp(visible_rect.bottom(), 2))
134effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        return false;
135effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // Fallthrough.
136effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case VideoFrame::YV16:
137effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      if (static_cast<size_t>(coded_size.width()) <
138effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          RoundUp(visible_rect.right(), 2))
139effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        return false;
140effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      break;
141effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case VideoFrame::NATIVE_TEXTURE:
142effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#if defined(VIDEO_HOLE)
143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case VideoFrame::HOLE:
144effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#endif  // defined(VIDEO_HOLE)
145effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      // NATIVE_TEXTURE and HOLE have no software-allocated buffers and are
146effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      // allowed to skip the below check and be empty.
147effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return true;
148effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
149effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
150effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Check that software-allocated buffer formats are not empty.
151effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return (!coded_size.IsEmpty() && !visible_rect.IsEmpty() &&
152effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          !natural_size.IsEmpty());
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::WrapNativeTexture(
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<gpu::MailboxHolder> mailbox_holder,
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const ReleaseMailboxCB& mailbox_holder_release_cb,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Size& coded_size,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& visible_rect,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Size& natural_size,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::TimeDelta timestamp,
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const ReadPixelsCB& read_pixels_cb) {
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<VideoFrame> frame(new VideoFrame(NATIVE_TEXTURE,
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                 coded_size,
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                 visible_rect,
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                 natural_size,
1685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                                 mailbox_holder.Pass(),
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                 timestamp,
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                 false));
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  frame->mailbox_holder_release_cb_ = mailbox_holder_release_cb;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  frame->read_pixels_cb_ = read_pixels_cb;
173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return frame;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void VideoFrame::ReadPixelsFromNativeTexture(const SkBitmap& pixels) {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(format_, NATIVE_TEXTURE);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!read_pixels_cb_.is_null())
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    read_pixels_cb_.Run(pixels);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::WrapExternalPackedMemory(
185ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    Format format,
186ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    const gfx::Size& coded_size,
187ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    const gfx::Rect& visible_rect,
188ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    const gfx::Size& natural_size,
189ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    uint8* data,
190424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    size_t data_size,
191ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    base::SharedMemoryHandle handle,
192ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    base::TimeDelta timestamp,
193ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    const base::Closure& no_longer_needed_cb) {
194effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!IsValidConfig(format, coded_size, visible_rect, natural_size))
195effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return NULL;
196424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (data_size < AllocationSize(format, coded_size))
197424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return NULL;
198424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
199ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  switch (format) {
20046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::I420: {
2015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      scoped_refptr<VideoFrame> frame(
2025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          new VideoFrame(format,
2035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                         coded_size,
2045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                         visible_rect,
2055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                         natural_size,
2065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                         scoped_ptr<gpu::MailboxHolder>(),
2075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                         timestamp,
2085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                         false));
209ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      frame->shared_memory_handle_ = handle;
210ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      frame->strides_[kYPlane] = coded_size.width();
211ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      frame->strides_[kUPlane] = coded_size.width() / 2;
212ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      frame->strides_[kVPlane] = coded_size.width() / 2;
213ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      frame->data_[kYPlane] = data;
214ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      frame->data_[kUPlane] = data + coded_size.GetArea();
215ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      frame->data_[kVPlane] = data + (coded_size.GetArea() * 5 / 4);
216ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      frame->no_longer_needed_cb_ = no_longer_needed_cb;
217ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      return frame;
218ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
219ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    default:
220ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      NOTIMPLEMENTED();
221ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      return NULL;
222ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
223ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
224ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
225010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#if defined(OS_POSIX)
226010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// static
227010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::WrapExternalDmabufs(
228010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    Format format,
229010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const gfx::Size& coded_size,
230010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const gfx::Rect& visible_rect,
231010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const gfx::Size& natural_size,
232010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const std::vector<int> dmabuf_fds,
233010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    base::TimeDelta timestamp,
234010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const base::Closure& no_longer_needed_cb) {
235010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!IsValidConfig(format, coded_size, visible_rect, natural_size))
236010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return NULL;
237010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
238010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (dmabuf_fds.size() != NumPlanes(format)) {
239010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    LOG(FATAL) << "Not enough dmabuf fds provided!";
240010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return NULL;
241010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
242010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
243010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scoped_refptr<VideoFrame> frame(
244010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      new VideoFrame(format,
245010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                     coded_size,
246010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                     visible_rect,
247010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                     natural_size,
248010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                     scoped_ptr<gpu::MailboxHolder>(),
249010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                     timestamp,
250010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                     false));
251010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
252010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (size_t i = 0; i < dmabuf_fds.size(); ++i) {
253010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    int duped_fd = HANDLE_EINTR(dup(dmabuf_fds[i]));
254010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (duped_fd == -1) {
255010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      // The already-duped in previous iterations fds will be closed when
256010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      // the partially-created frame drops out of scope here.
257010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      DLOG(ERROR) << "Failed duplicating a dmabuf fd";
258010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return NULL;
259010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
260010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
261010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    frame->dmabuf_fds_[i].reset(duped_fd);
262010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // Data is accessible only via fds.
263010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    frame->data_[i] = NULL;
264010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    frame->strides_[i] = 0;
265010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
266010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
267010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  frame->no_longer_needed_cb_ = no_longer_needed_cb;
268010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return frame;
269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
270010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#endif
271010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
272ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// static
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::WrapExternalYuvData(
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Format format,
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Size& coded_size,
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Rect& visible_rect,
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Size& natural_size,
278ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    int32 y_stride,
279ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    int32 u_stride,
280ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    int32 v_stride,
281ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    uint8* y_data,
282ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    uint8* u_data,
283ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    uint8* v_data,
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::TimeDelta timestamp,
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Closure& no_longer_needed_cb) {
286effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!IsValidConfig(format, coded_size, visible_rect, natural_size))
287effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return NULL;
288effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
2895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<VideoFrame> frame(
2905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      new VideoFrame(format,
2915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     coded_size,
2925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     visible_rect,
2935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     natural_size,
2945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     scoped_ptr<gpu::MailboxHolder>(),
2955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     timestamp,
2965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     false));
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frame->strides_[kYPlane] = y_stride;
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frame->strides_[kUPlane] = u_stride;
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frame->strides_[kVPlane] = v_stride;
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frame->data_[kYPlane] = y_data;
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frame->data_[kUPlane] = u_data;
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frame->data_[kVPlane] = v_data;
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frame->no_longer_needed_cb_ = no_longer_needed_cb;
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return frame;
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
308a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::WrapVideoFrame(
309a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const scoped_refptr<VideoFrame>& frame,
310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const gfx::Rect& visible_rect,
311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const gfx::Size& natural_size,
312a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const base::Closure& no_longer_needed_cb) {
313a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // NATIVE_TEXTURE frames need mailbox info propagated, and there's no support
314a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // for that here yet, see http://crbug/362521.
315a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  CHECK(frame->format() != NATIVE_TEXTURE);
316a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(frame->visible_rect().Contains(visible_rect));
3185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<VideoFrame> wrapped_frame(
3195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      new VideoFrame(frame->format(),
3205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     frame->coded_size(),
3215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     visible_rect,
3225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     natural_size,
3235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     scoped_ptr<gpu::MailboxHolder>(),
3245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     frame->timestamp(),
3255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     frame->end_of_stream()));
326a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
327a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  for (size_t i = 0; i < NumPlanes(frame->format()); ++i) {
328a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    wrapped_frame->strides_[i] = frame->stride(i);
329a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    wrapped_frame->data_[i] = frame->data(i);
330a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
331a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
332a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  wrapped_frame->no_longer_needed_cb_ = no_longer_needed_cb;
333a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return wrapped_frame;
334a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
335a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
336a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// static
337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::CreateEOSFrame() {
338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return new VideoFrame(VideoFrame::UNKNOWN,
339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        gfx::Size(),
340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        gfx::Rect(),
341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        gfx::Size(),
3425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                        scoped_ptr<gpu::MailboxHolder>(),
343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        kNoTimestamp(),
344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        true);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::CreateColorFrame(
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Size& size,
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8 y, uint8 u, uint8 v,
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::TimeDelta timestamp) {
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<VideoFrame> frame = VideoFrame::CreateFrame(
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      VideoFrame::YV12, size, gfx::Rect(size), size, timestamp);
354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FillYUV(frame.get(), y, u, v);
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return frame;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::CreateBlackFrame(const gfx::Size& size) {
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const uint8 kBlackY = 0x00;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const uint8 kBlackUV = 0x80;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::TimeDelta kZero;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CreateColorFrame(size, kBlackY, kBlackUV, kBlackUV, kZero);
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(VIDEO_HOLE)
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This block and other blocks wrapped around #if defined(VIDEO_HOLE) is not
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// maintained by the general compositor team. Please contact the following
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// people instead:
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// wonsik@chromium.org
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ycheo@chromium.org
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<VideoFrame> VideoFrame::CreateHoleFrame(
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Size& size) {
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsValidConfig(VideoFrame::HOLE, size, gfx::Rect(size), size));
3785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<VideoFrame> frame(
3795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      new VideoFrame(VideoFrame::HOLE,
3805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     size,
3815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     gfx::Rect(size),
3825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     size,
3835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     scoped_ptr<gpu::MailboxHolder>(),
3845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     base::TimeDelta(),
3855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     false));
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return frame;
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif  // defined(VIDEO_HOLE)
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t VideoFrame::NumPlanes(Format format) {
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (format) {
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case VideoFrame::NATIVE_TEXTURE:
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(VIDEO_HOLE)
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case VideoFrame::HOLE:
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif  // defined(VIDEO_HOLE)
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return 0;
398010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case VideoFrame::NV12:
399010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return 2;
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case VideoFrame::YV12:
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case VideoFrame::YV16:
402ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    case VideoFrame::I420:
403a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case VideoFrame::YV12J:
40446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV24:
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return 3;
406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case VideoFrame::YV12A:
407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return 4;
4080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    case VideoFrame::UNKNOWN:
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NOTREACHED() << "Unsupported video frame format: " << format;
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return 0;
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
415424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
416424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// static
417424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)size_t VideoFrame::AllocationSize(Format format, const gfx::Size& coded_size) {
418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  size_t total = 0;
419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (size_t i = 0; i < NumPlanes(format); ++i)
420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    total += PlaneAllocationSize(format, i, coded_size);
421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return total;
422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// static
425effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochgfx::Size VideoFrame::PlaneSize(Format format,
426effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                size_t plane,
427effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                const gfx::Size& coded_size) {
42846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Align to multiple-of-two size overall. This ensures that non-subsampled
42946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // planes can be addressed by pixel with the same scaling as the subsampled
43046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // planes.
431effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const int width = RoundUp(coded_size.width(), 2);
432effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const int height = RoundUp(coded_size.height(), 2);
433424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  switch (format) {
43446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV24:
43546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      switch (plane) {
43646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case VideoFrame::kYPlane:
43746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case VideoFrame::kUPlane:
43846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case VideoFrame::kVPlane:
43946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return gfx::Size(width, height);
44046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        default:
44146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          break;
44246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      }
44346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
444424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    case VideoFrame::YV12:
445a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case VideoFrame::YV12J:
44646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::I420:
447f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      switch (plane) {
448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        case VideoFrame::kYPlane:
449effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          return gfx::Size(width, height);
450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        case VideoFrame::kUPlane:
451f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        case VideoFrame::kVPlane:
452effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          return gfx::Size(width / 2, height / 2);
453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        default:
454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          break;
455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
45646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
45746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV12A:
458f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      switch (plane) {
459f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        case VideoFrame::kYPlane:
460f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        case VideoFrame::kAPlane:
461effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          return gfx::Size(width, height);
462f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        case VideoFrame::kUPlane:
463f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        case VideoFrame::kVPlane:
464effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          return gfx::Size(width / 2, height / 2);
465f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        default:
466f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          break;
467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
46846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
46946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV16:
470f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      switch (plane) {
471f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        case VideoFrame::kYPlane:
472effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          return gfx::Size(width, height);
473f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        case VideoFrame::kUPlane:
474f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        case VideoFrame::kVPlane:
475effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          return gfx::Size(width / 2, height);
476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        default:
477f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          break;
478f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
47946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
48046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::NV12:
481010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      switch (plane) {
482010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        case VideoFrame::kYPlane:
483010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          return gfx::Size(width, height);
484010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        case VideoFrame::kUVPlane:
485010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          return gfx::Size(width, height / 2);
486010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        default:
487010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          break;
488010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      }
48946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
4900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    case VideoFrame::UNKNOWN:
491424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    case VideoFrame::NATIVE_TEXTURE:
4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(VIDEO_HOLE)
493424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    case VideoFrame::HOLE:
4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif  // defined(VIDEO_HOLE)
495424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      break;
496424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
497f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  NOTREACHED() << "Unsupported video frame format/plane: "
498f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)               << format << "/" << plane;
499effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return gfx::Size();
500effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
501effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
502effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochsize_t VideoFrame::PlaneAllocationSize(Format format,
503effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                       size_t plane,
504effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                       const gfx::Size& coded_size) {
505effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // VideoFrame formats are (so far) all YUV and 1 byte per sample.
506effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return PlaneSize(format, plane, coded_size).GetArea();
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
509010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// static
510010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)int VideoFrame::PlaneHorizontalBitsPerPixel(Format format, size_t plane) {
511010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  switch (format) {
51246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV24:
51346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      switch (plane) {
51446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kYPlane:
51546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kUPlane:
51646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kVPlane:
51746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return 8;
51846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        default:
51946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          break;
52046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      }
52146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
522010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case VideoFrame::YV12:
523010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case VideoFrame::YV16:
524010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case VideoFrame::I420:
52546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV12J:
526010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      switch (plane) {
527010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        case kYPlane:
528010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          return 8;
529010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        case kUPlane:
530010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        case kVPlane:
531010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          return 2;
532010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        default:
533010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          break;
534010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      }
53546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
53646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV12A:
53746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      switch (plane) {
53846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kYPlane:
53946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kAPlane:
54046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return 8;
54146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kUPlane:
54246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kVPlane:
54346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return 2;
54446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        default:
54546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          break;
54646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      }
54746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
54846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::NV12:
549010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      switch (plane) {
550010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        case kYPlane:
551010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          return 8;
552010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        case kUVPlane:
553010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          return 4;
554010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        default:
555010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          break;
556010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      }
55746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
55846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::UNKNOWN:
55946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(VIDEO_HOLE)
56046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::HOLE:
56146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif  // defined(VIDEO_HOLE)
56246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::NATIVE_TEXTURE:
563010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      break;
564010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
56546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  NOTREACHED() << "Unsupported video frame format/plane: "
56646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)               << format << "/" << plane;
567010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return 0;
568010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
569010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
570f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Release data allocated by AllocateYUV().
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static void ReleaseData(uint8* data) {
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(data);
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::AlignedFree(data);
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoFrame::AllocateYUV() {
577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(format_ == VideoFrame::YV12 || format_ == VideoFrame::YV16 ||
578a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)         format_ == VideoFrame::YV12A || format_ == VideoFrame::I420 ||
57946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)         format_ == VideoFrame::YV12J || format_ == VideoFrame::YV24);
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Align Y rows at least at 16 byte boundaries.  The stride for both
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // YV12 and YV16 is 1/2 of the stride of Y.  For YV12, every row of bytes for
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // U and V applies to two rows of Y (one byte of UV for 4 bytes of Y), so in
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the case of YV12 the strides are identical for the same width surface, but
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the number of bytes allocated for YV12 is 1/2 the amount for U & V as
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // YV16. We also round the height of the surface allocated to be an even
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // number to avoid any potential of faulting by code that attempts to access
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the Y values of the final row, but assumes that the last row of U & V
588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // applies to a full two rows of Y. YV12A is the same as YV12, but with an
589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // additional alpha plane that has the same size and alignment as the Y plane.
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t y_stride = RoundUp(row_bytes(VideoFrame::kYPlane),
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            kFrameSizeAlignment);
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t uv_stride = RoundUp(row_bytes(VideoFrame::kUPlane),
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             kFrameSizeAlignment);
59446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The *2 here is because some formats (e.g. h264) allow interlaced coding,
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and then the size needs to be a multiple of two macroblocks (vertically).
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See libavcodec/utils.c:avcodec_align_dimensions2().
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t y_height = RoundUp(coded_size_.height(), kFrameSizeAlignment * 2);
599ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  size_t uv_height =
600ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      (format_ == VideoFrame::YV12 || format_ == VideoFrame::YV12A ||
601ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch       format_ == VideoFrame::I420)
602ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          ? y_height / 2
603ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          : y_height;
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t y_bytes = y_height * y_stride;
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t uv_bytes = uv_height * uv_stride;
606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  size_t a_bytes = format_ == VideoFrame::YV12A ? y_bytes : 0;
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The extra line of UV being allocated is because h264 chroma MC
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // overreads by one line in some cases, see libavcodec/utils.c:
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // avcodec_align_dimensions2() and libavcodec/x86/h264_chromamc.asm:
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // put_h264_chroma_mc4_ssse3().
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint8* data = reinterpret_cast<uint8*>(
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::AlignedAlloc(
614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          y_bytes + (uv_bytes * 2 + uv_stride) + a_bytes + kFrameSizePadding,
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          kFrameAddressAlignment));
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  no_longer_needed_cb_ = base::Bind(&ReleaseData, data);
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(0 == VideoFrame::kYPlane, y_plane_data_must_be_index_0);
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_[VideoFrame::kYPlane] = data;
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_[VideoFrame::kUPlane] = data + y_bytes;
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_[VideoFrame::kVPlane] = data + y_bytes + uv_bytes;
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  strides_[VideoFrame::kYPlane] = y_stride;
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  strides_[VideoFrame::kUPlane] = uv_stride;
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  strides_[VideoFrame::kVPlane] = uv_stride;
624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (format_ == YV12A) {
625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    data_[VideoFrame::kAPlane] = data + y_bytes + (2 * uv_bytes);
626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    strides_[VideoFrame::kAPlane] = y_stride;
627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VideoFrame::VideoFrame(VideoFrame::Format format,
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const gfx::Size& coded_size,
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const gfx::Rect& visible_rect,
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const gfx::Size& natural_size,
6345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                       scoped_ptr<gpu::MailboxHolder> mailbox_holder,
635f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       base::TimeDelta timestamp,
636f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       bool end_of_stream)
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : format_(format),
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      coded_size_(coded_size),
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      visible_rect_(visible_rect),
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      natural_size_(natural_size),
6415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      mailbox_holder_(mailbox_holder.Pass()),
642eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      shared_memory_handle_(base::SharedMemory::NULLHandle()),
643f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      timestamp_(timestamp),
644f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      end_of_stream_(end_of_stream) {
645effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK(IsValidConfig(format_, coded_size_, visible_rect_, natural_size_));
646effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(&strides_, 0, sizeof(strides_));
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(&data_, 0, sizeof(data_));
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VideoFrame::~VideoFrame() {
6525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!mailbox_holder_release_cb_.is_null()) {
6535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    std::vector<uint32> release_sync_points;
6545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    {
6555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      base::AutoLock locker(release_sync_point_lock_);
6565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      release_sync_points_.swap(release_sync_points);
6575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    }
6585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    base::ResetAndReturn(&mailbox_holder_release_cb_).Run(release_sync_points);
6595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!no_longer_needed_cb_.is_null())
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::ResetAndReturn(&no_longer_needed_cb_).Run();
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VideoFrame::IsValidPlane(size_t plane) const {
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (plane < NumPlanes(format_));
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int VideoFrame::stride(size_t plane) const {
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsValidPlane(plane));
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return strides_[plane];
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int VideoFrame::row_bytes(size_t plane) const {
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsValidPlane(plane));
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int width = coded_size_.width();
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (format_) {
67746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV24:
67846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      switch (plane) {
67946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kYPlane:
68046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kUPlane:
68146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kVPlane:
68246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return width;
68346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        default:
68446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          break;
68546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      }
686010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      break;
68746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV12:
68846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV16:
68946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::I420:
69046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV12J:
69146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      switch (plane) {
69246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kYPlane:
69346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return width;
69446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kUPlane:
69546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kVPlane:
69646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return RoundUp(width, 2) / 2;
69746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        default:
69846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          break;
69946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      }
700010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      break;
70146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV12A:
70246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      switch (plane) {
70346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kYPlane:
70446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kAPlane:
70546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return width;
70646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kUPlane:
70746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kVPlane:
70846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return RoundUp(width, 2) / 2;
70946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        default:
71046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          break;
71146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      }
71246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
71346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::NV12:
71446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      switch (plane) {
71546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kYPlane:
71646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kUVPlane:
71746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return width;
71846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        default:
71946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          break;
72046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      }
72146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
72246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::UNKNOWN:
72346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(VIDEO_HOLE)
72446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::HOLE:
72546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif  // defined(VIDEO_HOLE)
72646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::NATIVE_TEXTURE:
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
72946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  NOTREACHED() << "Unsupported video frame format/plane: "
73046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)               << format_ << "/" << plane;
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int VideoFrame::rows(size_t plane) const {
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsValidPlane(plane));
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int height = coded_size_.height();
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (format_) {
73846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV24:
73946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV16:
74046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      switch (plane) {
74146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kYPlane:
74246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kUPlane:
74346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kVPlane:
74446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return height;
74546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        default:
74646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          break;
74746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      }
748010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      break;
74946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV12:
75046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV12J:
75146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::I420:
75246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      switch (plane) {
75346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kYPlane:
75446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return height;
75546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kUPlane:
75646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kVPlane:
75746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return RoundUp(height, 2) / 2;
75846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        default:
75946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          break;
76046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      }
761010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      break;
76246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::YV12A:
76346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      switch (plane) {
76446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kYPlane:
76546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kAPlane:
76646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return height;
76746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kUPlane:
76846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kVPlane:
76946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return RoundUp(height, 2) / 2;
77046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        default:
77146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          break;
77246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      }
77346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
77446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::NV12:
77546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      switch (plane) {
77646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kYPlane:
77746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return height;
77846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        case kUVPlane:
77946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          return RoundUp(height, 2) / 2;
78046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        default:
78146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          break;
78246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      }
78346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
78446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::UNKNOWN:
78546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(VIDEO_HOLE)
78646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::HOLE:
78746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif  // defined(VIDEO_HOLE)
78846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case VideoFrame::NATIVE_TEXTURE:
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
79146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  NOTREACHED() << "Unsupported video frame format/plane: "
79246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)               << format_ << "/" << plane;
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint8* VideoFrame::data(size_t plane) const {
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsValidPlane(plane));
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return data_[plane];
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuconst gpu::MailboxHolder* VideoFrame::mailbox_holder() const {
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(format_, NATIVE_TEXTURE);
8035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return mailbox_holder_.get();
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
806eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbase::SharedMemoryHandle VideoFrame::shared_memory_handle() const {
807eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return shared_memory_handle_;
808eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
809eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
8105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid VideoFrame::AppendReleaseSyncPoint(uint32 sync_point) {
8115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  DCHECK_EQ(format_, NATIVE_TEXTURE);
8125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!sync_point)
8135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return;
8145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  base::AutoLock locker(release_sync_point_lock_);
8155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  release_sync_points_.push_back(sync_point);
8165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
8175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
818010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#if defined(OS_POSIX)
819010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)int VideoFrame::dmabuf_fd(size_t plane) const {
820010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return dmabuf_fds_[plane].get();
821010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
822010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#endif
823010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoFrame::HashFrameForTesting(base::MD5Context* context) {
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int plane = 0; plane < kMaxPlanes; ++plane) {
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!IsValidPlane(plane))
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int row = 0; row < rows(plane); ++row) {
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::MD5Update(context, base::StringPiece(
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          reinterpret_cast<char*>(data(plane) + stride(plane) * row),
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          row_bytes(plane)));
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
837