* Add code to pace sending a stream when it is being sent from a file.
[ffmpeg.git] / libav / utils.c
1 /*
2  * Various utilities for ffmpeg system
3  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library 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 GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19 #include "avformat.h"
20 #include "tick.h"
21 #include <ctype.h>
22 #ifndef CONFIG_WIN32
23 #include <unistd.h>
24 #include <fcntl.h>
25 #include <sys/time.h>
26 #else
27 #define strcasecmp _stricmp
28 #include <sys/types.h>
29 #include <sys/timeb.h>
30 #endif
31 #include <time.h>
32
33 #ifndef HAVE_STRPTIME
34 #include "strptime.h"
35 #endif
36
37 AVInputFormat *first_iformat;
38 AVOutputFormat *first_oformat;
39
40 void av_register_input_format(AVInputFormat *format)
41 {
42     AVInputFormat **p;
43     p = &first_iformat;
44     while (*p != NULL) p = &(*p)->next;
45     *p = format;
46     format->next = NULL;
47 }
48
49 void av_register_output_format(AVOutputFormat *format)
50 {
51     AVOutputFormat **p;
52     p = &first_oformat;
53     while (*p != NULL) p = &(*p)->next;
54     *p = format;
55     format->next = NULL;
56 }
57
58 int match_ext(const char *filename, const char *extensions)
59 {
60     const char *ext, *p;
61     char ext1[32], *q;
62
63     ext = strrchr(filename, '.');
64     if (ext) {
65         ext++;
66         p = extensions;
67         for(;;) {
68             q = ext1;
69             while (*p != '\0' && *p != ',') 
70                 *q++ = *p++;
71             *q = '\0';
72             if (!strcasecmp(ext1, ext)) 
73                 return 1;
74             if (*p == '\0') 
75                 break;
76             p++;
77         }
78     }
79     return 0;
80 }
81
82 AVOutputFormat *guess_format(const char *short_name, const char *filename, 
83                              const char *mime_type)
84 {
85     AVOutputFormat *fmt, *fmt_found;
86     int score_max, score;
87
88     /* find the proper file type */
89     fmt_found = NULL;
90     score_max = 0;
91     fmt = first_oformat;
92     while (fmt != NULL) {
93         score = 0;
94         if (fmt->name && short_name && !strcmp(fmt->name, short_name))
95             score += 100;
96         if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
97             score += 10;
98         if (filename && fmt->extensions && 
99             match_ext(filename, fmt->extensions)) {
100             score += 5;
101         }
102         if (score > score_max) {
103             score_max = score;
104             fmt_found = fmt;
105         }
106         fmt = fmt->next;
107     }
108     return fmt_found;
109 }   
110
111 AVOutputFormat *guess_stream_format(const char *short_name, const char *filename, 
112                              const char *mime_type)
113 {
114     AVOutputFormat *fmt = guess_format(short_name, filename, mime_type);
115
116     if (fmt) {
117         AVOutputFormat *stream_fmt;
118         char stream_format_name[64];
119
120         snprintf(stream_format_name, sizeof(stream_format_name), "%s_stream", fmt->name);
121         stream_fmt = guess_format(stream_format_name, NULL, NULL);
122
123         if (stream_fmt)
124             fmt = stream_fmt;
125     }
126
127     return fmt;
128 }
129
130 AVInputFormat *av_find_input_format(const char *short_name)
131 {
132     AVInputFormat *fmt;
133     for(fmt = first_iformat; fmt != NULL; fmt = fmt->next) {
134         if (!strcmp(fmt->name, short_name))
135             return fmt;
136     }
137     return NULL;
138 }
139
140 /* memory handling */
141
142 /**
143  * Allocate the payload of a packet and intialized its fields to default values.
144  *
145  * @param pkt packet
146  * @param size wanted payload size
147  * @return 0 if OK. AVERROR_xxx otherwise.
148  */
149 int av_new_packet(AVPacket *pkt, int size)
150 {
151     pkt->data = av_malloc(size);
152     if (!pkt->data)
153         return AVERROR_NOMEM;
154     pkt->size = size;
155     /* sane state */
156     pkt->pts = 0;
157     pkt->stream_index = 0;
158     pkt->flags = 0;
159     return 0;
160 }
161
162 /**
163  * Free a packet
164  *
165  * @param pkt packet to free
166  */
167 void av_free_packet(AVPacket *pkt)
168 {
169     av_freep(&pkt->data);
170     /* fail safe */
171     pkt->size = 0;
172 }
173
174 /* fifo handling */
175
176 int fifo_init(FifoBuffer *f, int size)
177 {
178     f->buffer = av_malloc(size);
179     if (!f->buffer)
180         return -1;
181     f->end = f->buffer + size;
182     f->wptr = f->rptr = f->buffer;
183     return 0;
184 }
185
186 void fifo_free(FifoBuffer *f)
187 {
188     av_free(f->buffer);
189 }
190
191 int fifo_size(FifoBuffer *f, UINT8 *rptr)
192 {
193     int size;
194
195     if (f->wptr >= rptr) {
196         size = f->wptr - rptr;
197     } else {
198         size = (f->end - rptr) + (f->wptr - f->buffer);
199     }
200     return size;
201 }
202
203 /* get data from the fifo (return -1 if not enough data) */
204 int fifo_read(FifoBuffer *f, UINT8 *buf, int buf_size, UINT8 **rptr_ptr)
205 {
206     UINT8 *rptr = *rptr_ptr;
207     int size, len;
208
209     if (f->wptr >= rptr) {
210         size = f->wptr - rptr;
211     } else {
212         size = (f->end - rptr) + (f->wptr - f->buffer);
213     }
214     
215     if (size < buf_size)
216         return -1;
217     while (buf_size > 0) {
218         len = f->end - rptr;
219         if (len > buf_size)
220             len = buf_size;
221         memcpy(buf, rptr, len);
222         buf += len;
223         rptr += len;
224         if (rptr >= f->end)
225             rptr = f->buffer;
226         buf_size -= len;
227     }
228     *rptr_ptr = rptr;
229     return 0;
230 }
231
232 void fifo_write(FifoBuffer *f, UINT8 *buf, int size, UINT8 **wptr_ptr)
233 {
234     int len;
235     UINT8 *wptr;
236     wptr = *wptr_ptr;
237     while (size > 0) {
238         len = f->end - wptr;
239         if (len > size)
240             len = size;
241         memcpy(wptr, buf, len);
242         wptr += len;
243         if (wptr >= f->end)
244             wptr = f->buffer;
245         buf += len;
246         size -= len;
247     }
248     *wptr_ptr = wptr;
249 }
250
251 int filename_number_test(const char *filename)
252 {
253     char buf[1024];
254     return get_frame_filename(buf, sizeof(buf), filename, 1);
255 }
256
257 /* guess file format */
258 AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened)
259 {
260     AVInputFormat *fmt1, *fmt;
261     int score, score_max;
262
263     fmt = NULL;
264     score_max = 0;
265     for(fmt1 = first_iformat; fmt1 != NULL; fmt1 = fmt1->next) {
266         if (!is_opened && !(fmt1->flags & AVFMT_NOFILE))
267             continue;
268         score = 0;
269         if (fmt1->read_probe) {
270             score = fmt1->read_probe(pd);
271         } else if (fmt1->extensions) {
272             if (match_ext(pd->filename, fmt1->extensions)) {
273                 score = 50;
274             }
275         } 
276         if (score > score_max) {
277             score_max = score;
278             fmt = fmt1;
279         }
280     }
281     return fmt;
282 }
283
284 /************************************************************/
285 /* input media file */
286
287 #define PROBE_BUF_SIZE 2048
288
289 /**
290  * Open a media file as input. The codec are not opened. Only the file
291  * header (if present) is read.
292  *
293  * @param ic_ptr the opened media file handle is put here
294  * @param filename filename to open.
295  * @param fmt if non NULL, force the file format to use
296  * @param buf_size optional buffer size (zero if default is OK)
297  * @param ap additionnal parameters needed when opening the file (NULL if default)
298  * @return 0 if OK. AVERROR_xxx otherwise.
299  */
300 int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, 
301                        AVInputFormat *fmt,
302                        int buf_size,
303                        AVFormatParameters *ap)
304 {
305     AVFormatContext *ic = NULL;
306     int err;
307     char buf[PROBE_BUF_SIZE];
308     AVProbeData probe_data, *pd = &probe_data;
309
310     ic = av_mallocz(sizeof(AVFormatContext));
311     if (!ic) {
312         err = AVERROR_NOMEM;
313         goto fail;
314     }
315     pstrcpy(ic->filename, sizeof(ic->filename), filename);
316     pd->filename = ic->filename;
317     pd->buf = buf;
318     pd->buf_size = 0;
319
320     if (!fmt) {
321         /* guess format if no file can be opened  */
322         fmt = av_probe_input_format(pd, 0);
323     }
324
325     /* if no file needed do not try to open one */
326     if (!fmt || !(fmt->flags & AVFMT_NOFILE)) {
327         if (url_fopen(&ic->pb, filename, URL_RDONLY) < 0) {
328             err = AVERROR_IO;
329             goto fail;
330         }
331         if (buf_size > 0) {
332             url_setbufsize(&ic->pb, buf_size);
333         }
334         /* read probe data */
335         pd->buf_size = get_buffer(&ic->pb, buf, PROBE_BUF_SIZE);
336         url_fseek(&ic->pb, 0, SEEK_SET);
337     }
338     
339     /* guess file format */
340     if (!fmt) {
341         fmt = av_probe_input_format(pd, 1);
342     }
343
344     /* if still no format found, error */
345     if (!fmt) {
346         err = AVERROR_NOFMT;
347         goto fail;
348     }
349         
350     ic->iformat = fmt;
351
352     /* allocate private data */
353     ic->priv_data = av_mallocz(fmt->priv_data_size);
354     if (!ic->priv_data) {
355         err = AVERROR_NOMEM;
356         goto fail;
357     }
358
359     /* check filename in case of an image number is expected */
360     if (ic->iformat->flags & AVFMT_NEEDNUMBER) {
361         if (filename_number_test(ic->filename) < 0) { 
362             err = AVERROR_NUMEXPECTED;
363             goto fail1;
364         }
365     }
366     
367     err = ic->iformat->read_header(ic, ap);
368     if (err < 0)
369         goto fail1;
370     *ic_ptr = ic;
371     return 0;
372  fail1:
373     if (!(fmt->flags & AVFMT_NOFILE)) {
374         url_fclose(&ic->pb);
375     }
376  fail:
377     if (ic) {
378         av_freep(&ic->priv_data);
379     }
380     av_free(ic);
381     *ic_ptr = NULL;
382     return err;
383 }
384
385 /**
386  * Read a packet from a media file
387  * @param s media file handle
388  * @param pkt is filled 
389  * @return 0 if OK. AVERROR_xxx if error.
390  */
391 int av_read_packet(AVFormatContext *s, AVPacket *pkt)
392 {
393     AVPacketList *pktl;
394
395     pktl = s->packet_buffer;
396     if (pktl) {
397         /* read packet from packet buffer, if there is data */
398         *pkt = pktl->pkt;
399         s->packet_buffer = pktl->next;
400         av_free(pktl);
401         return 0;
402     } else {
403         return s->iformat->read_packet(s, pkt);
404     }
405 }
406
407 /* state for codec information */
408 #define CSTATE_NOTFOUND    0
409 #define CSTATE_DECODING    1
410 #define CSTATE_FOUND       2
411
412 static int has_codec_parameters(AVCodecContext *enc)
413 {
414     int val;
415     switch(enc->codec_type) {
416     case CODEC_TYPE_AUDIO:
417         val = enc->sample_rate;
418         break;
419     case CODEC_TYPE_VIDEO:
420         val = enc->width;
421         break;
422     default:
423         val = 1;
424         break;
425     }
426     return (val != 0);
427 }
428
429 /**
430  * Read the beginning of a media file to get stream information. This
431  * is useful for file formats with no headers such as MPEG. This
432  * function also compute the real frame rate in case of mpeg2 repeat
433  * frame mode.
434  *
435  * @param ic media file handle
436  * @return >=0 if OK. AVERROR_xxx if error.  
437  */
438 int av_find_stream_info(AVFormatContext *ic)
439 {
440     int i, count, ret, got_picture, size, read_size;
441     AVCodec *codec;
442     AVStream *st;
443     AVPacket *pkt;
444     AVPicture picture;
445     AVPacketList *pktl=NULL, **ppktl;
446     short samples[AVCODEC_MAX_AUDIO_FRAME_SIZE / 2];
447     UINT8 *ptr;
448     int min_read_size, max_read_size;
449
450     /* typical mpeg ts rate is 40 Mbits. DVD rate is about 10
451        Mbits. We read at most 0.1 second of file to find all streams */
452
453     /* XXX: base it on stream bitrate when possible */
454     if (ic->iformat == &mpegts_demux) {
455         /* maximum number of bytes we accept to read to find all the streams
456            in a file */
457         min_read_size = 3000000;
458     } else {
459         min_read_size = 125000;
460     }
461     /* max read size is 2 seconds of video max */
462     max_read_size = min_read_size * 20;
463
464     /* set initial codec state */
465     for(i=0;i<ic->nb_streams;i++) {
466         st = ic->streams[i];
467         if (has_codec_parameters(&st->codec))
468             st->codec_info_state = CSTATE_FOUND;
469         else
470             st->codec_info_state = CSTATE_NOTFOUND;
471         st->codec_info_nb_repeat_frames = 0;
472         st->codec_info_nb_real_frames = 0;
473     }
474
475     count = 0;
476     read_size = 0;
477     ppktl = &ic->packet_buffer;
478     for(;;) {
479         /* check if one codec still needs to be handled */
480         for(i=0;i<ic->nb_streams;i++) {
481             st = ic->streams[i];
482             if (st->codec_info_state != CSTATE_FOUND)
483                 break;
484         }
485         if (i == ic->nb_streams) {
486             /* NOTE: if the format has no header, then we need to read
487                some packets to get most of the streams, so we cannot
488                stop here */
489             if (!(ic->iformat->flags & AVFMT_NOHEADER) ||
490                 read_size >= min_read_size) {
491                 /* if we found the info for all the codecs, we can stop */
492                 ret = count;
493                 break;
494             }
495         } else {
496             /* we did not get all the codec info, but we read too much data */
497             if (read_size >= max_read_size) {
498                 ret = count;
499                 break;
500             }
501         }
502
503         pktl = av_mallocz(sizeof(AVPacketList));
504         if (!pktl) {
505             ret = AVERROR_NOMEM;
506             break;
507         }
508
509         /* add the packet in the buffered packet list */
510         *ppktl = pktl;
511         ppktl = &pktl->next;
512
513         /* NOTE: a new stream can be added there if no header in file
514            (AVFMT_NOHEADER) */
515         pkt = &pktl->pkt;
516         if (ic->iformat->read_packet(ic, pkt) < 0) {
517             /* EOF or error */
518             ret = -1; /* we could not have all the codec parameters before EOF */
519             if ((ic->iformat->flags & AVFMT_NOHEADER) &&
520                 i == ic->nb_streams)
521                 ret = 0;
522             break;
523         }
524         read_size += pkt->size;
525
526         /* open new codecs */
527         for(i=0;i<ic->nb_streams;i++) {
528             st = ic->streams[i];
529             if (st->codec_info_state == CSTATE_NOTFOUND) {
530                 /* set to found in case of error */
531                 st->codec_info_state = CSTATE_FOUND; 
532                 codec = avcodec_find_decoder(st->codec.codec_id);
533                 if (codec) {
534                     ret = avcodec_open(&st->codec, codec);
535                     if (ret >= 0)
536                         st->codec_info_state = CSTATE_DECODING;
537                 }
538             }
539         }
540
541         st = ic->streams[pkt->stream_index];
542         if (st->codec_info_state == CSTATE_DECODING) {
543             /* decode the data and update codec parameters */
544             ptr = pkt->data;
545             size = pkt->size;
546             while (size > 0) {
547                 switch(st->codec.codec_type) {
548                 case CODEC_TYPE_VIDEO:
549                     ret = avcodec_decode_video(&st->codec, &picture, 
550                                                &got_picture, ptr, size);
551                     break;
552                 case CODEC_TYPE_AUDIO:
553                     ret = avcodec_decode_audio(&st->codec, samples, 
554                                                &got_picture, ptr, size);
555                     break;
556                 default:
557                     ret = -1;
558                     break;
559                 }
560                 if (ret < 0) {
561                     /* if error, simply ignore because another packet
562                        may be OK */
563                     break;
564                 }
565                 if (got_picture) {
566                     /* we got the parameters - now we can stop
567                        examining this stream */
568                     /* XXX: add a codec info so that we can decide if
569                        the codec can repeat frames */
570                     if (st->codec.codec_id == CODEC_ID_MPEG1VIDEO && 
571                         ic->iformat != &mpegts_demux &&
572                         st->codec.sub_id == 2) {
573                         /* for mpeg2 video, we want to know the real
574                            frame rate, so we decode 40 frames. In mpeg
575                            TS case we do not do it because it would be
576                            too long */
577                         st->codec_info_nb_real_frames++;
578                         st->codec_info_nb_repeat_frames += st->codec.repeat_pict;
579 #if 0
580                         /* XXX: testing */
581                         if ((st->codec_info_nb_real_frames % 24) == 23) {
582                             st->codec_info_nb_repeat_frames += 2;
583                         }
584 #endif
585                         /* stop after 40 frames */
586                         if (st->codec_info_nb_real_frames >= 40) {
587                             st->r_frame_rate = (st->codec.frame_rate * 
588                                                 st->codec_info_nb_real_frames) /
589                                 (st->codec_info_nb_real_frames + 
590                                  (st->codec_info_nb_repeat_frames >> 1));
591                             goto close_codec;
592                         }
593                     } else {
594                     close_codec:
595                         st->codec_info_state = CSTATE_FOUND;
596                         avcodec_close(&st->codec);
597                         break;
598                     }
599                 }
600                 ptr += ret;
601                 size -= ret;
602             }
603         }
604         count++;
605     }
606
607     /* close each codec if there are opened */
608     for(i=0;i<ic->nb_streams;i++) {
609         st = ic->streams[i];
610         if (st->codec_info_state == CSTATE_DECODING)
611             avcodec_close(&st->codec);
612     }
613
614     /* set real frame rate info */
615     for(i=0;i<ic->nb_streams;i++) {
616         st = ic->streams[i];
617         if (st->codec.codec_type == CODEC_TYPE_VIDEO) {
618             if (!st->r_frame_rate)
619                 st->r_frame_rate = st->codec.frame_rate;
620         }
621     }
622
623     return ret;
624 }
625
626 /**
627  * Close a media file (but not its codecs)
628  *
629  * @param s media file handle
630  */
631 void av_close_input_file(AVFormatContext *s)
632 {
633     int i;
634
635     if (s->iformat->read_close)
636         s->iformat->read_close(s);
637     for(i=0;i<s->nb_streams;i++) {
638         av_free(s->streams[i]);
639     }
640     if (s->packet_buffer) {
641         AVPacketList *p, *p1;
642         p = s->packet_buffer;
643         while (p != NULL) {
644             p1 = p->next;
645             av_free_packet(&p->pkt);
646             av_free(p);
647             p = p1;
648         }
649         s->packet_buffer = NULL;
650     }
651     if (!(s->iformat->flags & AVFMT_NOFILE)) {
652         url_fclose(&s->pb);
653     }
654     av_freep(&s->priv_data);
655     av_free(s);
656 }
657
658 /**
659  * Add a new stream to a media file. Can only be called in the
660  * read_header function. If the flag AVFMT_NOHEADER is in the format
661  * description, then new streams can be added in read_packet too.
662  *
663  *
664  * @param s media file handle
665  * @param id file format dependent stream id
666  */
667 AVStream *av_new_stream(AVFormatContext *s, int id)
668 {
669     AVStream *st;
670
671     if (s->nb_streams >= MAX_STREAMS)
672         return NULL;
673
674     st = av_mallocz(sizeof(AVStream));
675     if (!st)
676         return NULL;
677     st->index = s->nb_streams;
678     st->id = id;
679     s->streams[s->nb_streams++] = st;
680     return st;
681 }
682
683 /************************************************************/
684 /* output media file */
685
686 /**
687  * allocate the stream private data and write the stream header to an
688  * output media file
689  *
690  * @param s media file handle
691  * @return 0 if OK. AVERROR_xxx if error.  
692  */
693 int av_write_header(AVFormatContext *s)
694 {
695     s->priv_data = av_mallocz(s->oformat->priv_data_size);
696     if (!s->priv_data)
697         return AVERROR_NOMEM;
698     return s->oformat->write_header(s);
699 }
700
701 /**
702  * write a packet to an output media file
703  *
704  * @param s media file handle
705  * @param pkt packet to write
706  * @param force_pts XXX: need to suppress that
707  */
708 int av_write_packet(AVFormatContext *s, AVPacket *pkt, int force_pts)
709 {
710     /* XXX: currently, an emulation because internal API must change */
711     return s->oformat->write_packet(s, pkt->stream_index, pkt->data, pkt->size, force_pts);
712 }
713
714 /**
715  * write the stream trailer to an output media file and and free the
716  * file private data.
717  *
718  * @param s media file handle
719  * @return 0 if OK. AVERROR_xxx if error.  */
720 int av_write_trailer(AVFormatContext *s)
721 {
722     int ret;
723     ret = s->oformat->write_trailer(s);
724     av_freep(&s->priv_data);
725     return ret;
726 }
727
728 /* "user interface" functions */
729
730 void dump_format(AVFormatContext *ic,
731                  int index, 
732                  const char *url,
733                  int is_output)
734 {
735     int i, flags;
736     char buf[256];
737
738     fprintf(stderr, "%s #%d, %s, %s '%s':\n", 
739             is_output ? "Output" : "Input",
740             index, 
741             is_output ? ic->oformat->name : ic->iformat->name, 
742             is_output ? "to" : "from", url);
743     for(i=0;i<ic->nb_streams;i++) {
744         AVStream *st = ic->streams[i];
745         avcodec_string(buf, sizeof(buf), &st->codec, is_output);
746         fprintf(stderr, "  Stream #%d.%d", index, i);
747         /* the pid is an important information, so we display it */
748         /* XXX: add a generic system */
749         if (is_output)
750             flags = ic->oformat->flags;
751         else
752             flags = ic->iformat->flags;
753         if (flags & AVFMT_SHOW_IDS) {
754             fprintf(stderr, "[0x%x]", st->id);
755         }
756         fprintf(stderr, ": %s\n", buf);
757     }
758 }
759
760 typedef struct {
761     const char *str;
762     int width, height;
763 } SizeEntry;
764
765 static SizeEntry sizes[] = {
766     { "sqcif", 128, 96 },
767     { "qcif", 176, 144 },
768     { "cif", 352, 288 },
769     { "4cif", 704, 576 },
770 };
771     
772 int parse_image_size(int *width_ptr, int *height_ptr, const char *str)
773 {
774     int i;
775     int n = sizeof(sizes) / sizeof(SizeEntry);
776     const char *p;
777     int frame_width = 0, frame_height = 0;
778
779     for(i=0;i<n;i++) {
780         if (!strcmp(sizes[i].str, str)) {
781             frame_width = sizes[i].width;
782             frame_height = sizes[i].height;
783             break;
784         }
785     }
786     if (i == n) {
787         p = str;
788         frame_width = strtol(p, (char **)&p, 10);
789         if (*p)
790             p++;
791         frame_height = strtol(p, (char **)&p, 10);
792     }
793     if (frame_width <= 0 || frame_height <= 0)
794         return -1;
795     *width_ptr = frame_width;
796     *height_ptr = frame_height;
797     return 0;
798 }
799
800 INT64 av_gettime(void)
801 {
802 #ifdef CONFIG_WIN32
803     struct _timeb tb;
804     _ftime(&tb);
805     return ((INT64)tb.time * INT64_C(1000) + (INT64)tb.millitm) * INT64_C(1000);
806 #else
807     struct timeval tv;
808     gettimeofday(&tv,NULL);
809     return (INT64)tv.tv_sec * 1000000 + tv.tv_usec;
810 #endif
811 }
812
813 static time_t mktimegm(struct tm *tm)
814 {
815     time_t t;
816
817     int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
818
819     if (m < 3) {
820         m += 12;
821         y--;
822     }
823
824     t = 86400 * 
825         (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469);
826
827     t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
828
829     return t;
830 }
831
832 /* syntax:
833  *  [YYYY-MM-DD]{T| }HH[:MM[:SS[.m...]]][Z] . 
834  *  [YYYYMMDD]{T| }HH[MM[SS[.m...]]][Z] . 
835  * Time is localtime unless Z is suffixed to the end. In this case GMT
836  * Return the date in micro seconds since 1970 */
837 INT64 parse_date(const char *datestr, int duration)
838 {
839     const char *p;
840     INT64 t;
841     struct tm dt;
842     int i;
843     static const char *date_fmt[] = {
844         "%Y-%m-%d",
845         "%Y%m%d",
846     };
847     static const char *time_fmt[] = {
848         "%H:%M:%S",
849         "%H%M%S",
850     };
851     const char *q;
852     int is_utc;
853     char lastch;
854     time_t now = time(0);
855
856     lastch = datestr[strlen(datestr)-1];
857
858     is_utc = (lastch == 'z' || lastch == 'Z');
859
860     memset(&dt, 0, sizeof(dt));
861
862     p = datestr;
863     q = 0;
864
865     if (!duration) {
866         for (i = 0; i < sizeof(date_fmt) / sizeof(date_fmt[0]); i++) {
867             q = strptime(p, date_fmt[i], &dt);
868             if (q) {
869                 break;
870             }
871         }
872
873         if (!q) {
874             if (is_utc) {
875                 dt = *gmtime(&now);
876             } else {
877                 dt = *localtime(&now);
878             }
879             dt.tm_hour = dt.tm_min = dt.tm_sec = 0;
880         } else {
881             p = q;
882         }
883
884         if (*p == 'T' || *p == 't' || *p == ' ')
885             p++;
886     }
887
888     for (i = 0; i < sizeof(time_fmt) / sizeof(time_fmt[0]); i++) {
889         q = strptime(p, time_fmt[i], &dt);
890         if (q) {
891             break;
892         }
893     }
894
895     /* Now we have all the fields that we can get */
896     if (!q) {
897         if (duration)
898             return 0;
899         else
900             return now * INT64_C(1000000);
901     }
902
903     if (duration) {
904         t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
905     } else {
906         dt.tm_isdst = -1;       /* unknown */
907         if (is_utc) {
908             t = mktimegm(&dt);
909         } else {
910             t = mktime(&dt);
911         }
912     }
913
914     t *= 1000000;
915
916     if (*q == '.') {
917         int val, n;
918         q++;
919         for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
920             if (!isdigit(*q)) 
921                 break;
922             val += n * (*q - '0');
923         }
924         t += val;
925     }
926     return t;
927 }
928
929 /* syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done. Return
930    1 if found */
931 int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
932 {
933     const char *p;
934     char tag[128], *q;
935
936     p = info;
937     if (*p == '?')
938         p++;
939     for(;;) {
940         q = tag;
941         while (*p != '\0' && *p != '=' && *p != '&') {
942             if ((q - tag) < sizeof(tag) - 1)
943                 *q++ = *p;
944             p++;
945         }
946         *q = '\0';
947         q = arg;
948         if (*p == '=') {
949             p++;
950             while (*p != '&' && *p != '\0') {
951                 if ((q - arg) < arg_size - 1) {
952                     if (*p == '+')
953                         *q++ = ' ';
954                     else
955                         *q++ = *p;
956                 }
957                 p++;
958             }
959             *q = '\0';
960         }
961         if (!strcmp(tag, tag1)) 
962             return 1;
963         if (*p != '&')
964             break;
965         p++;
966     }
967     return 0;
968 }
969
970 /* Return in 'buf' the path with '%d' replaced by number. Also handles
971    the '%0nd' format where 'n' is the total number of digits and
972    '%%'. Return 0 if OK, and -1 if format error */
973 int get_frame_filename(char *buf, int buf_size,
974                        const char *path, int number)
975 {
976     const char *p;
977     char *q, buf1[20];
978     int nd, len, c, percentd_found;
979
980     q = buf;
981     p = path;
982     percentd_found = 0;
983     for(;;) {
984         c = *p++;
985         if (c == '\0')
986             break;
987         if (c == '%') {
988             nd = 0;
989             while (*p >= '0' && *p <= '9') {
990                 nd = nd * 10 + *p++ - '0';
991             }
992             c = *p++;
993             switch(c) {
994             case '%':
995                 goto addchar;
996             case 'd':
997                 if (percentd_found)
998                     goto fail;
999                 percentd_found = 1;
1000                 snprintf(buf1, sizeof(buf1), "%0*d", nd, number);
1001                 len = strlen(buf1);
1002                 if ((q - buf + len) > buf_size - 1)
1003                     goto fail;
1004                 memcpy(q, buf1, len);
1005                 q += len;
1006                 break;
1007             default:
1008                 goto fail;
1009             }
1010         } else {
1011         addchar:
1012             if ((q - buf) < buf_size - 1)
1013                 *q++ = c;
1014         }
1015     }
1016     if (!percentd_found)
1017         goto fail;
1018     *q = '\0';
1019     return 0;
1020  fail:
1021     *q = '\0';
1022     return -1;
1023 }
1024
1025 static int gcd(INT64 a, INT64 b)
1026 {
1027     INT64 c;
1028
1029     while (1) {
1030         c = a % b;
1031         if (c == 0)
1032             return b;
1033         a = b;
1034         b = c;
1035     }
1036 }
1037
1038 void ticker_init(Ticker *tick, INT64 inrate, INT64 outrate)
1039 {
1040     int g;
1041
1042     g = gcd(inrate, outrate);
1043     inrate /= g;
1044     outrate /= g;
1045
1046     tick->value = -outrate/2;
1047
1048     tick->inrate = inrate;
1049     tick->outrate = outrate;
1050     tick->div = tick->outrate / tick->inrate;
1051     tick->mod = tick->outrate % tick->inrate;
1052 }
1053
1054 /**
1055  *
1056  * Print on stdout a nice hexa dump of a buffer
1057  * @param buf buffer
1058  * @param size buffer size
1059  */
1060 void av_hex_dump(UINT8 *buf, int size)
1061 {
1062     int len, i, j, c;
1063
1064     for(i=0;i<size;i+=16) {
1065         len = size - i;
1066         if (len > 16)
1067             len = 16;
1068         printf("%08x ", i);
1069         for(j=0;j<16;j++) {
1070             if (j < len)
1071                 printf(" %02x", buf[i+j]);
1072             else
1073                 printf("   ");
1074         }
1075         printf(" ");
1076         for(j=0;j<len;j++) {
1077             c = buf[i+j];
1078             if (c < ' ' || c > '~')
1079                 c = '.';
1080             printf("%c", c);
1081         }
1082         printf("\n");
1083     }
1084 }
1085
1086 void url_split(char *proto, int proto_size,
1087                char *hostname, int hostname_size,
1088                int *port_ptr,
1089                char *path, int path_size,
1090                const char *url)
1091 {
1092     const char *p;
1093     char *q;
1094     int port;
1095
1096     port = -1;
1097
1098     p = url;
1099     q = proto;
1100     while (*p != ':' && *p != '\0') {
1101         if ((q - proto) < proto_size - 1)
1102             *q++ = *p;
1103         p++;
1104     }
1105     if (proto_size > 0)
1106         *q = '\0';
1107     if (*p == '\0') {
1108         if (proto_size > 0)
1109             proto[0] = '\0';
1110         if (hostname_size > 0)
1111             hostname[0] = '\0';
1112         p = url;
1113     } else {
1114         p++;
1115         if (*p == '/')
1116             p++;
1117         if (*p == '/')
1118             p++;
1119         q = hostname;
1120         while (*p != ':' && *p != '/' && *p != '?' && *p != '\0') {
1121             if ((q - hostname) < hostname_size - 1)
1122                 *q++ = *p;
1123             p++;
1124         }
1125         if (hostname_size > 0)
1126             *q = '\0';
1127         if (*p == ':') {
1128             p++;
1129             port = strtoul(p, (char **)&p, 10);
1130         }
1131     }
1132     if (port_ptr)
1133         *port_ptr = port;
1134     pstrcpy(path, path_size, p);
1135 }
1136