Skip to content

Commit 51968e7

Browse files
committed
Detections work (fix memory leak); fix sod always statically linked.
1 parent d1f85e5 commit 51968e7

File tree

3 files changed

+82
-67
lines changed

3 files changed

+82
-67
lines changed

Diff for: scripts/build.sh

+20-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ BUILD_TYPE="Release"
88
ENABLE_SOD=1
99
ENABLE_TESTS=1
1010

11+
# Default SOD linking mode
12+
SOD_DYNAMIC=0
13+
1114
# Parse command line arguments
1215
while [[ $# -gt 0 ]]; do
1316
key="$1"
@@ -32,6 +35,14 @@ while [[ $# -gt 0 ]]; do
3235
ENABLE_SOD=0
3336
shift
3437
;;
38+
--sod-dynamic)
39+
SOD_DYNAMIC=1
40+
shift
41+
;;
42+
--sod-static)
43+
SOD_DYNAMIC=0
44+
shift
45+
;;
3546
--with-tests)
3647
ENABLE_TESTS=1
3748
shift
@@ -48,6 +59,8 @@ while [[ $# -gt 0 ]]; do
4859
echo " --clean Clean build directory before building"
4960
echo " --with-sod Build with SOD support (default)"
5061
echo " --without-sod Build without SOD support"
62+
echo " --sod-dynamic Use dynamic linking for SOD"
63+
echo " --sod-static Use static linking for SOD (default)"
5164
echo " --with-tests Build test suite (default)"
5265
echo " --without-tests Build without test suite"
5366
echo " --help Show this help message"
@@ -85,8 +98,13 @@ fi
8598
# Configure SOD and Tests options
8699
SOD_OPTION=""
87100
if [ "$ENABLE_SOD" -eq 1 ]; then
88-
SOD_OPTION="-DENABLE_SOD=ON -DSOD_DYNAMIC_LINK=OFF"
89-
echo "Building with SOD support (static linking)"
101+
if [ "$SOD_DYNAMIC" -eq 1 ]; then
102+
SOD_OPTION="-DENABLE_SOD=ON -DSOD_DYNAMIC_LINK=ON"
103+
echo "Building with SOD support (dynamic linking)"
104+
else
105+
SOD_OPTION="-DENABLE_SOD=ON -DSOD_DYNAMIC_LINK=OFF"
106+
echo "Building with SOD support (static linking)"
107+
fi
90108
else
91109
SOD_OPTION="-DENABLE_SOD=OFF"
92110
echo "Building without SOD support"

Diff for: scripts/install.sh

+37-34
Original file line numberDiff line numberDiff line change
@@ -94,36 +94,23 @@ if [ "$(id -u)" -ne 0 ]; then
9494
exit 1
9595
fi
9696

97-
# Find the lightnvr binary and SOD library
97+
# Debug: List all SOD libraries and binaries
98+
echo "DEBUG: Searching for SOD libraries and binaries..."
99+
find build -name "lightnvr" -o -name "libsod.so*" | sort
100+
101+
# Directly set paths based on the known locations
102+
if [ -f "build/src/sod/libsod.so.1.1.9" ]; then
103+
LIB_PATH="build/src/sod"
104+
SOD_LIB_NAME="libsod.so.1.1.9"
105+
elif [ -f "build/src/sod/libsod.so" ]; then
106+
LIB_PATH="build/src/sod"
107+
SOD_LIB_NAME="libsod.so"
108+
fi
109+
98110
if [ -f "build/Release/lightnvr" ]; then
99111
BINARY_PATH="build/Release/lightnvr"
100-
if [ -f "build/Release/src/sod/libsod.so.1.1.9" ]; then
101-
LIB_PATH="build/Release/src/sod"
102-
fi
103-
elif [ -f "build/Debug/lightnvr" ]; then
104-
BINARY_PATH="build/Debug/lightnvr"
105-
if [ -f "build/Debug/src/sod/libsod.so.1.1.9" ]; then
106-
LIB_PATH="build/Debug/src/sod"
107-
fi
108-
# Also check the original expected paths
109-
elif [ -f "build/Release/bin/lightnvr" ]; then
110-
BINARY_PATH="build/Release/bin/lightnvr"
111-
if [ -f "build/Release/lib/libsod.so.1.1.9" ]; then
112-
LIB_PATH="build/Release/lib"
113-
elif [ -f "build/Release/src/sod/libsod.so.1.1.9" ]; then
114-
LIB_PATH="build/Release/src/sod"
115-
fi
116-
elif [ -f "build/Debug/bin/lightnvr" ]; then
117-
BINARY_PATH="build/Debug/bin/lightnvr"
118-
if [ -f "build/Debug/lib/libsod.so.1.1.9" ]; then
119-
LIB_PATH="build/Debug/lib"
120-
elif [ -f "build/Debug/src/sod/libsod.so.1.1.9" ]; then
121-
LIB_PATH="build/Debug/src/sod"
122-
fi
123-
else
124-
echo "Binary not found. Please build the project first:"
125-
echo "./scripts/build.sh --release"
126-
exit 1
112+
elif [ -f "build/lightnvr" ]; then
113+
BINARY_PATH="build/lightnvr"
127114
fi
128115

129116
# Check if we found the SOD library
@@ -133,10 +120,17 @@ if [ "$INSTALL_SOD" -eq 1 ] && [ -z "$LIB_PATH" ]; then
133120
exit 1
134121
fi
135122

123+
# Check if we found the binary
124+
if [ -z "$BINARY_PATH" ]; then
125+
echo "Binary not found. Please build the project first:"
126+
echo "./scripts/build.sh --release"
127+
exit 1
128+
fi
129+
136130
# Print paths for debugging
137131
echo "Using binary: $BINARY_PATH"
138132
if [ "$INSTALL_SOD" -eq 1 ]; then
139-
echo "Using SOD library: $LIB_PATH/libsod.so.1.1.9"
133+
echo "Using SOD library: $LIB_PATH/$SOD_LIB_NAME"
140134
fi
141135

142136
# Create directories
@@ -156,18 +150,27 @@ install -m 755 "$BINARY_PATH" "$PREFIX/bin/lightnvr"
156150
# Install SOD library if enabled
157151
if [ "$INSTALL_SOD" -eq 1 ]; then
158152
echo "Installing SOD library..."
159-
if [ -f "$LIB_PATH/libsod.so.1.1.9" ]; then
160-
install -m 755 "$LIB_PATH/libsod.so.1.1.9" "$PREFIX/lib/libsod.so.1.1.9"
161-
ln -sf "$PREFIX/lib/libsod.so.1.1.9" "$PREFIX/lib/libsod.so.1"
162-
ln -sf "$PREFIX/lib/libsod.so.1" "$PREFIX/lib/libsod.so"
153+
if [ -f "$LIB_PATH/$SOD_LIB_NAME" ]; then
154+
# Install the library
155+
install -m 755 "$LIB_PATH/$SOD_LIB_NAME" "$PREFIX/lib/$SOD_LIB_NAME"
156+
157+
# Create symlinks if needed
158+
if [ "$SOD_LIB_NAME" = "libsod.so.1.1.9" ]; then
159+
ln -sf "$PREFIX/lib/libsod.so.1.1.9" "$PREFIX/lib/libsod.so.1"
160+
ln -sf "$PREFIX/lib/libsod.so.1" "$PREFIX/lib/libsod.so"
161+
elif [ "$SOD_LIB_NAME" = "libsod.so" ]; then
162+
# If we only have libsod.so, create the versioned symlinks
163+
ln -sf "$PREFIX/lib/libsod.so" "$PREFIX/lib/libsod.so.1"
164+
ln -sf "$PREFIX/lib/libsod.so.1" "$PREFIX/lib/libsod.so.1.1.9"
165+
fi
163166

164167
# Run ldconfig to update the shared library cache
165168
# we can skip with --without-ldconfig
166169
if [ "$DO_LDCONFIG" -eq 1 ]; then
167170
ldconfig
168171
fi
169172

170-
echo "SOD library installed to $PREFIX/lib/libsod.so.1.1.9"
173+
echo "SOD library installed to $PREFIX/lib/$SOD_LIB_NAME"
171174
else
172175
echo "SOD library not found. Did you build with SOD support?"
173176
echo "Try running: ./scripts/build.sh --release --with-sod"

Diff for: src/video/sod_detection.c

+25-31
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ typedef struct {
2626
void *handle;
2727
int (*sod_cnn_create)(void **ppOut, const char *zArch, const char *zModelPath, const char **pzErr);
2828
int (*sod_cnn_config)(void *pNet, int conf, ...);
29-
int (*sod_cnn_predict)(void *pNet, float *pInput, void ***paBox, int *pnBox);
29+
int (*sod_cnn_predict)(void *pNet, float *pInput, sod_box **paBox, int *pnBox);
3030
void (*sod_cnn_destroy)(void *pNet);
3131
float * (*sod_cnn_prepare_image)(void *pNet, void *in);
3232
int (*sod_cnn_get_network_size)(void *pNet, int *pWidth, int *pHeight, int *pChannels);
@@ -226,7 +226,7 @@ detection_model_t load_sod_model(const char *model_path, float threshold) {
226226
}
227227

228228
// Use dynamic loading
229-
sod_funcs.sod_cnn_config(sod_model, SOD_CNN_DETECTION_THRESHOLD, threshold);
229+
sod_funcs.sod_cnn_config((sod_cnn*)sod_model, SOD_CNN_DETECTION_THRESHOLD, threshold);
230230
#else
231231
// Use static linking
232232
sod_cnn *cnn_model = NULL;
@@ -304,33 +304,29 @@ int detect_with_sod_model(detection_model_t model, const unsigned char *frame_da
304304
log_info("Step 1: Creating SOD image from frame data (dimensions: %dx%d, channels: %d)",
305305
width, height, channels);
306306

307-
void *img_ptr = sod_funcs.sod_make_image(width, height, channels);
308-
if (!img_ptr) {
307+
// In dynamic linking, sod_make_image returns a sod_img, not a pointer to sod_img
308+
sod_img img;
309+
memset(&img, 0, sizeof(sod_img));
310+
311+
// Call sod_make_image and store the result directly
312+
img = *(sod_img*)sod_funcs.sod_make_image(width, height, channels);
313+
314+
if (!img.data) {
309315
log_error("Failed to create SOD image");
310316
return -1;
311317
}
312318

313319
// Step 2: Copy the frame data to the SOD image
314320
log_info("Step 2: Copying frame data to SOD image");
315321

316-
// Cast the void* to sod_img*
317-
sod_img *sod_img_ptr = (sod_img *)img_ptr;
318-
319-
// Check if the data field is valid
320-
if (!sod_img_ptr->data) {
321-
log_error("SOD image data field is NULL");
322-
sod_funcs.sod_free_image(img_ptr);
323-
return -1;
324-
}
325-
326322
// Calculate the total size of the image data
327323
size_t total_size = width * height * channels;
328324

329325
// Allocate a temporary buffer to store the converted data
330326
float *temp_buffer = (float *)malloc(total_size * sizeof(float));
331327
if (!temp_buffer) {
332328
log_error("Failed to allocate temporary buffer for image data conversion");
333-
sod_funcs.sod_free_image(img_ptr);
329+
sod_funcs.sod_free_image(&img);
334330
return -1;
335331
}
336332

@@ -354,7 +350,7 @@ int detect_with_sod_model(detection_model_t model, const unsigned char *frame_da
354350
}
355351

356352
// Copy the converted data to the SOD image
357-
memcpy(sod_img_ptr->data, temp_buffer, total_size * sizeof(float));
353+
memcpy(img.data, temp_buffer, total_size * sizeof(float));
358354

359355
// Free the temporary buffer
360356
free(temp_buffer);
@@ -363,10 +359,10 @@ int detect_with_sod_model(detection_model_t model, const unsigned char *frame_da
363359

364360
// Step 3: Prepare the image for CNN detection
365361
log_info("Step 4: Preparing image for CNN detection with model=%p", (void*)m->sod.model);
366-
float *prepared_data = sod_funcs.sod_cnn_prepare_image(m->sod.model, img_ptr);
362+
float *prepared_data = sod_funcs.sod_cnn_prepare_image((sod_cnn*)m->sod.model, &img);
367363
if (!prepared_data) {
368364
log_error("Failed to prepare image for CNN detection");
369-
sod_funcs.sod_free_image(img_ptr);
365+
sod_funcs.sod_free_image(&img);
370366
return -1;
371367
}
372368

@@ -375,22 +371,22 @@ int detect_with_sod_model(detection_model_t model, const unsigned char *frame_da
375371
// Step 4: Run detection
376372
log_info("Step 6: Running CNN detection");
377373
int count = 0;
378-
void **boxes_ptr = NULL;
379374

380375
// Add extra safety check
381376
if (!m->sod.model) {
382377
log_error("Model pointer is NULL before prediction");
383-
sod_funcs.sod_free_image(img_ptr);
378+
sod_funcs.sod_free_image(&img);
384379
return -1;
385380
}
386381

387382
// Step 5: Call predict
388-
int rc = sod_funcs.sod_cnn_predict(m->sod.model, prepared_data, &boxes_ptr, &count);
383+
sod_box *boxes = NULL;
384+
int rc = sod_funcs.sod_cnn_predict((sod_cnn*)m->sod.model, prepared_data, &boxes, &count);
389385
log_info("Step 7: sod_cnn_predict returned with rc=%d, count=%d", rc, count);
390386

391387
if (rc != 0) { // SOD_OK is 0
392388
log_error("CNN detection failed with error code: %d", rc);
393-
sod_funcs.sod_free_image(img_ptr);
389+
sod_funcs.sod_free_image(&img);
394390
return -1;
395391
}
396392

@@ -403,21 +399,19 @@ int detect_with_sod_model(detection_model_t model, const unsigned char *frame_da
403399
// Process detection results
404400
int valid_count = 0;
405401

406-
// Skip processing boxes if count is 0 or boxes_ptr is NULL
407-
if (count <= 0 || !boxes_ptr) {
408-
log_warn("No detection boxes returned (count=%d, boxes_ptr=%p)", count, (void*)boxes_ptr);
409-
sod_funcs.sod_free_image(img_ptr);
402+
// Skip processing boxes if count is 0 or boxes is NULL
403+
if (count <= 0 || !boxes) {
404+
log_warn("No detection boxes returned (count=%d, boxes=%p)", count, (void*)boxes);
405+
sod_funcs.sod_free_image(&img);
410406
return 0;
411407
}
412408

413409
log_info("Processing %d detection boxes", count);
414410

415-
// In SOD, boxes_ptr is an array of pointers to sod_box structures
416-
sod_box_dynamic **boxes_array = (sod_box_dynamic**)boxes_ptr;
417-
411+
// For dynamic linking, boxes is already an array of sod_box structures
418412
for (int i = 0; i < count && valid_count < MAX_DETECTIONS; i++) {
419413
// Get the current box
420-
sod_box_dynamic *box = boxes_array[i];
414+
sod_box *box = &boxes[i];
421415

422416
if (!box) {
423417
log_warn("Box %d is NULL, skipping", i);
@@ -475,7 +469,7 @@ int detect_with_sod_model(detection_model_t model, const unsigned char *frame_da
475469

476470
// Step 7: Free the image data
477471
log_info("Step 9: Freeing SOD image");
478-
sod_funcs.sod_free_image(img_ptr);
472+
sod_funcs.sod_free_image(&img);
479473
#else
480474
// When SOD is statically linked, use direct function calls
481475
log_info("Using statically linked SOD functions");

0 commit comments

Comments
 (0)