Skip to content

Commit cd74a9c

Browse files
committed
Merge pull request #111206 from j20001970/camera-feed-datatype-changed
Emit `format_changed` on CameraFeed datatype change
2 parents cd13a9d + 2e00156 commit cd74a9c

File tree

1 file changed

+32
-12
lines changed

1 file changed

+32
-12
lines changed

servers/camera/camera_feed.cpp

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -188,17 +188,21 @@ void CameraFeed::set_rgb_image(const Ref<Image> &p_rgb_img) {
188188
int new_width = p_rgb_img->get_width();
189189
int new_height = p_rgb_img->get_height();
190190

191+
// Emit `format_changed` signal if feed datatype or frame size is changed.
192+
// The signal is deferred to ensure:
193+
// - They are emitted on Godot's main thread.
194+
// - Both datatype and frame size are updated before the emission.
195+
if (datatype != CameraFeed::FEED_RGB || (base_width != new_width) || (base_height != new_height)) {
196+
call_deferred("emit_signal", format_changed_signal_name);
197+
}
198+
191199
if ((base_width != new_width) || (base_height != new_height)) {
192200
// We're assuming here that our camera image doesn't change around formats etc, allocate the whole lot...
193201
base_width = new_width;
194202
base_height = new_height;
195203

196204
RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_rgb_img);
197205
RenderingServer::get_singleton()->texture_replace(texture[CameraServer::FEED_RGBA_IMAGE], new_texture);
198-
199-
// Defer `format_changed` signals to ensure they are emitted on Godot's main thread.
200-
// This also makes sure the datatype of the feed is updated before the emission.
201-
call_deferred("emit_signal", format_changed_signal_name);
202206
} else {
203207
RenderingServer::get_singleton()->texture_2d_update(texture[CameraServer::FEED_RGBA_IMAGE], p_rgb_img);
204208
}
@@ -216,17 +220,21 @@ void CameraFeed::set_ycbcr_image(const Ref<Image> &p_ycbcr_img) {
216220
int new_width = p_ycbcr_img->get_width();
217221
int new_height = p_ycbcr_img->get_height();
218222

223+
// Emit `format_changed` signal if feed datatype or frame size is changed.
224+
// The signal is deferred to ensure:
225+
// - They are emitted on Godot's main thread.
226+
// - Both datatype and frame size are updated before the emission.
227+
if (datatype != CameraFeed::FEED_YCBCR || (base_width != new_width) || (base_height != new_height)) {
228+
call_deferred("emit_signal", format_changed_signal_name);
229+
}
230+
219231
if ((base_width != new_width) || (base_height != new_height)) {
220232
// We're assuming here that our camera image doesn't change around formats etc, allocate the whole lot...
221233
base_width = new_width;
222234
base_height = new_height;
223235

224236
RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_ycbcr_img);
225237
RenderingServer::get_singleton()->texture_replace(texture[CameraServer::FEED_RGBA_IMAGE], new_texture);
226-
227-
// Defer `format_changed` signals to ensure they are emitted on Godot's main thread.
228-
// This also makes sure the datatype of the feed is updated before the emission.
229-
call_deferred("emit_signal", format_changed_signal_name);
230238
} else {
231239
RenderingServer::get_singleton()->texture_2d_update(texture[CameraServer::FEED_RGBA_IMAGE], p_ycbcr_img);
232240
}
@@ -249,6 +257,14 @@ void CameraFeed::set_ycbcr_images(const Ref<Image> &p_y_img, const Ref<Image> &p
249257
int new_y_width = p_y_img->get_width();
250258
int new_y_height = p_y_img->get_height();
251259

260+
// Emit `format_changed` signal if feed datatype or frame size is changed.
261+
// The signal is deferred to ensure:
262+
// - They are emitted on Godot's main thread.
263+
// - Both datatype and frame size are updated before the emission.
264+
if (datatype != CameraFeed::FEED_YCBCR_SEP || (base_width != new_y_width) || (base_height != new_y_height)) {
265+
call_deferred("emit_signal", format_changed_signal_name);
266+
}
267+
252268
if ((base_width != new_y_width) || (base_height != new_y_height)) {
253269
// We're assuming here that our camera image doesn't change around formats etc, allocate the whole lot...
254270
base_width = new_y_width;
@@ -261,10 +277,6 @@ void CameraFeed::set_ycbcr_images(const Ref<Image> &p_y_img, const Ref<Image> &p
261277
RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_cbcr_img);
262278
RenderingServer::get_singleton()->texture_replace(texture[CameraServer::FEED_CBCR_IMAGE], new_texture);
263279
}
264-
265-
// Defer `format_changed` signals to ensure they are emitted on Godot's main thread.
266-
// This also makes sure the datatype of the feed is updated before the emission.
267-
call_deferred("emit_signal", format_changed_signal_name);
268280
} else {
269281
RenderingServer::get_singleton()->texture_2d_update(texture[CameraServer::FEED_Y_IMAGE], p_y_img);
270282
RenderingServer::get_singleton()->texture_2d_update(texture[CameraServer::FEED_CBCR_IMAGE], p_cbcr_img);
@@ -278,6 +290,14 @@ void CameraFeed::set_ycbcr_images(const Ref<Image> &p_y_img, const Ref<Image> &p
278290
}
279291

280292
void CameraFeed::set_external(int p_width, int p_height) {
293+
// Emit `format_changed` signal if feed datatype or frame size is changed.
294+
// The signal is deferred to ensure:
295+
// - They are emitted on Godot's main thread.
296+
// - Both datatype and frame size are updated before the emission.
297+
if (datatype != CameraFeed::FEED_EXTERNAL || (base_width != p_width) || (base_height != p_height)) {
298+
call_deferred("emit_signal", format_changed_signal_name);
299+
}
300+
281301
if ((base_width != p_width) || (base_height != p_height)) {
282302
// We're assuming here that our camera image doesn't change around formats etc, allocate the whole lot...
283303
base_width = p_width;

0 commit comments

Comments
 (0)