UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
video_export.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define VIDEO_EXPORT_SUMMARY_VERSION   1
 

Functions

void video_export (struct video_export *state, struct video_frame *frame)
 
void video_export_destroy (struct video_export *state)
 
struct video_export * video_export_init (const char *path)
 

Detailed Description

Macro Definition Documentation

◆ VIDEO_EXPORT_SUMMARY_VERSION

#define VIDEO_EXPORT_SUMMARY_VERSION   1

Definition at line 41 of file video_export.h.

Referenced by output_summary(), and parse_video_desc_info().

Function Documentation

◆ video_export()

void video_export ( struct video_export * state,
struct video_frame * frame )

Definition at line 203 of file video_export.c.

204{
205 if(!s) {
206 return;
207 }
208
209 assert(frame != NULL);
210 s->total += 1;
211
212 if(s->saved_desc.width == 0) {
213 s->saved_desc = video_desc_from_frame(frame);
214 } else {
215 if(!video_desc_eq(s->saved_desc, video_desc_from_frame(frame))) {
216 fprintf(stderr, "[Video export] Format change detected, not exporting.\n");
217 return;
218 }
219 }
220
221 for (unsigned int i = 0; i < frame->tile_count; ++i) {
222 assert(frame->tiles[i].data != NULL && frame->tiles[i].data_len != 0);
223
224 struct output_entry *entry = malloc(sizeof(struct output_entry));
225
226 entry->data_len = frame->tiles[i].data_len;
227 entry->data = (char *) malloc(entry->data_len);
228 entry->filename = malloc(MAX_PATH_SIZE);
229 entry->next = NULL;
230
231 if(frame->tile_count == 1) {
232 snprintf(entry->filename, MAX_PATH_SIZE, "%s/%08d.%s", s->path,
233 s->total,
235 } else {
236 // add also tile index
237 snprintf(entry->filename, MAX_PATH_SIZE, "%s/%08d_%d.%s", s->path,
238 s->total, i,
240 }
241 memcpy(entry->data, frame->tiles[i].data, entry->data_len);
242
243 pthread_mutex_lock(&s->lock);
244 {
245 // check if we do not occupy too much memory
246 if(s->queue_len >= MAX_QUEUE_SIZE) {
247 fprintf(stderr, "[Video export] Maximal queue size (%d) exceeded, not saving frame %d.\n",
249 s->total); // we increment total size to keep the index
250 pthread_mutex_unlock(&s->lock);
251 free(entry->data);
252 free(entry);
253 return;
254 }
255
256 if(s->head) {
257 s->tail->next = entry;
258 s->tail = entry;
259 } else {
260 s->head = s->tail = entry;
261 }
262 s->queue_len += 1;
263 }
264 pthread_mutex_unlock(&s->lock);
265
266 platform_sem_post(&s->semaphore);
267 }
268}
struct video_frame * frame
struct video_desc video_desc_from_frame(const struct video_frame *frame)
Returns struct video_desc from video frame.
#define MAX_PATH_SIZE
Definition fs.h:48
void platform_sem_post(void *semStructure)
char * data
struct output_entry * next
char * filename
int data_len
char * data
Raw tile data. Pointer must be at least 4B aligned.
Definition types.h:287
unsigned int data_len
length of the data
Definition types.h:288
struct tile tiles[FLEXIBLE_ARRAY_MEMBER]
Definition types.h:345
unsigned int tile_count
Definition types.h:344
codec_t color_spec
Definition types.h:306
const char * get_codec_file_extension(codec_t codec)
#define MAX_QUEUE_SIZE
bool video_desc_eq(struct video_desc a, struct video_desc b)
Compares two video descriptions.

References video_frame::color_spec, output_entry::data, tile::data, output_entry::data_len, tile::data_len, output_entry::filename, frame, get_codec_file_extension(), video_export::head, video_export::lock, MAX_PATH_SIZE, MAX_QUEUE_SIZE, output_entry::next, video_export::path, platform_sem_post(), video_export::queue_len, video_export::saved_desc, video_export::semaphore, video_export::tail, video_frame::tile_count, video_frame::tiles, video_export::total, video_desc_eq(), video_desc_from_frame(), and video_desc::width.

Referenced by export_video().

Here is the call graph for this function:

◆ video_export_destroy()

void video_export_destroy ( struct video_export * state)

Definition at line 172 of file video_export.c.

173{
174 if(s) {
175 // poison
176 struct output_entry *entry = calloc(1, sizeof(struct output_entry));
177
178 pthread_mutex_lock(&s->lock);
179 {
180 if(s->head) {
181 s->tail->next = entry;
182 s->tail = entry;
183 } else {
184 s->head = s->tail = entry;
185 }
186 }
187 pthread_mutex_unlock(&s->lock);
188 platform_sem_post(&s->semaphore);
189
190 pthread_join(s->thread_id, NULL);
191 pthread_mutex_destroy(&s->lock);
192
193 // write summary
194 if(s->total > 0) {
196 }
197
198 free(s->path);
199 free(s);
200 }
201}
void output_summary(struct video_export *s)

References video_export::head, video_export::lock, output_entry::next, output_summary(), video_export::path, platform_sem_post(), video_export::semaphore, video_export::tail, video_export::thread_id, and video_export::total.

Referenced by disable_export(), and enable_export().

Here is the call graph for this function:

◆ video_export_init()

struct video_export * video_export_init ( const char * path)

Definition at line 125 of file video_export.c.

126{
127 struct video_export *s = calloc(1, sizeof *s);
128 assert(s != NULL);
129
130 platform_sem_init(&s->semaphore, 0, 0);
131 pthread_mutex_init(&s->lock, NULL);
132 s->total = s->queue_len = 0;
133 assert(path != NULL);
134 s->path = strdup(path);
135 s->head = s->tail = NULL;
136
137 memset(&s->saved_desc, 0, sizeof(s->saved_desc));
138
139 if(pthread_create(&s->thread_id, NULL, video_export_thread, s) != 0) {
140 fprintf(stderr, "[Video exporter] Failed to create thread.\n");
141 free(s);
142 return NULL;
143 }
144
145 return s;
146}
void platform_sem_init(void *semStructure, int pshared, int initialValue)
struct output_entry *volatile *volatile tail
uint32_t total
struct output_entry *volatile head
pthread_t thread_id
pthread_mutex_t lock
volatile int queue_len
struct video_desc saved_desc
static void * video_export_thread(void *arg)

References video_export::head, video_export::lock, video_export::path, platform_sem_init(), video_export::queue_len, video_export::saved_desc, video_export::semaphore, video_export::tail, video_export::thread_id, video_export::total, and video_export_thread().

Referenced by enable_export().

Here is the call graph for this function: