OpenShot Library | libopenshot 1.1.1
Loading...
Searching...
No Matches
WaylandBufferUtilities.h
Go to the documentation of this file.
1
6// Copyright (c) 2008-2026 OpenShot Studios, LLC
7//
8// SPDX-License-Identifier: LGPL-3.0-or-later
9
10#ifndef OPENSHOT_WAYLAND_BUFFER_UTILITIES_H
11#define OPENSHOT_WAYLAND_BUFFER_UTILITIES_H
12
13#include <algorithm>
14#include <cstddef>
15#include <cstdint>
16#include <cstring>
17#include <limits>
18
20{
22 {
23 size_t offset = 0;
24 size_t valid_size = 0;
25 int stride = 0;
26 int crop_x = 0;
27 int crop_y = 0;
28 int width = 0;
29 int height = 0;
30 bool valid = false;
31 };
32
34 size_t max_size,
35 size_t chunk_offset,
36 size_t chunk_size,
37 int chunk_stride,
38 int stream_width,
39 int stream_height,
40 int crop_x,
41 int crop_y,
42 int crop_width,
43 int crop_height)
44 {
45 PackedVideoLayout layout;
46 if (max_size == 0 || stream_width <= 0 || stream_height <= 0
47 || stream_width > std::numeric_limits<int>::max() / 4
48 || chunk_stride < 0) {
49 return layout;
50 }
51
52 layout.offset = chunk_offset % max_size;
53 layout.valid_size = std::min(chunk_size, max_size);
54 layout.stride = chunk_stride > 0 ? chunk_stride : stream_width * 4;
55 if (layout.stride < 4 || layout.valid_size < static_cast<size_t>(layout.stride)) {
56 return layout;
57 }
58
59 const int readable_width = std::min(
60 stream_width,
61 layout.stride / 4);
62 const int readable_height = std::min(
63 stream_height,
64 static_cast<int>(layout.valid_size / static_cast<size_t>(layout.stride)));
65
66 layout.crop_x = std::max(0, crop_x);
67 layout.crop_y = std::max(0, crop_y);
68 if (layout.crop_x >= readable_width || layout.crop_y >= readable_height) {
69 return layout;
70 }
71
72 const int requested_width = crop_width > 0
73 ? crop_width
74 : stream_width - layout.crop_x;
75 const int requested_height = crop_height > 0
76 ? crop_height
77 : stream_height - layout.crop_y;
78 layout.width = std::min(requested_width, readable_width - layout.crop_x);
79 layout.height = std::min(requested_height, readable_height - layout.crop_y);
80
81 // H.264 requires even dimensions, and capture callers already expect them.
82 layout.width -= layout.width % 2;
83 layout.height -= layout.height % 2;
84 if (layout.width <= 0 || layout.height <= 0) {
85 return layout;
86 }
87
88 const size_t final_row_end =
89 static_cast<size_t>(layout.crop_y + layout.height - 1) * layout.stride
90 + static_cast<size_t>(layout.crop_x + layout.width) * 4;
91 if (final_row_end > layout.valid_size) {
92 return layout;
93 }
94
95 layout.valid = true;
96 return layout;
97 }
98
99 inline int DamageFrameWaitMilliseconds(int fps_num, int fps_den, bool have_last_frame)
100 {
101 if (!have_last_frame) {
102 return 5000;
103 }
104 const double fps = fps_num > 0 && fps_den > 0
105 ? static_cast<double>(fps_num) / fps_den
106 : 30.0;
107 return std::max(1, static_cast<int>(1000.0 / std::max(1.0, fps)));
108 }
109
110 inline bool CopyWrappedBytes(
111 const uint8_t* source,
112 size_t max_size,
113 size_t chunk_offset,
114 size_t logical_offset,
115 uint8_t* destination,
116 size_t byte_count)
117 {
118 if (!source || !destination || max_size == 0 || byte_count > max_size) {
119 return false;
120 }
121 const size_t physical_offset = (
122 (chunk_offset % max_size) + (logical_offset % max_size)
123 ) % max_size;
124 const size_t first_size = std::min(byte_count, max_size - physical_offset);
125 std::memcpy(destination, source + physical_offset, first_size);
126 if (first_size < byte_count) {
127 std::memcpy(destination + first_size, source, byte_count - first_size);
128 }
129 return true;
130 }
131}
132
133#endif
bool CopyWrappedBytes(const uint8_t *source, size_t max_size, size_t chunk_offset, size_t logical_offset, uint8_t *destination, size_t byte_count)
PackedVideoLayout ResolvePackedVideoLayout(size_t max_size, size_t chunk_offset, size_t chunk_size, int chunk_stride, int stream_width, int stream_height, int crop_x, int crop_y, int crop_width, int crop_height)
int DamageFrameWaitMilliseconds(int fps_num, int fps_den, bool have_last_frame)