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