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.ValueOrDefault(0) > data_size || | |
dcheng
2017/06/08 09:41:08
Nit: use ValueOrDie() here (since we just checked
sandersd (OOO until July 31)
2017/06/08 20:10:09
Done.
| |
118 u_bound.ValueOrDefault(0) > data_size || | |
119 v_bound.ValueOrDefault(0) > data_size) { | |
120 DLOG(ERROR) << __func__ << " Invalid offset"; | |
121 return nullptr; | |
122 } | |
123 | |
75 // Now allocate the frame and initialize it. | 124 // Now allocate the frame and initialize it. |
76 scoped_refptr<MojoSharedBufferVideoFrame> frame( | 125 scoped_refptr<MojoSharedBufferVideoFrame> frame( |
77 new MojoSharedBufferVideoFrame(format, coded_size, visible_rect, | 126 new MojoSharedBufferVideoFrame(format, coded_size, visible_rect, |
78 natural_size, std::move(handle), data_size, | 127 natural_size, std::move(handle), data_size, |
79 timestamp)); | 128 timestamp)); |
80 if (!frame->Init(y_stride, u_stride, v_stride, y_offset, u_offset, v_offset)) | 129 if (!frame->Init(y_stride, u_stride, v_stride, y_offset, u_offset, v_offset)) |
81 return nullptr; | 130 return nullptr; |
82 | 131 |
83 return frame; | 132 return frame; |
84 } | 133 } |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
145 | 194 |
146 const mojo::SharedBufferHandle& MojoSharedBufferVideoFrame::Handle() const { | 195 const mojo::SharedBufferHandle& MojoSharedBufferVideoFrame::Handle() const { |
147 return shared_buffer_handle_.get(); | 196 return shared_buffer_handle_.get(); |
148 } | 197 } |
149 | 198 |
150 size_t MojoSharedBufferVideoFrame::MappedSize() const { | 199 size_t MojoSharedBufferVideoFrame::MappedSize() const { |
151 return shared_buffer_size_; | 200 return shared_buffer_size_; |
152 } | 201 } |
153 | 202 |
154 } // namespace media | 203 } // namespace media |
OLD | NEW |