VideoFrameUtils.cpp (3522B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set sw=2 ts=8 et ft=cpp : */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "VideoFrameUtils.h" 8 9 #include "api/video/video_frame.h" 10 #include "mozilla/ShmemPool.h" 11 12 namespace mozilla { 13 14 uint32_t VideoFrameUtils::TotalRequiredBufferSize( 15 const webrtc::VideoFrame& aVideoFrame) { 16 auto i420 = aVideoFrame.video_frame_buffer()->ToI420(); 17 auto height = i420->height(); 18 size_t size = height * i420->StrideY() + 19 ((height + 1) / 2) * i420->StrideU() + 20 ((height + 1) / 2) * i420->StrideV(); 21 MOZ_RELEASE_ASSERT(size < std::numeric_limits<uint32_t>::max()); 22 return static_cast<uint32_t>(size); 23 } 24 25 void VideoFrameUtils::InitFrameBufferProperties( 26 const webrtc::VideoFrame& aVideoFrame, 27 camera::VideoFrameProperties& aDestProps) { 28 aDestProps.captureTime() = TimeStamp::Now(); 29 30 // The VideoFrameBuffer image data stored in the accompanying buffer 31 // the buffer is at least this size of larger. 32 aDestProps.bufferSize() = TotalRequiredBufferSize(aVideoFrame); 33 34 aDestProps.rtpTimeStamp() = aVideoFrame.rtp_timestamp(); 35 aDestProps.ntpTimeMs() = aVideoFrame.ntp_time_ms(); 36 aDestProps.renderTimeMs() = aVideoFrame.render_time_ms(); 37 aDestProps.rotation() = aVideoFrame.rotation(); 38 39 auto i420 = aVideoFrame.video_frame_buffer()->ToI420(); 40 auto height = i420->height(); 41 aDestProps.yAllocatedSize() = height * i420->StrideY(); 42 aDestProps.uAllocatedSize() = ((height + 1) / 2) * i420->StrideU(); 43 aDestProps.vAllocatedSize() = ((height + 1) / 2) * i420->StrideV(); 44 45 aDestProps.width() = i420->width(); 46 aDestProps.height() = height; 47 48 aDestProps.yStride() = i420->StrideY(); 49 aDestProps.uStride() = i420->StrideU(); 50 aDestProps.vStride() = i420->StrideV(); 51 } 52 53 void VideoFrameUtils::CopyVideoFrameBuffers(uint8_t* aDestBuffer, 54 const size_t aDestBufferSize, 55 const webrtc::VideoFrame& aFrame) { 56 size_t aggregateSize = TotalRequiredBufferSize(aFrame); 57 58 MOZ_ASSERT(aDestBufferSize >= aggregateSize); 59 auto i420 = aFrame.video_frame_buffer()->ToI420(); 60 61 // If planes are ordered YUV and contiguous then do a single copy 62 if ((i420->DataY() != nullptr) && 63 // Check that the three planes are ordered 64 (i420->DataY() < i420->DataU()) && (i420->DataU() < i420->DataV()) && 65 // Check that the last plane ends at firstPlane[totalsize] 66 (&i420->DataY()[aggregateSize] == 67 &i420->DataV()[((i420->height() + 1) / 2) * i420->StrideV()])) { 68 memcpy(aDestBuffer, i420->DataY(), aggregateSize); 69 return; 70 } 71 72 // Copy each plane 73 size_t offset = 0; 74 size_t size; 75 auto height = i420->height(); 76 size = height * i420->StrideY(); 77 memcpy(&aDestBuffer[offset], i420->DataY(), size); 78 offset += size; 79 size = ((height + 1) / 2) * i420->StrideU(); 80 memcpy(&aDestBuffer[offset], i420->DataU(), size); 81 offset += size; 82 size = ((height + 1) / 2) * i420->StrideV(); 83 memcpy(&aDestBuffer[offset], i420->DataV(), size); 84 } 85 86 void VideoFrameUtils::CopyVideoFrameBuffers( 87 ShmemBuffer& aDestShmem, const webrtc::VideoFrame& aVideoFrame) { 88 CopyVideoFrameBuffers(aDestShmem.Get().get<uint8_t>(), 89 aDestShmem.Get().Size<uint8_t>(), aVideoFrame); 90 } 91 92 } // namespace mozilla