]> git.sesse.net Git - ffmpeg/blob - libavformat/utils.c
initial duration/start_time generic support - displays stream duration and average...
[ffmpeg] / libavformat / 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 #ifdef CONFIG_WIN32
22 #define strcasecmp _stricmp
23 #include <sys/types.h>
24 #include <sys/timeb.h>
25 #elif defined(CONFIG_OS2)
26 #include <string.h>
27 #define strcasecmp stricmp
28 #include <sys/time.h>
29 #else
30 #include <unistd.h>
31 #include <fcntl.h>
32 #include <sys/time.h>
33 #endif
34 #include <time.h>
35
36 #ifndef HAVE_STRPTIME
37 #include "strptime.h"
38 #endif
39
40 AVInputFormat *first_iformat;
41 AVOutputFormat *first_oformat;
42 AVImageFormat *first_image_format;
43
44 void av_register_input_format(AVInputFormat *format)
45 {
46     AVInputFormat **p;
47     p = &first_iformat;
48     while (*p != NULL) p = &(*p)->next;
49     *p = format;
50     format->next = NULL;
51 }
52
53 void av_register_output_format(AVOutputFormat *format)
54 {
55     AVOutputFormat **p;
56     p = &first_oformat;
57     while (*p != NULL) p = &(*p)->next;
58     *p = format;
59     format->next = NULL;
60 }
61
62 int match_ext(const char *filename, const char *extensions)
63 {
64     const char *ext, *p;
65     char ext1[32], *q;
66
67     ext = strrchr(filename, '.');
68     if (ext) {
69         ext++;
70         p = extensions;
71         for(;;) {
72             q = ext1;
73             while (*p != '\0' && *p != ',') 
74                 *q++ = *p++;
75             *q = '\0';
76             if (!strcasecmp(ext1, ext)) 
77                 return 1;
78             if (*p == '\0') 
79                 break;
80             p++;
81         }
82     }
83     return 0;
84 }
85
86 AVOutputFormat *guess_format(const char *short_name, const char *filename, 
87                              const char *mime_type)
88 {
89     AVOutputFormat *fmt, *fmt_found;
90     int score_max, score;
91
92     /* specific test for image sequences */
93     if (!short_name && filename && 
94         filename_number_test(filename) >= 0 &&
95         guess_image_format(filename)) {
96         return guess_format("image", NULL, NULL);
97     }
98
99     /* find the proper file type */
100     fmt_found = NULL;
101     score_max = 0;
102     fmt = first_oformat;
103     while (fmt != NULL) {
104         score = 0;
105         if (fmt->name && short_name && !strcmp(fmt->name, short_name))
106             score += 100;
107         if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
108             score += 10;
109         if (filename && fmt->extensions && 
110             match_ext(filename, fmt->extensions)) {
111             score += 5;
112         }
113         if (score > score_max) {
114             score_max = score;
115             fmt_found = fmt;
116         }
117         fmt = fmt->next;
118     }
119     return fmt_found;
120 }   
121
122 AVOutputFormat *guess_stream_format(const char *short_name, const char *filename, 
123                              const char *mime_type)
124 {
125     AVOutputFormat *fmt = guess_format(short_name, filename, mime_type);
126
127     if (fmt) {
128         AVOutputFormat *stream_fmt;
129         char stream_format_name[64];
130
131         snprintf(stream_format_name, sizeof(stream_format_name), "%s_stream", fmt->name);
132         stream_fmt = guess_format(stream_format_name, NULL, NULL);
133
134         if (stream_fmt)
135             fmt = stream_fmt;
136     }
137
138     return fmt;
139 }
140
141 AVInputFormat *av_find_input_format(const char *short_name)
142 {
143     AVInputFormat *fmt;
144     for(fmt = first_iformat; fmt != NULL; fmt = fmt->next) {
145         if (!strcmp(fmt->name, short_name))
146             return fmt;
147     }
148     return NULL;
149 }
150
151 /* memory handling */
152
153 /**
154  * Default packet destructor 
155  */
156 static void av_destruct_packet(AVPacket *pkt)
157 {
158     av_free(pkt->data);
159     pkt->data = NULL; pkt->size = 0;
160 }
161
162 /**
163  * Allocate the payload of a packet and intialized its fields to default values.
164  *
165  * @param pkt packet
166  * @param size wanted payload size
167  * @return 0 if OK. AVERROR_xxx otherwise.
168  */
169 int av_new_packet(AVPacket *pkt, int size)
170 {
171     void *data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
172     if (!data)
173         return AVERROR_NOMEM;
174     memset(data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
175
176     av_init_packet(pkt);
177     pkt->data = data; 
178     pkt->size = size;
179     pkt->destruct = av_destruct_packet;
180     return 0;
181 }
182
183 /* fifo handling */
184
185 int fifo_init(FifoBuffer *f, int size)
186 {
187     f->buffer = av_malloc(size);
188     if (!f->buffer)
189         return -1;
190     f->end = f->buffer + size;
191     f->wptr = f->rptr = f->buffer;
192     return 0;
193 }
194
195 void fifo_free(FifoBuffer *f)
196 {
197     av_free(f->buffer);
198 }
199
200 int fifo_size(FifoBuffer *f, uint8_t *rptr)
201 {
202     int size;
203
204     if (f->wptr >= rptr) {
205         size = f->wptr - rptr;
206     } else {
207         size = (f->end - rptr) + (f->wptr - f->buffer);
208     }
209     return size;
210 }
211
212 /* get data from the fifo (return -1 if not enough data) */
213 int fifo_read(FifoBuffer *f, uint8_t *buf, int buf_size, uint8_t **rptr_ptr)
214 {
215     uint8_t *rptr = *rptr_ptr;
216     int size, len;
217
218     if (f->wptr >= rptr) {
219         size = f->wptr - rptr;
220     } else {
221         size = (f->end - rptr) + (f->wptr - f->buffer);
222     }
223     
224     if (size < buf_size)
225         return -1;
226     while (buf_size > 0) {
227         len = f->end - rptr;
228         if (len > buf_size)
229             len = buf_size;
230         memcpy(buf, rptr, len);
231         buf += len;
232         rptr += len;
233         if (rptr >= f->end)
234             rptr = f->buffer;
235         buf_size -= len;
236     }
237     *rptr_ptr = rptr;
238     return 0;
239 }
240
241 void fifo_write(FifoBuffer *f, uint8_t *buf, int size, uint8_t **wptr_ptr)
242 {
243     int len;
244     uint8_t *wptr;
245     wptr = *wptr_ptr;
246     while (size > 0) {
247         len = f->end - wptr;
248         if (len > size)
249             len = size;
250         memcpy(wptr, buf, len);
251         wptr += len;
252         if (wptr >= f->end)
253             wptr = f->buffer;
254         buf += len;
255         size -= len;
256     }
257     *wptr_ptr = wptr;
258 }
259
260 int filename_number_test(const char *filename)
261 {
262     char buf[1024];
263     return get_frame_filename(buf, sizeof(buf), filename, 1);
264 }
265
266 /* guess file format */
267 AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened)
268 {
269     AVInputFormat *fmt1, *fmt;
270     int score, score_max;
271
272     fmt = NULL;
273     score_max = 0;
274     for(fmt1 = first_iformat; fmt1 != NULL; fmt1 = fmt1->next) {
275         if (!is_opened && !(fmt1->flags & AVFMT_NOFILE))
276             continue;
277         score = 0;
278         if (fmt1->read_probe) {
279             score = fmt1->read_probe(pd);
280         } else if (fmt1->extensions) {
281             if (match_ext(pd->filename, fmt1->extensions)) {
282                 score = 50;
283             }
284         } 
285         if (score > score_max) {
286             score_max = score;
287             fmt = fmt1;
288         }
289     }
290     return fmt;
291 }
292
293 /************************************************************/
294 /* input media file */
295
296 #define PROBE_BUF_SIZE 2048
297
298 /**
299  * Open a media file as input. The codec are not opened. Only the file
300  * header (if present) is read.
301  *
302  * @param ic_ptr the opened media file handle is put here
303  * @param filename filename to open.
304  * @param fmt if non NULL, force the file format to use
305  * @param buf_size optional buffer size (zero if default is OK)
306  * @param ap additionnal parameters needed when opening the file (NULL if default)
307  * @return 0 if OK. AVERROR_xxx otherwise.
308  */
309 int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, 
310                        AVInputFormat *fmt,
311                        int buf_size,
312                        AVFormatParameters *ap)
313 {
314     AVFormatContext *ic = NULL;
315     int err, must_open_file;
316     char buf[PROBE_BUF_SIZE];
317     AVProbeData probe_data, *pd = &probe_data;
318
319     ic = av_mallocz(sizeof(AVFormatContext));
320     if (!ic) {
321         err = AVERROR_NOMEM;
322         goto fail;
323     }
324     ic->duration = AV_NOPTS_VALUE;
325     ic->start_time = AV_NOPTS_VALUE;
326     pstrcpy(ic->filename, sizeof(ic->filename), filename);
327     pd->filename = ic->filename;
328     pd->buf = buf;
329     pd->buf_size = 0;
330
331     if (!fmt) {
332         /* guess format if no file can be opened  */
333         fmt = av_probe_input_format(pd, 0);
334     }
335
336     /* do not open file if the format does not need it. XXX: specific
337        hack needed to handle RTSP/TCP */
338     must_open_file = 1;
339     if ((fmt && (fmt->flags & AVFMT_NOFILE)) ||
340         (fmt == &rtp_demux && !strcmp(filename, "null"))) {
341         must_open_file = 0;
342     }
343
344     if (!fmt || must_open_file) {
345         /* if no file needed do not try to open one */
346         if (url_fopen(&ic->pb, filename, URL_RDONLY) < 0) {
347             err = AVERROR_IO;
348             goto fail;
349         }
350         if (buf_size > 0) {
351             url_setbufsize(&ic->pb, buf_size);
352         }
353         if (!fmt) {
354             /* read probe data */
355             pd->buf_size = get_buffer(&ic->pb, buf, PROBE_BUF_SIZE);
356             url_fseek(&ic->pb, 0, SEEK_SET);
357         }
358     }
359     
360     /* guess file format */
361     if (!fmt) {
362         fmt = av_probe_input_format(pd, 1);
363     }
364
365     /* if still no format found, error */
366     if (!fmt) {
367         err = AVERROR_NOFMT;
368         goto fail1;
369     }
370         
371     /* XXX: suppress this hack for redirectors */
372 #ifdef CONFIG_NETWORK
373     if (fmt == &redir_demux) {
374         err = redir_open(ic_ptr, &ic->pb);
375         url_fclose(&ic->pb);
376         av_free(ic);
377         return err;
378     }
379 #endif
380
381     ic->iformat = fmt;
382
383     /* check filename in case of an image number is expected */
384     if (ic->iformat->flags & AVFMT_NEEDNUMBER) {
385         if (filename_number_test(ic->filename) < 0) { 
386             err = AVERROR_NUMEXPECTED;
387             goto fail1;
388         }
389     }
390     
391     /* allocate private data */
392     if (fmt->priv_data_size > 0) {
393         ic->priv_data = av_mallocz(fmt->priv_data_size);
394         if (!ic->priv_data) {
395             err = AVERROR_NOMEM;
396         goto fail1;
397         }
398     } else
399         ic->priv_data = NULL;
400
401     /* default pts settings is MPEG like */
402     av_set_pts_info(ic, 33, 1, 90000);
403
404     err = ic->iformat->read_header(ic, ap);
405     if (err < 0)
406         goto fail1;
407     *ic_ptr = ic;
408     return 0;
409  fail1:
410     if (!fmt || must_open_file) {
411         url_fclose(&ic->pb);
412     }
413  fail:
414     if (ic) {
415         av_freep(&ic->priv_data);
416     }
417     av_free(ic);
418     *ic_ptr = NULL;
419     return err;
420 }
421
422 /**
423  * Read a packet from a media file
424  * @param s media file handle
425  * @param pkt is filled 
426  * @return 0 if OK. AVERROR_xxx if error.
427  */
428 int av_read_packet(AVFormatContext *s, AVPacket *pkt)
429 {
430     AVPacketList *pktl;
431
432     pktl = s->packet_buffer;
433     if (pktl) {
434         /* read packet from packet buffer, if there is data */
435         *pkt = pktl->pkt;
436         s->packet_buffer = pktl->next;
437         av_free(pktl);
438         return 0;
439     } else {
440         return s->iformat->read_packet(s, pkt);
441     }
442 }
443
444
445 /* return TRUE if the stream has accurate timings for at least one component */
446 static int av_has_timings(AVFormatContext *ic)
447 {
448     int i;
449     AVStream *st;
450
451     for(i = 0;i < ic->nb_streams; i++) {
452         st = ic->streams[i];
453         if (st->start_time != AV_NOPTS_VALUE &&
454             st->duration != AV_NOPTS_VALUE)
455             return 1;
456     }
457     return 0;
458 }
459
460 /* estimate the stream timings from the one of each components. Also
461    compute the global bitrate if possible */
462 static void av_update_stream_timings(AVFormatContext *ic)
463 {
464     int64_t start_time, end_time, end_time1;
465     int i;
466     AVStream *st;
467
468     start_time = MAXINT64;
469     end_time = MININT64;
470     for(i = 0;i < ic->nb_streams; i++) {
471         st = ic->streams[i];
472         if (st->start_time != AV_NOPTS_VALUE) {
473             if (st->start_time < start_time)
474                 start_time = st->start_time;
475             if (st->duration != AV_NOPTS_VALUE) {
476                 end_time1 = st->start_time + st->duration;
477                 if (end_time1 > end_time)
478                     end_time = end_time1;
479             }
480         }
481     }
482     if (start_time != MAXINT64) {
483         ic->start_time = start_time;
484         if (end_time != MAXINT64) {
485             ic->duration = end_time - start_time;
486             if (ic->file_size > 0) {
487                 /* compute the bit rate */
488                 ic->bit_rate = (double)ic->file_size * 8.0 * AV_TIME_BASE / 
489                     (double)ic->duration;
490             }
491         }
492     }
493
494 }
495
496 static void fill_all_stream_timings(AVFormatContext *ic)
497 {
498     int i;
499     AVStream *st;
500
501     av_update_stream_timings(ic);
502     for(i = 0;i < ic->nb_streams; i++) {
503         st = ic->streams[i];
504         if (st->start_time == AV_NOPTS_VALUE) {
505             st->start_time = ic->start_time;
506             st->duration = ic->duration;
507         }
508     }
509 }
510
511 static void av_estimate_timings_from_bit_rate(AVFormatContext *ic)
512 {
513     int64_t filesize, duration;
514     int bit_rate, i;
515     AVStream *st;
516
517     /* if bit_rate is already set, we believe it */
518     if (ic->bit_rate == 0) {
519         bit_rate = 0;
520         for(i=0;i<ic->nb_streams;i++) {
521             st = ic->streams[i];
522             bit_rate += st->codec.bit_rate;
523         }
524         ic->bit_rate = bit_rate;
525     }
526
527     /* if duration is already set, we believe it */
528     if (ic->duration == AV_NOPTS_VALUE && 
529         ic->bit_rate != 0 && 
530         ic->file_size != 0)  {
531         filesize = ic->file_size;
532         if (filesize > 0) {
533             duration = (int64_t)((8 * AV_TIME_BASE * (double)filesize) / (double)ic->bit_rate);
534             for(i = 0; i < ic->nb_streams; i++) {
535                 st = ic->streams[i];
536                 if (st->start_time == AV_NOPTS_VALUE ||
537                     st->duration == AV_NOPTS_VALUE) {
538                     st->start_time = 0;
539                     st->duration = duration;
540                 }
541             }
542         }
543     }
544 }
545
546 static void flush_packet_queue(AVFormatContext *s)
547 {
548     AVPacketList *pktl;
549
550     for(;;) {
551         pktl = s->packet_buffer;
552         if (!pktl) 
553             break;
554         s->packet_buffer = pktl->next;
555         av_free(pktl);
556     }
557 }
558
559 #define DURATION_MAX_READ_SIZE 250000
560
561 /* only usable for MPEG-PS streams */
562 static void av_estimate_timings_from_pts(AVFormatContext *ic)
563 {
564     AVPacket pkt1, *pkt = &pkt1;
565     AVStream *st;
566     int read_size, i, ret;
567     int64_t start_time, end_time, end_time1;
568     int64_t filesize, offset, duration;
569     
570     /* we read the first packets to get the first PTS (not fully
571        accurate, but it is enough now) */
572     url_fseek(&ic->pb, 0, SEEK_SET);
573     read_size = 0;
574     for(;;) {
575         if (read_size >= DURATION_MAX_READ_SIZE)
576             break;
577         /* if all info is available, we can stop */
578         for(i = 0;i < ic->nb_streams; i++) {
579             st = ic->streams[i];
580             if (st->start_time == AV_NOPTS_VALUE)
581                 break;
582         }
583         if (i == ic->nb_streams)
584             break;
585
586         ret = av_read_packet(ic, pkt);
587         if (ret != 0)
588             break;
589         read_size += pkt->size;
590         st = ic->streams[pkt->stream_index];
591         if (pkt->pts != AV_NOPTS_VALUE) {
592             if (st->start_time == AV_NOPTS_VALUE)
593                 st->start_time = (int64_t)((double)pkt->pts * ic->pts_num * (double)AV_TIME_BASE / ic->pts_den);
594          }
595          av_free_packet(pkt);
596      }
597
598     /* we compute the minimum start_time and use it as default */
599     start_time = MAXINT64;
600     for(i = 0; i < ic->nb_streams; i++) {
601         st = ic->streams[i];
602         if (st->start_time != AV_NOPTS_VALUE &&
603             st->start_time < start_time)
604             start_time = st->start_time;
605     }
606     printf("start=%lld\n", start_time);
607     if (start_time != MAXINT64)
608         ic->start_time = start_time;
609     
610     /* estimate the end time (duration) */
611     /* XXX: may need to support wrapping */
612     filesize = ic->file_size;
613     offset = filesize - DURATION_MAX_READ_SIZE;
614     if (offset < 0)
615         offset = 0;
616
617     /* flush packet queue */
618     flush_packet_queue(ic);
619
620     url_fseek(&ic->pb, offset, SEEK_SET);
621     read_size = 0;
622     for(;;) {
623         if (read_size >= DURATION_MAX_READ_SIZE)
624             break;
625         /* if all info is available, we can stop */
626         for(i = 0;i < ic->nb_streams; i++) {
627             st = ic->streams[i];
628             if (st->duration == AV_NOPTS_VALUE)
629                 break;
630         }
631         if (i == ic->nb_streams)
632             break;
633         
634         ret = av_read_packet(ic, pkt);
635         if (ret != 0)
636             break;
637         read_size += pkt->size;
638         st = ic->streams[pkt->stream_index];
639         if (pkt->pts != AV_NOPTS_VALUE) {
640             end_time = (int64_t)((double)pkt->pts * ic->pts_num * (double)AV_TIME_BASE / ic->pts_den);
641             duration = end_time - st->start_time;
642             if (duration > 0) {
643                 if (st->duration == AV_NOPTS_VALUE ||
644                     st->duration < duration)
645                     st->duration = duration;
646             }
647         }
648         av_free_packet(pkt);
649     }
650     
651     /* estimate total duration */
652     end_time = MININT64;
653     for(i = 0;i < ic->nb_streams; i++) {
654         st = ic->streams[i];
655         if (st->duration != AV_NOPTS_VALUE) {
656             end_time1 = st->start_time + st->duration;
657             if (end_time1 > end_time)
658                 end_time = end_time1;
659         }
660     }
661     
662     /* update start_time (new stream may have been created, so we do
663        it at the end */
664     if (ic->start_time != AV_NOPTS_VALUE) {
665         for(i = 0; i < ic->nb_streams; i++) {
666             st = ic->streams[i];
667             if (st->start_time == AV_NOPTS_VALUE)
668                 st->start_time = ic->start_time;
669         }
670     }
671
672     if (end_time != MININT64) {
673         /* put dummy values for duration if needed */
674         for(i = 0;i < ic->nb_streams; i++) {
675             st = ic->streams[i];
676             if (st->duration == AV_NOPTS_VALUE && 
677                 st->start_time != AV_NOPTS_VALUE)
678                 st->duration = end_time - st->start_time;
679         }
680         ic->duration = end_time - ic->start_time;
681     }
682
683     url_fseek(&ic->pb, 0, SEEK_SET);
684 }
685
686 static void av_estimate_timings(AVFormatContext *ic)
687 {
688     URLContext *h;
689     int64_t file_size;
690
691     /* get the file size, if possible */
692     if (ic->iformat->flags & AVFMT_NOFILE) {
693         file_size = 0;
694     } else {
695         h = url_fileno(&ic->pb);
696         file_size = url_filesize(h);
697         if (file_size < 0)
698             file_size = 0;
699     }
700     ic->file_size = file_size;
701
702     if (ic->iformat == &mpegps_demux) {
703         /* get accurate estimate from the PTSes */
704         av_estimate_timings_from_pts(ic);
705     } else if (av_has_timings(ic)) {
706         /* at least one components has timings - we use them for all
707            the components */
708         fill_all_stream_timings(ic);
709     } else {
710         /* less precise: use bit rate info */
711         av_estimate_timings_from_bit_rate(ic);
712     }
713     av_update_stream_timings(ic);
714
715 #if 0
716     {
717         int i;
718         AVStream *st;
719         for(i = 0;i < ic->nb_streams; i++) {
720             st = ic->streams[i];
721         printf("%d: start_time: %0.3f duration: %0.3f\n", 
722                i, (double)st->start_time / AV_TIME_BASE, 
723                (double)st->duration / AV_TIME_BASE);
724         }
725         printf("stream: start_time: %0.3f duration: %0.3f bitrate=%d kb/s\n", 
726                (double)ic->start_time / AV_TIME_BASE, 
727                (double)ic->duration / AV_TIME_BASE,
728                ic->bit_rate / 1000);
729     }
730 #endif
731 }
732
733 /* state for codec information */
734 #define CSTATE_NOTFOUND    0
735 #define CSTATE_DECODING    1
736 #define CSTATE_FOUND       2
737
738 static int has_codec_parameters(AVCodecContext *enc)
739 {
740     int val;
741     switch(enc->codec_type) {
742     case CODEC_TYPE_AUDIO:
743         val = enc->sample_rate;
744         break;
745     case CODEC_TYPE_VIDEO:
746         val = enc->width;
747         break;
748     default:
749         val = 1;
750         break;
751     }
752     return (val != 0);
753 }
754
755 /**
756  * Read the beginning of a media file to get stream information. This
757  * is useful for file formats with no headers such as MPEG. This
758  * function also compute the real frame rate in case of mpeg2 repeat
759  * frame mode.
760  *
761  * @param ic media file handle
762  * @return >=0 if OK. AVERROR_xxx if error.  
763  */
764 int av_find_stream_info(AVFormatContext *ic)
765 {
766     int i, count, ret, got_picture, size, read_size;
767     AVCodec *codec;
768     AVStream *st;
769     AVPacket *pkt;
770     AVFrame picture;
771     AVPacketList *pktl=NULL, **ppktl;
772     short samples[AVCODEC_MAX_AUDIO_FRAME_SIZE / 2];
773     uint8_t *ptr;
774     int min_read_size, max_read_size;
775
776     /* typical mpeg ts rate is 40 Mbits. DVD rate is about 10
777        Mbits. We read at most 0.2 second of file to find all streams */
778
779     /* XXX: base it on stream bitrate when possible */
780     if (ic->iformat == &mpegts_demux) {
781         /* maximum number of bytes we accept to read to find all the streams
782            in a file */
783         min_read_size = 6000000;
784     } else {
785         min_read_size = 250000;
786     }
787     /* max read size is 2 seconds of video max */
788     max_read_size = min_read_size * 10;
789
790     /* set initial codec state */
791     for(i=0;i<ic->nb_streams;i++) {
792         st = ic->streams[i];
793         if (has_codec_parameters(&st->codec))
794             st->codec_info_state = CSTATE_FOUND;
795         else
796             st->codec_info_state = CSTATE_NOTFOUND;
797         st->codec_info_nb_repeat_frames = 0;
798         st->codec_info_nb_real_frames = 0;
799     }
800
801     count = 0;
802     read_size = 0;
803     ppktl = &ic->packet_buffer;
804     for(;;) {
805         /* check if one codec still needs to be handled */
806         for(i=0;i<ic->nb_streams;i++) {
807             st = ic->streams[i];
808             if (st->codec_info_state != CSTATE_FOUND)
809                 break;
810         }
811         if (i == ic->nb_streams) {
812             /* NOTE: if the format has no header, then we need to read
813                some packets to get most of the streams, so we cannot
814                stop here */
815             if (!(ic->iformat->flags & AVFMT_NOHEADER) ||
816                 read_size >= min_read_size) {
817                 /* if we found the info for all the codecs, we can stop */
818                 ret = count;
819                 break;
820             }
821         } else {
822             /* we did not get all the codec info, but we read too much data */
823             if (read_size >= max_read_size) {
824                 ret = count;
825                 break;
826             }
827         }
828
829         pktl = av_mallocz(sizeof(AVPacketList));
830         if (!pktl) {
831             ret = AVERROR_NOMEM;
832             break;
833         }
834
835         /* add the packet in the buffered packet list */
836         *ppktl = pktl;
837         ppktl = &pktl->next;
838
839         /* NOTE: a new stream can be added there if no header in file
840            (AVFMT_NOHEADER) */
841         pkt = &pktl->pkt;
842         if (ic->iformat->read_packet(ic, pkt) < 0) {
843             /* EOF or error */
844             ret = -1; /* we could not have all the codec parameters before EOF */
845             if ((ic->iformat->flags & AVFMT_NOHEADER) &&
846                 i == ic->nb_streams)
847                 ret = 0;
848             break;
849         }
850         read_size += pkt->size;
851
852         /* open new codecs */
853         for(i=0;i<ic->nb_streams;i++) {
854             st = ic->streams[i];
855             if (st->codec_info_state == CSTATE_NOTFOUND) {
856                 /* set to found in case of error */
857                 st->codec_info_state = CSTATE_FOUND; 
858                 codec = avcodec_find_decoder(st->codec.codec_id);
859                 if (codec) {
860                     if(codec->capabilities & CODEC_CAP_TRUNCATED)
861                         st->codec.flags |= CODEC_FLAG_TRUNCATED;
862
863                     ret = avcodec_open(&st->codec, codec);
864                     if (ret >= 0)
865                         st->codec_info_state = CSTATE_DECODING;
866                 }
867             }
868         }
869
870         st = ic->streams[pkt->stream_index];
871         if (st->codec_info_state == CSTATE_DECODING) {
872             /* decode the data and update codec parameters */
873             ptr = pkt->data;
874             size = pkt->size;
875             while (size > 0) {
876                 switch(st->codec.codec_type) {
877                 case CODEC_TYPE_VIDEO:
878                     ret = avcodec_decode_video(&st->codec, &picture, 
879                                                &got_picture, ptr, size);
880                     break;
881                 case CODEC_TYPE_AUDIO:
882                     ret = avcodec_decode_audio(&st->codec, samples, 
883                                                &got_picture, ptr, size);
884                     break;
885                 default:
886                     ret = -1;
887                     break;
888                 }
889                 if (ret < 0) {
890                     /* if error, simply ignore because another packet
891                        may be OK */
892                     break;
893                 }
894                 if (got_picture) {
895                     /* we got the parameters - now we can stop
896                        examining this stream */
897                     /* XXX: add a codec info so that we can decide if
898                        the codec can repeat frames */
899                     if (st->codec.codec_id == CODEC_ID_MPEG1VIDEO && 
900                         ic->iformat != &mpegts_demux &&
901                         st->codec.sub_id == 2) {
902                         /* for mpeg2 video, we want to know the real
903                            frame rate, so we decode 40 frames. In mpeg
904                            TS case we do not do it because it would be
905                            too long */
906                         st->codec_info_nb_real_frames++;
907                         st->codec_info_nb_repeat_frames += st->codec.coded_frame->repeat_pict;
908 #if 0
909                         /* XXX: testing */
910                         if ((st->codec_info_nb_real_frames % 24) == 23) {
911                             st->codec_info_nb_repeat_frames += 2;
912                         }
913 #endif
914                         /* stop after 40 frames */
915                         if (st->codec_info_nb_real_frames >= 40) {
916                             av_reduce(
917                                 &st->r_frame_rate,
918                                 &st->r_frame_rate_base,
919                                 (int64_t)st->codec.frame_rate * st->codec_info_nb_real_frames,
920                                 (st->codec_info_nb_real_frames + (st->codec_info_nb_repeat_frames >> 1)) * st->codec.frame_rate_base,
921                                 1<<30);
922                             goto close_codec;
923                         }
924                     } else {
925                     close_codec:
926                         st->codec_info_state = CSTATE_FOUND;
927                         avcodec_close(&st->codec);
928                         break;
929                     }
930                 }
931                 ptr += ret;
932                 size -= ret;
933             }
934         }
935         count++;
936     }
937
938     /* close each codec if there are opened */
939     for(i=0;i<ic->nb_streams;i++) {
940         st = ic->streams[i];
941         if (st->codec_info_state == CSTATE_DECODING)
942             avcodec_close(&st->codec);
943     }
944
945     /* set real frame rate info */
946     for(i=0;i<ic->nb_streams;i++) {
947         st = ic->streams[i];
948         if (st->codec.codec_type == CODEC_TYPE_VIDEO) {
949             if (!st->r_frame_rate){
950                 st->r_frame_rate      = st->codec.frame_rate;
951                 st->r_frame_rate_base = st->codec.frame_rate_base;
952             }
953         }
954     }
955
956
957     av_estimate_timings(ic);
958     return ret;
959 }
960
961 /**
962  * Close a media file (but not its codecs)
963  *
964  * @param s media file handle
965  */
966 void av_close_input_file(AVFormatContext *s)
967 {
968     int i, must_open_file;
969
970     if (s->iformat->read_close)
971         s->iformat->read_close(s);
972     for(i=0;i<s->nb_streams;i++) {
973         av_free(s->streams[i]);
974     }
975     if (s->packet_buffer) {
976         AVPacketList *p, *p1;
977         p = s->packet_buffer;
978         while (p != NULL) {
979             p1 = p->next;
980             av_free_packet(&p->pkt);
981             av_free(p);
982             p = p1;
983         }
984         s->packet_buffer = NULL;
985     }
986     must_open_file = 1;
987     if ((s->iformat->flags & AVFMT_NOFILE) ||
988         (s->iformat == &rtp_demux && !strcmp(s->filename, "null"))) {
989         must_open_file = 0;
990     }
991     if (must_open_file) {
992         url_fclose(&s->pb);
993     }
994     av_freep(&s->priv_data);
995     av_free(s);
996 }
997
998 /**
999  * Add a new stream to a media file. Can only be called in the
1000  * read_header function. If the flag AVFMT_NOHEADER is in the format
1001  * description, then new streams can be added in read_packet too.
1002  *
1003  *
1004  * @param s media file handle
1005  * @param id file format dependent stream id
1006  */
1007 AVStream *av_new_stream(AVFormatContext *s, int id)
1008 {
1009     AVStream *st;
1010
1011     if (s->nb_streams >= MAX_STREAMS)
1012         return NULL;
1013
1014     st = av_mallocz(sizeof(AVStream));
1015     if (!st)
1016         return NULL;
1017     avcodec_get_context_defaults(&st->codec);
1018
1019     st->index = s->nb_streams;
1020     st->id = id;
1021     st->start_time = AV_NOPTS_VALUE;
1022     st->duration = AV_NOPTS_VALUE;
1023     s->streams[s->nb_streams++] = st;
1024     return st;
1025 }
1026
1027 /************************************************************/
1028 /* output media file */
1029
1030 int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap)
1031 {
1032     int ret;
1033     
1034     if (s->oformat->priv_data_size > 0) {
1035         s->priv_data = av_mallocz(s->oformat->priv_data_size);
1036         if (!s->priv_data)
1037             return AVERROR_NOMEM;
1038     } else
1039         s->priv_data = NULL;
1040         
1041     if (s->oformat->set_parameters) {
1042         ret = s->oformat->set_parameters(s, ap);
1043         if (ret < 0)
1044             return ret;
1045     }
1046     return 0;
1047 }
1048
1049 /**
1050  * allocate the stream private data and write the stream header to an
1051  * output media file
1052  *
1053  * @param s media file handle
1054  * @return 0 if OK. AVERROR_xxx if error.  
1055  */
1056 int av_write_header(AVFormatContext *s)
1057 {
1058     int ret, i;
1059     AVStream *st;
1060
1061     /* default pts settings is MPEG like */
1062     av_set_pts_info(s, 33, 1, 90000);
1063     ret = s->oformat->write_header(s);
1064     if (ret < 0)
1065         return ret;
1066
1067     /* init PTS generation */
1068     for(i=0;i<s->nb_streams;i++) {
1069         st = s->streams[i];
1070
1071         switch (st->codec.codec_type) {
1072         case CODEC_TYPE_AUDIO:
1073             av_frac_init(&st->pts, 0, 0, 
1074                          (int64_t)s->pts_num * st->codec.sample_rate);
1075             break;
1076         case CODEC_TYPE_VIDEO:
1077             av_frac_init(&st->pts, 0, 0, 
1078                          (int64_t)s->pts_num * st->codec.frame_rate);
1079             break;
1080         default:
1081             break;
1082         }
1083     }
1084     return 0;
1085 }
1086
1087 /**
1088  * Write a packet to an output media file. The packet shall contain
1089  * one audio or video frame.
1090  *
1091  * @param s media file handle
1092  * @param stream_index stream index
1093  * @param buf buffer containing the frame data
1094  * @param size size of buffer
1095  * @return < 0 if error, = 0 if OK, 1 if end of stream wanted.
1096  */
1097 int av_write_frame(AVFormatContext *s, int stream_index, const uint8_t *buf, 
1098                    int size)
1099 {
1100     AVStream *st;
1101     int64_t pts_mask;
1102     int ret, frame_size;
1103
1104     st = s->streams[stream_index];
1105     pts_mask = (1LL << s->pts_wrap_bits) - 1;
1106     ret = s->oformat->write_packet(s, stream_index, (uint8_t *)buf, size, 
1107                                    st->pts.val & pts_mask);
1108     if (ret < 0)
1109         return ret;
1110
1111     /* update pts */
1112     switch (st->codec.codec_type) {
1113     case CODEC_TYPE_AUDIO:
1114         if (st->codec.frame_size <= 1) {
1115             frame_size = size / st->codec.channels;
1116             /* specific hack for pcm codecs because no frame size is provided */
1117             switch(st->codec.codec_id) {
1118             case CODEC_ID_PCM_S16LE:
1119             case CODEC_ID_PCM_S16BE:
1120             case CODEC_ID_PCM_U16LE:
1121             case CODEC_ID_PCM_U16BE:
1122                 frame_size >>= 1;
1123                 break;
1124             default:
1125                 break;
1126             }
1127         } else {
1128             frame_size = st->codec.frame_size;
1129         }
1130         av_frac_add(&st->pts, 
1131                     (int64_t)s->pts_den * frame_size);
1132         break;
1133     case CODEC_TYPE_VIDEO:
1134         av_frac_add(&st->pts, 
1135                     (int64_t)s->pts_den * st->codec.frame_rate_base);
1136         break;
1137     default:
1138         break;
1139     }
1140     return ret;
1141 }
1142
1143 /**
1144  * write the stream trailer to an output media file and and free the
1145  * file private data.
1146  *
1147  * @param s media file handle
1148  * @return 0 if OK. AVERROR_xxx if error.  */
1149 int av_write_trailer(AVFormatContext *s)
1150 {
1151     int ret;
1152     ret = s->oformat->write_trailer(s);
1153     av_freep(&s->priv_data);
1154     return ret;
1155 }
1156
1157 /* "user interface" functions */
1158
1159 void dump_format(AVFormatContext *ic,
1160                  int index, 
1161                  const char *url,
1162                  int is_output)
1163 {
1164     int i, flags;
1165     char buf[256];
1166
1167     fprintf(stderr, "%s #%d, %s, %s '%s':\n", 
1168             is_output ? "Output" : "Input",
1169             index, 
1170             is_output ? ic->oformat->name : ic->iformat->name, 
1171             is_output ? "to" : "from", url);
1172     if (!is_output) {
1173         printf("  Duration: ");
1174         if (ic->duration != AV_NOPTS_VALUE) {
1175             int hours, mins, secs, us;
1176             secs = ic->duration / AV_TIME_BASE;
1177             us = ic->duration % AV_TIME_BASE;
1178             mins = secs / 60;
1179             secs %= 60;
1180             hours = mins / 60;
1181             mins %= 60;
1182             printf("%02d:%02d:%02d.%01d", hours, mins, secs, 
1183                    (10 * us) / AV_TIME_BASE);
1184         } else {
1185             printf("N/A");
1186         }
1187         printf(", bitrate: ");
1188         if (ic->bit_rate) {
1189             printf("%d kb/s", ic->bit_rate / 1000);
1190         } else {
1191             printf("N/A");
1192         }
1193         printf("\n");
1194     }
1195     for(i=0;i<ic->nb_streams;i++) {
1196         AVStream *st = ic->streams[i];
1197         avcodec_string(buf, sizeof(buf), &st->codec, is_output);
1198         fprintf(stderr, "  Stream #%d.%d", index, i);
1199         /* the pid is an important information, so we display it */
1200         /* XXX: add a generic system */
1201         if (is_output)
1202             flags = ic->oformat->flags;
1203         else
1204             flags = ic->iformat->flags;
1205         if (flags & AVFMT_SHOW_IDS) {
1206             fprintf(stderr, "[0x%x]", st->id);
1207         }
1208         fprintf(stderr, ": %s\n", buf);
1209     }
1210 }
1211
1212 typedef struct {
1213     const char *abv;
1214     int width, height;
1215     int frame_rate, frame_rate_base;
1216 } AbvEntry;
1217
1218 static AbvEntry frame_abvs[] = {
1219     { "ntsc",      352, 240, 30000, 1001 },
1220     { "pal",       352, 288,    25,    1 },
1221     { "film",      352, 240,    24,    1 },
1222     { "ntsc-film", 352, 240, 24000, 1001 },
1223     { "sqcif",     128,  96,     0,    0 },
1224     { "qcif",      176, 144,     0,    0 },
1225     { "cif",       352, 288,     0,    0 },
1226     { "4cif",      704, 576,     0,    0 },
1227 };
1228
1229 int parse_image_size(int *width_ptr, int *height_ptr, const char *str)
1230 {
1231     int i;
1232     int n = sizeof(frame_abvs) / sizeof(AbvEntry);
1233     const char *p;
1234     int frame_width = 0, frame_height = 0;
1235
1236     for(i=0;i<n;i++) {
1237         if (!strcmp(frame_abvs[i].abv, str)) {
1238             frame_width = frame_abvs[i].width;
1239             frame_height = frame_abvs[i].height;
1240             break;
1241         }
1242     }
1243     if (i == n) {
1244         p = str;
1245         frame_width = strtol(p, (char **)&p, 10);
1246         if (*p)
1247             p++;
1248         frame_height = strtol(p, (char **)&p, 10);
1249     }
1250     if (frame_width <= 0 || frame_height <= 0)
1251         return -1;
1252     *width_ptr = frame_width;
1253     *height_ptr = frame_height;
1254     return 0;
1255 }
1256
1257 int parse_frame_rate(int *frame_rate, int *frame_rate_base, const char *arg)
1258 {
1259     int i;
1260     char* cp;
1261    
1262     /* First, we check our abbreviation table */
1263     for (i = 0; i < sizeof(frame_abvs)/sizeof(*frame_abvs); ++i)
1264          if (!strcmp(frame_abvs[i].abv, arg)) {
1265              *frame_rate = frame_abvs[i].frame_rate;
1266              *frame_rate_base = frame_abvs[i].frame_rate_base;
1267              return 0;
1268          }
1269
1270     /* Then, we try to parse it as fraction */
1271     cp = strchr(arg, '/');
1272     if (cp) {
1273         char* cpp;
1274         *frame_rate = strtol(arg, &cpp, 10);
1275         if (cpp != arg || cpp == cp) 
1276             *frame_rate_base = strtol(cp+1, &cpp, 10);
1277         else
1278            *frame_rate = 0;
1279     } 
1280     else {
1281         /* Finally we give up and parse it as double */
1282         *frame_rate_base = DEFAULT_FRAME_RATE_BASE;
1283         *frame_rate = (int)(strtod(arg, 0) * (*frame_rate_base) + 0.5);
1284     }
1285     if (!*frame_rate || !*frame_rate_base)
1286         return -1;
1287     else
1288         return 0;
1289 }
1290
1291 int64_t av_gettime(void)
1292 {
1293 #ifdef CONFIG_WIN32
1294     struct _timeb tb;
1295     _ftime(&tb);
1296     return ((int64_t)tb.time * int64_t_C(1000) + (int64_t)tb.millitm) * int64_t_C(1000);
1297 #else
1298     struct timeval tv;
1299     gettimeofday(&tv,NULL);
1300     return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
1301 #endif
1302 }
1303
1304 static time_t mktimegm(struct tm *tm)
1305 {
1306     time_t t;
1307
1308     int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
1309
1310     if (m < 3) {
1311         m += 12;
1312         y--;
1313     }
1314
1315     t = 86400 * 
1316         (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469);
1317
1318     t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
1319
1320     return t;
1321 }
1322
1323 /* Syntax:
1324  * - If not a duration:
1325  *  [{YYYY-MM-DD|YYYYMMDD}]{T| }{HH[:MM[:SS[.m...]]][Z]|HH[MM[SS[.m...]]][Z]}
1326  * Time is localtime unless Z is suffixed to the end. In this case GMT
1327  * Return the date in micro seconds since 1970 
1328  * - If duration:
1329  *  HH[:MM[:SS[.m...]]]
1330  *  S+[.m...]
1331  */
1332 int64_t parse_date(const char *datestr, int duration)
1333 {
1334     const char *p;
1335     int64_t t;
1336     struct tm dt;
1337     int i;
1338     static const char *date_fmt[] = {
1339         "%Y-%m-%d",
1340         "%Y%m%d",
1341     };
1342     static const char *time_fmt[] = {
1343         "%H:%M:%S",
1344         "%H%M%S",
1345     };
1346     const char *q;
1347     int is_utc, len;
1348     char lastch;
1349     time_t now = time(0);
1350
1351     len = strlen(datestr);
1352     if (len > 0)
1353         lastch = datestr[len - 1];
1354     else
1355         lastch = '\0';
1356     is_utc = (lastch == 'z' || lastch == 'Z');
1357
1358     memset(&dt, 0, sizeof(dt));
1359
1360     p = datestr;
1361     q = NULL;
1362     if (!duration) {
1363         for (i = 0; i < sizeof(date_fmt) / sizeof(date_fmt[0]); i++) {
1364             q = strptime(p, date_fmt[i], &dt);
1365             if (q) {
1366                 break;
1367             }
1368         }
1369
1370         if (!q) {
1371             if (is_utc) {
1372                 dt = *gmtime(&now);
1373             } else {
1374                 dt = *localtime(&now);
1375             }
1376             dt.tm_hour = dt.tm_min = dt.tm_sec = 0;
1377         } else {
1378             p = q;
1379         }
1380
1381         if (*p == 'T' || *p == 't' || *p == ' ')
1382             p++;
1383
1384         for (i = 0; i < sizeof(time_fmt) / sizeof(time_fmt[0]); i++) {
1385             q = strptime(p, time_fmt[i], &dt);
1386             if (q) {
1387                 break;
1388             }
1389         }
1390     } else {
1391         q = strptime(p, time_fmt[0], &dt);
1392         if (!q) {
1393             dt.tm_sec = strtol(p, (char **)&q, 10);
1394             dt.tm_min = 0;
1395             dt.tm_hour = 0;
1396         }
1397     }
1398
1399     /* Now we have all the fields that we can get */
1400     if (!q) {
1401         if (duration)
1402             return 0;
1403         else
1404             return now * int64_t_C(1000000);
1405     }
1406
1407     if (duration) {
1408         t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
1409     } else {
1410         dt.tm_isdst = -1;       /* unknown */
1411         if (is_utc) {
1412             t = mktimegm(&dt);
1413         } else {
1414             t = mktime(&dt);
1415         }
1416     }
1417
1418     t *= 1000000;
1419
1420     if (*q == '.') {
1421         int val, n;
1422         q++;
1423         for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
1424             if (!isdigit(*q)) 
1425                 break;
1426             val += n * (*q - '0');
1427         }
1428         t += val;
1429     }
1430     return t;
1431 }
1432
1433 /* syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done. Return
1434    1 if found */
1435 int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
1436 {
1437     const char *p;
1438     char tag[128], *q;
1439
1440     p = info;
1441     if (*p == '?')
1442         p++;
1443     for(;;) {
1444         q = tag;
1445         while (*p != '\0' && *p != '=' && *p != '&') {
1446             if ((q - tag) < sizeof(tag) - 1)
1447                 *q++ = *p;
1448             p++;
1449         }
1450         *q = '\0';
1451         q = arg;
1452         if (*p == '=') {
1453             p++;
1454             while (*p != '&' && *p != '\0') {
1455                 if ((q - arg) < arg_size - 1) {
1456                     if (*p == '+')
1457                         *q++ = ' ';
1458                     else
1459                         *q++ = *p;
1460                 }
1461                 p++;
1462             }
1463             *q = '\0';
1464         }
1465         if (!strcmp(tag, tag1)) 
1466             return 1;
1467         if (*p != '&')
1468             break;
1469         p++;
1470     }
1471     return 0;
1472 }
1473
1474 /* Return in 'buf' the path with '%d' replaced by number. Also handles
1475    the '%0nd' format where 'n' is the total number of digits and
1476    '%%'. Return 0 if OK, and -1 if format error */
1477 int get_frame_filename(char *buf, int buf_size,
1478                        const char *path, int number)
1479 {
1480     const char *p;
1481     char *q, buf1[20];
1482     int nd, len, c, percentd_found;
1483
1484     q = buf;
1485     p = path;
1486     percentd_found = 0;
1487     for(;;) {
1488         c = *p++;
1489         if (c == '\0')
1490             break;
1491         if (c == '%') {
1492             do {
1493                 nd = 0;
1494                 while (isdigit(*p)) {
1495                     nd = nd * 10 + *p++ - '0';
1496                 }
1497                 c = *p++;
1498                 if (c == '*' && nd > 0) {
1499                     // The nd field is actually the modulus
1500                     number = number % nd;
1501                     c = *p++;
1502                     nd = 0;
1503                 }
1504             } while (isdigit(c));
1505
1506             switch(c) {
1507             case '%':
1508                 goto addchar;
1509             case 'd':
1510                 if (percentd_found)
1511                     goto fail;
1512                 percentd_found = 1;
1513                 snprintf(buf1, sizeof(buf1), "%0*d", nd, number);
1514                 len = strlen(buf1);
1515                 if ((q - buf + len) > buf_size - 1)
1516                     goto fail;
1517                 memcpy(q, buf1, len);
1518                 q += len;
1519                 break;
1520             default:
1521                 goto fail;
1522             }
1523         } else {
1524         addchar:
1525             if ((q - buf) < buf_size - 1)
1526                 *q++ = c;
1527         }
1528     }
1529     if (!percentd_found)
1530         goto fail;
1531     *q = '\0';
1532     return 0;
1533  fail:
1534     *q = '\0';
1535     return -1;
1536 }
1537
1538 /**
1539  *
1540  * Print on stdout a nice hexa dump of a buffer
1541  * @param buf buffer
1542  * @param size buffer size
1543  */
1544 void av_hex_dump(uint8_t *buf, int size)
1545 {
1546     int len, i, j, c;
1547
1548     for(i=0;i<size;i+=16) {
1549         len = size - i;
1550         if (len > 16)
1551             len = 16;
1552         printf("%08x ", i);
1553         for(j=0;j<16;j++) {
1554             if (j < len)
1555                 printf(" %02x", buf[i+j]);
1556             else
1557                 printf("   ");
1558         }
1559         printf(" ");
1560         for(j=0;j<len;j++) {
1561             c = buf[i+j];
1562             if (c < ' ' || c > '~')
1563                 c = '.';
1564             printf("%c", c);
1565         }
1566         printf("\n");
1567     }
1568 }
1569
1570 void url_split(char *proto, int proto_size,
1571                char *hostname, int hostname_size,
1572                int *port_ptr,
1573                char *path, int path_size,
1574                const char *url)
1575 {
1576     const char *p;
1577     char *q;
1578     int port;
1579
1580     port = -1;
1581
1582     p = url;
1583     q = proto;
1584     while (*p != ':' && *p != '\0') {
1585         if ((q - proto) < proto_size - 1)
1586             *q++ = *p;
1587         p++;
1588     }
1589     if (proto_size > 0)
1590         *q = '\0';
1591     if (*p == '\0') {
1592         if (proto_size > 0)
1593             proto[0] = '\0';
1594         if (hostname_size > 0)
1595             hostname[0] = '\0';
1596         p = url;
1597     } else {
1598         p++;
1599         if (*p == '/')
1600             p++;
1601         if (*p == '/')
1602             p++;
1603         q = hostname;
1604         while (*p != ':' && *p != '/' && *p != '?' && *p != '\0') {
1605             if ((q - hostname) < hostname_size - 1)
1606                 *q++ = *p;
1607             p++;
1608         }
1609         if (hostname_size > 0)
1610             *q = '\0';
1611         if (*p == ':') {
1612             p++;
1613             port = strtoul(p, (char **)&p, 10);
1614         }
1615     }
1616     if (port_ptr)
1617         *port_ptr = port;
1618     pstrcpy(path, path_size, p);
1619 }
1620
1621 /**
1622  * Set the pts for a given stream
1623  * @param s stream 
1624  * @param pts_wrap_bits number of bits effectively used by the pts
1625  *        (used for wrap control, 33 is the value for MPEG) 
1626  * @param pts_num numerator to convert to seconds (MPEG: 1) 
1627  * @param pts_den denominator to convert to seconds (MPEG: 90000)
1628  */
1629 void av_set_pts_info(AVFormatContext *s, int pts_wrap_bits,
1630                      int pts_num, int pts_den)
1631 {
1632     s->pts_wrap_bits = pts_wrap_bits;
1633     s->pts_num = pts_num;
1634     s->pts_den = pts_den;
1635 }
1636
1637 /* fraction handling */
1638
1639 /**
1640  * f = val + (num / den) + 0.5. 'num' is normalized so that it is such
1641  * as 0 <= num < den.
1642  *
1643  * @param f fractional number
1644  * @param val integer value
1645  * @param num must be >= 0
1646  * @param den must be >= 1 
1647  */
1648 void av_frac_init(AVFrac *f, int64_t val, int64_t num, int64_t den)
1649 {
1650     num += (den >> 1);
1651     if (num >= den) {
1652         val += num / den;
1653         num = num % den;
1654     }
1655     f->val = val;
1656     f->num = num;
1657     f->den = den;
1658 }
1659
1660 /* set f to (val + 0.5) */
1661 void av_frac_set(AVFrac *f, int64_t val)
1662 {
1663     f->val = val;
1664     f->num = f->den >> 1;
1665 }
1666
1667 /**
1668  * Fractionnal addition to f: f = f + (incr / f->den)
1669  *
1670  * @param f fractional number
1671  * @param incr increment, can be positive or negative
1672  */
1673 void av_frac_add(AVFrac *f, int64_t incr)
1674 {
1675     int64_t num, den;
1676
1677     num = f->num + incr;
1678     den = f->den;
1679     if (num < 0) {
1680         f->val += num / den;
1681         num = num % den;
1682         if (num < 0) {
1683             num += den;
1684             f->val--;
1685         }
1686     } else if (num >= den) {
1687         f->val += num / den;
1688         num = num % den;
1689     }
1690     f->num = num;
1691 }
1692
1693 /**
1694  * register a new image format
1695  * @param img_fmt Image format descriptor
1696  */
1697 void av_register_image_format(AVImageFormat *img_fmt)
1698 {
1699     AVImageFormat **p;
1700
1701     p = &first_image_format;
1702     while (*p != NULL) p = &(*p)->next;
1703     *p = img_fmt;
1704     img_fmt->next = NULL;
1705 }
1706
1707 /* guess image format */
1708 AVImageFormat *av_probe_image_format(AVProbeData *pd)
1709 {
1710     AVImageFormat *fmt1, *fmt;
1711     int score, score_max;
1712
1713     fmt = NULL;
1714     score_max = 0;
1715     for(fmt1 = first_image_format; fmt1 != NULL; fmt1 = fmt1->next) {
1716         if (fmt1->img_probe) {
1717             score = fmt1->img_probe(pd);
1718             if (score > score_max) {
1719                 score_max = score;
1720                 fmt = fmt1;
1721             }
1722         }
1723     }
1724     return fmt;
1725 }
1726
1727 AVImageFormat *guess_image_format(const char *filename)
1728 {
1729     AVImageFormat *fmt1;
1730
1731     for(fmt1 = first_image_format; fmt1 != NULL; fmt1 = fmt1->next) {
1732         if (fmt1->extensions && match_ext(filename, fmt1->extensions))
1733             return fmt1;
1734     }
1735     return NULL;
1736 }
1737
1738 /**
1739  * Read an image from a stream. 
1740  * @param gb byte stream containing the image
1741  * @param fmt image format, NULL if probing is required
1742  */
1743 int av_read_image(ByteIOContext *pb, const char *filename,
1744                   AVImageFormat *fmt,
1745                   int (*alloc_cb)(void *, AVImageInfo *info), void *opaque)
1746 {
1747     char buf[PROBE_BUF_SIZE];
1748     AVProbeData probe_data, *pd = &probe_data;
1749     offset_t pos;
1750     int ret;
1751
1752     if (!fmt) {
1753         pd->filename = filename;
1754         pd->buf = buf;
1755         pos = url_ftell(pb);
1756         pd->buf_size = get_buffer(pb, buf, PROBE_BUF_SIZE);
1757         url_fseek(pb, pos, SEEK_SET);
1758         fmt = av_probe_image_format(pd);
1759     }
1760     if (!fmt)
1761         return AVERROR_NOFMT;
1762     ret = fmt->img_read(pb, alloc_cb, opaque);
1763     return ret;
1764 }
1765
1766 /**
1767  * Write an image to a stream.
1768  * @param pb byte stream for the image output
1769  * @param fmt image format
1770  * @param img image data and informations
1771  */
1772 int av_write_image(ByteIOContext *pb, AVImageFormat *fmt, AVImageInfo *img)
1773 {
1774     return fmt->img_write(pb, img);
1775 }
1776