/***************************************************************************** # # # uStreamer - Lightweight and fast MJPEG-HTTP streamer. # # # # Copyright (C) 2018-2024 Maxim Devaev # # # # This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation, either version 3 of the License, or # # (at your option) any later version. # # # # This program is distributed in the hope that it will be useful, # # but WITHOUT ANY WARRANTY; without even the implied warranty of # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # # GNU General Public License for more details. # # # # You should have received a copy of the GNU General Public License # # along with this program. If not, see . # # # *****************************************************************************/ #include "file.h" us_output_file_s *us_output_file_init(const char *path, bool json) { us_output_file_s *out; US_CALLOC(out, 1); if (!strcmp(path, "-")) { US_LOG_INFO("Using output: "); out->fp = stdout; } else { US_LOG_INFO("Using output: %s", path); if ((out->fp = fopen(path, "wb")) == NULL) { US_LOG_PERROR("Can't open output file"); goto error; } } out->json = json; return out; error: us_output_file_destroy(out); return NULL; } void us_output_file_write(void *v_out, const us_frame_s *frame) { us_output_file_s *out = v_out; if (out->json) { us_base64_encode(frame->data, frame->used, &out->base64_data, &out->base64_allocated); fprintf( out->fp, "{\"size\": %zu," " \"width\": %u," " \"height\": %u," " \"format\": %u," " \"stride\": %u," " \"online\": %u," " \"key\": %u," " \"gop\": %u," " \"grab_begin_ts\": %.3Lf," " \"grab_end_ts\": %.3Lf," " \"encode_begin_ts\": %.3Lf," " \"encode_end_ts\": %.3Lf," " \"data\": \"%s\"}\n", frame->used, frame->width, frame->height, frame->format, frame->stride, frame->online, frame->key, frame->gop, frame->grab_begin_ts, frame->grab_end_ts, frame->encode_begin_ts, frame->encode_end_ts, out->base64_data); } else { fwrite(frame->data, 1, frame->used, out->fp); } fflush(out->fp); } void us_output_file_destroy(void *v_out) { us_output_file_s *out = v_out; US_DELETE(out->base64_data, free); if (out->fp && out->fp != stdout) { if (fclose(out->fp) < 0) { US_LOG_PERROR("Can't close output file"); } } free(out); }