]> git.sesse.net Git - ffmpeg/blob - libav/utils.c
do not read probe data if format is specified - match_ext() must be exported
[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 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         if (!fmt) {
339             /* read probe data */
340             pd->buf_size = get_buffer(&ic->pb, buf, PROBE_BUF_SIZE);
341             url_fseek(&ic->pb, 0, SEEK_SET);
342         }
343     }
344     
345     /* guess file format */
346     if (!fmt) {
347         fmt = av_probe_input_format(pd, 1);
348     }
349
350     /* if still no format found, error */
351     if (!fmt) {
352         err = AVERROR_NOFMT;
353         goto fail;
354     }
355         
356     ic->iformat = fmt;
357
358     /* allocate private data */
359     ic->priv_data = av_mallocz(fmt->priv_data_size);
360     if (!ic->priv_data) {
361         err = AVERROR_NOMEM;
362         goto fail;
363     }
364
365     /* default pts settings is MPEG like */
366     av_set_pts_info(ic, 33, 1, 90000);
367
368     /* check filename in case of an image number is expected */
369     if (ic->iformat->flags & AVFMT_NEEDNUMBER) {
370         if (filename_number_test(ic->filename) < 0) { 
371             err = AVERROR_NUMEXPECTED;
372             goto fail1;
373         }
374     }
375     
376     err = ic->iformat->read_header(ic, ap);
377     if (err < 0)
378         goto fail1;
379     *ic_ptr = ic;
380     return 0;
381  fail1:
382     if (!(fmt->flags & AVFMT_NOFILE)) {
383         url_fclose(&ic->pb);
384     }
385  fail:
386     if (ic) {
387         av_freep(&ic->priv_data);
388     }
389     av_free(ic);
390     *ic_ptr = NULL;
391     return err;
392 }
393
394 /**
395  * Read a packet from a media file
396  * @param s media file handle
397  * @param pkt is filled 
398  * @return 0 if OK. AVERROR_xxx if error.
399  */
400 int av_read_packet(AVFormatContext *s, AVPacket *pkt)
401 {
402     AVPacketList *pktl;
403
404     pktl = s->packet_buffer;
405     if (pktl) {
406         /* read packet from packet buffer, if there is data */
407         *pkt = pktl->pkt;
408         s->packet_buffer = pktl->next;
409         av_free(pktl);
410         return 0;
411     } else {
412         return s->iformat->read_packet(s, pkt);
413     }
414 }
415
416 /* state for codec information */
417 #define CSTATE_NOTFOUND    0
418 #define CSTATE_DECODING    1
419 #define CSTATE_FOUND       2
420
421 static int has_codec_parameters(AVCodecContext *enc)
422 {
423     int val;
424     switch(enc->codec_type) {
425     case CODEC_TYPE_AUDIO:
426         val = enc->sample_rate;
427         break;
428     case CODEC_TYPE_VIDEO:
429         val = enc->width;
430         break;
431     default:
432         val = 1;
433         break;
434     }
435     return (val != 0);
436 }
437
438 /**
439  * Read the beginning of a media file to get stream information. This
440  * is useful for file formats with no headers such as MPEG. This
441  * function also compute the real frame rate in case of mpeg2 repeat
442  * frame mode.
443  *
444  * @param ic media file handle
445  * @return >=0 if OK. AVERROR_xxx if error.  
446  */
447 int av_find_stream_info(AVFormatContext *ic)
448 {
449     int i, count, ret, got_picture, size, read_size;
450     AVCodec *codec;
451     AVStream *st;
452     AVPacket *pkt;
453     AVPicture picture;
454     AVPacketList *pktl=NULL, **ppktl;
455     short samples[AVCODEC_MAX_AUDIO_FRAME_SIZE / 2];
456     UINT8 *ptr;
457     int min_read_size, max_read_size;
458
459     /* typical mpeg ts rate is 40 Mbits. DVD rate is about 10
460        Mbits. We read at most 0.1 second of file to find all streams */
461
462     /* XXX: base it on stream bitrate when possible */
463     if (ic->iformat == &mpegts_demux) {
464         /* maximum number of bytes we accept to read to find all the streams
465            in a file */
466         min_read_size = 3000000;
467     } else {
468         min_read_size = 125000;
469     }
470     /* max read size is 2 seconds of video max */
471     max_read_size = min_read_size * 20;
472
473     /* set initial codec state */
474     for(i=0;i<ic->nb_streams;i++) {
475         st = ic->streams[i];
476         if (has_codec_parameters(&st->codec))
477             st->codec_info_state = CSTATE_FOUND;
478         else
479             st->codec_info_state = CSTATE_NOTFOUND;
480         st->codec_info_nb_repeat_frames = 0;
481         st->codec_info_nb_real_frames = 0;
482     }
483
484     count = 0;
485     read_size = 0;
486     ppktl = &ic->packet_buffer;
487     for(;;) {
488         /* check if one codec still needs to be handled */
489         for(i=0;i<ic->nb_streams;i++) {
490             st = ic->streams[i];
491             if (st->codec_info_state != CSTATE_FOUND)
492                 break;
493         }
494         if (i == ic->nb_streams) {
495             /* NOTE: if the format has no header, then we need to read
496                some packets to get most of the streams, so we cannot
497                stop here */
498             if (!(ic->iformat->flags & AVFMT_NOHEADER) ||
499                 read_size >= min_read_size) {
500                 /* if we found the info for all the codecs, we can stop */
501                 ret = count;
502                 break;
503             }
504         } else {
505             /* we did not get all the codec info, but we read too much data */
506             if (read_size >= max_read_size) {
507                 ret = count;
508                 break;
509             }
510         }
511
512         pktl = av_mallocz(sizeof(AVPacketList));
513         if (!pktl) {
514             ret = AVERROR_NOMEM;
515             break;
516         }
517
518         /* add the packet in the buffered packet list */
519         *ppktl = pktl;
520         ppktl = &pktl->next;
521
522         /* NOTE: a new stream can be added there if no header in file
523            (AVFMT_NOHEADER) */
524         pkt = &pktl->pkt;
525         if (ic->iformat->read_packet(ic, pkt) < 0) {
526             /* EOF or error */
527             ret = -1; /* we could not have all the codec parameters before EOF */
528             if ((ic->iformat->flags & AVFMT_NOHEADER) &&
529                 i == ic->nb_streams)
530                 ret = 0;
531             break;
532         }
533         read_size += pkt->size;
534
535         /* open new codecs */
536         for(i=0;i<ic->nb_streams;i++) {
537             st = ic->streams[i];
538             if (st->codec_info_state == CSTATE_NOTFOUND) {
539                 /* set to found in case of error */
540                 st->codec_info_state = CSTATE_FOUND; 
541                 codec = avcodec_find_decoder(st->codec.codec_id);
542                 if (codec) {
543                     if(codec->capabilities & CODEC_CAP_TRUNCATED)
544                         st->codec.flags |= CODEC_FLAG_TRUNCATED;
545
546                     ret = avcodec_open(&st->codec, codec);
547                     if (ret >= 0)
548                         st->codec_info_state = CSTATE_DECODING;
549                 }
550             }
551         }
552
553         st = ic->streams[pkt->stream_index];
554         if (st->codec_info_state == CSTATE_DECODING) {
555             /* decode the data and update codec parameters */
556             ptr = pkt->data;
557             size = pkt->size;
558             while (size > 0) {
559                 switch(st->codec.codec_type) {
560                 case CODEC_TYPE_VIDEO:
561                     ret = avcodec_decode_video(&st->codec, &picture, 
562                                                &got_picture, ptr, size);
563                     break;
564                 case CODEC_TYPE_AUDIO:
565                     ret = avcodec_decode_audio(&st->codec, samples, 
566                                                &got_picture, ptr, size);
567                     break;
568                 default:
569                     ret = -1;
570                     break;
571                 }
572                 if (ret < 0) {
573                     /* if error, simply ignore because another packet
574                        may be OK */
575                     break;
576                 }
577                 if (got_picture) {
578                     /* we got the parameters - now we can stop
579                        examining this stream */
580                     /* XXX: add a codec info so that we can decide if
581                        the codec can repeat frames */
582                     if (st->codec.codec_id == CODEC_ID_MPEG1VIDEO && 
583                         ic->iformat != &mpegts_demux &&
584                         st->codec.sub_id == 2) {
585                         /* for mpeg2 video, we want to know the real
586                            frame rate, so we decode 40 frames. In mpeg
587                            TS case we do not do it because it would be
588                            too long */
589                         st->codec_info_nb_real_frames++;
590                         st->codec_info_nb_repeat_frames += st->codec.repeat_pict;
591 #if 0
592                         /* XXX: testing */
593                         if ((st->codec_info_nb_real_frames % 24) == 23) {
594                             st->codec_info_nb_repeat_frames += 2;
595                         }
596 #endif
597                         /* stop after 40 frames */
598                         if (st->codec_info_nb_real_frames >= 40) {
599                             st->r_frame_rate = (st->codec.frame_rate * 
600                                                 st->codec_info_nb_real_frames) /
601                                 (st->codec_info_nb_real_frames + 
602                                  (st->codec_info_nb_repeat_frames >> 1));
603                             goto close_codec;
604                         }
605                     } else {
606                     close_codec:
607                         st->codec_info_state = CSTATE_FOUND;
608                         avcodec_close(&st->codec);
609                         break;
610                     }
611                 }
612                 ptr += ret;
613                 size -= ret;
614             }
615         }
616         count++;
617     }
618
619     /* close each codec if there are opened */
620     for(i=0;i<ic->nb_streams;i++) {
621         st = ic->streams[i];
622         if (st->codec_info_state == CSTATE_DECODING)
623             avcodec_close(&st->codec);
624     }
625
626     /* set real frame rate info */
627     for(i=0;i<ic->nb_streams;i++) {
628         st = ic->streams[i];
629         if (st->codec.codec_type == CODEC_TYPE_VIDEO) {
630             if (!st->r_frame_rate)
631                 st->r_frame_rate = st->codec.frame_rate;
632         }
633     }
634
635     return ret;
636 }
637
638 /**
639  * Close a media file (but not its codecs)
640  *
641  * @param s media file handle
642  */
643 void av_close_input_file(AVFormatContext *s)
644 {
645     int i;
646
647     if (s->iformat->read_close)
648         s->iformat->read_close(s);
649     for(i=0;i<s->nb_streams;i++) {
650         av_free(s->streams[i]);
651     }
652     if (s->packet_buffer) {
653         AVPacketList *p, *p1;
654         p = s->packet_buffer;
655         while (p != NULL) {
656             p1 = p->next;
657             av_free_packet(&p->pkt);
658             av_free(p);
659             p = p1;
660         }
661         s->packet_buffer = NULL;
662     }
663     if (!(s->iformat->flags & AVFMT_NOFILE)) {
664         url_fclose(&s->pb);
665     }
666     av_freep(&s->priv_data);
667     av_free(s);
668 }
669
670 /**
671  * Add a new stream to a media file. Can only be called in the
672  * read_header function. If the flag AVFMT_NOHEADER is in the format
673  * description, then new streams can be added in read_packet too.
674  *
675  *
676  * @param s media file handle
677  * @param id file format dependent stream id
678  */
679 AVStream *av_new_stream(AVFormatContext *s, int id)
680 {
681     AVStream *st;
682
683     if (s->nb_streams >= MAX_STREAMS)
684         return NULL;
685
686     st = av_mallocz(sizeof(AVStream));
687     if (!st)
688         return NULL;
689     st->index = s->nb_streams;
690     st->id = id;
691     s->streams[s->nb_streams++] = st;
692     return st;
693 }
694
695 /************************************************************/
696 /* output media file */
697
698 /**
699  * allocate the stream private data and write the stream header to an
700  * output media file
701  *
702  * @param s media file handle
703  * @return 0 if OK. AVERROR_xxx if error.  
704  */
705 int av_write_header(AVFormatContext *s)
706 {
707     int ret, i;
708     AVStream *st;
709
710     s->priv_data = av_mallocz(s->oformat->priv_data_size);
711     if (!s->priv_data)
712         return AVERROR_NOMEM;
713     /* default pts settings is MPEG like */
714     av_set_pts_info(s, 33, 1, 90000);
715     ret = s->oformat->write_header(s);
716     if (ret < 0)
717         return ret;
718
719     /* init PTS generation */
720     for(i=0;i<s->nb_streams;i++) {
721         st = s->streams[i];
722
723         switch (st->codec.codec_type) {
724         case CODEC_TYPE_AUDIO:
725             av_frac_init(&st->pts, 0, 0, 
726                          (INT64)s->pts_num * st->codec.sample_rate);
727             break;
728         case CODEC_TYPE_VIDEO:
729             av_frac_init(&st->pts, 0, 0, 
730                          (INT64)s->pts_num * st->codec.frame_rate);
731             break;
732         default:
733             break;
734         }
735     }
736     return 0;
737 }
738
739 /**
740  * Write a packet to an output media file. The packet shall contain
741  * one audio or video frame.
742  *
743  * @param s media file handle
744  * @param stream_index stream index
745  * @param buf buffer containing the frame data
746  * @param size size of buffer
747  * @return < 0 if error, = 0 if OK, 1 if end of stream wanted.
748  */
749 int av_write_frame(AVFormatContext *s, int stream_index, const uint8_t *buf, 
750                    int size)
751 {
752     AVStream *st;
753     INT64 pts_mask;
754     int ret;
755
756     st = s->streams[stream_index];
757     pts_mask = (1LL << s->pts_wrap_bits) - 1;
758     ret = s->oformat->write_packet(s, stream_index, (uint8_t *)buf, size, 
759                                    st->pts.val & pts_mask);
760     if (ret < 0)
761         return ret;
762
763     /* update pts */
764     switch (st->codec.codec_type) {
765     case CODEC_TYPE_AUDIO:
766         av_frac_add(&st->pts, 
767                     (INT64)s->pts_den * st->codec.frame_size);
768         break;
769     case CODEC_TYPE_VIDEO:
770         av_frac_add(&st->pts, 
771                     (INT64)s->pts_den * FRAME_RATE_BASE);
772         break;
773     default:
774         break;
775     }
776     return ret;
777 }
778
779 /**
780  * write the stream trailer to an output media file and and free the
781  * file private data.
782  *
783  * @param s media file handle
784  * @return 0 if OK. AVERROR_xxx if error.  */
785 int av_write_trailer(AVFormatContext *s)
786 {
787     int ret;
788     ret = s->oformat->write_trailer(s);
789     av_freep(&s->priv_data);
790     return ret;
791 }
792
793 /* "user interface" functions */
794
795 void dump_format(AVFormatContext *ic,
796                  int index, 
797                  const char *url,
798                  int is_output)
799 {
800     int i, flags;
801     char buf[256];
802
803     fprintf(stderr, "%s #%d, %s, %s '%s':\n", 
804             is_output ? "Output" : "Input",
805             index, 
806             is_output ? ic->oformat->name : ic->iformat->name, 
807             is_output ? "to" : "from", url);
808     for(i=0;i<ic->nb_streams;i++) {
809         AVStream *st = ic->streams[i];
810         avcodec_string(buf, sizeof(buf), &st->codec, is_output);
811         fprintf(stderr, "  Stream #%d.%d", index, i);
812         /* the pid is an important information, so we display it */
813         /* XXX: add a generic system */
814         if (is_output)
815             flags = ic->oformat->flags;
816         else
817             flags = ic->iformat->flags;
818         if (flags & AVFMT_SHOW_IDS) {
819             fprintf(stderr, "[0x%x]", st->id);
820         }
821         fprintf(stderr, ": %s\n", buf);
822     }
823 }
824
825 typedef struct {
826     const char *str;
827     int width, height;
828 } SizeEntry;
829
830 static SizeEntry sizes[] = {
831     { "sqcif", 128, 96 },
832     { "qcif", 176, 144 },
833     { "cif", 352, 288 },
834     { "4cif", 704, 576 },
835 };
836     
837 int parse_image_size(int *width_ptr, int *height_ptr, const char *str)
838 {
839     int i;
840     int n = sizeof(sizes) / sizeof(SizeEntry);
841     const char *p;
842     int frame_width = 0, frame_height = 0;
843
844     for(i=0;i<n;i++) {
845         if (!strcmp(sizes[i].str, str)) {
846             frame_width = sizes[i].width;
847             frame_height = sizes[i].height;
848             break;
849         }
850     }
851     if (i == n) {
852         p = str;
853         frame_width = strtol(p, (char **)&p, 10);
854         if (*p)
855             p++;
856         frame_height = strtol(p, (char **)&p, 10);
857     }
858     if (frame_width <= 0 || frame_height <= 0)
859         return -1;
860     *width_ptr = frame_width;
861     *height_ptr = frame_height;
862     return 0;
863 }
864
865 INT64 av_gettime(void)
866 {
867 #ifdef CONFIG_WIN32
868     struct _timeb tb;
869     _ftime(&tb);
870     return ((INT64)tb.time * INT64_C(1000) + (INT64)tb.millitm) * INT64_C(1000);
871 #else
872     struct timeval tv;
873     gettimeofday(&tv,NULL);
874     return (INT64)tv.tv_sec * 1000000 + tv.tv_usec;
875 #endif
876 }
877
878 static time_t mktimegm(struct tm *tm)
879 {
880     time_t t;
881
882     int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
883
884     if (m < 3) {
885         m += 12;
886         y--;
887     }
888
889     t = 86400 * 
890         (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469);
891
892     t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
893
894     return t;
895 }
896
897 /* Syntax:
898  * - If not a duration:
899  *  [{YYYY-MM-DD|YYYYMMDD}]{T| }{HH[:MM[:SS[.m...]]][Z]|HH[MM[SS[.m...]]][Z]}
900  * Time is localtime unless Z is suffixed to the end. In this case GMT
901  * Return the date in micro seconds since 1970 
902  * - If duration:
903  *  HH[:MM[:SS[.m...]]]
904  *  S+[.m...]
905  */
906 INT64 parse_date(const char *datestr, int duration)
907 {
908     const char *p;
909     INT64 t;
910     struct tm dt;
911     int i;
912     static const char *date_fmt[] = {
913         "%Y-%m-%d",
914         "%Y%m%d",
915     };
916     static const char *time_fmt[] = {
917         "%H:%M:%S",
918         "%H%M%S",
919     };
920     const char *q;
921     int is_utc, len;
922     char lastch;
923     time_t now = time(0);
924
925     len = strlen(datestr);
926     if (len > 0)
927         lastch = datestr[len - 1];
928     else
929         lastch = '\0';
930     is_utc = (lastch == 'z' || lastch == 'Z');
931
932     memset(&dt, 0, sizeof(dt));
933
934     p = datestr;
935     q = NULL;
936     if (!duration) {
937         for (i = 0; i < sizeof(date_fmt) / sizeof(date_fmt[0]); i++) {
938             q = strptime(p, date_fmt[i], &dt);
939             if (q) {
940                 break;
941             }
942         }
943
944         if (!q) {
945             if (is_utc) {
946                 dt = *gmtime(&now);
947             } else {
948                 dt = *localtime(&now);
949             }
950             dt.tm_hour = dt.tm_min = dt.tm_sec = 0;
951         } else {
952             p = q;
953         }
954
955         if (*p == 'T' || *p == 't' || *p == ' ')
956             p++;
957
958         for (i = 0; i < sizeof(time_fmt) / sizeof(time_fmt[0]); i++) {
959             q = strptime(p, time_fmt[i], &dt);
960             if (q) {
961                 break;
962             }
963         }
964     } else {
965         q = strptime(p, time_fmt[0], &dt);
966         if (!q) {
967             dt.tm_sec = strtol(p, (char **)&q, 10);
968             dt.tm_min = 0;
969             dt.tm_hour = 0;
970         }
971     }
972
973     /* Now we have all the fields that we can get */
974     if (!q) {
975         if (duration)
976             return 0;
977         else
978             return now * INT64_C(1000000);
979     }
980
981     if (duration) {
982         t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
983     } else {
984         dt.tm_isdst = -1;       /* unknown */
985         if (is_utc) {
986             t = mktimegm(&dt);
987         } else {
988             t = mktime(&dt);
989         }
990     }
991
992     t *= 1000000;
993
994     if (*q == '.') {
995         int val, n;
996         q++;
997         for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
998             if (!isdigit(*q)) 
999                 break;
1000             val += n * (*q - '0');
1001         }
1002         t += val;
1003     }
1004     return t;
1005 }
1006
1007 /* syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done. Return
1008    1 if found */
1009 int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
1010 {
1011     const char *p;
1012     char tag[128], *q;
1013
1014     p = info;
1015     if (*p == '?')
1016         p++;
1017     for(;;) {
1018         q = tag;
1019         while (*p != '\0' && *p != '=' && *p != '&') {
1020             if ((q - tag) < sizeof(tag) - 1)
1021                 *q++ = *p;
1022             p++;
1023         }
1024         *q = '\0';
1025         q = arg;
1026         if (*p == '=') {
1027             p++;
1028             while (*p != '&' && *p != '\0') {
1029                 if ((q - arg) < arg_size - 1) {
1030                     if (*p == '+')
1031                         *q++ = ' ';
1032                     else
1033                         *q++ = *p;
1034                 }
1035                 p++;
1036             }
1037             *q = '\0';
1038         }
1039         if (!strcmp(tag, tag1)) 
1040             return 1;
1041         if (*p != '&')
1042             break;
1043         p++;
1044     }
1045     return 0;
1046 }
1047
1048 /* Return in 'buf' the path with '%d' replaced by number. Also handles
1049    the '%0nd' format where 'n' is the total number of digits and
1050    '%%'. Return 0 if OK, and -1 if format error */
1051 int get_frame_filename(char *buf, int buf_size,
1052                        const char *path, int number)
1053 {
1054     const char *p;
1055     char *q, buf1[20];
1056     int nd, len, c, percentd_found;
1057
1058     q = buf;
1059     p = path;
1060     percentd_found = 0;
1061     for(;;) {
1062         c = *p++;
1063         if (c == '\0')
1064             break;
1065         if (c == '%') {
1066             nd = 0;
1067             while (*p >= '0' && *p <= '9') {
1068                 nd = nd * 10 + *p++ - '0';
1069             }
1070             c = *p++;
1071             switch(c) {
1072             case '%':
1073                 goto addchar;
1074             case 'd':
1075                 if (percentd_found)
1076                     goto fail;
1077                 percentd_found = 1;
1078                 snprintf(buf1, sizeof(buf1), "%0*d", nd, number);
1079                 len = strlen(buf1);
1080                 if ((q - buf + len) > buf_size - 1)
1081                     goto fail;
1082                 memcpy(q, buf1, len);
1083                 q += len;
1084                 break;
1085             default:
1086                 goto fail;
1087             }
1088         } else {
1089         addchar:
1090             if ((q - buf) < buf_size - 1)
1091                 *q++ = c;
1092         }
1093     }
1094     if (!percentd_found)
1095         goto fail;
1096     *q = '\0';
1097     return 0;
1098  fail:
1099     *q = '\0';
1100     return -1;
1101 }
1102
1103 /**
1104  *
1105  * Print on stdout a nice hexa dump of a buffer
1106  * @param buf buffer
1107  * @param size buffer size
1108  */
1109 void av_hex_dump(UINT8 *buf, int size)
1110 {
1111     int len, i, j, c;
1112
1113     for(i=0;i<size;i+=16) {
1114         len = size - i;
1115         if (len > 16)
1116             len = 16;
1117         printf("%08x ", i);
1118         for(j=0;j<16;j++) {
1119             if (j < len)
1120                 printf(" %02x", buf[i+j]);
1121             else
1122                 printf("   ");
1123         }
1124         printf(" ");
1125         for(j=0;j<len;j++) {
1126             c = buf[i+j];
1127             if (c < ' ' || c > '~')
1128                 c = '.';
1129             printf("%c", c);
1130         }
1131         printf("\n");
1132     }
1133 }
1134
1135 void url_split(char *proto, int proto_size,
1136                char *hostname, int hostname_size,
1137                int *port_ptr,
1138                char *path, int path_size,
1139                const char *url)
1140 {
1141     const char *p;
1142     char *q;
1143     int port;
1144
1145     port = -1;
1146
1147     p = url;
1148     q = proto;
1149     while (*p != ':' && *p != '\0') {
1150         if ((q - proto) < proto_size - 1)
1151             *q++ = *p;
1152         p++;
1153     }
1154     if (proto_size > 0)
1155         *q = '\0';
1156     if (*p == '\0') {
1157         if (proto_size > 0)
1158             proto[0] = '\0';
1159         if (hostname_size > 0)
1160             hostname[0] = '\0';
1161         p = url;
1162     } else {
1163         p++;
1164         if (*p == '/')
1165             p++;
1166         if (*p == '/')
1167             p++;
1168         q = hostname;
1169         while (*p != ':' && *p != '/' && *p != '?' && *p != '\0') {
1170             if ((q - hostname) < hostname_size - 1)
1171                 *q++ = *p;
1172             p++;
1173         }
1174         if (hostname_size > 0)
1175             *q = '\0';
1176         if (*p == ':') {
1177             p++;
1178             port = strtoul(p, (char **)&p, 10);
1179         }
1180     }
1181     if (port_ptr)
1182         *port_ptr = port;
1183     pstrcpy(path, path_size, p);
1184 }
1185
1186 /**
1187  * Set the pts for a given stream
1188  * @param s stream 
1189  * @param pts_wrap_bits number of bits effectively used by the pts
1190  *        (used for wrap control, 33 is the value for MPEG) 
1191  * @param pts_num numerator to convert to seconds (MPEG: 1) 
1192  * @param pts_den denominator to convert to seconds (MPEG: 90000)
1193  */
1194 void av_set_pts_info(AVFormatContext *s, int pts_wrap_bits,
1195                      int pts_num, int pts_den)
1196 {
1197     s->pts_wrap_bits = pts_wrap_bits;
1198     s->pts_num = pts_num;
1199     s->pts_den = pts_den;
1200 }
1201
1202 /* fraction handling */
1203
1204 /**
1205  * f = val + (num / den) + 0.5. 'num' is normalized so that it is such
1206  * as 0 <= num < den.
1207  *
1208  * @param f fractional number
1209  * @param val integer value
1210  * @param num must be >= 0
1211  * @param den must be >= 1 
1212  */
1213 void av_frac_init(AVFrac *f, INT64 val, INT64 num, INT64 den)
1214 {
1215     num += (den >> 1);
1216     if (num >= den) {
1217         val += num / den;
1218         num = num % den;
1219     }
1220     f->val = val;
1221     f->num = num;
1222     f->den = den;
1223 }
1224
1225 /* set f to (val + 0.5) */
1226 void av_frac_set(AVFrac *f, INT64 val)
1227 {
1228     f->val = val;
1229     f->num = f->den >> 1;
1230 }
1231
1232 /**
1233  * Fractionnal addition to f: f = f + (incr / f->den)
1234  *
1235  * @param f fractional number
1236  * @param incr increment, can be positive or negative
1237  */
1238 void av_frac_add(AVFrac *f, INT64 incr)
1239 {
1240     INT64 num, den;
1241
1242     num = f->num + incr;
1243     den = f->den;
1244     if (num < 0) {
1245         f->val += num / den;
1246         num = num % den;
1247         if (num < 0) {
1248             num += den;
1249             f->val--;
1250         }
1251     } else if (num >= den) {
1252         f->val += num / den;
1253         num = num % den;
1254     }
1255     f->num = num;
1256 }