gstreamer
Loading...
Searching...
No Matches
gstreamerJSONConnection.cc
Go to the documentation of this file.
1// gstreamer
4
5// c++
6#include <iomanip>
7
8// Implementation summary:
9// Manage the JSON output stream and the lifetime of the top-level JSON document.
10
11bool GstreamerJsonFactory::openConnection() {
12 if (ofile.is_open()) {
13 // Already open for this streamer instance.
14 return true;
15 }
16
17 ofile.clear();
18 ofile.open(filename(), std::ios::out | std::ios::trunc);
19
20 if (!ofile.is_open() || !ofile) {
21 log->error(ERR_CANTOPENOUTPUT, SFUNCTION_NAME, " could not open file ", filename());
22 return false;
23 }
24
25 log->info(1, SFUNCTION_NAME, "GstreamerJsonFactory: opened file " + filename());
26
27 // The top-level JSON container depends on whether this instance ends up writing
28 // events or frames, so defer initialization until the first publish call.
29 is_file_initialized = false;
30 wrote_first_top_level_entry = false;
31 top_level_type.clear();
32
33 return true;
34}
35
36bool GstreamerJsonFactory::closeConnectionImpl() {
37 // The public closeConnection() wrapper already flushes buffered events before this method runs.
38
39 // Finalize the top-level JSON structure only if it was ever started.
40 closeTopLevelObjectIfNeeded();
41
42 if (ofile.is_open()) ofile.close();
43 if (ofile.is_open()) {
44 log->error(ERR_CANTCLOSEOUTPUT, SFUNCTION_NAME, " could not close file ", filename());
45 }
46
47 log->info(1, SFUNCTION_NAME, "GstreamerJsonFactory: closed file " + filename());
48
49 return true;
50}
51
52void GstreamerJsonFactory::ensureFileInitializedForType(const std::string& type) {
53 if (is_file_initialized) return;
54
55 top_level_type = type;
56
57 // Single top-level object with exactly one active array:
58 // { "type": "event", "events": [ ... ] }
59 // or
60 // { "type": "stream", "frames": [ ... ] }
61 ofile << "{\n";
62 ofile << " \"type\": \"" << jsonEscape(type) << "\",\n";
63
64 if (type == "event") {
65 ofile << " \"events\": [\n";
66 }
67 else {
68 ofile << " \"frames\": [\n";
69 }
70
71 is_file_initialized = true;
72 wrote_first_top_level_entry = false;
73}
74
75void GstreamerJsonFactory::writeTopLevelEntry(const std::string& entry_json) {
76 // This helper assumes the correct top-level array has already been opened.
77 if (!is_file_initialized) {
78 log->error(ERR_PUBLISH_ERROR, "JSON file is not initialized in GstreamerJsonFactory::writeTopLevelEntry");
79 return;
80 }
81
82 // Entries inside the top-level array are comma-separated.
83 if (wrote_first_top_level_entry) {
84 ofile << ",\n";
85 }
86 wrote_first_top_level_entry = true;
87
88 // Keep a stable indentation level for readability.
89 ofile << " " << entry_json;
90}
91
92void GstreamerJsonFactory::closeTopLevelObjectIfNeeded() {
93 if (!is_file_initialized) return;
94
95 // Close the active top-level array and then the containing object.
96 ofile << "\n ]\n";
97 ofile << "}\n";
98 is_file_initialized = false;
99}
std::shared_ptr< GLogger > log
void info(int level, Args &&... args) const
void error(int exit_code, Args &&... args) const
Shared constants and error codes for the gstreamer module.
#define ERR_CANTCLOSEOUTPUT
Output medium could not be closed cleanly.
#define ERR_PUBLISH_ERROR
Publish sequence encountered invalid state or invalid input data.
#define ERR_CANTOPENOUTPUT
Output medium could not be opened successfully.
JSON streamer plugin declarations.