Skip to content

Commit b1067e0

Browse files
Merge pull request #4616 from ZoneMinder/copilot/refactor-filepath-handling
Refactor EventStream::sendFrame to use reusable filepath member
2 parents 08edd36 + f61a2e0 commit b1067e0

2 files changed

Lines changed: 21 additions & 18 deletions

File tree

src/zm_eventstream.cpp

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -845,27 +845,29 @@ bool EventStream::sendFrame(Microseconds delta_us) {
845845
curr_frame_id = std::clamp(curr_frame_id, 1, (int)event_data->frames.size());
846846
}
847847

848-
std::string filepath;
848+
// Reusable string member avoids per-frame heap allocations.
849+
// After the first frame, the string's buffer is reused (unless path exceeds capacity).
850+
reuse_filepath_.clear();
849851
struct stat filestat = {};
850852

851853
// This needs to be abstracted. If we are saving jpgs, then load the capture file.
852854
// If we are only saving analysis frames, then send that.
853855
if ((frame_type == FRAME_ANALYSIS) && (event_data->SaveJPEGs & 2)) {
854-
filepath = stringtf(staticConfig.analyse_file_format.c_str(), event_data->path.c_str(), curr_frame_id);
855-
if (stat(filepath.c_str(), &filestat) < 0) {
856-
Debug(1, "analyze file %s not found will try to stream from other", filepath.c_str());
857-
filepath = stringtf(staticConfig.capture_file_format.c_str(), event_data->path.c_str(), curr_frame_id);
858-
if (stat(filepath.c_str(), &filestat) < 0) {
859-
Debug(1, "capture file %s not found either", filepath.c_str());
860-
filepath = "";
856+
reuse_filepath_ = stringtf(staticConfig.analyse_file_format.c_str(), event_data->path.c_str(), curr_frame_id);
857+
if (stat(reuse_filepath_.c_str(), &filestat) < 0) {
858+
Debug(1, "analyze file %s not found will try to stream from other", reuse_filepath_.c_str());
859+
reuse_filepath_ = stringtf(staticConfig.capture_file_format.c_str(), event_data->path.c_str(), curr_frame_id);
860+
if (stat(reuse_filepath_.c_str(), &filestat) < 0) {
861+
Debug(1, "capture file %s not found either", reuse_filepath_.c_str());
862+
reuse_filepath_.clear();
861863
}
862864
}
863865
} else if (event_data->SaveJPEGs & 1) {
864-
filepath = stringtf(staticConfig.capture_file_format.c_str(), event_data->path.c_str(), curr_frame_id);
865-
if (stat(filepath.c_str(), &filestat) < 0) {
866+
reuse_filepath_ = stringtf(staticConfig.capture_file_format.c_str(), event_data->path.c_str(), curr_frame_id);
867+
if (stat(reuse_filepath.c_str(), &filestat) < 0) {
866868
Debug(1, "Capture file %s not found (bulk/interpolated frame %d), trying ffmpeg_input",
867-
filepath.c_str(), curr_frame_id);
868-
filepath = "";
869+
reuse_filepath.c_str(), curr_frame_id);
870+
reuse_filepathi.clear();
869871
// Fall through — ffmpeg_input will be tried below if available
870872
}
871873
} else if (!ffmpeg_input) {
@@ -874,7 +876,7 @@ bool EventStream::sendFrame(Microseconds delta_us) {
874876
}
875877

876878
if ( type == STREAM_MPEG ) {
877-
Image image(filepath.c_str());
879+
Image image(reuse_filepath_.c_str());
878880

879881
Image *send_image = prepareImage(&image);
880882

@@ -889,19 +891,19 @@ bool EventStream::sendFrame(Microseconds delta_us) {
889891
config.mpeg_timed_frames,
890892
delta_us.count() * 1000);
891893
} else {
892-
bool send_raw = (type == STREAM_JPEG) && ((scale >= ZM_SCALE_BASE) && (zoom == ZM_SCALE_BASE)) && !filepath.empty();
894+
bool send_raw = (type == STREAM_JPEG) && ((scale >= ZM_SCALE_BASE) && (zoom == ZM_SCALE_BASE)) && !reuse_filepath_.empty();
893895

894896
if (send_raw) {
895897
fprintf(stdout, "--" BOUNDARY "\r\n");
896-
if (!send_file(filepath)) {
897-
Error("Can't send %s: %s", filepath.c_str(), strerror(errno));
898+
if (!send_file(reuse_filepath_)) {
899+
Error("Can't send %s: %s", reuse_filepath_.c_str(), strerror(errno));
898900
return false;
899901
}
900902
} else {
901903
Image *image = nullptr;
902904

903-
if (!filepath.empty()) {
904-
image = new Image(filepath.c_str());
905+
if (!reuse_filepath_.empty()) {
906+
image = new Image(reuse_filepath_.c_str());
905907
} else if (ffmpeg_input) {
906908
// Get the frame from the mp4 input
907909
const FrameData *frame_data = &event_data->frames[curr_frame_id-1];

src/zm_eventstream.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ class EventStream : public StreamBase {
127127
bool send_buffer(uint8_t * buffer, int size);
128128
Storage *storage;
129129
FFmpeg_Input *ffmpeg_input;
130+
std::string reuse_filepath_; // reused across sendFrame calls to avoid per-frame heap alloc
130131
};
131132

132133
#endif // ZM_EVENTSTREAM_H

0 commit comments

Comments
 (0)