/src/mozilla-central/dom/media/systemservices/VideoFrameUtils.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | #include "webrtc/video_frame.h" |
9 | | #include "mozilla/ShmemPool.h" |
10 | | |
11 | | namespace mozilla { |
12 | | |
13 | | size_t |
14 | | VideoFrameUtils::TotalRequiredBufferSize( |
15 | | const webrtc::VideoFrame& aVideoFrame) |
16 | 0 | { |
17 | 0 | auto height = aVideoFrame.video_frame_buffer()->height(); |
18 | 0 | return height * aVideoFrame.video_frame_buffer()->StrideY() + |
19 | 0 | ((height+1)/2) * aVideoFrame.video_frame_buffer()->StrideU() + |
20 | 0 | ((height+1)/2) * aVideoFrame.video_frame_buffer()->StrideV(); |
21 | 0 | } |
22 | | |
23 | | void VideoFrameUtils::InitFrameBufferProperties( |
24 | | const webrtc::VideoFrame& aVideoFrame, |
25 | | camera::VideoFrameProperties& aDestProps) |
26 | 0 | { |
27 | 0 | // The VideoFrameBuffer image data stored in the accompanying buffer |
28 | 0 | // the buffer is at least this size of larger. |
29 | 0 | aDestProps.bufferSize() = TotalRequiredBufferSize(aVideoFrame); |
30 | 0 |
|
31 | 0 | aDestProps.timeStamp() = aVideoFrame.timestamp(); |
32 | 0 | aDestProps.ntpTimeMs() = aVideoFrame.ntp_time_ms(); |
33 | 0 | aDestProps.renderTimeMs() = aVideoFrame.render_time_ms(); |
34 | 0 |
|
35 | 0 | aDestProps.rotation() = aVideoFrame.rotation(); |
36 | 0 |
|
37 | 0 | auto height = aVideoFrame.video_frame_buffer()->height(); |
38 | 0 | aDestProps.yAllocatedSize() = height * aVideoFrame.video_frame_buffer()->StrideY(); |
39 | 0 | aDestProps.uAllocatedSize() = ((height+1)/2) * aVideoFrame.video_frame_buffer()->StrideU(); |
40 | 0 | aDestProps.vAllocatedSize() = ((height+1)/2) * aVideoFrame.video_frame_buffer()->StrideV(); |
41 | 0 |
|
42 | 0 | aDestProps.width() = aVideoFrame.video_frame_buffer()->width(); |
43 | 0 | aDestProps.height() = height; |
44 | 0 |
|
45 | 0 | aDestProps.yStride() = aVideoFrame.video_frame_buffer()->StrideY(); |
46 | 0 | aDestProps.uStride() = aVideoFrame.video_frame_buffer()->StrideU(); |
47 | 0 | aDestProps.vStride() = aVideoFrame.video_frame_buffer()->StrideV(); |
48 | 0 | } |
49 | | |
50 | | void VideoFrameUtils::CopyVideoFrameBuffers(uint8_t* aDestBuffer, |
51 | | const size_t aDestBufferSize, |
52 | | const webrtc::VideoFrame& aFrame) |
53 | 0 | { |
54 | 0 | size_t aggregateSize = TotalRequiredBufferSize(aFrame); |
55 | 0 |
|
56 | 0 | MOZ_ASSERT(aDestBufferSize >= aggregateSize); |
57 | 0 |
|
58 | 0 | // If planes are ordered YUV and contiguous then do a single copy |
59 | 0 | if ((aFrame.video_frame_buffer()->DataY() != nullptr) && |
60 | 0 | // Check that the three planes are ordered |
61 | 0 | (aFrame.video_frame_buffer()->DataY() |
62 | 0 | < aFrame.video_frame_buffer()->DataU()) && |
63 | 0 | (aFrame.video_frame_buffer()->DataU() |
64 | 0 | < aFrame.video_frame_buffer()->DataV()) && |
65 | 0 | // Check that the last plane ends at firstPlane[totalsize] |
66 | 0 | (&aFrame.video_frame_buffer()->DataY()[aggregateSize] == |
67 | 0 | &aFrame.video_frame_buffer() |
68 | 0 | ->DataV()[((aFrame.video_frame_buffer()->height() + 1) / 2) |
69 | 0 | * aFrame.video_frame_buffer()->StrideV()])) { |
70 | 0 | memcpy(aDestBuffer, aFrame.video_frame_buffer()->DataY(), aggregateSize); |
71 | 0 | return; |
72 | 0 | } |
73 | 0 | |
74 | 0 | // Copy each plane |
75 | 0 | size_t offset = 0; |
76 | 0 | size_t size; |
77 | 0 | auto height = aFrame.video_frame_buffer()->height(); |
78 | 0 | size = height * aFrame.video_frame_buffer()->StrideY(); |
79 | 0 | memcpy(&aDestBuffer[offset], aFrame.video_frame_buffer()->DataY(), size); |
80 | 0 | offset += size; |
81 | 0 | size = ((height+1)/2) * aFrame.video_frame_buffer()->StrideU(); |
82 | 0 | memcpy(&aDestBuffer[offset], aFrame.video_frame_buffer()->DataU(), size); |
83 | 0 | offset += size; |
84 | 0 | size = ((height+1)/2) * aFrame.video_frame_buffer()->StrideV(); |
85 | 0 | memcpy(&aDestBuffer[offset], aFrame.video_frame_buffer()->DataV(), size); |
86 | 0 | } |
87 | | |
88 | | void VideoFrameUtils::CopyVideoFrameBuffers(ShmemBuffer& aDestShmem, |
89 | | const webrtc::VideoFrame& aVideoFrame) |
90 | 0 | { |
91 | 0 | CopyVideoFrameBuffers(aDestShmem.Get().get<uint8_t>(), aDestShmem.Get().Size<uint8_t>(), aVideoFrame); |
92 | 0 | } |
93 | | |
94 | | } |