Merge svn changes up to r30876
[mplayer/kovensky.git] / edl.c
blobf20ee3d0491b07dd71ca6065288b6a50f6929864
1 /*
2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include "config.h"
22 #include "mp_msg.h"
23 #include "edl.h"
24 #include "help_mp.h"
26 char *edl_filename; // file to extract EDL entries from (-edl)
27 char *edl_output_filename; // file to put EDL entries in (-edlout)
29 /**
30 * Allocates a new EDL record and makes sure allocation was successful.
32 * \return New allocated EDL record.
33 * \brief Allocate new EDL record
36 static edl_record_ptr edl_alloc_new(edl_record_ptr next_edl_record)
38 edl_record_ptr new_record = calloc(1, sizeof(struct edl_record));
39 if (!new_record) {
40 mp_tmsg(MSGT_CPLAYER, MSGL_FATAL, "Can't allocate enough memory to hold EDL data.\n");
41 exit(1);
44 if (next_edl_record) // if this isn't the first record, tell the previous one what the new one is.
45 next_edl_record->next = new_record;
46 new_record->prev = next_edl_record;
47 new_record->next = NULL;
49 return new_record;
52 /**
53 * Goes through entire EDL records and frees all memory.
54 * Assumes next_edl_record is valid or NULL.
56 * \brief Free EDL memory
59 void free_edl(edl_record_ptr next_edl_record)
61 edl_record_ptr tmp;
62 while (next_edl_record) {
63 tmp = next_edl_record->next;
64 free(next_edl_record);
65 next_edl_record = tmp;
69 /** Parses edl_filename to fill EDL operations queue.
70 * Prints out how many EDL operations recorded total.
71 * \brief Fills EDL operations queue.
74 edl_record_ptr edl_parse_file(void)
76 FILE *fd;
77 char line[100];
78 float start, stop;
79 int action;
80 int record_count = 0;
81 int lineCount = 0;
82 edl_record_ptr edl_records = NULL;
83 edl_record_ptr next_edl_record = NULL;
85 if (edl_filename)
87 if ((fd = fopen(edl_filename, "r")) == NULL)
89 return NULL;
92 while (fgets(line, 99, fd) != NULL)
94 lineCount++;
96 if ((sscanf(line, "%f %f %d", &start, &stop, &action))
97 != 3)
99 mp_tmsg(MSGT_CPLAYER, MSGL_WARN, "Badly formatted EDL line [%d], discarding.\n",
100 lineCount);
101 continue;
104 if (next_edl_record && start <= next_edl_record->stop_sec)
106 mp_tmsg(MSGT_CPLAYER, MSGL_WARN, "Invalid EDL line: %s\n", line);
107 mp_tmsg(MSGT_CPLAYER, MSGL_WARN,
108 "Last stop position was [%f]; next start is [%f].\n"\
109 "Entries must be in chronological order, cannot overlap. Discarding.\n",
110 next_edl_record->stop_sec, start);
111 continue;
114 if (stop <= start)
116 mp_tmsg(MSGT_CPLAYER, MSGL_WARN, "Invalid EDL line: %s\n",
117 line);
118 mp_tmsg(MSGT_CPLAYER, MSGL_WARN, "Stop time has to be after start time.\n");
119 continue;
122 next_edl_record = edl_alloc_new(next_edl_record);
124 if (!edl_records) edl_records = next_edl_record;
126 next_edl_record->action = action;
128 if (action == EDL_MUTE)
130 next_edl_record->length_sec = 0;
131 next_edl_record->start_sec = start;
132 next_edl_record->stop_sec = start;
134 next_edl_record = edl_alloc_new(next_edl_record);
136 next_edl_record->action = action;
137 next_edl_record->length_sec = 0;
138 next_edl_record->start_sec = stop;
139 next_edl_record->stop_sec = stop;
140 } else
142 next_edl_record->length_sec = stop - start;
143 next_edl_record->start_sec = start;
144 next_edl_record->stop_sec = stop;
147 record_count++;
150 fclose(fd);
153 if (edl_records)
154 mp_tmsg(MSGT_CPLAYER, MSGL_INFO, "Read %d EDL actions.\n", record_count);
155 else
156 mp_tmsg(MSGT_CPLAYER, MSGL_INFO, "There are no EDL actions to take care of.\n");
158 return edl_records;