1 /*******************************************************************************
2 elst.c
3
4 libquicktime - A library for reading and writing quicktime/avi/mp4 files.
5 http://libquicktime.sourceforge.net
6
7 Copyright (C) 2002 Heroine Virtual Ltd.
8 Copyright (C) 2002-2011 Members of the libquicktime project.
9
10 This library is free software; you can redistribute it and/or modify it under
11 the terms of the GNU Lesser General Public License as published by the Free
12 Software Foundation; either version 2.1 of the License, or (at your option)
13 any later version.
14
15 This library is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
18 details.
19
20 You should have received a copy of the GNU Lesser General Public License along
21 with this library; if not, write to the Free Software Foundation, Inc., 51
22 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 *******************************************************************************/
24
25 #include "lqt_private.h"
26 #include <stdlib.h>
27 #include <string.h>
28
quicktime_elst_table_init(quicktime_elst_table_t * table)29 void quicktime_elst_table_init(quicktime_elst_table_t *table)
30 {
31 table->duration = 0;
32 table->time = 0;
33 table->rate = 1;
34 }
35
quicktime_elst_table_delete(quicktime_elst_table_t * table)36 void quicktime_elst_table_delete(quicktime_elst_table_t *table)
37 {
38 }
39
quicktime_read_elst_table(quicktime_t * file,quicktime_elst_table_t * table)40 void quicktime_read_elst_table(quicktime_t *file, quicktime_elst_table_t *table)
41 {
42 table->duration = quicktime_read_int32(file);
43 table->time = quicktime_read_int32(file);
44 table->rate = quicktime_read_fixed32(file);
45 }
46
quicktime_write_elst_table(quicktime_t * file,quicktime_elst_table_t * table)47 void quicktime_write_elst_table(quicktime_t *file, quicktime_elst_table_t *table)
48 {
49 quicktime_write_int32(file, table->duration);
50 quicktime_write_int32(file, table->time);
51 quicktime_write_fixed32(file, table->rate);
52 }
53
quicktime_elst_table_dump(quicktime_elst_table_t * table)54 void quicktime_elst_table_dump(quicktime_elst_table_t *table)
55 {
56 lqt_dump(" edit list table\n");
57 lqt_dump(" duration %d\n", table->duration);
58 lqt_dump(" time %d\n", table->time);
59 lqt_dump(" rate %f\n", table->rate);
60 }
61
quicktime_elst_init(quicktime_elst_t * elst)62 void quicktime_elst_init(quicktime_elst_t *elst)
63 {
64 elst->version = 0;
65 elst->flags = 0;
66 elst->total_entries = 0;
67 elst->table = 0;
68 }
69
quicktime_elst_init_all(quicktime_elst_t * elst)70 void quicktime_elst_init_all(quicktime_elst_t *elst)
71 {
72 if(!elst->total_entries)
73 {
74 elst->total_entries = 1;
75 elst->table = realloc(NULL, sizeof(*elst->table) * elst->total_entries);
76 quicktime_elst_table_init(&elst->table[0]);
77 }
78 }
79
quicktime_elst_fix_counts(quicktime_elst_t * elst,int moov_scale,quicktime_trak_t * trak,int timescale)80 void quicktime_elst_fix_counts(quicktime_elst_t *elst,
81 int moov_scale, quicktime_trak_t * trak, int timescale)
82 {
83 int64_t offset_scaled;
84 offset_scaled = (int64_t)((double)trak->pts_offset / timescale * moov_scale + 0.5);
85 elst->table[0].duration = trak->tkhd.duration;
86
87 if(trak->pts_offset < 0)
88 {
89 elst->table[0].time = -trak->pts_offset;
90 }
91 else if(offset_scaled > 0)
92 {
93 /* Insert empty edit */
94 elst->total_entries++;
95 elst->table = realloc(elst->table, sizeof(*elst->table) * elst->total_entries);
96 memmove(elst->table + 1, elst->table, sizeof(*elst->table) * (elst->total_entries-1));
97 elst->table[0].time = -1;
98 elst->table[0].duration = offset_scaled;
99 elst->table[0].rate = 1.0;
100 }
101 }
102
quicktime_elst_get_pts_offset(quicktime_elst_t * elst,int moov_scale,int timescale)103 int64_t quicktime_elst_get_pts_offset(quicktime_elst_t *elst,
104 int moov_scale, int timescale)
105 {
106 if(elst->total_entries == 1)
107 {
108 if(elst->table[0].time > 0)
109 return - elst->table[0].time;
110 }
111 /* Detect empty edit */
112 else if((elst->total_entries == 2) &&
113 (elst->table[0].time == -1))
114 return (int64_t)((double)elst->table[0].duration / moov_scale * timescale + 0.5);
115 return 0;
116 }
117
quicktime_elst_delete(quicktime_elst_t * elst)118 void quicktime_elst_delete(quicktime_elst_t *elst)
119 {
120 int i;
121 if(elst->total_entries)
122 {
123 for(i = 0; i < elst->total_entries; i++)
124 quicktime_elst_table_delete(&elst->table[i]);
125 free(elst->table);
126 }
127 elst->total_entries = 0;
128 }
129
quicktime_elst_dump(quicktime_elst_t * elst)130 void quicktime_elst_dump(quicktime_elst_t *elst)
131 {
132 int i;
133 lqt_dump(" edit list (elst)\n");
134 lqt_dump(" version %d\n", elst->version);
135 lqt_dump(" flags %ld\n", elst->flags);
136 lqt_dump(" total_entries %ld\n", elst->total_entries);
137
138 for(i = 0; i < elst->total_entries; i++)
139 {
140 quicktime_elst_table_dump(&elst->table[i]);
141 }
142 }
143
quicktime_read_elst(quicktime_t * file,quicktime_elst_t * elst)144 void quicktime_read_elst(quicktime_t *file, quicktime_elst_t *elst)
145 {
146 int i;
147
148 elst->version = quicktime_read_char(file);
149 elst->flags = quicktime_read_int24(file);
150 elst->total_entries = quicktime_read_int32(file);
151 elst->table = (quicktime_elst_table_t*)calloc(1, sizeof(quicktime_elst_table_t) * elst->total_entries);
152 for(i = 0; i < elst->total_entries; i++)
153 {
154 quicktime_elst_table_init(&elst->table[i]);
155 quicktime_read_elst_table(file, &elst->table[i]);
156 }
157 }
158
quicktime_write_elst(quicktime_t * file,quicktime_elst_t * elst)159 void quicktime_write_elst(quicktime_t *file, quicktime_elst_t *elst)
160 {
161 quicktime_atom_t atom;
162 int i;
163 quicktime_atom_write_header(file, &atom, "elst");
164
165 quicktime_write_char(file, elst->version);
166 quicktime_write_int24(file, elst->flags);
167 quicktime_write_int32(file, elst->total_entries);
168 for(i = 0; i < elst->total_entries; i++)
169 quicktime_write_elst_table(file, &elst->table[i]);
170 quicktime_atom_write_footer(file, &atom);
171 }
172