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