]> git.sesse.net Git - ffmpeg/blob - libav/utils.c
* cleanup statics & const
[ffmpeg] / 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 <ctype.h>
21 #ifndef CONFIG_WIN32
22 #include <unistd.h>
23 #include <fcntl.h>
24 #include <sys/time.h>
25 #else
26 #define strcasecmp _stricmp
27 #include <sys/types.h>
28 #include <sys/timeb.h>
29 #endif
30 #include <time.h>
31
32 #ifndef HAVE_STRPTIME
33 #include "strptime.h"
34 #endif
35
36 AVInputFormat *first_iformat;
37 AVOutputFormat *first_oformat;
38
39 void av_register_input_format(AVInputFormat *format)
40 {
41     AVInputFormat **p;
42     p = &first_iformat;
43     while (*p != NULL) p = &(*p)->next;
44     *p = format;
45     format->next = NULL;
46 }
47
48 void av_register_output_format(AVOutputFormat *format)
49 {
50     AVOutputFormat **p;
51     p = &first_oformat;
52     while (*p != NULL) p = &(*p)->next;
53     *p = format;
54     format->next = NULL;
55 }
56
57 static int match_ext(const char *filename, const char *extensions)
58 {
59     const char *ext, *p;
60     char ext1[32], *q;
61
62     ext = strrchr(filename, '.');
63     if (ext) {
64         ext++;
65         p = extensions;
66         for(;;) {
67             q = ext1;
68             while (*p != '\0' && *p != ',') 
69                 *q++ = *p++;
70             *q = '\0';
71             if (!strcasecmp(ext1, ext)) 
72                 return 1;
73             if (*p == '\0') 
74                 break;
75             p++;
76         }
77     }
78     return 0;
79 }
80
81 AVOutputFormat *guess_format(const char *short_name, const char *filename, 
82                              const char *mime_type)
83 {
84     AVOutputFormat *fmt, *fmt_found;
85     int score_max, score;
86
87     /* find the proper file type */
88     fmt_found = NULL;
89     score_max = 0;
90     fmt = first_oformat;
91     while (fmt != NULL) {
92         score = 0;
93         if (fmt->name && short_name && !strcmp(fmt->name, short_name))
94             score += 100;
95         if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
96             score += 10;
97         if (filename && fmt->extensions && 
98             match_ext(filename, fmt->extensions)) {
99             score += 5;
100         }
101         if (score > score_max) {
102             score_max = score;
103             fmt_found = fmt;
104         }
105         fmt = fmt->next;
106     }
107     return fmt_found;
108 }   
109
110 AVOutputFormat *guess_stream_format(const char *short_name, const char *filename, 
111                              const char *mime_type)
112 {
113     AVOutputFormat *fmt = guess_format(short_name, filename, mime_type);
114
115     if (fmt) {
116         AVOutputFormat *stream_fmt;
117         char stream_format_name[64];
118
119         snprintf(stream_format_name, sizeof(stream_format_name), "%s_stream", fmt->name);
120         stream_fmt = guess_format(stream_format_name, NULL, NULL);
121
122         if (stream_fmt)
123             fmt = stream_fmt;
124     }
125
126     return fmt;
127 }
128
129 AVInputFormat *av_find_input_format(const char *short_name)
130 {
131     AVInputFormat *fmt;
132     for(fmt = first_iformat; fmt != NULL; fmt = fmt->next) {
133         if (!strcmp(fmt->name, short_name))
134             return fmt;
135     }
136     return NULL;
137 }
138
139 /* memory handling */
140
141 /**
142  * Allocate the payload of a packet and intialized its fields to default values.
143  *
144  * @param pkt packet
145  * @param size wanted payload size
146  * @return 0 if OK. AVERROR_xxx otherwise.
147  */
148 int av_new_packet(AVPacket *pkt, int size)
149 {
150     int i;
151     pkt->data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
152     if (!pkt->data)
153         return AVERROR_NOMEM;
154     pkt->size = size;
155     /* sane state */
156     pkt->pts = AV_NOPTS_VALUE;
157     pkt->stream_index = 0;
158     pkt->flags = 0;
159     
160     for(i=0; i<FF_INPUT_BUFFER_PADDING_SIZE; i++)
161         pkt->data[size+i]= 0;
162
163     return 0;
164 }
165
166 /**
167  * Free a packet
168  *
169  * @param pkt packet to free
170  */
171 void av_free_packet(AVPacket *pkt)
172 {
173     av_freep(&pkt->data);
174     /* fail safe */
175     pkt->size = 0;
176 }
177
178 /* fifo handling */
179
180 int fifo_init(FifoBuffer *f, int size)
181 {
182     f->buffer = av_malloc(size);
183     if (!f->buffer)
184         return -1;
185     f->end = f->buffer + size;
186     f->wptr = f->rptr = f->buffer;
187     return 0;
188 }
189
190 void fifo_free(FifoBuffer *f)
191 {
192     av_free(f->buffer);
193 }
194
195 int fifo_size(FifoBuffer *f, UINT8 *rptr)
196 {
197     int size;
198
199     if (f->wptr >= rptr) {
200         size = f->wptr - rptr;
201     } else {
202         size = (f->end - rptr) + (f->wptr - f->buffer);
203     }
204     return size;
205 }
206
207 /* get data from the fifo (return -1 if not enough data) */
208 int fifo_read(FifoBuffer *f, UINT8 *buf, int buf_size, UINT8 **rptr_ptr)
209 {
210     UINT8 *rptr = *rptr_ptr;
211     int size, len;
212
213     if (f->wptr >= rptr) {
214         size = f->wptr - rptr;
215     } else {
216         size = (f->end - rptr) + (f->wptr - f->buffer);
217     }
218     
219     if (size < buf_size)
220         return -1;
221     while (buf_size > 0) {
222         len = f->end - rptr;
223         if (len > buf_size)
224             len = buf_size;
225         memcpy(buf, rptr, len);
226         buf += len;
227         rptr += len;
228         if (rptr >= f->end)
229             rptr = f->buffer;
230         buf_size -= len;
231     }
232     *rptr_ptr = rptr;
233     return 0;
234 }
235
236 void fifo_write(FifoBuffer *f, UINT8 *buf, int size, UINT8 **wptr_ptr)
237 {
238     int len;
239     UINT8 *wptr;
240     wptr = *wptr_ptr;
241     while (size > 0) {
242         len = f->end - wptr;
243         if (len > size)
244             len = size;
245         memcpy(wptr, buf, len);
246         wptr += len;
247         if (wptr >= f->end)
248             wptr = f->buffer;
249         buf += len;
250         size -= len;
251     }
252     *wptr_ptr = wptr;
253 }
254
255 int filename_number_test(const char *filename)
256 {
257     char buf[1024];
258     return get_frame_filename(buf, sizeof(buf), filename, 1);
259 }
260
261 /* guess file format */
262 AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened)
263 {
264     AVInputFormat *fmt1, *fmt;
265     int score, score_max;
266
267     fmt = NULL;
268     score_max = 0;
269     for(fmt1 = first_iformat; fmt1 != NULL; fmt1 = fmt1->next) {
270         if (!is_opened && !(fmt1->flags & AVFMT_NOFILE))
271             continue;
272         score = 0;
273         if (fmt1->read_probe) {
274             score = fmt1->read_probe(pd);
275         } else if (fmt1->extensions) {
276             if (match_ext(pd->filename, fmt1->extensions)) {
277                 score = 50;
278             }
279         } 
280         if (score > score_max) {
281             score_max = score;
282             fmt = fmt1;
283         }
284     }
285     return fmt;
286 }
287
288 /************************************************************/
289 /* input media file */
290
291 #define PROBE_BUF_SIZE 2048
292
293 /**
294  * Open a media file as input. The codec are not opened. Only the file
295  * header (if present) is read.
296  *
297  * @param ic_ptr the opened media file handle is put here
298  * @param filename filename to open.
299  * @param fmt if non NULL, force the file format to use
300  * @param buf_size optional buffer size (zero if default is OK)
301  * @param ap additionnal parameters needed when opening the file (NULL if default)
302  * @return 0 if OK. AVERROR_xxx otherwise.
303  */
304 int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, 
305                        AVInputFormat *fmt,
306                        int buf_size,
307                        AVFormatParameters *ap)
308 {
309     AVFormatContext *ic = NULL;
310     int err;
311     char buf[PROBE_BUF_SIZE];
312     AVProbeData probe_data, *pd = &probe_data;
313
314     ic = av_mallocz(sizeof(AVFormatContext));
315     if (!ic) {
316         err = AVERROR_NOMEM;
317         goto fail;
318     }
319     pstrcpy(ic->filename, sizeof(ic->filename), filename);
320     pd->filename = ic->filename;
321     pd->buf = buf;
322     pd->buf_size = 0;
323
324     if (!fmt) {
325         /* guess format if no file can be opened  */
326         fmt = av_probe_input_format(pd, 0);
327     }
328
329     /* if no file needed do not try to open one */
330     if (!fmt || !(fmt->flags & AVFMT_NOFILE)) {
331         if (url_fopen(&ic->pb, filename, URL_RDONLY) < 0) {
332             err = AVERROR_IO;
333             goto fail;
334         }
335         if (buf_size > 0) {
336             url_setbufsize(&ic->pb, buf_size);
337         }
338         /* read probe data */
339         pd->buf_size = get_buffer(&ic->pb, buf, PROBE_BUF_SIZE);
340         url_fseek(&ic->pb, 0, SEEK_SET);
341     }
342     
343     /* guess file format */
344     if (!fmt) {
345         fmt = av_probe_input_format(pd, 1);
346     }
347
348     /* if still no format found, error */
349     if (!fmt) {
350         err = AVERROR_NOFMT;
351         goto fail;
352     }
353         
354     ic->iformat = fmt;
355
356     /* allocate private data */
357     ic->priv_data = av_mallocz(fmt->priv_data_size);
358     if (!ic->priv_data) {
359         err = AVERROR_NOMEM;
360         goto fail;
361     }
362
363     /* default pts settings is MPEG like */
364     av_set_pts_info(ic, 33, 1, 90000);
365
366     /* check filename in case of an image number is expected */
367     if (ic->iformat->flags & AVFMT_NEEDNUMBER) {
368         if (filename_number_test(ic->filename) < 0) { 
369             err = AVERROR_NUMEXPECTED;
370             goto fail1;
371         }
372     }
373     
374     err = ic->iformat->read_header(ic, ap);
375     if (err < 0)
376         goto fail1;
377     *ic_ptr = ic;
378     return 0;
379  fail1:
380     if (!(fmt->flags & AVFMT_NOFILE)) {
381         url_fclose(&ic->pb);
382     }
383  fail:
384     if (ic) {
385         av_freep(&ic->priv_data);
386     }
387     av_free(ic);
388     *ic_ptr = NULL;
389     return err;
390 }
391
392 /**
393  * Read a packet from a media file
394  * @param s media file handle
395  * @param pkt is filled 
396  * @return 0 if OK. AVERROR_xxx if error.
397  */
398 int av_read_packet(AVFormatContext *s, AVPacket *pkt)
399 {
400     AVPacketList *pktl;
401
402     pktl = s->packet_buffer;
403     if (pktl) {
404         /* read packet from packet buffer, if there is data */
405         *pkt = pktl->pkt;
406         s->packet_buffer = pktl->next;
407         av_free(pktl);
408         return 0;
409     } else {
410         return s->iformat->read_packet(s, pkt);
411     }
412 }
413
414 /* state for codec information */
415 #define CSTATE_NOTFOUND    0
416 #define CSTATE_DECODING    1
417 #define CSTATE_FOUND       2
418
419 static int has_codec_parameters(AVCodecContext *enc)
420 {
421     int val;
422     switch(enc->codec_type) {
423     case CODEC_TYPE_AUDIO:
424         val = enc->sample_rate;
425         break;
426     case CODEC_TYPE_VIDEO:
427         val = enc->width;
428         break;
429     default:
430         val = 1;
431         break;
432     }
433     return (val != 0);
434 }
435
436 /**
437  * Read the beginning of a media file to get stream information. This
438  * is useful for file formats with no headers such as MPEG. This
439  * function also compute the real frame rate in case of mpeg2 repeat
440  * frame mode.
441  *
442  * @param ic media file handle
443  * @return >=0 if OK. AVERROR_xxx if error.  
444  */
445 int av_find_stream_info(AVFormatContext *ic)
446 {
447     int i, count, ret, got_picture, size, read_size;
448     AVCodec *codec;
449     AVStream *st;
450     AVPacket *pkt;
451     AVPicture picture;
452     AVPacketList *pktl=NULL, **ppktl;
453     short samples[AVCODEC_MAX_AUDIO_FRAME_SIZE / 2];
454     UINT8 *ptr;
455     int min_read_size, max_read_size;
456
457     /* typical mpeg ts rate is 40 Mbits. DVD rate is about 10
458        Mbits. We read at most 0.1 second of file to find all streams */
459
460     /* XXX: base it on stream bitrate when possible */
461     if (ic->iformat == &mpegts_demux) {
462         /* maximum number of bytes we accept to read to find all the streams
463            in a file */
464         min_read_size = 3000000;
465     } else {
466         min_read_size = 125000;
467     }
468     /* max read size is 2 seconds of video max */
469     max_read_size = min_read_size * 20;
470
471     /* set initial codec state */
472     for(i=0;i<ic->nb_streams;i++) {
473         st = ic->streams[i];
474         if (has_codec_parameters(&st->codec))
475             st->codec_info_state = CSTATE_FOUND;
476         else
477             st->codec_info_state = CSTATE_NOTFOUND;
478         st->codec_info_nb_repeat_frames = 0;
479         st->codec_info_nb_real_frames = 0;
480     }
481
482     count = 0;
483     read_size = 0;
484     ppktl = &ic->packet_buffer;
485     for(;;) {
486         /* check if one codec still needs to be handled */
487         for(i=0;i<ic->nb_streams;i++) {
488             st = ic->streams[i];
489             if (st->codec_info_state != CSTATE_FOUND)
490                 break;
491         }
492         if (i == ic->nb_streams) {
493             /* NOTE: if the format has no header, then we need to read
494                some packets to get most of the streams, so we cannot
495                stop here */
496             if (!(ic->iformat->flags & AVFMT_NOHEADER) ||
497                 read_size >= min_read_size) {
498                 /* if we found the info for all the codecs, we can stop */
499                 ret = count;
500                 break;
501             }
502         } else {
503             /* we did not get all the codec info, but we read too much data */
504             if (read_size >= max_read_size) {
505                 ret = count;
506                 break;
507             }
508         }
509
510         pktl = av_mallocz(sizeof(AVPacketList));
511         if (!pktl) {
512             ret = AVERROR_NOMEM;
513             break;
514         }
515
516         /* add the packet in the buffered packet list */
517         *ppktl = pktl;
518         ppktl = &pktl->next;
519
520         /* NOTE: a new stream can be added there if no header in file
521            (AVFMT_NOHEADER) */
522         pkt = &pktl->pkt;
523         if (ic->iformat->read_packet(ic, pkt) < 0) {
524             /* EOF or error */
525             ret = -1; /* we could not have all the codec parameters before EOF */
526             if ((ic->iformat->flags & AVFMT_NOHEADER) &&
527                 i == ic->nb_streams)
528                 ret = 0;
529             break;
530         }
531         read_size += pkt->size;
532
533         /* open new codecs */
534         for(i=0;i<ic->nb_streams;i++) {
535             st = ic->streams[i];
536             if (st->codec_info_state == CSTATE_NOTFOUND) {
537                 /* set to found in case of error */
538                 st->codec_info_state = CSTATE_FOUND; 
539                 codec = avcodec_find_decoder(st->codec.codec_id);
540                 if (codec) {
541                     if(codec->capabilities & CODEC_CAP_TRUNCATED)
542                         st->codec.flags |= CODEC_FLAG_TRUNCATED;
543
544                     ret = avcodec_open(&st->codec, codec);
545                     if (ret >= 0)
546                         st->codec_info_state = CSTATE_DECODING;
547                 }
548             }
549         }
550
551         st = ic->streams[pkt->stream_index];
552         if (st->codec_info_state == CSTATE_DECODING) {
553             /* decode the data and update codec parameters */
554             ptr = pkt->data;
555             size = pkt->size;
556             while (size > 0) {
557                 switch(st->codec.codec_type) {
558                 case CODEC_TYPE_VIDEO:
559                     ret = avcodec_decode_video(&st->codec, &picture, 
560                                                &got_picture, ptr, size);
561                     break;
562                 case CODEC_TYPE_AUDIO:
563                     ret = avcodec_decode_audio(&st->codec, samples, 
564                                                &got_picture, ptr, size);
565                     break;
566                 default:
567                     ret = -1;
568                     break;
569                 }
570                 if (ret < 0) {
571                     /* if error, simply ignore because another packet
572                        may be OK */
573                     break;
574                 }
575                 if (got_picture) {
576                     /* we got the parameters - now we can stop
577                        examining this stream */
578                     /* XXX: add a codec info so that we can decide if
579                        the codec can repeat frames */
580                     if (st->codec.codec_id == CODEC_ID_MPEG1VIDEO && 
581                         ic->iformat != &mpegts_demux &&
582                         st->codec.sub_id == 2) {
583                         /* for mpeg2 video, we want to know the real
584                            frame rate, so we decode 40 frames. In mpeg
585                            TS case we do not do it because it would be
586                            too long */
587                         st->codec_info_nb_real_frames++;
588                         st->codec_info_nb_repeat_frames += st->codec.repeat_pict;
589 #if 0
590                         /* XXX: testing */
591                         if ((st->codec_info_nb_real_frames % 24) == 23) {
592                             st->codec_info_nb_repeat_frames += 2;
593                         }
594 #endif
595                         /* stop after 40 frames */
596                         if (st->codec_info_nb_real_frames >= 40) {
597                             st->r_frame_rate = (st->codec.frame_rate * 
598                                                 st->codec_info_nb_real_frames) /
599                                 (st->codec_info_nb_real_frames + 
600                                  (st->codec_info_nb_repeat_frames >> 1));
601                             goto close_codec;
602                         }
603                     } else {
604                     close_codec:
605                         st->codec_info_state = CSTATE_FOUND;
606                         avcodec_close(&st->codec);
607                         break;
608                     }
609                 }
610                 ptr += ret;
611                 size -= ret;
612             }
613         }
614         count++;
615     }
616
617     /* close each codec if there are opened */
618     for(i=0;i<ic->nb_streams;i++) {
619         st = ic->streams[i];
620         if (st->codec_info_state == CSTATE_DECODING)
621             avcodec_close(&st->codec);
622     }
623
624     /* set real frame rate info */
625     for(i=0;i<ic->nb_streams;i++) {
626         st = ic->streams[i];
627         if (st->codec.codec_type == CODEC_TYPE_VIDEO) {
628             if (!st->r_frame_rate)
629                 st->r_frame_rate = st->codec.frame_rate;
630         }
631     }
632
633     return ret;
634 }
635
636 /**
637  * Close a media file (but not its codecs)
638  *
639  * @param s media file handle
640  */
641 void av_close_input_file(AVFormatContext *s)
642 {
643     int i;
644
645     if (s->iformat->read_close)
646         s->iformat->read_close(s);
647     for(i=0;i<s->nb_streams;i++) {
648         av_free(s->streams[i]);
649     }
650     if (s->packet_buffer) {
651         AVPacketList *p, *p1;
652         p = s->packet_buffer;
653         while (p != NULL) {
654             p1 = p->next;
655             av_free_packet(&p->pkt);
656             av_free(p);
657             p = p1;
658         }
659         s->packet_buffer = NULL;
660     }
661     if (!(s->iformat->flags & AVFMT_NOFILE)) {
662         url_fclose(&s->pb);
663     }
664     av_freep(&s->priv_data);
665     av_free(s);
666 }
667
668 /**
669  * Add a new stream to a media file. Can only be called in the
670  * read_header function. If the flag AVFMT_NOHEADER is in the format
671  * description, then new streams can be added in read_packet too.
672  *
673  *
674  * @param s media file handle
675  * @param id file format dependent stream id
676  */
677 AVStream *av_new_stream(AVFormatContext *s, int id)
678 {
679     AVStream *st;
680
681     if (s->nb_streams >= MAX_STREAMS)
682         return NULL;
683
684     st = av_mallocz(sizeof(AVStream));
685     if (!st)
686         return NULL;
687     st->index = s->nb_streams;
688     st->id = id;
689     s->streams[s->nb_streams++] = st;
690     return st;
691 }
692
693 /************************************************************/
694 /* output media file */
695
696 /**
697  * allocate the stream private data and write the stream header to an
698  * output media file
699  *
700  * @param s media file handle
701  * @return 0 if OK. AVERROR_xxx if error.  
702  */
703 int av_write_header(AVFormatContext *s)
704 {
705     int ret, i;
706     AVStream *st;
707
708     s->priv_data = av_mallocz(s->oformat->priv_data_size);
709     if (!s->priv_data)
710         return AVERROR_NOMEM;
711     /* default pts settings is MPEG like */
712     av_set_pts_info(s, 33, 1, 90000);
713     ret = s->oformat->write_header(s);
714     if (ret < 0)
715         return ret;
716
717     /* init PTS generation */
718     for(i=0;i<s->nb_streams;i++) {
719         st = s->streams[i];
720
721         switch (st->codec.codec_type) {
722         case CODEC_TYPE_AUDIO:
723             av_frac_init(&st->pts, 0, 0, 
724                          (INT64)s->pts_num * st->codec.sample_rate);
725             break;
726         case CODEC_TYPE_VIDEO:
727             av_frac_init(&st->pts, 0, 0, 
728                          (INT64)s->pts_num * st->codec.frame_rate);
729             break;
730         default:
731             break;
732         }
733     }
734     return 0;
735 }
736
737 /**
738  * Write a packet to an output media file. The packet shall contain
739  * one audio or video frame.
740  *
741  * @param s media file handle
742  * @param stream_index stream index
743  * @param buf buffer containing the frame data
744  * @param size size of buffer
745  * @return < 0 if error, = 0 if OK, 1 if end of stream wanted.
746  */
747 int av_write_frame(AVFormatContext *s, int stream_index, const uint8_t *buf, 
748                    int size)
749 {
750     AVStream *st;
751     INT64 pts_mask;
752     int ret;
753
754     st = s->streams[stream_index];
755     pts_mask = (1LL << s->pts_wrap_bits) - 1;
756     ret = s->oformat->write_packet(s, stream_index, (uint8_t *)buf, size, 
757                                    st->pts.val & pts_mask);
758     if (ret < 0)
759         return ret;
760
761     /* update pts */
762     switch (st->codec.codec_type) {
763     case CODEC_TYPE_AUDIO:
764         av_frac_add(&st->pts, 
765                     (INT64)s->pts_den * st->codec.frame_size);
766         break;
767     case CODEC_TYPE_VIDEO:
768         av_frac_add(&st->pts, 
769                     (INT64)s->pts_den * FRAME_RATE_BASE);
770         break;
771     default:
772         break;
773     }
774     return ret;
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 av_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 static time_t mktimegm(struct tm *tm)
877 {
878     time_t t;
879
880     int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
881
882     if (m < 3) {
883         m += 12;
884         y--;
885     }
886
887     t = 86400 * 
888         (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469);
889
890     t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
891
892     return t;
893 }
894
895 /* Syntax:
896  * - If not a duration:
897  *  [{YYYY-MM-DD|YYYYMMDD}]{T| }{HH[:MM[:SS[.m...]]][Z]|HH[MM[SS[.m...]]][Z]}
898  * Time is localtime unless Z is suffixed to the end. In this case GMT
899  * Return the date in micro seconds since 1970 
900  * - If duration:
901  *  HH[:MM[:SS[.m...]]]
902  *  S+[.m...]
903  */
904 INT64 parse_date(const char *datestr, int duration)
905 {
906     const char *p;
907     INT64 t;
908     struct tm dt;
909     int i;
910     static const char *date_fmt[] = {
911         "%Y-%m-%d",
912         "%Y%m%d",
913     };
914     static const char *time_fmt[] = {
915         "%H:%M:%S",
916         "%H%M%S",
917     };
918     const char *q;
919     int is_utc, len;
920     char lastch;
921     time_t now = time(0);
922
923     len = strlen(datestr);
924     if (len > 0)
925         lastch = datestr[len - 1];
926     else
927         lastch = '\0';
928     is_utc = (lastch == 'z' || lastch == 'Z');
929
930     memset(&dt, 0, sizeof(dt));
931
932     p = datestr;
933     q = NULL;
934     if (!duration) {
935         for (i = 0; i < sizeof(date_fmt) / sizeof(date_fmt[0]); i++) {
936             q = strptime(p, date_fmt[i], &dt);
937             if (q) {
938                 break;
939             }
940         }
941
942         if (!q) {
943             if (is_utc) {
944                 dt = *gmtime(&now);
945             } else {
946                 dt = *localtime(&now);
947             }
948             dt.tm_hour = dt.tm_min = dt.tm_sec = 0;
949         } else {
950             p = q;
951         }
952
953         if (*p == 'T' || *p == 't' || *p == ' ')
954             p++;
955
956         for (i = 0; i < sizeof(time_fmt) / sizeof(time_fmt[0]); i++) {
957             q = strptime(p, time_fmt[i], &dt);
958             if (q) {
959                 break;
960             }
961         }
962     } else {
963         q = strptime(p, time_fmt[0], &dt);
964         if (!q) {
965             dt.tm_sec = strtol(p, (char **)&q, 10);
966             dt.tm_min = 0;
967             dt.tm_hour = 0;
968         }
969     }
970
971     /* Now we have all the fields that we can get */
972     if (!q) {
973         if (duration)
974             return 0;
975         else
976             return now * INT64_C(1000000);
977     }
978
979     if (duration) {
980         t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
981     } else {
982         dt.tm_isdst = -1;       /* unknown */
983         if (is_utc) {
984             t = mktimegm(&dt);
985         } else {
986             t = mktime(&dt);
987         }
988     }
989
990     t *= 1000000;
991
992     if (*q == '.') {
993         int val, n;
994         q++;
995         for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
996             if (!isdigit(*q)) 
997                 break;
998             val += n * (*q - '0');
999         }
1000         t += val;
1001     }
1002     return t;
1003 }
1004
1005 /* syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done. Return
1006    1 if found */
1007 int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
1008 {
1009     const char *p;
1010     char tag[128], *q;
1011
1012     p = info;
1013     if (*p == '?')
1014         p++;
1015     for(;;) {
1016         q = tag;
1017         while (*p != '\0' && *p != '=' && *p != '&') {
1018             if ((q - tag) < sizeof(tag) - 1)
1019                 *q++ = *p;
1020             p++;
1021         }
1022         *q = '\0';
1023         q = arg;
1024         if (*p == '=') {
1025             p++;
1026             while (*p != '&' && *p != '\0') {
1027                 if ((q - arg) < arg_size - 1) {
1028                     if (*p == '+')
1029                         *q++ = ' ';
1030                     else
1031                         *q++ = *p;
1032                 }
1033                 p++;
1034             }
1035             *q = '\0';
1036         }
1037         if (!strcmp(tag, tag1)) 
1038             return 1;
1039         if (*p != '&')
1040             break;
1041         p++;
1042     }
1043     return 0;
1044 }
1045
1046 /* Return in 'buf' the path with '%d' replaced by number. Also handles
1047    the '%0nd' format where 'n' is the total number of digits and
1048    '%%'. Return 0 if OK, and -1 if format error */
1049 int get_frame_filename(char *buf, int buf_size,
1050                        const char *path, int number)
1051 {
1052     const char *p;
1053     char *q, buf1[20];
1054     int nd, len, c, percentd_found;
1055
1056     q = buf;
1057     p = path;
1058     percentd_found = 0;
1059     for(;;) {
1060         c = *p++;
1061         if (c == '\0')
1062             break;
1063         if (c == '%') {
1064             nd = 0;
1065             while (*p >= '0' && *p <= '9') {
1066                 nd = nd * 10 + *p++ - '0';
1067             }
1068             c = *p++;
1069             switch(c) {
1070             case '%':
1071                 goto addchar;
1072             case 'd':
1073                 if (percentd_found)
1074                     goto fail;
1075                 percentd_found = 1;
1076                 snprintf(buf1, sizeof(buf1), "%0*d", nd, number);
1077                 len = strlen(buf1);
1078                 if ((q - buf + len) > buf_size - 1)
1079                     goto fail;
1080                 memcpy(q, buf1, len);
1081                 q += len;
1082                 break;
1083             default:
1084                 goto fail;
1085             }
1086         } else {
1087         addchar:
1088             if ((q - buf) < buf_size - 1)
1089                 *q++ = c;
1090         }
1091     }
1092     if (!percentd_found)
1093         goto fail;
1094     *q = '\0';
1095     return 0;
1096  fail:
1097     *q = '\0';
1098     return -1;
1099 }
1100
1101 /**
1102  *
1103  * Print on stdout a nice hexa dump of a buffer
1104  * @param buf buffer
1105  * @param size buffer size
1106  */
1107 void av_hex_dump(UINT8 *buf, int size)
1108 {
1109     int len, i, j, c;
1110
1111     for(i=0;i<size;i+=16) {
1112         len = size - i;
1113         if (len > 16)
1114             len = 16;
1115         printf("%08x ", i);
1116         for(j=0;j<16;j++) {
1117             if (j < len)
1118                 printf(" %02x", buf[i+j]);
1119             else
1120                 printf("   ");
1121         }
1122         printf(" ");
1123         for(j=0;j<len;j++) {
1124             c = buf[i+j];
1125             if (c < ' ' || c > '~')
1126                 c = '.';
1127             printf("%c", c);
1128         }
1129         printf("\n");
1130     }
1131 }
1132
1133 void url_split(char *proto, int proto_size,
1134                char *hostname, int hostname_size,
1135                int *port_ptr,
1136                char *path, int path_size,
1137                const char *url)
1138 {
1139     const char *p;
1140     char *q;
1141     int port;
1142
1143     port = -1;
1144
1145     p = url;
1146     q = proto;
1147     while (*p != ':' && *p != '\0') {
1148         if ((q - proto) < proto_size - 1)
1149             *q++ = *p;
1150         p++;
1151     }
1152     if (proto_size > 0)
1153         *q = '\0';
1154     if (*p == '\0') {
1155         if (proto_size > 0)
1156             proto[0] = '\0';
1157         if (hostname_size > 0)
1158             hostname[0] = '\0';
1159         p = url;
1160     } else {
1161         p++;
1162         if (*p == '/')
1163             p++;
1164         if (*p == '/')
1165             p++;
1166         q = hostname;
1167         while (*p != ':' && *p != '/' && *p != '?' && *p != '\0') {
1168             if ((q - hostname) < hostname_size - 1)
1169                 *q++ = *p;
1170             p++;
1171         }
1172         if (hostname_size > 0)
1173             *q = '\0';
1174         if (*p == ':') {
1175             p++;
1176             port = strtoul(p, (char **)&p, 10);
1177         }
1178     }
1179     if (port_ptr)
1180         *port_ptr = port;
1181     pstrcpy(path, path_size, p);
1182 }
1183
1184 /**
1185  * Set the pts for a given stream
1186  * @param s stream 
1187  * @param pts_wrap_bits number of bits effectively used by the pts
1188  *        (used for wrap control, 33 is the value for MPEG) 
1189  * @param pts_num numerator to convert to seconds (MPEG: 1) 
1190  * @param pts_den denominator to convert to seconds (MPEG: 90000)
1191  */
1192 void av_set_pts_info(AVFormatContext *s, int pts_wrap_bits,
1193                      int pts_num, int pts_den)
1194 {
1195     s->pts_wrap_bits = pts_wrap_bits;
1196     s->pts_num = pts_num;
1197     s->pts_den = pts_den;
1198 }
1199
1200 /* fraction handling */
1201
1202 /**
1203  * f = val + (num / den) + 0.5. 'num' is normalized so that it is such
1204  * as 0 <= num < den.
1205  *
1206  * @param f fractional number
1207  * @param val integer value
1208  * @param num must be >= 0
1209  * @param den must be >= 1 
1210  */
1211 void av_frac_init(AVFrac *f, INT64 val, INT64 num, INT64 den)
1212 {
1213     num += (den >> 1);
1214     if (num >= den) {
1215         val += num / den;
1216         num = num % den;
1217     }
1218     f->val = val;
1219     f->num = num;
1220     f->den = den;
1221 }
1222
1223 /* set f to (val + 0.5) */
1224 void av_frac_set(AVFrac *f, INT64 val)
1225 {
1226     f->val = val;
1227     f->num = f->den >> 1;
1228 }
1229
1230 /**
1231  * Fractionnal addition to f: f = f + (incr / f->den)
1232  *
1233  * @param f fractional number
1234  * @param incr increment, can be positive or negative
1235  */
1236 void av_frac_add(AVFrac *f, INT64 incr)
1237 {
1238     INT64 num, den;
1239
1240     num = f->num + incr;
1241     den = f->den;
1242     if (num < 0) {
1243         f->val += num / den;
1244         num = num % den;
1245         if (num < 0) {
1246             num += den;
1247             f->val--;
1248         }
1249     } else if (num >= den) {
1250         f->val += num / den;
1251         num = num % den;
1252     }
1253     f->num = num;
1254 }