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