summaryrefslogtreecommitdiffstats
path: root/media/base/video_util.cc
blob: 4bef0adc88b1e92a17ff0e3e9fe3543ac646fce9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/base/video_util.h"

#include <cmath>

#include "base/logging.h"
#include "media/base/video_frame.h"

namespace media {

gfx::Size GetNaturalSize(const gfx::Size& visible_size,
                         int aspect_ratio_numerator,
                         int aspect_ratio_denominator) {
  if (aspect_ratio_denominator == 0 ||
      aspect_ratio_numerator < 0 ||
      aspect_ratio_denominator < 0)
    return gfx::Size();

  double aspect_ratio = aspect_ratio_numerator /
      static_cast<double>(aspect_ratio_denominator);

  int width = floor(visible_size.width() * aspect_ratio + 0.5);
  int height = visible_size.height();

  // An even width makes things easier for YV12 and appears to be the behavior
  // expected by WebKit layout tests.
  return gfx::Size(width & ~1, height);
}

static void CopyPlane(size_t plane, const uint8* source, int stride, int rows,
                      VideoFrame* frame) {
  uint8* dest = frame->data(plane);
  int dest_stride = frame->stride(plane);

  // Clamp in case source frame has smaller stride.
  int bytes_to_copy_per_row = std::min(frame->row_bytes(plane), stride);

  // Clamp in case source frame has smaller height.
  int rows_to_copy = std::min(frame->rows(plane), rows);

  // Copy!
  for (int row = 0; row < rows_to_copy; ++row) {
    memcpy(dest, source, bytes_to_copy_per_row);
    source += stride;
    dest += dest_stride;
  }
}

void CopyYPlane(const uint8* source, int stride, int rows, VideoFrame* frame) {
  CopyPlane(VideoFrame::kYPlane, source, stride, rows, frame);
}

void CopyUPlane(const uint8* source, int stride, int rows, VideoFrame* frame) {
  CopyPlane(VideoFrame::kUPlane, source, stride, rows, frame);
}

void CopyVPlane(const uint8* source, int stride, int rows, VideoFrame* frame) {
  CopyPlane(VideoFrame::kVPlane, source, stride, rows, frame);
}

void FillYUV(VideoFrame* frame, uint8 y, uint8 u, uint8 v) {
  // Fill the Y plane.
  uint8* y_plane = frame->data(VideoFrame::kYPlane);
  int y_rows = frame->rows(VideoFrame::kYPlane);
  int y_row_bytes = frame->row_bytes(VideoFrame::kYPlane);
  for (int i = 0; i < y_rows; ++i) {
    memset(y_plane, y, y_row_bytes);
    y_plane += frame->stride(VideoFrame::kYPlane);
  }

  // Fill the U and V planes.
  uint8* u_plane = frame->data(VideoFrame::kUPlane);
  uint8* v_plane = frame->data(VideoFrame::kVPlane);
  int uv_rows = frame->rows(VideoFrame::kUPlane);
  int u_row_bytes = frame->row_bytes(VideoFrame::kUPlane);
  int v_row_bytes = frame->row_bytes(VideoFrame::kVPlane);
  for (int i = 0; i < uv_rows; ++i) {
    memset(u_plane, u, u_row_bytes);
    memset(v_plane, v, v_row_bytes);
    u_plane += frame->stride(VideoFrame::kUPlane);
    v_plane += frame->stride(VideoFrame::kVPlane);
  }
}

}  // namespace media