OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/base/video_frame.h" | 5 #include "media/base/video_frame.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 return !coded_size.IsEmpty() && !visible_rect.IsEmpty() && | 188 return !coded_size.IsEmpty() && !visible_rect.IsEmpty() && |
189 !natural_size.IsEmpty(); | 189 !natural_size.IsEmpty(); |
190 } | 190 } |
191 | 191 |
192 // static | 192 // static |
193 scoped_refptr<VideoFrame> VideoFrame::CreateFrame(VideoPixelFormat format, | 193 scoped_refptr<VideoFrame> VideoFrame::CreateFrame(VideoPixelFormat format, |
194 const gfx::Size& coded_size, | 194 const gfx::Size& coded_size, |
195 const gfx::Rect& visible_rect, | 195 const gfx::Rect& visible_rect, |
196 const gfx::Size& natural_size, | 196 const gfx::Size& natural_size, |
197 base::TimeDelta timestamp) { | 197 base::TimeDelta timestamp) { |
| 198 return CreateFrame(format, coded_size, visible_rect, natural_size, timestamp, |
| 199 false); |
| 200 } |
| 201 |
| 202 scoped_refptr<VideoFrame> VideoFrame::CreateFrame(VideoPixelFormat format, |
| 203 const gfx::Size& coded_size, |
| 204 const gfx::Rect& visible_rect, |
| 205 const gfx::Size& natural_size, |
| 206 base::TimeDelta timestamp, |
| 207 bool zero_initialize_memory) { |
198 if (!IsYuvPlanar(format)) { | 208 if (!IsYuvPlanar(format)) { |
199 NOTIMPLEMENTED(); | 209 NOTIMPLEMENTED(); |
200 return nullptr; | 210 return nullptr; |
201 } | 211 } |
202 | 212 |
203 // Since we're creating a new YUV frame (and allocating memory for it | 213 // Since we're creating a new YUV frame (and allocating memory for it |
204 // ourselves), we can pad the requested |coded_size| if necessary if the | 214 // ourselves), we can pad the requested |coded_size| if necessary if the |
205 // request does not line up on sample boundaries. See discussion at | 215 // request does not line up on sample boundaries. See discussion at |
206 // http://crrev.com/1240833003 | 216 // http://crrev.com/1240833003 |
207 const gfx::Size alignment = CommonAlignment(format); | 217 const gfx::Size alignment = CommonAlignment(format); |
208 const gfx::Size new_coded_size = | 218 const gfx::Size new_coded_size = |
209 gfx::Size(RoundUp(coded_size.width(), alignment.width()), | 219 gfx::Size(RoundUp(coded_size.width(), alignment.width()), |
210 RoundUp(coded_size.height(), alignment.height())); | 220 RoundUp(coded_size.height(), alignment.height())); |
211 DCHECK((new_coded_size.width() % alignment.width() == 0) && | 221 DCHECK((new_coded_size.width() % alignment.width() == 0) && |
212 (new_coded_size.height() % alignment.height() == 0)); | 222 (new_coded_size.height() % alignment.height() == 0)); |
213 | 223 |
214 const StorageType storage = STORAGE_OWNED_MEMORY; | 224 const StorageType storage = STORAGE_OWNED_MEMORY; |
215 if (!IsValidConfig(format, storage, new_coded_size, visible_rect, | 225 if (!IsValidConfig(format, storage, new_coded_size, visible_rect, |
216 natural_size)) { | 226 natural_size)) { |
217 DLOG(ERROR) << __FUNCTION__ << " Invalid config." | 227 DLOG(ERROR) << __FUNCTION__ << " Invalid config." |
218 << ConfigToString(format, storage, coded_size, visible_rect, | 228 << ConfigToString(format, storage, coded_size, visible_rect, |
219 natural_size); | 229 natural_size); |
220 return nullptr; | 230 return nullptr; |
221 } | 231 } |
222 | 232 |
223 scoped_refptr<VideoFrame> frame(new VideoFrame( | 233 scoped_refptr<VideoFrame> frame(new VideoFrame( |
224 format, storage, new_coded_size, visible_rect, natural_size, timestamp)); | 234 format, storage, new_coded_size, visible_rect, natural_size, timestamp)); |
225 frame->AllocateYUV(); | 235 frame->AllocateYUV(zero_initialize_memory); |
226 return frame; | 236 return frame; |
227 } | 237 } |
228 | 238 |
229 // static | 239 // static |
230 scoped_refptr<VideoFrame> VideoFrame::WrapNativeTexture( | 240 scoped_refptr<VideoFrame> VideoFrame::WrapNativeTexture( |
231 VideoPixelFormat format, | 241 VideoPixelFormat format, |
232 const gpu::MailboxHolder& mailbox_holder, | 242 const gpu::MailboxHolder& mailbox_holder, |
233 const ReleaseMailboxCB& mailbox_holder_release_cb, | 243 const ReleaseMailboxCB& mailbox_holder_release_cb, |
234 const gfx::Size& coded_size, | 244 const gfx::Size& coded_size, |
235 const gfx::Rect& visible_rect, | 245 const gfx::Rect& visible_rect, |
(...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
890 base::AutoLock locker(release_sync_point_lock_); | 900 base::AutoLock locker(release_sync_point_lock_); |
891 release_sync_point = release_sync_point_; | 901 release_sync_point = release_sync_point_; |
892 } | 902 } |
893 base::ResetAndReturn(&mailbox_holders_release_cb_).Run(release_sync_point); | 903 base::ResetAndReturn(&mailbox_holders_release_cb_).Run(release_sync_point); |
894 } | 904 } |
895 | 905 |
896 for (auto& callback : done_callbacks_) | 906 for (auto& callback : done_callbacks_) |
897 base::ResetAndReturn(&callback).Run(); | 907 base::ResetAndReturn(&callback).Run(); |
898 } | 908 } |
899 | 909 |
900 void VideoFrame::AllocateYUV() { | 910 void VideoFrame::AllocateYUV(bool zero_initialize_memory) { |
901 DCHECK_EQ(storage_type_, STORAGE_OWNED_MEMORY); | 911 DCHECK_EQ(storage_type_, STORAGE_OWNED_MEMORY); |
902 static_assert(0 == kYPlane, "y plane data must be index 0"); | 912 static_assert(0 == kYPlane, "y plane data must be index 0"); |
903 | 913 |
904 size_t data_size = 0; | 914 size_t data_size = 0; |
905 size_t offset[kMaxPlanes]; | 915 size_t offset[kMaxPlanes]; |
906 for (size_t plane = 0; plane < NumPlanes(format_); ++plane) { | 916 for (size_t plane = 0; plane < NumPlanes(format_); ++plane) { |
907 // The *2 in alignment for height is because some formats (e.g. h264) allow | 917 // The *2 in alignment for height is because some formats (e.g. h264) allow |
908 // interlaced coding, and then the size needs to be a multiple of two | 918 // interlaced coding, and then the size needs to be a multiple of two |
909 // macroblocks (vertically). See | 919 // macroblocks (vertically). See |
910 // libavcodec/utils.c:avcodec_align_dimensions2(). | 920 // libavcodec/utils.c:avcodec_align_dimensions2(). |
911 const size_t height = RoundUp(rows(plane), kFrameSizeAlignment * 2); | 921 const size_t height = RoundUp(rows(plane), kFrameSizeAlignment * 2); |
912 strides_[plane] = RoundUp(row_bytes(plane), kFrameSizeAlignment); | 922 strides_[plane] = RoundUp(row_bytes(plane), kFrameSizeAlignment); |
913 offset[plane] = data_size; | 923 offset[plane] = data_size; |
914 data_size += height * strides_[plane]; | 924 data_size += height * strides_[plane]; |
915 } | 925 } |
916 | 926 |
917 // The extra line of UV being allocated is because h264 chroma MC | 927 // The extra line of UV being allocated is because h264 chroma MC |
918 // overreads by one line in some cases, see libavcodec/utils.c: | 928 // overreads by one line in some cases, see libavcodec/utils.c: |
919 // avcodec_align_dimensions2() and libavcodec/x86/h264_chromamc.asm: | 929 // avcodec_align_dimensions2() and libavcodec/x86/h264_chromamc.asm: |
920 // put_h264_chroma_mc4_ssse3(). | 930 // put_h264_chroma_mc4_ssse3(). |
921 DCHECK(IsValidPlane(kUPlane, format_)); | 931 DCHECK(IsValidPlane(kUPlane, format_)); |
922 data_size += strides_[kUPlane] + kFrameSizePadding; | 932 data_size += strides_[kUPlane] + kFrameSizePadding; |
923 | 933 |
924 uint8* data = reinterpret_cast<uint8*>( | 934 uint8* data = reinterpret_cast<uint8*>( |
925 base::AlignedAlloc(data_size, kFrameAddressAlignment)); | 935 base::AlignedAlloc(data_size, kFrameAddressAlignment)); |
| 936 if (zero_initialize_memory) |
| 937 memset(data, 0, data_size); |
926 | 938 |
927 for (size_t plane = 0; plane < NumPlanes(format_); ++plane) | 939 for (size_t plane = 0; plane < NumPlanes(format_); ++plane) |
928 data_[plane] = data + offset[plane]; | 940 data_[plane] = data + offset[plane]; |
929 | 941 |
930 AddDestructionObserver(base::Bind(&base::AlignedFree, data)); | 942 AddDestructionObserver(base::Bind(&base::AlignedFree, data)); |
931 } | 943 } |
932 | 944 |
933 } // namespace media | 945 } // namespace media |
OLD | NEW |