OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/mojo/common/mojo_shared_buffer_video_frame.h" | 5 #include "media/mojo/common/mojo_shared_buffer_video_frame.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback.h" | 8 #include "base/callback.h" |
9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/numerics/safe_conversions.h" |
| 12 #include "base/numerics/safe_math.h" |
11 | 13 |
12 namespace media { | 14 namespace media { |
13 | 15 |
14 // static | 16 // static |
15 scoped_refptr<MojoSharedBufferVideoFrame> | 17 scoped_refptr<MojoSharedBufferVideoFrame> |
16 MojoSharedBufferVideoFrame::CreateDefaultI420(const gfx::Size& dimensions, | 18 MojoSharedBufferVideoFrame::CreateDefaultI420(const gfx::Size& dimensions, |
17 base::TimeDelta timestamp) { | 19 base::TimeDelta timestamp) { |
18 const VideoPixelFormat format = PIXEL_FORMAT_I420; | 20 const VideoPixelFormat format = PIXEL_FORMAT_I420; |
19 const gfx::Rect visible_rect(dimensions); | 21 const gfx::Rect visible_rect(dimensions); |
20 | 22 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 int32_t v_stride, | 67 int32_t v_stride, |
66 base::TimeDelta timestamp) { | 68 base::TimeDelta timestamp) { |
67 if (!IsValidConfig(format, STORAGE_MOJO_SHARED_BUFFER, coded_size, | 69 if (!IsValidConfig(format, STORAGE_MOJO_SHARED_BUFFER, coded_size, |
68 visible_rect, natural_size)) { | 70 visible_rect, natural_size)) { |
69 LOG(DFATAL) << __func__ << " Invalid config. " | 71 LOG(DFATAL) << __func__ << " Invalid config. " |
70 << ConfigToString(format, STORAGE_MOJO_SHARED_BUFFER, | 72 << ConfigToString(format, STORAGE_MOJO_SHARED_BUFFER, |
71 coded_size, visible_rect, natural_size); | 73 coded_size, visible_rect, natural_size); |
72 return nullptr; | 74 return nullptr; |
73 } | 75 } |
74 | 76 |
| 77 // Validate that the offsets and strides fit in the buffer. |
| 78 // |
| 79 // We can rely on coded_size.GetArea() being relatively small (compared to the |
| 80 // range of an int) due to the IsValidConfig() check above. |
| 81 // |
| 82 // TODO(sandersd): Allow non-sequential formats. |
| 83 if (NumPlanes(format) != 3) { |
| 84 DLOG(ERROR) << __func__ << " " << VideoPixelFormatToString(format) |
| 85 << " is not supported; only YUV formats are allowed"; |
| 86 return nullptr; |
| 87 } |
| 88 |
| 89 if (y_stride < 0 || u_stride < 0 || v_stride < 0) { |
| 90 DLOG(ERROR) << __func__ << " Invalid stride"; |
| 91 return nullptr; |
| 92 } |
| 93 |
| 94 // Safe given sizeof(size_t) >= sizeof(int32_t). |
| 95 size_t y_stride_size_t = y_stride; |
| 96 size_t u_stride_size_t = u_stride; |
| 97 size_t v_stride_size_t = v_stride; |
| 98 if (y_stride_size_t < RowBytes(kYPlane, format, coded_size.width()) || |
| 99 u_stride_size_t < RowBytes(kUPlane, format, coded_size.width()) || |
| 100 v_stride_size_t < RowBytes(kVPlane, format, coded_size.width())) { |
| 101 DLOG(ERROR) << __func__ << " Invalid stride"; |
| 102 return nullptr; |
| 103 } |
| 104 |
| 105 base::CheckedNumeric<size_t> y_rows = |
| 106 Rows(kYPlane, format, coded_size.height()); |
| 107 base::CheckedNumeric<size_t> u_rows = |
| 108 Rows(kUPlane, format, coded_size.height()); |
| 109 base::CheckedNumeric<size_t> v_rows = |
| 110 Rows(kVPlane, format, coded_size.height()); |
| 111 |
| 112 base::CheckedNumeric<size_t> y_bound = y_rows * y_stride + y_offset; |
| 113 base::CheckedNumeric<size_t> u_bound = u_rows * u_stride + u_offset; |
| 114 base::CheckedNumeric<size_t> v_bound = v_rows * v_stride + v_offset; |
| 115 |
| 116 if (!y_bound.IsValid() || !u_bound.IsValid() || !v_bound.IsValid() || |
| 117 y_bound.ValueOrDie() > data_size || u_bound.ValueOrDie() > data_size || |
| 118 v_bound.ValueOrDie() > data_size) { |
| 119 DLOG(ERROR) << __func__ << " Invalid offset"; |
| 120 return nullptr; |
| 121 } |
| 122 |
75 // Now allocate the frame and initialize it. | 123 // Now allocate the frame and initialize it. |
76 scoped_refptr<MojoSharedBufferVideoFrame> frame( | 124 scoped_refptr<MojoSharedBufferVideoFrame> frame( |
77 new MojoSharedBufferVideoFrame(format, coded_size, visible_rect, | 125 new MojoSharedBufferVideoFrame(format, coded_size, visible_rect, |
78 natural_size, std::move(handle), data_size, | 126 natural_size, std::move(handle), data_size, |
79 timestamp)); | 127 timestamp)); |
80 if (!frame->Init(y_stride, u_stride, v_stride, y_offset, u_offset, v_offset)) | 128 if (!frame->Init(y_stride, u_stride, v_stride, y_offset, u_offset, v_offset)) |
81 return nullptr; | 129 return nullptr; |
82 | 130 |
83 return frame; | 131 return frame; |
84 } | 132 } |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 | 193 |
146 const mojo::SharedBufferHandle& MojoSharedBufferVideoFrame::Handle() const { | 194 const mojo::SharedBufferHandle& MojoSharedBufferVideoFrame::Handle() const { |
147 return shared_buffer_handle_.get(); | 195 return shared_buffer_handle_.get(); |
148 } | 196 } |
149 | 197 |
150 size_t MojoSharedBufferVideoFrame::MappedSize() const { | 198 size_t MojoSharedBufferVideoFrame::MappedSize() const { |
151 return shared_buffer_size_; | 199 return shared_buffer_size_; |
152 } | 200 } |
153 | 201 |
154 } // namespace media | 202 } // namespace media |
OLD | NEW |