| 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 |