subtitles: Fix recent filter-rendered libass timing problem
[mplayer/glamo.git] / edl.c
blob35950bdfdecf61cf3b613ac06925f85e59358efd
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "config.h"
4 #include "mp_msg.h"
5 #include "edl.h"
6 #include "help_mp.h"
8 char *edl_filename; // file to extract EDL entries from (-edl)
9 char *edl_output_filename; // file to put EDL entries in (-edlout)
11 /**
12 * Allocates a new EDL record and makes sure allocation was successful.
14 * \return New allocated EDL record.
15 * \brief Allocate new EDL record
18 static edl_record_ptr edl_alloc_new(edl_record_ptr next_edl_record)
20 edl_record_ptr new_record = calloc(1, sizeof(struct edl_record));
21 if (!new_record) {
22 mp_tmsg(MSGT_CPLAYER, MSGL_FATAL, "Can't allocate enough memory to hold EDL data.\n");
23 exit(1);
26 if (next_edl_record) // if this isn't the first record, tell the previous one what the new one is.
27 next_edl_record->next = new_record;
28 new_record->prev = next_edl_record;
29 new_record->next = NULL;
31 return new_record;
34 /**
35 * Goes through entire EDL records and frees all memory.
36 * Assumes next_edl_record is valid or NULL.
38 * \brief Free EDL memory
41 void free_edl(edl_record_ptr next_edl_record)
43 edl_record_ptr tmp;
44 while (next_edl_record) {
45 tmp = next_edl_record->next;
46 free(next_edl_record);
47 next_edl_record = tmp;
51 /** Parses edl_filename to fill EDL operations queue.
52 * Prints out how many EDL operations recorded total.
53 * \brief Fills EDL operations queue.
56 edl_record_ptr edl_parse_file(void)
58 FILE *fd;
59 char line[100];
60 float start, stop;
61 int action;
62 int record_count = 0;
63 int lineCount = 0;
64 edl_record_ptr edl_records = NULL;
65 edl_record_ptr next_edl_record = NULL;
67 if (edl_filename)
69 if ((fd = fopen(edl_filename, "r")) == NULL)
71 return NULL;
74 while (fgets(line, 99, fd) != NULL)
76 lineCount++;
78 if ((sscanf(line, "%f %f %d", &start, &stop, &action))
79 != 3)
81 mp_tmsg(MSGT_CPLAYER, MSGL_WARN, "Badly formatted EDL line [%d], discarding.\n",
82 lineCount);
83 continue;
86 if (next_edl_record && start <= next_edl_record->stop_sec)
88 mp_tmsg(MSGT_CPLAYER, MSGL_WARN, "Invalid EDL line: %s\n", line);
89 mp_tmsg(MSGT_CPLAYER, MSGL_WARN,
90 "Last stop position was [%f]; next start is [%f].\n"\
91 "Entries must be in chronological order, cannot overlap. Discarding.\n",
92 next_edl_record->stop_sec, start);
93 continue;
96 if (stop <= start)
98 mp_tmsg(MSGT_CPLAYER, MSGL_WARN, "Invalid EDL line: %s\n",
99 line);
100 mp_tmsg(MSGT_CPLAYER, MSGL_WARN, "Stop time has to be after start time.\n");
101 continue;
104 next_edl_record = edl_alloc_new(next_edl_record);
106 if (!edl_records) edl_records = next_edl_record;
108 next_edl_record->action = action;
110 if (action == EDL_MUTE)
112 next_edl_record->length_sec = 0;
113 next_edl_record->start_sec = start;
114 next_edl_record->stop_sec = start;
116 next_edl_record = edl_alloc_new(next_edl_record);
118 next_edl_record->action = action;
119 next_edl_record->length_sec = 0;
120 next_edl_record->start_sec = stop;
121 next_edl_record->stop_sec = stop;
122 } else
124 next_edl_record->length_sec = stop - start;
125 next_edl_record->start_sec = start;
126 next_edl_record->stop_sec = stop;
129 record_count++;
132 fclose(fd);
135 if (edl_records)
136 mp_tmsg(MSGT_CPLAYER, MSGL_INFO, "Read %d EDL actions.\n", record_count);
137 else
138 mp_tmsg(MSGT_CPLAYER, MSGL_INFO, "There are no EDL actions to take care of.\n");
140 return edl_records;