diff options
| author | dec05eba <dec05eba@protonmail.com> | 2026-08-07 13:53:40 +0200 |
|---|---|---|
| committer | dec05eba <dec05eba@protonmail.com> | 2026-08-07 13:53:40 +0200 |
| commit | 90ac49f372f4c3d3d12f4d0d58ab0473a86821d5 (patch) | |
| tree | d3faf489bc8bb5d9c67abda5a4f04d330ce42607 | |
| parent | e31968fc4074df739c00947b993ee19be4ef1caa (diff) | |
Revert "Clear replay data in replay save thread to not block the main capture thread"
This reverts commit 5db30f3fb99545524fc80f87ecc488972aec1711.
| -rw-r--r-- | include/recorder/replay_save.h | 10 | ||||
| -rw-r--r-- | include/replay_buffer/replay_buffer.h | 9 | ||||
| -rw-r--r-- | src/recorder/recorder.c | 8 | ||||
| -rw-r--r-- | src/recorder/replay_save.c | 17 | ||||
| -rw-r--r-- | src/replay_buffer/replay_buffer.c | 4 | ||||
| -rw-r--r-- | src/replay_buffer/replay_buffer_disk.c | 31 | ||||
| -rw-r--r-- | src/replay_buffer/replay_buffer_ram.c | 27 |
7 files changed, 10 insertions, 96 deletions
diff --git a/include/recorder/replay_save.h b/include/recorder/replay_save.h index ac4eb98..7f48851 100644 --- a/include/recorder/replay_save.h +++ b/include/recorder/replay_save.h @@ -37,20 +37,14 @@ typedef struct { gsr_audio_pts_offset *audio_pts_offsets; size_t num_audio_pts_offsets; gsr_replay_buffer *cloned_replay_buffer; - /* The data that the replay buffer had before it was restarted, free'd on the replay save thread */ - gsr_replay_buffer *restarted_replay_buffer_data; gsr_encoder *encoder; } gsr_replay_save; void gsr_replay_save_init(gsr_replay_save *self); bool gsr_replay_save_is_running(const gsr_replay_save *self); -/* - Returns false if the replay failed to start. |current_save_replay_seconds| can be GSR_SAVE_REPLAY_SECONDS_FULL to save the whole replay buffer. - The replay buffer of |encoder| is restarted (emptied) when |restart_replay| is set, which is done without blocking the - thread that appends to the replay buffer by free'ing the old data on the replay save thread. -*/ -bool gsr_replay_save_start(gsr_replay_save *self, AVCodecContext *video_codec_context, int video_stream_index, const gsr_audio_capture *audio_capture, gsr_encoder *encoder, const gsr_recorder_settings *settings, const char *file_extension, bool hdr, gsr_video_sources *video_sources, int current_save_replay_seconds, bool restart_replay); +/* Returns false if the replay failed to start. |current_save_replay_seconds| can be GSR_SAVE_REPLAY_SECONDS_FULL to save the whole replay buffer */ +bool gsr_replay_save_start(gsr_replay_save *self, AVCodecContext *video_codec_context, int video_stream_index, const gsr_audio_capture *audio_capture, gsr_encoder *encoder, const gsr_recorder_settings *settings, const char *file_extension, bool hdr, gsr_video_sources *video_sources, int current_save_replay_seconds); /* Returns true when the replay finished saving, in which case |success| and |output_filepath| are set. |output_filepath| is empty when nothing was saved */ bool gsr_replay_save_poll(gsr_replay_save *self, bool *success, const char **output_filepath); /* Waits for an ongoing replay save to finish. Returns the same values as gsr_replay_save_poll */ diff --git a/include/replay_buffer/replay_buffer.h b/include/replay_buffer/replay_buffer.h index 3ac452a..bf2e4e6 100644 --- a/include/replay_buffer/replay_buffer.h +++ b/include/replay_buffer/replay_buffer.h @@ -22,8 +22,6 @@ struct gsr_replay_buffer { uint8_t* (*iterator_get_packet_data)(gsr_replay_buffer *self, gsr_replay_buffer_iterator iterator); /* The clone has to be destroyed before the replay buffer it clones is destroyed */ gsr_replay_buffer* (*clone)(gsr_replay_buffer *self); - /* Returns NULL on failure, in which case |self| is left untouched */ - gsr_replay_buffer* (*take_data)(gsr_replay_buffer *self); /* Returns {0, 0} if replay buffer is empty */ gsr_replay_buffer_iterator (*find_packet_index_by_time_passed)(gsr_replay_buffer *self, int seconds); /* Returns {-1, 0} if not found */ @@ -48,13 +46,6 @@ AVPacket* gsr_replay_buffer_iterator_get_packet(gsr_replay_buffer *self, gsr_rep uint8_t* gsr_replay_buffer_iterator_get_packet_data(gsr_replay_buffer *self, gsr_replay_buffer_iterator iterator); /* The clone has to be destroyed before the replay buffer it clones is destroyed */ gsr_replay_buffer* gsr_replay_buffer_clone(gsr_replay_buffer *self); -/* - Moves the data of |self| into a new replay buffer and leaves |self| empty and ready to be used again. - This is a cheap operation, unlike gsr_replay_buffer_clear, because freeing the data is deferred to - gsr_replay_buffer_destroy of the returned replay buffer, which can be done without blocking |self|. - Returns NULL on failure, in which case |self| is left untouched. -*/ -gsr_replay_buffer* gsr_replay_buffer_take_data(gsr_replay_buffer *self); /* Returns {0, 0} if replay buffer is empty */ gsr_replay_buffer_iterator gsr_replay_buffer_find_packet_index_by_time_passed(gsr_replay_buffer *self, int seconds); /* Returns {-1, 0} if not found */ diff --git a/src/recorder/recorder.c b/src/recorder/recorder.c index f24495c..901077c 100644 --- a/src/recorder/recorder.c +++ b/src/recorder/recorder.c @@ -752,9 +752,15 @@ static void recorder_poll_replay_save(gsr_recorder *self) { atomic_store(&self->save_replay_seconds, 0); const int restart_replay_request = atomic_exchange(&self->save_replay_restart_replay, GSR_RESTART_REPLAY_USE_OPTION); const bool restart_replay = restart_replay_request == GSR_RESTART_REPLAY_USE_OPTION ? self->settings.restart_replay_on_save : restart_replay_request == GSR_RESTART_REPLAY_ENABLE; - const bool replay_start_result = gsr_replay_save_start(&self->replay_save, self->video_codec_context, GSR_VIDEO_STREAM_INDEX, &self->audio_capture, &self->encoder, &self->settings, self->file_extension, self->hdr, self->video_sources, current_save_replay_seconds, restart_replay && current_save_replay_seconds == GSR_SAVE_REPLAY_SECONDS_FULL); + const bool replay_start_result = gsr_replay_save_start(&self->replay_save, self->video_codec_context, GSR_VIDEO_STREAM_INDEX, &self->audio_capture, &self->encoder, &self->settings, self->file_extension, self->hdr, self->video_sources, current_save_replay_seconds); if(!replay_start_result && self->callbacks.replay_saved) self->callbacks.replay_saved(NULL, self->callbacks.userdata); + + if(restart_replay && current_save_replay_seconds == GSR_SAVE_REPLAY_SECONDS_FULL) { + pthread_mutex_lock(&self->encoder.replay_mutex); + gsr_replay_buffer_clear(self->encoder.replay_buffer); + pthread_mutex_unlock(&self->encoder.replay_mutex); + } } } diff --git a/src/recorder/replay_save.c b/src/recorder/replay_save.c index 55cf35d..3251616 100644 --- a/src/recorder/replay_save.c +++ b/src/recorder/replay_save.c @@ -23,15 +23,6 @@ static void gsr_replay_save_cleanup(gsr_replay_save *self) { self->cloned_replay_buffer = NULL; } - /* - This is the data that the replay buffer had before the replay was saved and nothing references it anymore, - so it can be free'd without holding the replay mutex. This can take a while when the replay buffer is large. - */ - if(self->restarted_replay_buffer_data) { - gsr_replay_buffer_destroy(self->restarted_replay_buffer_data); - self->restarted_replay_buffer_data = NULL; - } - if(self->audio_pts_offsets) { free(self->audio_pts_offsets); self->audio_pts_offsets = NULL; @@ -125,7 +116,7 @@ static void* replay_save_thread(void *userdata) { return NULL; } -bool gsr_replay_save_start(gsr_replay_save *self, AVCodecContext *video_codec_context, int video_stream_index, const gsr_audio_capture *audio_capture, gsr_encoder *encoder, const gsr_recorder_settings *settings, const char *file_extension, bool hdr, gsr_video_sources *video_sources, int current_save_replay_seconds, bool restart_replay) { +bool gsr_replay_save_start(gsr_replay_save *self, AVCodecContext *video_codec_context, int video_stream_index, const gsr_audio_capture *audio_capture, gsr_encoder *encoder, const gsr_recorder_settings *settings, const char *file_extension, bool hdr, gsr_video_sources *video_sources, int current_save_replay_seconds) { if(self->thread_created) return true; @@ -134,16 +125,10 @@ bool gsr_replay_save_start(gsr_replay_save *self, AVCodecContext *video_codec_co self->video_stream_index = video_stream_index; self->output_filepath[0] = '\0'; self->success = false; - self->restarted_replay_buffer_data = NULL; atomic_store(&self->finished, 0); pthread_mutex_lock(&encoder->replay_mutex); self->cloned_replay_buffer = gsr_replay_buffer_clone(encoder->replay_buffer); - if(self->cloned_replay_buffer && restart_replay) { - self->restarted_replay_buffer_data = gsr_replay_buffer_take_data(encoder->replay_buffer); - if(!self->restarted_replay_buffer_data) - gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_replay_save: failed to restart the replay buffer"); - } pthread_mutex_unlock(&encoder->replay_mutex); if(!self->cloned_replay_buffer) { /* TODO: Return this error to mark the replay as failed */ diff --git a/src/replay_buffer/replay_buffer.c b/src/replay_buffer/replay_buffer.c index 4958bba..2f7db54 100644 --- a/src/replay_buffer/replay_buffer.c +++ b/src/replay_buffer/replay_buffer.c @@ -47,10 +47,6 @@ gsr_replay_buffer* gsr_replay_buffer_clone(gsr_replay_buffer *self) { return self->clone(self); } -gsr_replay_buffer* gsr_replay_buffer_take_data(gsr_replay_buffer *self) { - return self->take_data(self); -} - gsr_replay_buffer_iterator gsr_replay_buffer_find_packet_index_by_time_passed(gsr_replay_buffer *self, int seconds) { return self->find_packet_index_by_time_passed(self, seconds); } diff --git a/src/replay_buffer/replay_buffer_disk.c b/src/replay_buffer/replay_buffer_disk.c index da82df5..b61ccfa 100644 --- a/src/replay_buffer/replay_buffer_disk.c +++ b/src/replay_buffer/replay_buffer_disk.c @@ -254,36 +254,6 @@ static uint8_t* gsr_replay_buffer_disk_iterator_get_packet_data(gsr_replay_buffe return packet_data; } -static gsr_replay_buffer* gsr_replay_buffer_disk_take_data(gsr_replay_buffer *replay_buffer) { - gsr_replay_buffer_disk *self = (gsr_replay_buffer_disk*)replay_buffer; - gsr_replay_buffer_disk *destination = calloc(1, sizeof(gsr_replay_buffer_disk)); - if(!destination) - return NULL; - - gsr_replay_buffer_disk_set_impl_funcs(destination); - - destination->replay_buffer_time = self->replay_buffer_time; - destination->storage_counter = self->storage_counter; - destination->storage_num_bytes_written = self->storage_num_bytes_written; - destination->storage_fd = self->storage_fd; - - for(size_t i = 0; i < self->num_files; ++i) { - destination->files[i] = self->files[i]; - } - destination->num_files = self->num_files; - - snprintf(destination->replay_directory, sizeof(destination->replay_directory), "%s", self->replay_directory); - /* |self| keeps writing to the same directory, so it's the one that removes it */ - destination->owns_directory = false; - - self->num_files = 0; - self->storage_fd = 0; - self->storage_num_bytes_written = 0; - /* |storage_counter| is not reset, to not overwrite the files that were moved to |destination| */ - - return (gsr_replay_buffer*)destination; -} - static gsr_replay_buffer* gsr_replay_buffer_disk_clone(gsr_replay_buffer *replay_buffer) { gsr_replay_buffer_disk *self = (gsr_replay_buffer_disk*)replay_buffer; gsr_replay_buffer_disk *destination = calloc(1, sizeof(gsr_replay_buffer_disk)); @@ -430,7 +400,6 @@ static void gsr_replay_buffer_disk_set_impl_funcs(gsr_replay_buffer_disk *self) self->replay_buffer.iterator_get_packet = gsr_replay_buffer_disk_iterator_get_packet; self->replay_buffer.iterator_get_packet_data = gsr_replay_buffer_disk_iterator_get_packet_data; self->replay_buffer.clone = gsr_replay_buffer_disk_clone; - self->replay_buffer.take_data = gsr_replay_buffer_disk_take_data; self->replay_buffer.find_packet_index_by_time_passed = gsr_replay_buffer_disk_find_file_index_by_time_passed; self->replay_buffer.find_keyframe = gsr_replay_buffer_disk_find_keyframe; self->replay_buffer.iterator_next = gsr_replay_buffer_disk_iterator_next; diff --git a/src/replay_buffer/replay_buffer_ram.c b/src/replay_buffer/replay_buffer_ram.c index ce3914b..39f31b1 100644 --- a/src/replay_buffer/replay_buffer_ram.c +++ b/src/replay_buffer/replay_buffer_ram.c @@ -130,32 +130,6 @@ static uint8_t* gsr_replay_buffer_ram_iterator_get_packet_data(gsr_replay_buffer return NULL; } -static gsr_replay_buffer* gsr_replay_buffer_ram_take_data(gsr_replay_buffer *replay_buffer) { - gsr_replay_buffer_ram *self = (gsr_replay_buffer_ram*)replay_buffer; - gsr_av_packet_ram **packets = calloc(self->capacity_num_packets, sizeof(gsr_av_packet_ram*)); - if(!packets) - return NULL; - - gsr_replay_buffer_ram *destination = calloc(1, sizeof(gsr_replay_buffer_ram)); - if(!destination) { - free(packets); - return NULL; - } - - gsr_replay_buffer_ram_set_impl_funcs(destination); - - destination->packets = self->packets; - destination->capacity_num_packets = self->capacity_num_packets; - destination->num_packets = self->num_packets; - destination->index = self->index; - - self->packets = packets; - self->num_packets = 0; - self->index = 0; - - return (gsr_replay_buffer*)destination; -} - static gsr_replay_buffer* gsr_replay_buffer_ram_clone(gsr_replay_buffer *replay_buffer) { gsr_replay_buffer_ram *self = (gsr_replay_buffer_ram*)replay_buffer; gsr_replay_buffer_ram *destination = calloc(1, sizeof(gsr_replay_buffer_ram)); @@ -242,7 +216,6 @@ static void gsr_replay_buffer_ram_set_impl_funcs(gsr_replay_buffer_ram *self) { self->replay_buffer.iterator_get_packet = gsr_replay_buffer_ram_iterator_get_packet; self->replay_buffer.iterator_get_packet_data = gsr_replay_buffer_ram_iterator_get_packet_data; self->replay_buffer.clone = gsr_replay_buffer_ram_clone; - self->replay_buffer.take_data = gsr_replay_buffer_ram_take_data; self->replay_buffer.find_packet_index_by_time_passed = gsr_replay_buffer_ram_find_packet_index_by_time_passed; self->replay_buffer.find_keyframe = gsr_replay_buffer_ram_find_keyframe; self->replay_buffer.iterator_next = gsr_replay_buffer_ram_iterator_next; |
