Mercurial > mplayer.hg
annotate stream/realrtsp/rmff.c @ 34102:dd8320c2a2cb
libmpcodec: add vf_lavfi.
This filter wraps a complete libavfilter filter graph.
As the API of libavfilter is not completely stable yet, the filter is not
enabled by default, so as not to let mplayer unbuildable.
Some strange behaviours may appear due to the very different model of buffer
allocation between mplayer and lavfi.
author | cigaes |
---|---|
date | Wed, 12 Oct 2011 11:38:10 +0000 |
parents | 8fa2f43cb760 |
children |
rev | line source |
---|---|
9922 | 1 /* |
2 * This file was ported to MPlayer from xine CVS rmff.c,v 1.3 2002/12/24 01:30:22 | |
3 */ | |
4 | |
5 /* | |
6 * Copyright (C) 2002 the xine project | |
7 * | |
8 * This file is part of xine, a free video player. | |
9 * | |
10 * xine is free software; you can redistribute it and/or modify | |
11 * it under the terms of the GNU General Public License as published by | |
12 * the Free Software Foundation; either version 2 of the License, or | |
13 * (at your option) any later version. | |
14 * | |
15 * xine is distributed in the hope that it will be useful, | |
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 * GNU General Public License for more details. | |
19 * | |
20 * You should have received a copy of the GNU General Public License | |
21 * along with this program; if not, write to the Free Software | |
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | |
23 * | |
24 * | |
25 * functions for real media file format | |
26 * adopted from joschkas real tools | |
27 */ | |
28 | |
29 #include "rmff.h" | |
30 #include "xbuffer.h" | |
20711 | 31 #include "mp_msg.h" |
22376
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
32 #include "libavutil/intreadwrite.h" |
9922 | 33 |
34 /* | |
35 #define LOG | |
36 */ | |
37 | |
38 static void hexdump (const char *buf, int length) { | |
39 | |
40 int i; | |
41 | |
42 printf ("rmff: ascii>"); | |
43 for (i = 0; i < length; i++) { | |
44 unsigned char c = buf[i]; | |
45 | |
46 if ((c >= 32) && (c <= 128)) | |
47 printf ("%c", c); | |
48 else | |
49 printf ("."); | |
50 } | |
51 printf ("\n"); | |
52 | |
53 printf ("rmff: hexdump> "); | |
54 for (i = 0; i < length; i++) { | |
55 unsigned char c = buf[i]; | |
56 | |
57 printf ("%02x", c); | |
58 | |
59 if ((i % 16) == 15) | |
60 printf ("\nrmff: "); | |
61 | |
62 if ((i % 2) == 1) | |
63 printf (" "); | |
64 | |
65 } | |
66 printf ("\n"); | |
67 } | |
68 | |
69 /* | |
70 * writes header data to a buffer | |
71 */ | |
72 | |
22803 | 73 static int rmff_dump_fileheader(rmff_fileheader_t *fileheader, char *buffer, int bufsize) { |
74 | |
75 if (!fileheader) return 0; | |
9922 | 76 |
22803 | 77 if (bufsize < RMFF_FILEHEADER_SIZE) |
78 return -1; | |
79 | |
22783 | 80 AV_WB32(buffer, fileheader->object_id); |
81 AV_WB32(buffer+4, fileheader->size); | |
82 AV_WB16(buffer+8, fileheader->object_version); | |
83 AV_WB32(buffer+10, fileheader->file_version); | |
84 AV_WB32(buffer+14, fileheader->num_headers); | |
22803 | 85 |
86 return RMFF_FILEHEADER_SIZE; | |
9922 | 87 } |
88 | |
22803 | 89 static int rmff_dump_prop(rmff_prop_t *prop, char *buffer, int bufsize) { |
90 | |
91 if (!prop) return 0; | |
9922 | 92 |
22803 | 93 if (bufsize < RMFF_PROPHEADER_SIZE) |
94 return -1; | |
95 | |
22783 | 96 AV_WB32(buffer, prop->object_id); |
97 AV_WB32(buffer+4, prop->size); | |
98 AV_WB16(buffer+8, prop->object_version); | |
99 AV_WB32(buffer+10, prop->max_bit_rate); | |
100 AV_WB32(buffer+14, prop->avg_bit_rate); | |
101 AV_WB32(buffer+18, prop->max_packet_size); | |
102 AV_WB32(buffer+22, prop->avg_packet_size); | |
103 AV_WB32(buffer+26, prop->num_packets); | |
104 AV_WB32(buffer+30, prop->duration); | |
105 AV_WB32(buffer+34, prop->preroll); | |
106 AV_WB32(buffer+38, prop->index_offset); | |
107 AV_WB32(buffer+42, prop->data_offset); | |
108 AV_WB16(buffer+46, prop->num_streams); | |
109 AV_WB16(buffer+48, prop->flags); | |
22803 | 110 |
111 return RMFF_PROPHEADER_SIZE; | |
9922 | 112 } |
113 | |
22803 | 114 static int rmff_dump_mdpr(rmff_mdpr_t *mdpr, char *buffer, int bufsize) { |
9922 | 115 |
116 int s1, s2, s3; | |
117 | |
22803 | 118 if (!mdpr) return 0; |
119 | |
120 if (!(bufsize > RMFF_MDPRHEADER_SIZE + mdpr->stream_name_size + mdpr->mime_type_size && | |
121 (unsigned)bufsize - RMFF_MDPRHEADER_SIZE - mdpr->stream_name_size - mdpr->mime_type_size > mdpr->type_specific_len)) | |
122 return -1; | |
123 | |
22783 | 124 AV_WB32(buffer, mdpr->object_id); |
125 AV_WB32(buffer+4, mdpr->size); | |
126 AV_WB16(buffer+8, mdpr->object_version); | |
127 AV_WB16(buffer+10, mdpr->stream_number); | |
128 AV_WB32(buffer+12, mdpr->max_bit_rate); | |
129 AV_WB32(buffer+16, mdpr->avg_bit_rate); | |
130 AV_WB32(buffer+20, mdpr->max_packet_size); | |
131 AV_WB32(buffer+24, mdpr->avg_packet_size); | |
132 AV_WB32(buffer+28, mdpr->start_time); | |
133 AV_WB32(buffer+32, mdpr->preroll); | |
134 AV_WB32(buffer+36, mdpr->duration); | |
9922 | 135 |
22783 | 136 buffer[40] = mdpr->stream_name_size; |
9922 | 137 s1=mdpr->stream_name_size; |
138 memcpy(&buffer[41], mdpr->stream_name, s1); | |
139 | |
22783 | 140 buffer[41+s1] = mdpr->mime_type_size; |
9922 | 141 s2=mdpr->mime_type_size; |
142 memcpy(&buffer[42+s1], mdpr->mime_type, s2); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
143 |
22783 | 144 AV_WB32(buffer+42+s1+s2, mdpr->type_specific_len); |
9922 | 145 s3=mdpr->type_specific_len; |
146 memcpy(&buffer[46+s1+s2], mdpr->type_specific_data, s3); | |
22803 | 147 |
148 return RMFF_MDPRHEADER_SIZE + s1 + s2 + s3; | |
9922 | 149 } |
150 | |
22803 | 151 static int rmff_dump_cont(rmff_cont_t *cont, char *buffer, int bufsize) { |
9922 | 152 |
153 int p; | |
154 | |
22803 | 155 if (!cont) return 0; |
156 | |
157 if (bufsize < RMFF_CONTHEADER_SIZE + cont->title_len + cont->author_len + | |
158 cont->copyright_len + cont->comment_len) | |
159 return -1; | |
160 | |
22783 | 161 AV_WB32(buffer, cont->object_id); |
162 AV_WB32(buffer+4, cont->size); | |
163 AV_WB16(buffer+8, cont->object_version); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
164 |
22783 | 165 AV_WB16(buffer+10, cont->title_len); |
9922 | 166 memcpy(&buffer[12], cont->title, cont->title_len); |
167 p=12+cont->title_len; | |
168 | |
22783 | 169 AV_WB16(buffer+p, cont->author_len); |
9922 | 170 memcpy(&buffer[p+2], cont->author, cont->author_len); |
171 p+=2+cont->author_len; | |
172 | |
22783 | 173 AV_WB16(buffer+p, cont->copyright_len); |
9922 | 174 memcpy(&buffer[p+2], cont->copyright, cont->copyright_len); |
175 p+=2+cont->copyright_len; | |
176 | |
22783 | 177 AV_WB16(buffer+p, cont->comment_len); |
9922 | 178 memcpy(&buffer[p+2], cont->comment, cont->comment_len); |
22803 | 179 |
180 return RMFF_CONTHEADER_SIZE + cont->title_len + cont->author_len + | |
181 cont->copyright_len + cont->comment_len; | |
9922 | 182 } |
183 | |
22803 | 184 static int rmff_dump_dataheader(rmff_data_t *data, char *buffer, int bufsize) { |
185 | |
186 if (!data) return 0; | |
9922 | 187 |
22803 | 188 if (bufsize < RMFF_DATAHEADER_SIZE) |
189 return -1; | |
190 | |
22783 | 191 AV_WB32(buffer, data->object_id); |
192 AV_WB32(buffer+4, data->size); | |
193 AV_WB16(buffer+8, data->object_version); | |
194 AV_WB32(buffer+10, data->num_packets); | |
195 AV_WB32(buffer+14, data->next_data_header); | |
22803 | 196 |
197 return RMFF_DATAHEADER_SIZE; | |
9922 | 198 } |
199 | |
200 int rmff_dump_header(rmff_header_t *h, char *buffer, int max) { | |
201 | |
22803 | 202 int written=0, size; |
9922 | 203 rmff_mdpr_t **stream=h->streams; |
204 | |
22803 | 205 if ((size=rmff_dump_fileheader(h->fileheader, &buffer[written], max)) < 0) |
206 goto buftoosmall; | |
207 written+=size; | |
208 max -= size; | |
209 if ((size=rmff_dump_prop(h->prop, &buffer[written], max)) < 0) | |
210 goto buftoosmall; | |
211 written+=size; | |
212 max -= size; | |
213 if ((size=rmff_dump_cont(h->cont, &buffer[written], max)) < 0) | |
214 goto buftoosmall; | |
215 written+=size; | |
216 max -= size; | |
9922 | 217 if (stream) |
218 { | |
219 while(*stream) | |
220 { | |
22803 | 221 if ((size=rmff_dump_mdpr(*stream, &buffer[written], max)) < 0) |
222 goto buftoosmall; | |
223 written+=size; | |
224 max -= size; | |
9922 | 225 stream++; |
226 } | |
227 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
228 |
22803 | 229 if ((size=rmff_dump_dataheader(h->data, &buffer[written], max)) < 0) |
230 goto buftoosmall; | |
231 written+=size; | |
9922 | 232 |
233 return written; | |
22803 | 234 |
235 buftoosmall: | |
236 mp_msg(MSGT_STREAM, MSGL_ERR, "rmff_dumpheader: buffer too small, aborting. Please report\n"); | |
237 return -1; | |
9922 | 238 } |
239 | |
240 void rmff_dump_pheader(rmff_pheader_t *h, char *data) { | |
241 | |
242 data[0]=(h->object_version>>8) & 0xff; | |
243 data[1]=h->object_version & 0xff; | |
244 data[2]=(h->length>>8) & 0xff; | |
245 data[3]=h->length & 0xff; | |
246 data[4]=(h->stream_number>>8) & 0xff; | |
247 data[5]=h->stream_number & 0xff; | |
248 data[6]=(h->timestamp>>24) & 0xff; | |
249 data[7]=(h->timestamp>>16) & 0xff; | |
250 data[8]=(h->timestamp>>8) & 0xff; | |
251 data[9]=h->timestamp & 0xff; | |
252 data[10]=h->reserved; | |
253 data[11]=h->flags; | |
254 } | |
255 | |
256 static rmff_fileheader_t *rmff_scan_fileheader(const char *data) { | |
257 | |
258 rmff_fileheader_t *fileheader=malloc(sizeof(rmff_fileheader_t)); | |
259 | |
22376
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
260 fileheader->object_id=AV_RB32(data); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
261 fileheader->size=AV_RB32(&data[4]); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
262 fileheader->object_version=AV_RB16(&data[8]); |
9922 | 263 if (fileheader->object_version != 0) |
264 { | |
20711 | 265 mp_msg(MSGT_STREAM, MSGL_WARN, "warning: unknown object version in .RMF: 0x%04x\n", |
9922 | 266 fileheader->object_version); |
267 } | |
22376
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
268 fileheader->file_version=AV_RB32(&data[10]); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
269 fileheader->num_headers=AV_RB32(&data[14]); |
9922 | 270 |
271 return fileheader; | |
272 } | |
273 | |
274 static rmff_prop_t *rmff_scan_prop(const char *data) { | |
275 | |
276 rmff_prop_t *prop=malloc(sizeof(rmff_prop_t)); | |
277 | |
22376
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
278 prop->object_id=AV_RB32(data); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
279 prop->size=AV_RB32(&data[4]); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
280 prop->object_version=AV_RB16(&data[8]); |
9922 | 281 if (prop->object_version != 0) |
282 { | |
20711 | 283 mp_msg(MSGT_STREAM, MSGL_WARN, "warning: unknown object version in PROP: 0x%04x\n", |
9922 | 284 prop->object_version); |
285 } | |
22376
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
286 prop->max_bit_rate=AV_RB32(&data[10]); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
287 prop->avg_bit_rate=AV_RB32(&data[14]); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
288 prop->max_packet_size=AV_RB32(&data[18]); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
289 prop->avg_packet_size=AV_RB32(&data[22]); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
290 prop->num_packets=AV_RB32(&data[26]); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
291 prop->duration=AV_RB32(&data[30]); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
292 prop->preroll=AV_RB32(&data[34]); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
293 prop->index_offset=AV_RB32(&data[38]); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
294 prop->data_offset=AV_RB32(&data[42]); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
295 prop->num_streams=AV_RB16(&data[46]); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
296 prop->flags=AV_RB16(&data[48]); |
9922 | 297 |
298 return prop; | |
299 } | |
300 | |
301 static rmff_mdpr_t *rmff_scan_mdpr(const char *data) { | |
302 | |
303 rmff_mdpr_t *mdpr=malloc(sizeof(rmff_mdpr_t)); | |
304 | |
22376
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
305 mdpr->object_id=AV_RB32(data); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
306 mdpr->size=AV_RB32(&data[4]); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
307 mdpr->object_version=AV_RB16(&data[8]); |
9922 | 308 if (mdpr->object_version != 0) |
309 { | |
20711 | 310 mp_msg(MSGT_STREAM, MSGL_WARN, "warning: unknown object version in MDPR: 0x%04x\n", |
9922 | 311 mdpr->object_version); |
312 } | |
22376
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
313 mdpr->stream_number=AV_RB16(&data[10]); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
314 mdpr->max_bit_rate=AV_RB32(&data[12]); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
315 mdpr->avg_bit_rate=AV_RB32(&data[16]); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
316 mdpr->max_packet_size=AV_RB32(&data[20]); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
317 mdpr->avg_packet_size=AV_RB32(&data[24]); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
318 mdpr->start_time=AV_RB32(&data[28]); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
319 mdpr->preroll=AV_RB32(&data[32]); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
320 mdpr->duration=AV_RB32(&data[36]); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
321 |
9922 | 322 mdpr->stream_name_size=data[40]; |
19074
d385666efa27
removes unused parentheses lefted behind in the r19075 sizeof(char) cleanups, noticed by dalias
reynaldo
parents:
19070
diff
changeset
|
323 mdpr->stream_name=malloc(mdpr->stream_name_size+1); |
9922 | 324 memcpy(mdpr->stream_name, &data[41], mdpr->stream_name_size); |
325 mdpr->stream_name[mdpr->stream_name_size]=0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
326 |
9922 | 327 mdpr->mime_type_size=data[41+mdpr->stream_name_size]; |
19074
d385666efa27
removes unused parentheses lefted behind in the r19075 sizeof(char) cleanups, noticed by dalias
reynaldo
parents:
19070
diff
changeset
|
328 mdpr->mime_type=malloc(mdpr->mime_type_size+1); |
9922 | 329 memcpy(mdpr->mime_type, &data[42+mdpr->stream_name_size], mdpr->mime_type_size); |
330 mdpr->mime_type[mdpr->mime_type_size]=0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
331 |
22376
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
332 mdpr->type_specific_len=AV_RB32(&data[42+mdpr->stream_name_size+mdpr->mime_type_size]); |
19074
d385666efa27
removes unused parentheses lefted behind in the r19075 sizeof(char) cleanups, noticed by dalias
reynaldo
parents:
19070
diff
changeset
|
333 mdpr->type_specific_data=malloc(mdpr->type_specific_len); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
334 memcpy(mdpr->type_specific_data, |
9922 | 335 &data[46+mdpr->stream_name_size+mdpr->mime_type_size], mdpr->type_specific_len); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
336 |
9922 | 337 return mdpr; |
338 } | |
339 | |
340 static rmff_cont_t *rmff_scan_cont(const char *data) { | |
341 | |
342 rmff_cont_t *cont=malloc(sizeof(rmff_cont_t)); | |
343 int pos; | |
344 | |
22376
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
345 cont->object_id=AV_RB32(data); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
346 cont->size=AV_RB32(&data[4]); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
347 cont->object_version=AV_RB16(&data[8]); |
9922 | 348 if (cont->object_version != 0) |
349 { | |
20711 | 350 mp_msg(MSGT_STREAM, MSGL_WARN, "warning: unknown object version in CONT: 0x%04x\n", |
9922 | 351 cont->object_version); |
352 } | |
22376
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
353 cont->title_len=AV_RB16(&data[10]); |
19074
d385666efa27
removes unused parentheses lefted behind in the r19075 sizeof(char) cleanups, noticed by dalias
reynaldo
parents:
19070
diff
changeset
|
354 cont->title=malloc(cont->title_len+1); |
9922 | 355 memcpy(cont->title, &data[12], cont->title_len); |
356 cont->title[cont->title_len]=0; | |
357 pos=cont->title_len+12; | |
22376
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
358 cont->author_len=AV_RB16(&data[pos]); |
19074
d385666efa27
removes unused parentheses lefted behind in the r19075 sizeof(char) cleanups, noticed by dalias
reynaldo
parents:
19070
diff
changeset
|
359 cont->author=malloc(cont->author_len+1); |
9922 | 360 memcpy(cont->author, &data[pos+2], cont->author_len); |
361 cont->author[cont->author_len]=0; | |
362 pos=pos+2+cont->author_len; | |
22376
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
363 cont->copyright_len=AV_RB16(&data[pos]); |
19074
d385666efa27
removes unused parentheses lefted behind in the r19075 sizeof(char) cleanups, noticed by dalias
reynaldo
parents:
19070
diff
changeset
|
364 cont->copyright=malloc(cont->copyright_len+1); |
9922 | 365 memcpy(cont->copyright, &data[pos+2], cont->copyright_len); |
366 cont->copyright[cont->copyright_len]=0; | |
367 pos=pos+2+cont->copyright_len; | |
22376
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
368 cont->comment_len=AV_RB16(&data[pos]); |
19074
d385666efa27
removes unused parentheses lefted behind in the r19075 sizeof(char) cleanups, noticed by dalias
reynaldo
parents:
19070
diff
changeset
|
369 cont->comment=malloc(cont->comment_len+1); |
9922 | 370 memcpy(cont->comment, &data[pos+2], cont->comment_len); |
371 cont->comment[cont->comment_len]=0; | |
372 | |
373 return cont; | |
374 } | |
375 | |
376 static rmff_data_t *rmff_scan_dataheader(const char *data) { | |
377 | |
378 rmff_data_t *dh=malloc(sizeof(rmff_data_t)); | |
379 | |
22376
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
380 dh->object_id=AV_RB32(data); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
381 dh->size=AV_RB32(&data[4]); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
382 dh->object_version=AV_RB16(&data[8]); |
9922 | 383 if (dh->object_version != 0) |
384 { | |
20711 | 385 mp_msg(MSGT_STREAM, MSGL_WARN, "warning: unknown object version in DATA: 0x%04x\n", |
9922 | 386 dh->object_version); |
387 } | |
22376
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
388 dh->num_packets=AV_RB32(&data[10]); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
389 dh->next_data_header=AV_RB32(&data[14]); |
9922 | 390 |
391 return dh; | |
392 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
393 |
9922 | 394 rmff_header_t *rmff_scan_header(const char *data) { |
395 | |
396 rmff_header_t *header=malloc(sizeof(rmff_header_t)); | |
397 rmff_mdpr_t *mdpr=NULL; | |
398 int chunk_size; | |
399 uint32_t chunk_type; | |
400 const char *ptr=data; | |
401 int i; | |
402 | |
403 header->fileheader=NULL; | |
404 header->prop=NULL; | |
405 header->cont=NULL; | |
406 header->data=NULL; | |
407 | |
22376
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
408 chunk_type = AV_RB32(ptr); |
9922 | 409 if (chunk_type != RMF_TAG) |
410 { | |
20711 | 411 mp_msg(MSGT_STREAM, MSGL_ERR, "rmff: not an real media file header (.RMF tag not found).\n"); |
9922 | 412 free(header); |
413 return NULL; | |
414 } | |
415 header->fileheader=rmff_scan_fileheader(ptr); | |
416 ptr += header->fileheader->size; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
417 |
9922 | 418 header->streams=malloc(sizeof(rmff_mdpr_t*)*(header->fileheader->num_headers)); |
419 for (i=0; i<header->fileheader->num_headers; i++) { | |
420 header->streams[i]=NULL; | |
421 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
422 |
9922 | 423 for (i=1; i<header->fileheader->num_headers; i++) { |
22376
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
424 chunk_type = AV_RB32(ptr); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
425 |
9922 | 426 if (ptr[0] == 0) |
427 { | |
20711 | 428 mp_msg(MSGT_STREAM, MSGL_WARN, "rmff: warning: only %d of %d header found.\n", i, header->fileheader->num_headers); |
9922 | 429 break; |
430 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
431 |
9922 | 432 chunk_size=1; |
433 switch (chunk_type) { | |
434 case PROP_TAG: | |
435 header->prop=rmff_scan_prop(ptr); | |
436 chunk_size=header->prop->size; | |
437 break; | |
438 case MDPR_TAG: | |
439 mdpr=rmff_scan_mdpr(ptr); | |
440 chunk_size=mdpr->size; | |
441 header->streams[mdpr->stream_number]=mdpr; | |
442 break; | |
443 case CONT_TAG: | |
444 header->cont=rmff_scan_cont(ptr); | |
445 chunk_size=header->cont->size; | |
446 break; | |
447 case DATA_TAG: | |
448 header->data=rmff_scan_dataheader(ptr); | |
449 chunk_size=34; /* hard coded header size */ | |
450 break; | |
451 default: | |
20711 | 452 mp_msg(MSGT_STREAM, MSGL_WARN, "unknown chunk\n"); |
9922 | 453 hexdump(ptr,10); |
454 chunk_size=1; | |
455 break; | |
456 } | |
457 ptr+=chunk_size; | |
458 } | |
459 | |
460 return header; | |
461 } | |
462 | |
463 rmff_header_t *rmff_scan_header_stream(int fd) { | |
464 | |
465 rmff_header_t *header; | |
466 char *buf=xbuffer_init(1024); | |
467 int index=0; | |
468 uint32_t chunk_type; | |
469 uint32_t chunk_size; | |
470 | |
471 do { | |
472 buf = xbuffer_ensure_size(buf, index+8); | |
10206
35e306346e59
Using recv/send instead read/write for proper MinGW support (it's a 4.2BSD standard). Patch by FloDt <flodt8@yahoo.de>
alex
parents:
9922
diff
changeset
|
473 recv(fd, buf+index, 8, 0); |
22376
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
474 chunk_type=AV_RB32(buf+index); index+=4; |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
475 chunk_size=AV_RB32(buf+index); index+=4; |
9922 | 476 |
477 switch (chunk_type) { | |
478 case DATA_TAG: | |
479 chunk_size=18; | |
480 case MDPR_TAG: | |
481 case CONT_TAG: | |
482 case RMF_TAG: | |
483 case PROP_TAG: | |
484 buf = xbuffer_ensure_size(buf, index+chunk_size-8); | |
10206
35e306346e59
Using recv/send instead read/write for proper MinGW support (it's a 4.2BSD standard). Patch by FloDt <flodt8@yahoo.de>
alex
parents:
9922
diff
changeset
|
485 recv(fd, buf+index, (chunk_size-8), 0); |
9922 | 486 index+=(chunk_size-8); |
487 break; | |
488 default: | |
20711 | 489 mp_msg(MSGT_STREAM, MSGL_WARN, "rmff_scan_header_stream: unknown chunk"); |
9922 | 490 hexdump(buf+index-8, 8); |
491 chunk_type=DATA_TAG; | |
492 } | |
493 } while (chunk_type != DATA_TAG); | |
494 | |
495 header = rmff_scan_header(buf); | |
496 | |
497 xbuffer_free(buf); | |
498 | |
499 return header; | |
500 } | |
501 | |
502 void rmff_scan_pheader(rmff_pheader_t *h, char *data) { | |
503 | |
22376
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
504 h->object_version=AV_RB16(data); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
505 h->length=AV_RB16(data+2); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
506 h->stream_number=AV_RB16(data+4); |
6c1fe779b704
Use libavutil AV_RB/AV_WB macros instead of defining out own variants.
reimar
parents:
20711
diff
changeset
|
507 h->timestamp=AV_RB32(data+6); |
9922 | 508 h->reserved=(uint8_t)data[10]; |
509 h->flags=(uint8_t)data[11]; | |
510 } | |
511 | |
512 rmff_fileheader_t *rmff_new_fileheader(uint32_t num_headers) { | |
513 | |
514 rmff_fileheader_t *fileheader=malloc(sizeof(rmff_fileheader_t)); | |
515 | |
516 fileheader->object_id=RMF_TAG; | |
517 fileheader->size=18; | |
518 fileheader->object_version=0; | |
519 fileheader->file_version=0; | |
520 fileheader->num_headers=num_headers; | |
521 | |
522 return fileheader; | |
523 } | |
524 | |
525 rmff_prop_t *rmff_new_prop ( | |
526 uint32_t max_bit_rate, | |
527 uint32_t avg_bit_rate, | |
528 uint32_t max_packet_size, | |
529 uint32_t avg_packet_size, | |
530 uint32_t num_packets, | |
531 uint32_t duration, | |
532 uint32_t preroll, | |
533 uint32_t index_offset, | |
534 uint32_t data_offset, | |
535 uint16_t num_streams, | |
536 uint16_t flags ) { | |
537 | |
538 rmff_prop_t *prop=malloc(sizeof(rmff_prop_t)); | |
539 | |
540 prop->object_id=PROP_TAG; | |
541 prop->size=50; | |
542 prop->object_version=0; | |
543 | |
544 prop->max_bit_rate=max_bit_rate; | |
545 prop->avg_bit_rate=avg_bit_rate; | |
546 prop->max_packet_size=max_packet_size; | |
547 prop->avg_packet_size=avg_packet_size; | |
548 prop->num_packets=num_packets; | |
549 prop->duration=duration; | |
550 prop->preroll=preroll; | |
551 prop->index_offset=index_offset; | |
552 prop->data_offset=data_offset; | |
553 prop->num_streams=num_streams; | |
554 prop->flags=flags; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
555 |
9922 | 556 return prop; |
557 } | |
558 | |
559 rmff_mdpr_t *rmff_new_mdpr( | |
560 uint16_t stream_number, | |
561 uint32_t max_bit_rate, | |
562 uint32_t avg_bit_rate, | |
563 uint32_t max_packet_size, | |
564 uint32_t avg_packet_size, | |
565 uint32_t start_time, | |
566 uint32_t preroll, | |
567 uint32_t duration, | |
568 const char *stream_name, | |
569 const char *mime_type, | |
570 uint32_t type_specific_len, | |
571 const char *type_specific_data ) { | |
572 | |
29581
ee34a7062df0
Use calloc to ensure rmff_new_mdpr returns fully initialized data.
reimar
parents:
29263
diff
changeset
|
573 rmff_mdpr_t *mdpr=calloc(sizeof(rmff_mdpr_t),1); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
574 |
9922 | 575 mdpr->object_id=MDPR_TAG; |
576 mdpr->object_version=0; | |
577 | |
578 mdpr->stream_number=stream_number; | |
579 mdpr->max_bit_rate=max_bit_rate; | |
580 mdpr->avg_bit_rate=avg_bit_rate; | |
581 mdpr->max_packet_size=max_packet_size; | |
582 mdpr->avg_packet_size=avg_packet_size; | |
583 mdpr->start_time=start_time; | |
584 mdpr->preroll=preroll; | |
585 mdpr->duration=duration; | |
586 mdpr->stream_name_size=0; | |
587 if (stream_name) { | |
588 mdpr->stream_name=strdup(stream_name); | |
589 mdpr->stream_name_size=strlen(stream_name); | |
590 } | |
591 mdpr->mime_type_size=0; | |
592 if (mime_type) { | |
593 mdpr->mime_type=strdup(mime_type); | |
594 mdpr->mime_type_size=strlen(mime_type); | |
595 } | |
596 mdpr->type_specific_len=type_specific_len; | |
19070 | 597 mdpr->type_specific_data=malloc(type_specific_len); |
9922 | 598 memcpy(mdpr->type_specific_data,type_specific_data,type_specific_len); |
599 mdpr->mlti_data=NULL; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
600 |
9922 | 601 mdpr->size=mdpr->stream_name_size+mdpr->mime_type_size+mdpr->type_specific_len+46; |
602 | |
603 return mdpr; | |
604 } | |
605 | |
606 rmff_cont_t *rmff_new_cont(const char *title, const char *author, const char *copyright, const char *comment) { | |
607 | |
608 rmff_cont_t *cont=malloc(sizeof(rmff_cont_t)); | |
609 | |
610 cont->object_id=CONT_TAG; | |
611 cont->object_version=0; | |
612 | |
613 cont->title=NULL; | |
614 cont->author=NULL; | |
615 cont->copyright=NULL; | |
616 cont->comment=NULL; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
617 |
9922 | 618 cont->title_len=0; |
619 cont->author_len=0; | |
620 cont->copyright_len=0; | |
621 cont->comment_len=0; | |
622 | |
623 if (title) { | |
624 cont->title_len=strlen(title); | |
625 cont->title=strdup(title); | |
626 } | |
627 if (author) { | |
628 cont->author_len=strlen(author); | |
629 cont->author=strdup(author); | |
630 } | |
631 if (copyright) { | |
632 cont->copyright_len=strlen(copyright); | |
633 cont->copyright=strdup(copyright); | |
634 } | |
635 if (comment) { | |
636 cont->comment_len=strlen(comment); | |
637 cont->comment=strdup(comment); | |
638 } | |
639 cont->size=cont->title_len+cont->author_len+cont->copyright_len+cont->comment_len+18; | |
640 | |
641 return cont; | |
642 } | |
643 | |
644 rmff_data_t *rmff_new_dataheader(uint32_t num_packets, uint32_t next_data_header) { | |
645 | |
646 rmff_data_t *data=malloc(sizeof(rmff_data_t)); | |
647 | |
648 data->object_id=DATA_TAG; | |
649 data->size=18; | |
650 data->object_version=0; | |
651 data->num_packets=num_packets; | |
652 data->next_data_header=next_data_header; | |
653 | |
654 return data; | |
655 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
656 |
9922 | 657 void rmff_print_header(rmff_header_t *h) { |
658 | |
659 rmff_mdpr_t **stream; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
660 |
9922 | 661 if(!h) { |
662 printf("rmff_print_header: NULL given\n"); | |
663 return; | |
664 } | |
665 if(h->fileheader) | |
666 { | |
667 printf("\nFILE:\n"); | |
668 printf("file version : %d\n", h->fileheader->file_version); | |
669 printf("number of headers : %d\n", h->fileheader->num_headers); | |
670 } | |
671 if(h->cont) | |
672 { | |
673 printf("\nCONTENT:\n"); | |
674 printf("title : %s\n", h->cont->title); | |
675 printf("author : %s\n", h->cont->author); | |
676 printf("copyright : %s\n", h->cont->copyright); | |
677 printf("comment : %s\n", h->cont->comment); | |
678 } | |
679 if(h->prop) | |
680 { | |
681 printf("\nSTREAM PROPERTIES:\n"); | |
682 printf("bit rate (max/avg) : %i/%i\n", h->prop->max_bit_rate, h->prop->avg_bit_rate); | |
683 printf("packet size (max/avg) : %i/%i bytes\n", h->prop->max_packet_size, h->prop->avg_packet_size); | |
684 printf("packets : %i\n", h->prop->num_packets); | |
685 printf("duration : %i ms\n", h->prop->duration); | |
686 printf("pre-buffer : %i ms\n", h->prop->preroll); | |
687 printf("index offset : %i bytes\n", h->prop->index_offset); | |
688 printf("data offset : %i bytes\n", h->prop->data_offset); | |
689 printf("media streams : %i\n", h->prop->num_streams); | |
690 printf("flags : "); | |
691 if (h->prop->flags & PN_SAVE_ENABLED) printf("save_enabled "); | |
692 if (h->prop->flags & PN_PERFECT_PLAY_ENABLED) printf("perfect_play_enabled "); | |
693 if (h->prop->flags & PN_LIVE_BROADCAST) printf("live_broadcast "); | |
694 printf("\n"); | |
695 } | |
696 stream=h->streams; | |
697 if(stream) | |
698 { | |
699 while (*stream) | |
700 { | |
701 printf("\nSTREAM %i:\n", (*stream)->stream_number); | |
702 printf("stream name [mime type] : %s [%s]\n", (*stream)->stream_name, (*stream)->mime_type); | |
703 printf("bit rate (max/avg) : %i/%i\n", (*stream)->max_bit_rate, (*stream)->avg_bit_rate); | |
704 printf("packet size (max/avg) : %i/%i bytes\n", (*stream)->max_packet_size, (*stream)->avg_packet_size); | |
705 printf("start time : %i\n", (*stream)->start_time); | |
706 printf("pre-buffer : %i ms\n", (*stream)->preroll); | |
707 printf("duration : %i ms\n", (*stream)->duration); | |
708 printf("type specific data:\n"); | |
709 hexdump((*stream)->type_specific_data, (*stream)->type_specific_len); | |
710 stream++; | |
711 } | |
712 } | |
713 if(h->data) | |
714 { | |
715 printf("\nDATA:\n"); | |
716 printf("size : %i\n", h->data->size); | |
717 printf("packets : %i\n", h->data->num_packets); | |
718 printf("next DATA : 0x%08x\n", h->data->next_data_header); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
719 } |
9922 | 720 } |
721 | |
722 void rmff_fix_header(rmff_header_t *h) { | |
723 | |
724 int num_headers=0; | |
725 int header_size=0; | |
726 rmff_mdpr_t **streams; | |
727 int num_streams=0; | |
728 | |
729 if (!h) { | |
20711 | 730 mp_msg(MSGT_STREAM, MSGL_ERR, "rmff_fix_header: fatal: no header given.\n"); |
9922 | 731 return; |
732 } | |
733 | |
734 if (!h->streams) { | |
20711 | 735 mp_msg(MSGT_STREAM, MSGL_WARN, "rmff_fix_header: warning: no MDPR chunks\n"); |
9922 | 736 } else |
737 { | |
738 streams=h->streams; | |
739 while (*streams) | |
740 { | |
741 num_streams++; | |
742 num_headers++; | |
743 header_size+=(*streams)->size; | |
744 streams++; | |
745 } | |
746 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
747 |
9922 | 748 if (h->prop) { |
749 if (h->prop->size != 50) | |
750 { | |
751 #ifdef LOG | |
752 printf("rmff_fix_header: correcting prop.size from %i to %i\n", h->prop->size, 50); | |
753 #endif | |
754 h->prop->size=50; | |
755 } | |
756 if (h->prop->num_streams != num_streams) | |
757 { | |
758 #ifdef LOG | |
759 printf("rmff_fix_header: correcting prop.num_streams from %i to %i\n", h->prop->num_streams, num_streams); | |
760 #endif | |
761 h->prop->num_streams=num_streams; | |
762 } | |
763 num_headers++; | |
764 header_size+=50; | |
765 } else | |
20711 | 766 mp_msg(MSGT_STREAM, MSGL_WARN, "rmff_fix_header: warning: no PROP chunk.\n"); |
9922 | 767 |
768 if (h->cont) { | |
769 num_headers++; | |
770 header_size+=h->cont->size; | |
771 } else | |
20711 | 772 mp_msg(MSGT_STREAM, MSGL_WARN, "rmff_fix_header: warning: no CONT chunk.\n"); |
9922 | 773 |
774 if (!h->data) { | |
775 #ifdef LOG | |
776 printf("rmff_fix_header: no DATA chunk, creating one\n"); | |
777 #endif | |
778 h->data=malloc(sizeof(rmff_data_t)); | |
779 h->data->object_id=DATA_TAG; | |
780 h->data->object_version=0; | |
781 h->data->size=34; | |
782 h->data->num_packets=0; | |
783 h->data->next_data_header=0; | |
784 } | |
785 num_headers++; | |
786 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
787 |
9922 | 788 if (!h->fileheader) { |
789 #ifdef LOG | |
790 printf("rmff_fix_header: no fileheader, creating one"); | |
791 #endif | |
792 h->fileheader=malloc(sizeof(rmff_fileheader_t)); | |
793 h->fileheader->object_id=RMF_TAG; | |
794 h->fileheader->size=34; | |
795 h->fileheader->object_version=0; | |
796 h->fileheader->file_version=0; | |
797 h->fileheader->num_headers=num_headers+1; | |
798 } | |
799 header_size+=h->fileheader->size; | |
800 num_headers++; | |
801 | |
802 if(h->fileheader->num_headers != num_headers) { | |
803 #ifdef LOG | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
804 printf("rmff_fix_header: setting num_headers from %i to %i\n", h->fileheader->num_headers, num_headers); |
9922 | 805 #endif |
806 h->fileheader->num_headers=num_headers; | |
807 } | |
808 | |
809 if(h->prop) { | |
810 if (h->prop->data_offset != header_size) { | |
811 #ifdef LOG | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
812 printf("rmff_fix_header: setting prop.data_offset from %i to %i\n", h->prop->data_offset, header_size); |
9922 | 813 #endif |
814 h->prop->data_offset=header_size; | |
815 } | |
816 if (h->prop->num_packets == 0) { | |
817 int p=(int)(h->prop->avg_bit_rate/8.0*(h->prop->duration/1000.0)/h->prop->avg_packet_size); | |
818 #ifdef LOG | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
819 printf("rmff_fix_header: assuming prop.num_packets=%i\n", p); |
9922 | 820 #endif |
821 h->prop->num_packets=p; | |
822 } | |
823 if (h->data->num_packets == 0) { | |
824 #ifdef LOG | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
825 printf("rmff_fix_header: assuming data.num_packets=%i\n", h->prop->num_packets); |
9922 | 826 #endif |
827 h->data->num_packets=h->prop->num_packets; | |
828 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
829 |
9922 | 830 #ifdef LOG |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
831 printf("rmff_fix_header: assuming data.size=%i\n", h->prop->num_packets*h->prop->avg_packet_size); |
9922 | 832 #endif |
833 h->data->size=h->prop->num_packets*h->prop->avg_packet_size; | |
834 } | |
835 } | |
836 | |
837 int rmff_get_header_size(rmff_header_t *h) { | |
838 | |
839 if (!h) return 0; | |
840 if (!h->prop) return -1; | |
841 | |
842 return h->prop->data_offset+18; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22803
diff
changeset
|
843 |
9922 | 844 } |
845 | |
846 void rmff_free_header(rmff_header_t *h) { | |
847 | |
848 if (!h) return; | |
849 | |
32537
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
29581
diff
changeset
|
850 free(h->fileheader); |
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
29581
diff
changeset
|
851 free(h->prop); |
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
29581
diff
changeset
|
852 free(h->data); |
9922 | 853 if (h->cont) |
854 { | |
855 free(h->cont->title); | |
856 free(h->cont->author); | |
857 free(h->cont->copyright); | |
858 free(h->cont->comment); | |
859 free(h->cont); | |
860 } | |
861 if (h->streams) | |
862 { | |
863 rmff_mdpr_t **s=h->streams; | |
864 | |
865 while(*s) { | |
866 free((*s)->stream_name); | |
867 free((*s)->mime_type); | |
868 free((*s)->type_specific_data); | |
869 free(*s); | |
870 s++; | |
871 } | |
872 free(h->streams); | |
873 } | |
874 free(h); | |
875 } |