Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/video/mp4_writer_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ bool is_audio_codec_compatible_with_mp4(enum AVCodecID codec_id, const char **co
* @param transcoded_params Output parameter to store the transcoded codec parameters
* @return 0 on success, negative on error
*/
int transcode_mulaw_to_aac(const AVCodecParameters *codec_params,
int transcode_pcm_to_aac(const AVCodecParameters *codec_params,
const AVRational *time_base,
const char *stream_name,
AVCodecParameters **transcoded_params);
Expand Down
11 changes: 6 additions & 5 deletions src/video/go2rtc/go2rtc_process.c
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ bool go2rtc_process_init(const char *binary_path, const char *config_dir, int ap
if (!g_config_path) {
log_error("Memory allocation failed for config path");
free(g_config_dir);
g_config_dir = NULL;
return false;
}

Expand Down Expand Up @@ -473,7 +474,7 @@ bool go2rtc_process_generate_config(const char *config_path, int api_port) {
}
FILE *config_file = fdopen(config_fd, "w");
if (!config_file) {
log_error("Failed to open go2rtc config file for writing: %s", config_path);
log_error("Failed to create file stream for go2rtc config file: %s", config_path);
close(config_fd);
return false;
}
Expand Down Expand Up @@ -1137,10 +1138,10 @@ bool go2rtc_process_start(int api_port) {
}

// Redirect stdout and stderr to log files
char log_path[1024]; // Use a reasonable fixed size instead of PATH_MAX
char log_path[PATH_MAX]; // Use PATH_MAX to accommodate full filesystem paths

// Extract directory from g_config->log_file
char log_dir[1024] = {0};
char log_dir[PATH_MAX] = {0};
if (g_config.log_file[0] != '\0') {
strncpy(log_dir, g_config.log_file, sizeof(log_dir) - 1);

Expand All @@ -1161,11 +1162,11 @@ bool go2rtc_process_start(int api_port) {
}

// Log the path we're using for the log file
log_info("Using go2rtc log file: %s", log_path);
fprintf(stderr, "Using go2rtc log file: %s\n", log_path);

int log_fd = open(log_path, O_WRONLY | O_CREAT | O_APPEND, 0644);
if (log_fd == -1) {
log_error("Failed to open log file: %s", log_path);
fprintf(stderr, "Failed to open log file: %s\n", log_path);
exit(EXIT_FAILURE);
}

Expand Down
6 changes: 3 additions & 3 deletions src/video/hls/hls_unified_thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*
* This file implements the unified thread approach for HLS streaming.
*
* CRITICAL FIX (2025-04-11): Fixed segmentation fault issues related to thread safety
* CRITICAL FIX: Fixed segmentation fault issues related to thread safety
* in the writer cleanup process. The main issue was that the hls_writer was being accessed
* after it had been freed by another thread. The fix uses atomic operations to ensure
* thread-safe access to the writer pointer.
Expand Down Expand Up @@ -2982,7 +2982,7 @@ static void ffmpeg_buffer_cleanup(void) {

// CRITICAL FIX: Skip direct av_freep(NULL) call during shutdown or hard deletion
// This is the most likely cause of segmentation faults
if (!is_shutdown_initiated() && !is_stream_stopping(NULL)) {
if (!is_shutdown_initiated()) {
// Use a safer approach to release memory
log_debug("Using safer approach to release FFmpeg memory");

Expand All @@ -2993,7 +2993,7 @@ static void ffmpeg_buffer_cleanup(void) {
av_free(dummy);
}
} else {
log_info("Skipping av_freep(NULL) during shutdown or stream deletion to prevent segmentation fault");
log_info("Skipping av_freep(NULL) during shutdown to prevent segmentation fault");
}

// Call FFmpeg's internal memory cleanup functions - safely
Expand Down
12 changes: 6 additions & 6 deletions src/video/mp4_writer_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ static int init_audio_transcoder(const char *stream_name,
strncpy(audio_transcoder_stream_names[slot], stream_name, MAX_STREAM_NAME - 1);
audio_transcoder_stream_names[slot][MAX_STREAM_NAME - 1] = '\0';

log_info("Successfully initialized audio transcoder from μ-law to AAC for %s", stream_name);
log_info("Successfully initialized audio transcoder from PCM to AAC for %s", stream_name);

#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(59, 37, 100)
log_info("Sample rate: %d, Channels: %d, Bit rate: %ld",
Expand Down Expand Up @@ -395,7 +395,7 @@ int transcode_audio_packet(const char *stream_name,
* @param transcoded_params Output parameter to store the transcoded codec parameters
* @return 0 on success, negative on error
*/
int transcode_mulaw_to_aac(const AVCodecParameters *codec_params,
int transcode_pcm_to_aac(const AVCodecParameters *codec_params,
const AVRational *time_base,
const char *stream_name,
AVCodecParameters **transcoded_params) {
Expand Down Expand Up @@ -456,7 +456,7 @@ int transcode_mulaw_to_aac(const AVCodecParameters *codec_params,
// Open decoder
ret = avcodec_open2(decoder_ctx, decoder, NULL);
if (ret < 0) {
log_ffmpeg_error(ret, "Failed to open μ-law decoder");
log_ffmpeg_error(ret, "Failed to open PCM decoder");
goto cleanup;
}

Expand Down Expand Up @@ -505,7 +505,7 @@ int transcode_mulaw_to_aac(const AVCodecParameters *codec_params,
goto cleanup;
}

log_info("Successfully configured transcoding from μ-law to AAC for %s",
log_info("Successfully configured transcoding from PCM to AAC for %s",
stream_name ? stream_name : "unknown");

#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(59, 37, 100)
Expand Down Expand Up @@ -871,7 +871,7 @@ int mp4_writer_initialize(mp4_writer_t *writer, const AVPacket *pkt, const AVStr

// Try to transcode PCM to AAC
AVCodecParameters *transcoded_params = NULL;
int transcode_ret = transcode_mulaw_to_aac(input_stream->codecpar,
int transcode_ret = transcode_pcm_to_aac(input_stream->codecpar,
&input_stream->time_base,
writer->stream_name,
&transcoded_params);
Expand Down Expand Up @@ -1290,7 +1290,7 @@ int mp4_writer_add_audio_stream(mp4_writer_t *writer, const AVCodecParameters *c

// Try to transcode PCM to AAC
AVCodecParameters *transcoded_params = NULL;
int transcode_ret = transcode_mulaw_to_aac(codec_params, &safe_time_base,
int transcode_ret = transcode_pcm_to_aac(codec_params, &safe_time_base,
writer->stream_name, &transcoded_params);

if (transcode_ret >= 0 && transcoded_params) {
Expand Down
3 changes: 2 additions & 1 deletion src/video/onvif_device_management.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ static char* create_security_header(const char *username, const char *password,
memcpy(concatenated, nonce_bytes, nonce_len);
// Raw byte copies for SHA-1 input: intermediate parts are not C strings
memcpy((void *)(concatenated + nonce_len), created, created_len); // NOLINT(bugprone-not-null-terminated-result)
memcpy((void *)(concatenated + nonce_len + created_len), password, password_len + 1);
// Exclude the null terminator: WS-Security spec requires raw bytes only
memcpy((void *)(concatenated + nonce_len + created_len), password, password_len);

// Calculate SHA1 digest
mbedtls_sha1((unsigned char*)concatenated, nonce_len + created_len + password_len, digest);
Expand Down
11 changes: 7 additions & 4 deletions web/js/components/preact/WebRTCView.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,11 @@ export function WebRTCView() {
setIsLoading(isLoadingStreams);
}, [isLoadingStreams]);

// Process streams data when it's loaded or when the selected stream changes.
// Process streams data when it's loaded.
useEffect(() => {
// If a stream is already selected (e.g. by the user or URL), don't override it here.
if (selectedStream) return;

if (streamsData && Array.isArray(streamsData)) {
// Process the streams data
const processStreams = async () => {
Expand Down Expand Up @@ -226,9 +229,9 @@ export function WebRTCView() {

processStreams();
}
// Note: This effect now explicitly depends on selectedStream.
// It is written to be idempotent and will only update selectedStream when necessary.
}, [streamsData, selectedStream]);
// Note: This effect now explicitly depends on streamsData and autoGrid.
// It will only update selectedStream when none is already selected.
}, [streamsData, autoGrid]);

// Sync layout/page/stream to URL — only meaningful once streams are loaded.
useEffect(() => {
Expand Down