changed av_open_input_file() prototype
[libav.git] / libav / utils.c
1 /*
2 * Various utilities for ffmpeg system
3 * Copyright (c) 2000,2001 Gerard Lantau
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 #include "avformat.h"
20 #ifndef CONFIG_WIN32
21 #include <unistd.h>
22 #include <fcntl.h>
23 #include <sys/time.h>
24 #include <time.h>
25 #else
26 #define strcasecmp _stricmp
27 #include <sys/types.h>
28 #include <sys/timeb.h>
29 #endif
30
31 AVFormat *first_format;
32
33 void register_avformat(AVFormat *format)
34 {
35 AVFormat **p;
36 p = &first_format;
37 while (*p != NULL) p = &(*p)->next;
38 *p = format;
39 format->next = NULL;
40 }
41
42 int match_ext(const char *filename, const char *extensions)
43 {
44 const char *ext, *p;
45 char ext1[32], *q;
46
47 ext = strrchr(filename, '.');
48 if (ext) {
49 ext++;
50 p = extensions;
51 for(;;) {
52 q = ext1;
53 while (*p != '\0' && *p != ',')
54 *q++ = *p++;
55 *q = '\0';
56 if (!strcasecmp(ext1, ext))
57 return 1;
58 if (*p == '\0')
59 break;
60 p++;
61 }
62 }
63 return 0;
64 }
65
66 AVFormat *guess_format(const char *short_name, const char *filename, const char *mime_type)
67 {
68 AVFormat *fmt, *fmt_found;
69 int score_max, score;
70
71 /* find the proper file type */
72 fmt_found = NULL;
73 score_max = 0;
74 fmt = first_format;
75 while (fmt != NULL) {
76 score = 0;
77 if (fmt->name && short_name && !strcmp(fmt->name, short_name))
78 score += 100;
79 if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
80 score += 10;
81 if (filename && fmt->extensions &&
82 match_ext(filename, fmt->extensions)) {
83 score += 5;
84 }
85 if (score > score_max) {
86 score_max = score;
87 fmt_found = fmt;
88 }
89 fmt = fmt->next;
90 }
91 return fmt_found;
92 }
93
94 /* return TRUE if val is a prefix of str. If it returns TRUE, ptr is
95 set to the next character in 'str' after the prefix */
96 int strstart(const char *str, const char *val, const char **ptr)
97 {
98 const char *p, *q;
99 p = str;
100 q = val;
101 while (*q != '\0') {
102 if (*p != *q)
103 return 0;
104 p++;
105 q++;
106 }
107 if (ptr)
108 *ptr = p;
109 return 1;
110 }
111
112 void nstrcpy(char *buf, int buf_size, const char *str)
113 {
114 int c;
115 char *q = buf;
116
117 for(;;) {
118 c = *str++;
119 if (c == 0 || q >= buf + buf_size - 1)
120 break;
121 *q++ = c;
122 }
123 *q = '\0';
124 }
125
126 void register_all(void)
127 {
128 avcodec_init();
129 avcodec_register_all();
130
131 register_avformat(&mp2_format);
132 register_avformat(&ac3_format);
133 register_avformat(&mpeg_mux_format);
134 register_avformat(&mpeg1video_format);
135 register_avformat(&mjpeg_format);
136 register_avformat(&h263_format);
137 register_avformat(&rm_format);
138 register_avformat(&asf_format);
139 register_avformat(&avi_format);
140 register_avformat(&mpjpeg_format);
141 register_avformat(&jpeg_format);
142 register_avformat(&single_jpeg_format);
143 register_avformat(&swf_format);
144 register_avformat(&wav_format);
145 register_avformat(&pcm_s16le_format);
146 register_avformat(&pcm_s16be_format);
147 register_avformat(&pcm_u16le_format);
148 register_avformat(&pcm_u16be_format);
149 register_avformat(&pcm_s8_format);
150 register_avformat(&pcm_u8_format);
151 register_avformat(&pcm_mulaw_format);
152 register_avformat(&pcm_alaw_format);
153 register_avformat(&rawvideo_format);
154 #ifndef CONFIG_WIN32
155 register_avformat(&ffm_format);
156 #endif
157 register_avformat(&pgm_format);
158 register_avformat(&ppm_format);
159 register_avformat(&pgmyuv_format);
160 register_avformat(&imgyuv_format);
161 register_avformat(&pgmpipe_format);
162 register_avformat(&pgmyuvpipe_format);
163 register_avformat(&ppmpipe_format);
164 #ifdef CONFIG_GRAB
165 register_avformat(&video_grab_device_format);
166 register_avformat(&audio_device_format);
167 #endif
168
169 /* file protocols */
170 register_protocol(&file_protocol);
171 register_protocol(&pipe_protocol);
172 #ifndef CONFIG_WIN32
173 register_protocol(&udp_protocol);
174 register_protocol(&http_protocol);
175 #endif
176 }
177
178 /* memory handling */
179
180 int av_new_packet(AVPacket *pkt, int size)
181 {
182 pkt->data = malloc(size);
183 if (!pkt->data)
184 return -ENOMEM;
185 pkt->size = size;
186 /* sane state */
187 pkt->pts = 0;
188 pkt->stream_index = 0;
189 pkt->flags = 0;
190 return 0;
191 }
192
193 void av_free_packet(AVPacket *pkt)
194 {
195 free(pkt->data);
196 /* fail safe */
197 pkt->data = NULL;
198 pkt->size = 0;
199 }
200
201 /* fifo handling */
202
203 int fifo_init(FifoBuffer *f, int size)
204 {
205 f->buffer = malloc(size);
206 if (!f->buffer)
207 return -1;
208 f->end = f->buffer + size;
209 f->wptr = f->rptr = f->buffer;
210 return 0;
211 }
212
213 void fifo_free(FifoBuffer *f)
214 {
215 free(f->buffer);
216 }
217
218 int fifo_size(FifoBuffer *f, UINT8 *rptr)
219 {
220 int size;
221
222 if (f->wptr >= rptr) {
223 size = f->wptr - rptr;
224 } else {
225 size = (f->end - rptr) + (f->wptr - f->buffer);
226 }
227 return size;
228 }
229
230 /* get data from the fifo (return -1 if not enough data) */
231 int fifo_read(FifoBuffer *f, UINT8 *buf, int buf_size, UINT8 **rptr_ptr)
232 {
233 UINT8 *rptr = *rptr_ptr;
234 int size, len;
235
236 if (f->wptr >= rptr) {
237 size = f->wptr - rptr;
238 } else {
239 size = (f->end - rptr) + (f->wptr - f->buffer);
240 }
241
242 if (size < buf_size)
243 return -1;
244 while (buf_size > 0) {
245 len = f->end - rptr;
246 if (len > buf_size)
247 len = buf_size;
248 memcpy(buf, rptr, len);
249 buf += len;
250 rptr += len;
251 if (rptr >= f->end)
252 rptr = f->buffer;
253 buf_size -= len;
254 }
255 *rptr_ptr = rptr;
256 return 0;
257 }
258
259 void fifo_write(FifoBuffer *f, UINT8 *buf, int size, UINT8 **wptr_ptr)
260 {
261 int len;
262 UINT8 *wptr;
263 wptr = *wptr_ptr;
264 while (size > 0) {
265 len = f->end - wptr;
266 if (len > size)
267 len = size;
268 memcpy(wptr, buf, len);
269 wptr += len;
270 if (wptr >= f->end)
271 wptr = f->buffer;
272 buf += len;
273 size -= len;
274 }
275 *wptr_ptr = wptr;
276 }
277
278 /* media file handling.
279 'filename' is the filename to open.
280 'format_name' is used to force the file format (NULL if auto guess).
281 'buf_size' is the optional buffer size (zero if default is OK).
282 'ap' are additionnal parameters needed when opening the file (NULL if default).
283 */
284
285 AVFormatContext *av_open_input_file(const char *filename,
286 const char *format_name,
287 int buf_size,
288 AVFormatParameters *ap)
289 {
290 AVFormat *fmt;
291 AVFormatContext *ic = NULL;
292 int err;
293
294 ic = av_mallocz(sizeof(AVFormatContext));
295 if (!ic)
296 goto fail;
297
298 /* find format */
299 if (format_name != NULL) {
300 fmt = guess_format(format_name, NULL, NULL);
301 } else {
302 fmt = guess_format(NULL, filename, NULL);
303 }
304 if (!fmt || !fmt->read_header) {
305 return NULL;
306 }
307 ic->format = fmt;
308
309 /* if no file needed do not try to open one */
310 if (!(fmt->flags & AVFMT_NOFILE)) {
311 if (url_fopen(&ic->pb, filename, URL_RDONLY) < 0)
312 goto fail;
313 if (buf_size > 0) {
314 url_setbufsize(&ic->pb, buf_size);
315 }
316 }
317
318 err = ic->format->read_header(ic, ap);
319 if (err < 0) {
320 if (!(fmt->flags & AVFMT_NOFILE)) {
321 url_fclose(&ic->pb);
322 }
323 goto fail;
324 }
325
326 return ic;
327
328 fail:
329 if (ic)
330 free(ic);
331 return NULL;
332 }
333
334 int av_read_packet(AVFormatContext *s, AVPacket *pkt)
335 {
336 AVPacketList *pktl;
337
338 pktl = s->packet_buffer;
339 if (pktl) {
340 /* read packet from packet buffer, if there is data */
341 *pkt = pktl->pkt;
342 s->packet_buffer = pktl->next;
343 free(pktl);
344 return 0;
345 } else {
346 return s->format->read_packet(s, pkt);
347 }
348 }
349
350 void av_close_input_file(AVFormatContext *s)
351 {
352 int i;
353
354 if (s->format->read_close)
355 s->format->read_close(s);
356 for(i=0;i<s->nb_streams;i++) {
357 free(s->streams[i]);
358 }
359 if (s->packet_buffer) {
360 AVPacketList *p, *p1;
361 p = s->packet_buffer;
362 while (p != NULL) {
363 p1 = p->next;
364 av_free_packet(&p->pkt);
365 free(p);
366 p = p1;
367 }
368 s->packet_buffer = NULL;
369 }
370 if (!(s->format->flags & AVFMT_NOFILE)) {
371 url_fclose(&s->pb);
372 }
373 free(s);
374 }
375
376
377 int av_write_packet(AVFormatContext *s, AVPacket *pkt)
378 {
379 /* XXX: currently, an emulation because internal API must change */
380 return s->format->write_packet(s, pkt->stream_index, pkt->data, pkt->size);
381 }
382
383 /* "user interface" functions */
384
385 void dump_format(AVFormatContext *ic,
386 int index,
387 const char *url,
388 int is_output)
389 {
390 int i;
391 char buf[256];
392
393 fprintf(stderr, "%s #%d, %s, %s '%s':\n",
394 is_output ? "Output" : "Input",
395 index, ic->format->name,
396 is_output ? "to" : "from", url);
397 for(i=0;i<ic->nb_streams;i++) {
398 AVStream *st = ic->streams[i];
399 avcodec_string(buf, sizeof(buf), &st->codec, is_output);
400 fprintf(stderr, " Stream #%d.%d: %s\n", index, i, buf);
401 }
402 }
403
404 typedef struct {
405 const char *str;
406 int width, height;
407 } SizeEntry;
408
409 static SizeEntry sizes[] = {
410 { "sqcif", 128, 96 },
411 { "qcif", 176, 144 },
412 { "cif", 352, 288 },
413 { "4cif", 704, 576 },
414 };
415
416 int parse_image_size(int *width_ptr, int *height_ptr, const char *str)
417 {
418 int i;
419 int n = sizeof(sizes) / sizeof(SizeEntry);
420 const char *p;
421 int frame_width = 0, frame_height = 0;
422
423 for(i=0;i<n;i++) {
424 if (!strcmp(sizes[i].str, str)) {
425 frame_width = sizes[i].width;
426 frame_height = sizes[i].height;
427 break;
428 }
429 }
430 if (i == n) {
431 p = str;
432 frame_width = strtol(p, (char **)&p, 10);
433 if (*p)
434 p++;
435 frame_height = strtol(p, (char **)&p, 10);
436 }
437 if (frame_width <= 0 || frame_height <= 0)
438 return -1;
439 *width_ptr = frame_width;
440 *height_ptr = frame_height;
441 return 0;
442 }
443
444 INT64 gettime(void)
445 {
446 #ifdef CONFIG_WIN32
447 struct _timeb tb;
448 _ftime(&tb);
449 return ((INT64)tb.time * INT64_C(1000) + (INT64)tb.millitm) * INT64_C(1000);
450 #else
451 struct timeval tv;
452 gettimeofday(&tv,NULL);
453 return (INT64)tv.tv_sec * 1000000 + tv.tv_usec;
454 #endif
455 }
456
457 /* syntax: [YYYY-MM-DD ][[HH:]MM:]SS[.m...] . Return the date in micro seconds since 1970 */
458 INT64 parse_date(const char *datestr, int duration)
459 {
460 const char *p;
461 INT64 t;
462 int sec;
463
464 p = datestr;
465 if (!duration) {
466 static const UINT8 months[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
467 int year, month, day, i;
468
469 if (strlen(p) >= 5 && p[4] == '-') {
470
471 year = strtol(p, (char **)&p, 10);
472 if (*p)
473 p++;
474 month = strtol(p, (char **)&p, 10) - 1;
475 if (*p)
476 p++;
477 day = strtol(p, (char **)&p, 10) - 1;
478 if (*p)
479 p++;
480 day += (year - 1970) * 365;
481 /* if >= March, take February of current year into account too */
482 if (month >= 2)
483 year++;
484 for(i=1970;i<year;i++) {
485 if ((i % 100) == 0) {
486 if ((i % 400) == 0) day++;
487 } else if ((i % 4) == 0) {
488 day++;
489 }
490 }
491 for(i=0;i<month;i++)
492 day += months[i];
493 } else {
494 day = (time(NULL) / (3600 * 24));
495 }
496 t = day * (3600 * 24);
497 } else {
498 t = 0;
499 }
500
501 sec = 0;
502 for(;;) {
503 int val;
504 val = strtol(p, (char **)&p, 10);
505 sec = sec * 60 + val;
506 if (*p != ':')
507 break;
508 p++;
509 }
510 t = (t + sec) * 1000000;
511 if (*p == '.') {
512 int val, n;
513 p++;
514 n = strlen(p);
515 if (n > 6)
516 n = 6;
517 val = strtol(p, NULL, 10);
518 while (n < 6) {
519 val = val * 10;
520 n++;
521 }
522 t += val;
523 }
524 return t;
525 }
526
527 /* syntax: '?tag1=val1&tag2=val2...'. No URL decoding is done. Return
528 1 if found */
529 int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
530 {
531 const char *p;
532 char tag[128], *q;
533
534 p = info;
535 if (*p == '?')
536 p++;
537 for(;;) {
538 q = tag;
539 while (*p != '\0' && *p != '=' && *p != '&') {
540 if ((q - tag) < sizeof(tag) - 1)
541 *q++ = *p;
542 p++;
543 }
544 *q = '\0';
545 q = arg;
546 if (*p == '=') {
547 p++;
548 while (*p != '&' && *p != '\0') {
549 if ((q - arg) < arg_size - 1)
550 *q++ = *p;
551 p++;
552 }
553 *q = '\0';
554 }
555 if (!strcmp(tag, tag1))
556 return 1;
557 if (*p != '&')
558 break;
559 }
560 return 0;
561 }
562
563 /* Return in 'buf' the path with '%d' replaced by number. Also handles
564 the '%0nd' format where 'n' is the total number of digits and
565 '%%'. Return 0 if OK, and -1 if format error */
566 int get_frame_filename(char *buf, int buf_size,
567 const char *path, int number)
568 {
569 const char *p;
570 char *q, buf1[20];
571 int nd, len, c, percentd_found;
572
573 q = buf;
574 p = path;
575 percentd_found = 0;
576 for(;;) {
577 c = *p++;
578 if (c == '\0')
579 break;
580 if (c == '%') {
581 nd = 0;
582 while (*p >= '0' && *p <= '9') {
583 nd = nd * 10 + *p++ - '0';
584 }
585 c = *p++;
586 switch(c) {
587 case '%':
588 goto addchar;
589 case 'd':
590 if (percentd_found)
591 goto fail;
592 percentd_found = 1;
593 snprintf(buf1, sizeof(buf1), "%0*d", nd, number);
594 len = strlen(buf1);
595 if ((q - buf + len) > buf_size - 1)
596 goto fail;
597 memcpy(q, buf1, len);
598 q += len;
599 break;
600 default:
601 goto fail;
602 }
603 } else {
604 addchar:
605 if ((q - buf) < buf_size - 1)
606 *q++ = c;
607 }
608 }
609 if (!percentd_found)
610 goto fail;
611 *q = '\0';
612 return 0;
613 fail:
614 *q = '\0';
615 return -1;
616 }
617
618