Update to MPlayer SVN rev 30589 and FFmpeg SVN rev 21847.
[vaapi:kinkis-mplayer.git] / edl.c
1 /*
2  * This file is part of MPlayer.
3  *
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.
8  *
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.
13  *
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.
17  */
18
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"
25
26 char *edl_filename; // file to extract EDL entries from (-edl)
27 char *edl_output_filename; // file to put EDL entries in (-edlout)
28
29 /**
30  *  Allocates a new EDL record and makes sure allocation was successful.
31  *
32  *  \return New allocated EDL record.
33  *  \brief Allocate new EDL record
34  */
35
36 static edl_record_ptr edl_alloc_new(edl_record_ptr next_edl_record)
37 {
38     edl_record_ptr new_record = calloc(1, sizeof(struct edl_record));
39     if (!new_record) {
40         mp_msg(MSGT_CPLAYER, MSGL_FATAL, MSGTR_EdlOutOfMem);
41         exit(1);
42     }
43
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;
48
49     return new_record;
50 }
51
52 /**
53  *  Goes through entire EDL records and frees all memory.
54  *  Assumes next_edl_record is valid or NULL.
55  *
56  *  \brief Free EDL memory
57  */
58
59 void free_edl(edl_record_ptr next_edl_record)
60 {
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;
66     }
67 }
68
69 /** Parses edl_filename to fill EDL operations queue.
70  * Prints out how many EDL operations recorded total.
71  *  \brief Fills EDL operations queue.
72  */
73
74 edl_record_ptr edl_parse_file(void)
75 {
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;
84
85     if (edl_filename)
86     {
87         if ((fd = fopen(edl_filename, "r")) == NULL)
88         {
89             return NULL;
90         }
91
92         while (fgets(line, 99, fd) != NULL)
93         {
94             lineCount++;
95
96             if ((sscanf(line, "%f %f %d", &start, &stop, &action))
97                 != 3)
98             {
99                 mp_msg(MSGT_CPLAYER, MSGL_WARN, MSGTR_EdlBadlyFormattedLine,
100                        lineCount);
101                 continue;
102             }
103
104             if (next_edl_record && start <= next_edl_record->stop_sec)
105             {
106                 mp_msg(MSGT_CPLAYER, MSGL_WARN, MSGTR_EdlNOValidLine, line);
107                 mp_msg(MSGT_CPLAYER, MSGL_WARN, MSGTR_EdlBadLineOverlap,
108                        next_edl_record->stop_sec, start);
109                 continue;
110             }
111
112             if (stop <= start)
113             {
114                 mp_msg(MSGT_CPLAYER, MSGL_WARN, MSGTR_EdlNOValidLine,
115                        line);
116                 mp_msg(MSGT_CPLAYER, MSGL_WARN, MSGTR_EdlBadLineBadStop);
117                 continue;
118             }
119
120             next_edl_record = edl_alloc_new(next_edl_record);
121
122             if (!edl_records) edl_records = next_edl_record;
123
124             next_edl_record->action = action;
125
126             if (action == EDL_MUTE)
127             {
128                 next_edl_record->length_sec = 0;
129                 next_edl_record->start_sec = start;
130                 next_edl_record->stop_sec = start;
131
132                 next_edl_record = edl_alloc_new(next_edl_record);
133
134                 next_edl_record->action = action;
135                 next_edl_record->length_sec = 0;
136                 next_edl_record->start_sec = stop;
137                 next_edl_record->stop_sec = stop;
138             } else
139             {
140                 next_edl_record->length_sec = stop - start;
141                 next_edl_record->start_sec = start;
142                 next_edl_record->stop_sec = stop;
143             }
144
145             record_count++;
146         }
147
148         fclose(fd);
149     }
150
151     if (edl_records)
152         mp_msg(MSGT_CPLAYER, MSGL_INFO, MSGTR_EdlRecordsNo, record_count);
153     else
154         mp_msg(MSGT_CPLAYER, MSGL_INFO, MSGTR_EdlQueueEmpty);
155
156     return edl_records;
157 }