]> git.sesse.net Git - ffmpeg/blob - libavformat/utils.c
f811b2c6280ab4bcbd5d4e6719a5ec8c5b128cb5
[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  * Allocate the payload of a packet and intialized its fields to default values.
155  *
156  * @param pkt packet
157  * @param size wanted payload size
158  * @return 0 if OK. AVERROR_xxx otherwise.
159  */
160 int av_new_packet(AVPacket *pkt, int size)
161 {
162     int i;
163     pkt->data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
164     if (!pkt->data)
165         return AVERROR_NOMEM;
166     pkt->size = size;
167     /* sane state */
168     pkt->pts = AV_NOPTS_VALUE;
169     pkt->stream_index = 0;
170     pkt->flags = 0;
171     
172     for(i=0; i<FF_INPUT_BUFFER_PADDING_SIZE; i++)
173         pkt->data[size+i]= 0;
174
175     return 0;
176 }
177
178 /**
179  * Free a packet
180  *
181  * @param pkt packet to free
182  */
183 void av_free_packet(AVPacket *pkt)
184 {
185     av_freep(&pkt->data);
186     /* fail safe */
187     pkt->size = 0;
188 }
189
190 /* fifo handling */
191
192 int fifo_init(FifoBuffer *f, int size)
193 {
194     f->buffer = av_malloc(size);
195     if (!f->buffer)
196         return -1;
197     f->end = f->buffer + size;
198     f->wptr = f->rptr = f->buffer;
199     return 0;
200 }
201
202 void fifo_free(FifoBuffer *f)
203 {
204     av_free(f->buffer);
205 }
206
207 int fifo_size(FifoBuffer *f, UINT8 *rptr)
208 {
209     int size;
210
211     if (f->wptr >= rptr) {
212         size = f->wptr - rptr;
213     } else {
214         size = (f->end - rptr) + (f->wptr - f->buffer);
215     }
216     return size;
217 }
218
219 /* get data from the fifo (return -1 if not enough data) */
220 int fifo_read(FifoBuffer *f, UINT8 *buf, int buf_size, UINT8 **rptr_ptr)
221 {
222     UINT8 *rptr = *rptr_ptr;
223     int size, len;
224
225     if (f->wptr >= rptr) {
226         size = f->wptr - rptr;
227     } else {
228         size = (f->end - rptr) + (f->wptr - f->buffer);
229     }
230     
231     if (size < buf_size)
232         return -1;
233     while (buf_size > 0) {
234         len = f->end - rptr;
235         if (len > buf_size)
236             len = buf_size;
237         memcpy(buf, rptr, len);
238         buf += len;
239         rptr += len;
240         if (rptr >= f->end)
241             rptr = f->buffer;
242         buf_size -= len;
243     }
244     *rptr_ptr = rptr;
245     return 0;
246 }
247
248 void fifo_write(FifoBuffer *f, UINT8 *buf, int size, UINT8 **wptr_ptr)
249 {
250     int len;
251     UINT8 *wptr;
252     wptr = *wptr_ptr;
253     while (size > 0) {
254         len = f->end - wptr;
255         if (len > size)
256             len = size;
257         memcpy(wptr, buf, len);
258         wptr += len;
259         if (wptr >= f->end)
260             wptr = f->buffer;
261         buf += len;
262         size -= len;
263     }
264     *wptr_ptr = wptr;
265 }
266
267 int filename_number_test(const char *filename)
268 {
269     char buf[1024];
270     return get_frame_filename(buf, sizeof(buf), filename, 1);
271 }
272
273 /* guess file format */
274 AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened)
275 {
276     AVInputFormat *fmt1, *fmt;
277     int score, score_max;
278
279     fmt = NULL;
280     score_max = 0;
281     for(fmt1 = first_iformat; fmt1 != NULL; fmt1 = fmt1->next) {
282         if (!is_opened && !(fmt1->flags & AVFMT_NOFILE))
283             continue;
284         score = 0;
285         if (fmt1->read_probe) {
286             score = fmt1->read_probe(pd);
287         } else if (fmt1->extensions) {
288             if (match_ext(pd->filename, fmt1->extensions)) {
289                 score = 50;
290             }
291         } 
292         if (score > score_max) {
293             score_max = score;
294             fmt = fmt1;
295         }
296     }
297     return fmt;
298 }
299
300 /************************************************************/
301 /* input media file */
302
303 #define PROBE_BUF_SIZE 2048
304
305 /**
306  * Open a media file as input. The codec are not opened. Only the file
307  * header (if present) is read.
308  *
309  * @param ic_ptr the opened media file handle is put here
310  * @param filename filename to open.
311  * @param fmt if non NULL, force the file format to use
312  * @param buf_size optional buffer size (zero if default is OK)
313  * @param ap additionnal parameters needed when opening the file (NULL if default)
314  * @return 0 if OK. AVERROR_xxx otherwise.
315  */
316 int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, 
317                        AVInputFormat *fmt,
318                        int buf_size,
319                        AVFormatParameters *ap)
320 {
321     AVFormatContext *ic = NULL;
322     int err;
323     char buf[PROBE_BUF_SIZE];
324     AVProbeData probe_data, *pd = &probe_data;
325
326     ic = av_mallocz(sizeof(AVFormatContext));
327     if (!ic) {
328         err = AVERROR_NOMEM;
329         goto fail;
330     }
331     pstrcpy(ic->filename, sizeof(ic->filename), filename);
332     pd->filename = ic->filename;
333     pd->buf = buf;
334     pd->buf_size = 0;
335
336     if (!fmt) {
337         /* guess format if no file can be opened  */
338         fmt = av_probe_input_format(pd, 0);
339     }
340
341     if (!fmt || !(fmt->flags & AVFMT_NOFILE)) {
342         /* if no file needed do not try to open one */
343         if (url_fopen(&ic->pb, filename, URL_RDONLY) < 0) {
344             err = AVERROR_IO;
345             goto fail;
346         }
347         if (buf_size > 0) {
348             url_setbufsize(&ic->pb, buf_size);
349         }
350         if (!fmt) {
351             /* read probe data */
352             pd->buf_size = get_buffer(&ic->pb, buf, PROBE_BUF_SIZE);
353             url_fseek(&ic->pb, 0, SEEK_SET);
354         }
355     }
356     
357     /* guess file format */
358     if (!fmt) {
359         fmt = av_probe_input_format(pd, 1);
360     }
361
362     /* if still no format found, error */
363     if (!fmt) {
364         err = AVERROR_NOFMT;
365         goto fail;
366     }
367         
368     /* XXX: suppress this hack for redirectors */
369 #ifdef CONFIG_NETWORK
370     if (fmt == &redir_demux) {
371         err = redir_open(ic_ptr, &ic->pb);
372         url_fclose(&ic->pb);
373         av_free(ic);
374         return err;
375     }
376 #endif
377
378     ic->iformat = fmt;
379
380     /* check filename in case of an image number is expected */
381     if (ic->iformat->flags & AVFMT_NEEDNUMBER) {
382         if (filename_number_test(ic->filename) < 0) { 
383             err = AVERROR_NUMEXPECTED;
384             goto fail1;
385         }
386     }
387     
388     /* allocate private data */
389     ic->priv_data = av_mallocz(fmt->priv_data_size);
390     if (!ic->priv_data) {
391         err = AVERROR_NOMEM;
392         goto fail;
393     }
394
395     /* default pts settings is MPEG like */
396     av_set_pts_info(ic, 33, 1, 90000);
397
398     err = ic->iformat->read_header(ic, ap);
399     if (err < 0)
400         goto fail1;
401     *ic_ptr = ic;
402     return 0;
403  fail1:
404     if (!(fmt->flags & AVFMT_NOFILE)) {
405         url_fclose(&ic->pb);
406     }
407  fail:
408     if (ic) {
409         av_freep(&ic->priv_data);
410     }
411     av_free(ic);
412     *ic_ptr = NULL;
413     return err;
414 }
415
416 /**
417  * Read a packet from a media file
418  * @param s media file handle
419  * @param pkt is filled 
420  * @return 0 if OK. AVERROR_xxx if error.
421  */
422 int av_read_packet(AVFormatContext *s, AVPacket *pkt)
423 {
424     AVPacketList *pktl;
425
426     pktl = s->packet_buffer;
427     if (pktl) {
428         /* read packet from packet buffer, if there is data */
429         *pkt = pktl->pkt;
430         s->packet_buffer = pktl->next;
431         av_free(pktl);
432         return 0;
433     } else {
434         return s->iformat->read_packet(s, pkt);
435     }
436 }
437
438 /* state for codec information */
439 #define CSTATE_NOTFOUND    0
440 #define CSTATE_DECODING    1
441 #define CSTATE_FOUND       2
442
443 static int has_codec_parameters(AVCodecContext *enc)
444 {
445     int val;
446     switch(enc->codec_type) {
447     case CODEC_TYPE_AUDIO:
448         val = enc->sample_rate;
449         break;
450     case CODEC_TYPE_VIDEO:
451         val = enc->width;
452         break;
453     default:
454         val = 1;
455         break;
456     }
457     return (val != 0);
458 }
459
460 /**
461  * Read the beginning of a media file to get stream information. This
462  * is useful for file formats with no headers such as MPEG. This
463  * function also compute the real frame rate in case of mpeg2 repeat
464  * frame mode.
465  *
466  * @param ic media file handle
467  * @return >=0 if OK. AVERROR_xxx if error.  
468  */
469 int av_find_stream_info(AVFormatContext *ic)
470 {
471     int i, count, ret, got_picture, size, read_size;
472     AVCodec *codec;
473     AVStream *st;
474     AVPacket *pkt;
475     AVFrame picture;
476     AVPacketList *pktl=NULL, **ppktl;
477     short samples[AVCODEC_MAX_AUDIO_FRAME_SIZE / 2];
478     UINT8 *ptr;
479     int min_read_size, max_read_size;
480
481     /* typical mpeg ts rate is 40 Mbits. DVD rate is about 10
482        Mbits. We read at most 0.1 second of file to find all streams */
483
484     /* XXX: base it on stream bitrate when possible */
485     if (ic->iformat == &mpegts_demux) {
486         /* maximum number of bytes we accept to read to find all the streams
487            in a file */
488         min_read_size = 3000000;
489     } else {
490         min_read_size = 125000;
491     }
492     /* max read size is 2 seconds of video max */
493     max_read_size = min_read_size * 20;
494
495     /* set initial codec state */
496     for(i=0;i<ic->nb_streams;i++) {
497         st = ic->streams[i];
498         if (has_codec_parameters(&st->codec))
499             st->codec_info_state = CSTATE_FOUND;
500         else
501             st->codec_info_state = CSTATE_NOTFOUND;
502         st->codec_info_nb_repeat_frames = 0;
503         st->codec_info_nb_real_frames = 0;
504     }
505
506     count = 0;
507     read_size = 0;
508     ppktl = &ic->packet_buffer;
509     for(;;) {
510         /* check if one codec still needs to be handled */
511         for(i=0;i<ic->nb_streams;i++) {
512             st = ic->streams[i];
513             if (st->codec_info_state != CSTATE_FOUND)
514                 break;
515         }
516         if (i == ic->nb_streams) {
517             /* NOTE: if the format has no header, then we need to read
518                some packets to get most of the streams, so we cannot
519                stop here */
520             if (!(ic->iformat->flags & AVFMT_NOHEADER) ||
521                 read_size >= min_read_size) {
522                 /* if we found the info for all the codecs, we can stop */
523                 ret = count;
524                 break;
525             }
526         } else {
527             /* we did not get all the codec info, but we read too much data */
528             if (read_size >= max_read_size) {
529                 ret = count;
530                 break;
531             }
532         }
533
534         pktl = av_mallocz(sizeof(AVPacketList));
535         if (!pktl) {
536             ret = AVERROR_NOMEM;
537             break;
538         }
539
540         /* add the packet in the buffered packet list */
541         *ppktl = pktl;
542         ppktl = &pktl->next;
543
544         /* NOTE: a new stream can be added there if no header in file
545            (AVFMT_NOHEADER) */
546         pkt = &pktl->pkt;
547         if (ic->iformat->read_packet(ic, pkt) < 0) {
548             /* EOF or error */
549             ret = -1; /* we could not have all the codec parameters before EOF */
550             if ((ic->iformat->flags & AVFMT_NOHEADER) &&
551                 i == ic->nb_streams)
552                 ret = 0;
553             break;
554         }
555         read_size += pkt->size;
556
557         /* open new codecs */
558         for(i=0;i<ic->nb_streams;i++) {
559             st = ic->streams[i];
560             if (st->codec_info_state == CSTATE_NOTFOUND) {
561                 /* set to found in case of error */
562                 st->codec_info_state = CSTATE_FOUND; 
563                 codec = avcodec_find_decoder(st->codec.codec_id);
564                 if (codec) {
565                     if(codec->capabilities & CODEC_CAP_TRUNCATED)
566                         st->codec.flags |= CODEC_FLAG_TRUNCATED;
567
568                     ret = avcodec_open(&st->codec, codec);
569                     if (ret >= 0)
570                         st->codec_info_state = CSTATE_DECODING;
571                 }
572             }
573         }
574
575         st = ic->streams[pkt->stream_index];
576         if (st->codec_info_state == CSTATE_DECODING) {
577             /* decode the data and update codec parameters */
578             ptr = pkt->data;
579             size = pkt->size;
580             while (size > 0) {
581                 switch(st->codec.codec_type) {
582                 case CODEC_TYPE_VIDEO:
583                     ret = avcodec_decode_video(&st->codec, &picture, 
584                                                &got_picture, ptr, size);
585                     break;
586                 case CODEC_TYPE_AUDIO:
587                     ret = avcodec_decode_audio(&st->codec, samples, 
588                                                &got_picture, ptr, size);
589                     break;
590                 default:
591                     ret = -1;
592                     break;
593                 }
594                 if (ret < 0) {
595                     /* if error, simply ignore because another packet
596                        may be OK */
597                     break;
598                 }
599                 if (got_picture) {
600                     /* we got the parameters - now we can stop
601                        examining this stream */
602                     /* XXX: add a codec info so that we can decide if
603                        the codec can repeat frames */
604                     if (st->codec.codec_id == CODEC_ID_MPEG1VIDEO && 
605                         ic->iformat != &mpegts_demux &&
606                         st->codec.sub_id == 2) {
607                         /* for mpeg2 video, we want to know the real
608                            frame rate, so we decode 40 frames. In mpeg
609                            TS case we do not do it because it would be
610                            too long */
611                         st->codec_info_nb_real_frames++;
612                         st->codec_info_nb_repeat_frames += st->codec.repeat_pict;
613 #if 0
614                         /* XXX: testing */
615                         if ((st->codec_info_nb_real_frames % 24) == 23) {
616                             st->codec_info_nb_repeat_frames += 2;
617                         }
618 #endif
619                         /* stop after 40 frames */
620                         if (st->codec_info_nb_real_frames >= 40) {
621                             st->r_frame_rate = (st->codec.frame_rate * 
622                                                 st->codec_info_nb_real_frames) /
623                                 (st->codec_info_nb_real_frames + 
624                                  (st->codec_info_nb_repeat_frames >> 1));
625                             goto close_codec;
626                         }
627                     } else {
628                     close_codec:
629                         st->codec_info_state = CSTATE_FOUND;
630                         avcodec_close(&st->codec);
631                         break;
632                     }
633                 }
634                 ptr += ret;
635                 size -= ret;
636             }
637         }
638         count++;
639     }
640
641     /* close each codec if there are opened */
642     for(i=0;i<ic->nb_streams;i++) {
643         st = ic->streams[i];
644         if (st->codec_info_state == CSTATE_DECODING)
645             avcodec_close(&st->codec);
646     }
647
648     /* set real frame rate info */
649     for(i=0;i<ic->nb_streams;i++) {
650         st = ic->streams[i];
651         if (st->codec.codec_type == CODEC_TYPE_VIDEO) {
652             if (!st->r_frame_rate)
653                 st->r_frame_rate = st->codec.frame_rate;
654         }
655     }
656
657     return ret;
658 }
659
660 /**
661  * Close a media file (but not its codecs)
662  *
663  * @param s media file handle
664  */
665 void av_close_input_file(AVFormatContext *s)
666 {
667     int i;
668
669     if (s->iformat->read_close)
670         s->iformat->read_close(s);
671     for(i=0;i<s->nb_streams;i++) {
672         av_free(s->streams[i]);
673     }
674     if (s->packet_buffer) {
675         AVPacketList *p, *p1;
676         p = s->packet_buffer;
677         while (p != NULL) {
678             p1 = p->next;
679             av_free_packet(&p->pkt);
680             av_free(p);
681             p = p1;
682         }
683         s->packet_buffer = NULL;
684     }
685     if (!(s->iformat->flags & AVFMT_NOFILE)) {
686         url_fclose(&s->pb);
687     }
688     av_freep(&s->priv_data);
689     av_free(s);
690 }
691
692 /**
693  * Add a new stream to a media file. Can only be called in the
694  * read_header function. If the flag AVFMT_NOHEADER is in the format
695  * description, then new streams can be added in read_packet too.
696  *
697  *
698  * @param s media file handle
699  * @param id file format dependent stream id
700  */
701 AVStream *av_new_stream(AVFormatContext *s, int id)
702 {
703     AVStream *st;
704
705     if (s->nb_streams >= MAX_STREAMS)
706         return NULL;
707
708     st = av_mallocz(sizeof(AVStream));
709     if (!st)
710         return NULL;
711     avcodec_get_context_defaults(&st->codec);
712
713     st->index = s->nb_streams;
714     st->id = id;
715     s->streams[s->nb_streams++] = st;
716     return st;
717 }
718
719 /************************************************************/
720 /* output media file */
721
722 int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap)
723 {
724     int ret;
725
726     s->priv_data = av_mallocz(s->oformat->priv_data_size);
727     if (!s->priv_data)
728         return AVERROR_NOMEM;
729     if (s->oformat->set_parameters) {
730         ret = s->oformat->set_parameters(s, ap);
731         if (ret < 0)
732             return ret;
733     }
734     return 0;
735 }
736
737 /**
738  * allocate the stream private data and write the stream header to an
739  * output media file
740  *
741  * @param s media file handle
742  * @return 0 if OK. AVERROR_xxx if error.  
743  */
744 int av_write_header(AVFormatContext *s)
745 {
746     int ret, i;
747     AVStream *st;
748
749     /* default pts settings is MPEG like */
750     av_set_pts_info(s, 33, 1, 90000);
751     ret = s->oformat->write_header(s);
752     if (ret < 0)
753         return ret;
754
755     /* init PTS generation */
756     for(i=0;i<s->nb_streams;i++) {
757         st = s->streams[i];
758
759         switch (st->codec.codec_type) {
760         case CODEC_TYPE_AUDIO:
761             av_frac_init(&st->pts, 0, 0, 
762                          (INT64)s->pts_num * st->codec.sample_rate);
763             break;
764         case CODEC_TYPE_VIDEO:
765             av_frac_init(&st->pts, 0, 0, 
766                          (INT64)s->pts_num * st->codec.frame_rate);
767             break;
768         default:
769             break;
770         }
771     }
772     return 0;
773 }
774
775 /**
776  * Write a packet to an output media file. The packet shall contain
777  * one audio or video frame.
778  *
779  * @param s media file handle
780  * @param stream_index stream index
781  * @param buf buffer containing the frame data
782  * @param size size of buffer
783  * @return < 0 if error, = 0 if OK, 1 if end of stream wanted.
784  */
785 int av_write_frame(AVFormatContext *s, int stream_index, const uint8_t *buf, 
786                    int size)
787 {
788     AVStream *st;
789     INT64 pts_mask;
790     int ret, frame_size;
791
792     st = s->streams[stream_index];
793     pts_mask = (1LL << s->pts_wrap_bits) - 1;
794     ret = s->oformat->write_packet(s, stream_index, (uint8_t *)buf, size, 
795                                    st->pts.val & pts_mask);
796     if (ret < 0)
797         return ret;
798
799     /* update pts */
800     switch (st->codec.codec_type) {
801     case CODEC_TYPE_AUDIO:
802         if (st->codec.frame_size <= 1) {
803             frame_size = size / st->codec.channels;
804             /* specific hack for pcm codecs because no frame size is provided */
805             switch(st->codec.codec_id) {
806             case CODEC_ID_PCM_S16LE:
807             case CODEC_ID_PCM_S16BE:
808             case CODEC_ID_PCM_U16LE:
809             case CODEC_ID_PCM_U16BE:
810                 frame_size >>= 1;
811                 break;
812             default:
813                 break;
814             }
815         } else {
816             frame_size = st->codec.frame_size;
817         }
818         av_frac_add(&st->pts, 
819                     (INT64)s->pts_den * frame_size);
820         break;
821     case CODEC_TYPE_VIDEO:
822         av_frac_add(&st->pts, 
823                     (INT64)s->pts_den * FRAME_RATE_BASE);
824         break;
825     default:
826         break;
827     }
828     return ret;
829 }
830
831 /**
832  * write the stream trailer to an output media file and and free the
833  * file private data.
834  *
835  * @param s media file handle
836  * @return 0 if OK. AVERROR_xxx if error.  */
837 int av_write_trailer(AVFormatContext *s)
838 {
839     int ret;
840     ret = s->oformat->write_trailer(s);
841     av_freep(&s->priv_data);
842     return ret;
843 }
844
845 /* "user interface" functions */
846
847 void dump_format(AVFormatContext *ic,
848                  int index, 
849                  const char *url,
850                  int is_output)
851 {
852     int i, flags;
853     char buf[256];
854
855     fprintf(stderr, "%s #%d, %s, %s '%s':\n", 
856             is_output ? "Output" : "Input",
857             index, 
858             is_output ? ic->oformat->name : ic->iformat->name, 
859             is_output ? "to" : "from", url);
860     for(i=0;i<ic->nb_streams;i++) {
861         AVStream *st = ic->streams[i];
862         avcodec_string(buf, sizeof(buf), &st->codec, is_output);
863         fprintf(stderr, "  Stream #%d.%d", index, i);
864         /* the pid is an important information, so we display it */
865         /* XXX: add a generic system */
866         if (is_output)
867             flags = ic->oformat->flags;
868         else
869             flags = ic->iformat->flags;
870         if (flags & AVFMT_SHOW_IDS) {
871             fprintf(stderr, "[0x%x]", st->id);
872         }
873         fprintf(stderr, ": %s\n", buf);
874     }
875 }
876
877 typedef struct {
878     const char *str;
879     int width, height;
880 } SizeEntry;
881
882 static SizeEntry sizes[] = {
883     { "sqcif", 128, 96 },
884     { "qcif", 176, 144 },
885     { "cif", 352, 288 },
886     { "4cif", 704, 576 },
887 };
888     
889 int parse_image_size(int *width_ptr, int *height_ptr, const char *str)
890 {
891     int i;
892     int n = sizeof(sizes) / sizeof(SizeEntry);
893     const char *p;
894     int frame_width = 0, frame_height = 0;
895
896     for(i=0;i<n;i++) {
897         if (!strcmp(sizes[i].str, str)) {
898             frame_width = sizes[i].width;
899             frame_height = sizes[i].height;
900             break;
901         }
902     }
903     if (i == n) {
904         p = str;
905         frame_width = strtol(p, (char **)&p, 10);
906         if (*p)
907             p++;
908         frame_height = strtol(p, (char **)&p, 10);
909     }
910     if (frame_width <= 0 || frame_height <= 0)
911         return -1;
912     *width_ptr = frame_width;
913     *height_ptr = frame_height;
914     return 0;
915 }
916
917 INT64 av_gettime(void)
918 {
919 #ifdef CONFIG_WIN32
920     struct _timeb tb;
921     _ftime(&tb);
922     return ((INT64)tb.time * INT64_C(1000) + (INT64)tb.millitm) * INT64_C(1000);
923 #else
924     struct timeval tv;
925     gettimeofday(&tv,NULL);
926     return (INT64)tv.tv_sec * 1000000 + tv.tv_usec;
927 #endif
928 }
929
930 static time_t mktimegm(struct tm *tm)
931 {
932     time_t t;
933
934     int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
935
936     if (m < 3) {
937         m += 12;
938         y--;
939     }
940
941     t = 86400 * 
942         (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469);
943
944     t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
945
946     return t;
947 }
948
949 /* Syntax:
950  * - If not a duration:
951  *  [{YYYY-MM-DD|YYYYMMDD}]{T| }{HH[:MM[:SS[.m...]]][Z]|HH[MM[SS[.m...]]][Z]}
952  * Time is localtime unless Z is suffixed to the end. In this case GMT
953  * Return the date in micro seconds since 1970 
954  * - If duration:
955  *  HH[:MM[:SS[.m...]]]
956  *  S+[.m...]
957  */
958 INT64 parse_date(const char *datestr, int duration)
959 {
960     const char *p;
961     INT64 t;
962     struct tm dt;
963     int i;
964     static const char *date_fmt[] = {
965         "%Y-%m-%d",
966         "%Y%m%d",
967     };
968     static const char *time_fmt[] = {
969         "%H:%M:%S",
970         "%H%M%S",
971     };
972     const char *q;
973     int is_utc, len;
974     char lastch;
975     time_t now = time(0);
976
977     len = strlen(datestr);
978     if (len > 0)
979         lastch = datestr[len - 1];
980     else
981         lastch = '\0';
982     is_utc = (lastch == 'z' || lastch == 'Z');
983
984     memset(&dt, 0, sizeof(dt));
985
986     p = datestr;
987     q = NULL;
988     if (!duration) {
989         for (i = 0; i < sizeof(date_fmt) / sizeof(date_fmt[0]); i++) {
990             q = strptime(p, date_fmt[i], &dt);
991             if (q) {
992                 break;
993             }
994         }
995
996         if (!q) {
997             if (is_utc) {
998                 dt = *gmtime(&now);
999             } else {
1000                 dt = *localtime(&now);
1001             }
1002             dt.tm_hour = dt.tm_min = dt.tm_sec = 0;
1003         } else {
1004             p = q;
1005         }
1006
1007         if (*p == 'T' || *p == 't' || *p == ' ')
1008             p++;
1009
1010         for (i = 0; i < sizeof(time_fmt) / sizeof(time_fmt[0]); i++) {
1011             q = strptime(p, time_fmt[i], &dt);
1012             if (q) {
1013                 break;
1014             }
1015         }
1016     } else {
1017         q = strptime(p, time_fmt[0], &dt);
1018         if (!q) {
1019             dt.tm_sec = strtol(p, (char **)&q, 10);
1020             dt.tm_min = 0;
1021             dt.tm_hour = 0;
1022         }
1023     }
1024
1025     /* Now we have all the fields that we can get */
1026     if (!q) {
1027         if (duration)
1028             return 0;
1029         else
1030             return now * INT64_C(1000000);
1031     }
1032
1033     if (duration) {
1034         t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
1035     } else {
1036         dt.tm_isdst = -1;       /* unknown */
1037         if (is_utc) {
1038             t = mktimegm(&dt);
1039         } else {
1040             t = mktime(&dt);
1041         }
1042     }
1043
1044     t *= 1000000;
1045
1046     if (*q == '.') {
1047         int val, n;
1048         q++;
1049         for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
1050             if (!isdigit(*q)) 
1051                 break;
1052             val += n * (*q - '0');
1053         }
1054         t += val;
1055     }
1056     return t;
1057 }
1058
1059 /* syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done. Return
1060    1 if found */
1061 int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
1062 {
1063     const char *p;
1064     char tag[128], *q;
1065
1066     p = info;
1067     if (*p == '?')
1068         p++;
1069     for(;;) {
1070         q = tag;
1071         while (*p != '\0' && *p != '=' && *p != '&') {
1072             if ((q - tag) < sizeof(tag) - 1)
1073                 *q++ = *p;
1074             p++;
1075         }
1076         *q = '\0';
1077         q = arg;
1078         if (*p == '=') {
1079             p++;
1080             while (*p != '&' && *p != '\0') {
1081                 if ((q - arg) < arg_size - 1) {
1082                     if (*p == '+')
1083                         *q++ = ' ';
1084                     else
1085                         *q++ = *p;
1086                 }
1087                 p++;
1088             }
1089             *q = '\0';
1090         }
1091         if (!strcmp(tag, tag1)) 
1092             return 1;
1093         if (*p != '&')
1094             break;
1095         p++;
1096     }
1097     return 0;
1098 }
1099
1100 /* Return in 'buf' the path with '%d' replaced by number. Also handles
1101    the '%0nd' format where 'n' is the total number of digits and
1102    '%%'. Return 0 if OK, and -1 if format error */
1103 int get_frame_filename(char *buf, int buf_size,
1104                        const char *path, int number)
1105 {
1106     const char *p;
1107     char *q, buf1[20];
1108     int nd, len, c, percentd_found;
1109
1110     q = buf;
1111     p = path;
1112     percentd_found = 0;
1113     for(;;) {
1114         c = *p++;
1115         if (c == '\0')
1116             break;
1117         if (c == '%') {
1118             do {
1119                 nd = 0;
1120                 while (isdigit(*p)) {
1121                     nd = nd * 10 + *p++ - '0';
1122                 }
1123                 c = *p++;
1124                 if (c == '*' && nd > 0) {
1125                     // The nd field is actually the modulus
1126                     number = number % nd;
1127                     c = *p++;
1128                     nd = 0;
1129                 }
1130             } while (isdigit(c));
1131
1132             switch(c) {
1133             case '%':
1134                 goto addchar;
1135             case 'd':
1136                 if (percentd_found)
1137                     goto fail;
1138                 percentd_found = 1;
1139                 snprintf(buf1, sizeof(buf1), "%0*d", nd, number);
1140                 len = strlen(buf1);
1141                 if ((q - buf + len) > buf_size - 1)
1142                     goto fail;
1143                 memcpy(q, buf1, len);
1144                 q += len;
1145                 break;
1146             default:
1147                 goto fail;
1148             }
1149         } else {
1150         addchar:
1151             if ((q - buf) < buf_size - 1)
1152                 *q++ = c;
1153         }
1154     }
1155     if (!percentd_found)
1156         goto fail;
1157     *q = '\0';
1158     return 0;
1159  fail:
1160     *q = '\0';
1161     return -1;
1162 }
1163
1164 /**
1165  *
1166  * Print on stdout a nice hexa dump of a buffer
1167  * @param buf buffer
1168  * @param size buffer size
1169  */
1170 void av_hex_dump(UINT8 *buf, int size)
1171 {
1172     int len, i, j, c;
1173
1174     for(i=0;i<size;i+=16) {
1175         len = size - i;
1176         if (len > 16)
1177             len = 16;
1178         printf("%08x ", i);
1179         for(j=0;j<16;j++) {
1180             if (j < len)
1181                 printf(" %02x", buf[i+j]);
1182             else
1183                 printf("   ");
1184         }
1185         printf(" ");
1186         for(j=0;j<len;j++) {
1187             c = buf[i+j];
1188             if (c < ' ' || c > '~')
1189                 c = '.';
1190             printf("%c", c);
1191         }
1192         printf("\n");
1193     }
1194 }
1195
1196 void url_split(char *proto, int proto_size,
1197                char *hostname, int hostname_size,
1198                int *port_ptr,
1199                char *path, int path_size,
1200                const char *url)
1201 {
1202     const char *p;
1203     char *q;
1204     int port;
1205
1206     port = -1;
1207
1208     p = url;
1209     q = proto;
1210     while (*p != ':' && *p != '\0') {
1211         if ((q - proto) < proto_size - 1)
1212             *q++ = *p;
1213         p++;
1214     }
1215     if (proto_size > 0)
1216         *q = '\0';
1217     if (*p == '\0') {
1218         if (proto_size > 0)
1219             proto[0] = '\0';
1220         if (hostname_size > 0)
1221             hostname[0] = '\0';
1222         p = url;
1223     } else {
1224         p++;
1225         if (*p == '/')
1226             p++;
1227         if (*p == '/')
1228             p++;
1229         q = hostname;
1230         while (*p != ':' && *p != '/' && *p != '?' && *p != '\0') {
1231             if ((q - hostname) < hostname_size - 1)
1232                 *q++ = *p;
1233             p++;
1234         }
1235         if (hostname_size > 0)
1236             *q = '\0';
1237         if (*p == ':') {
1238             p++;
1239             port = strtoul(p, (char **)&p, 10);
1240         }
1241     }
1242     if (port_ptr)
1243         *port_ptr = port;
1244     pstrcpy(path, path_size, p);
1245 }
1246
1247 /**
1248  * Set the pts for a given stream
1249  * @param s stream 
1250  * @param pts_wrap_bits number of bits effectively used by the pts
1251  *        (used for wrap control, 33 is the value for MPEG) 
1252  * @param pts_num numerator to convert to seconds (MPEG: 1) 
1253  * @param pts_den denominator to convert to seconds (MPEG: 90000)
1254  */
1255 void av_set_pts_info(AVFormatContext *s, int pts_wrap_bits,
1256                      int pts_num, int pts_den)
1257 {
1258     s->pts_wrap_bits = pts_wrap_bits;
1259     s->pts_num = pts_num;
1260     s->pts_den = pts_den;
1261 }
1262
1263 /* fraction handling */
1264
1265 /**
1266  * f = val + (num / den) + 0.5. 'num' is normalized so that it is such
1267  * as 0 <= num < den.
1268  *
1269  * @param f fractional number
1270  * @param val integer value
1271  * @param num must be >= 0
1272  * @param den must be >= 1 
1273  */
1274 void av_frac_init(AVFrac *f, INT64 val, INT64 num, INT64 den)
1275 {
1276     num += (den >> 1);
1277     if (num >= den) {
1278         val += num / den;
1279         num = num % den;
1280     }
1281     f->val = val;
1282     f->num = num;
1283     f->den = den;
1284 }
1285
1286 /* set f to (val + 0.5) */
1287 void av_frac_set(AVFrac *f, INT64 val)
1288 {
1289     f->val = val;
1290     f->num = f->den >> 1;
1291 }
1292
1293 /**
1294  * Fractionnal addition to f: f = f + (incr / f->den)
1295  *
1296  * @param f fractional number
1297  * @param incr increment, can be positive or negative
1298  */
1299 void av_frac_add(AVFrac *f, INT64 incr)
1300 {
1301     INT64 num, den;
1302
1303     num = f->num + incr;
1304     den = f->den;
1305     if (num < 0) {
1306         f->val += num / den;
1307         num = num % den;
1308         if (num < 0) {
1309             num += den;
1310             f->val--;
1311         }
1312     } else if (num >= den) {
1313         f->val += num / den;
1314         num = num % den;
1315     }
1316     f->num = num;
1317 }
1318
1319 /**
1320  * register a new image format
1321  * @param img_fmt Image format descriptor
1322  */
1323 void av_register_image_format(AVImageFormat *img_fmt)
1324 {
1325     AVImageFormat **p;
1326
1327     p = &first_image_format;
1328     while (*p != NULL) p = &(*p)->next;
1329     *p = img_fmt;
1330     img_fmt->next = NULL;
1331 }
1332
1333 /* guess image format */
1334 AVImageFormat *av_probe_image_format(AVProbeData *pd)
1335 {
1336     AVImageFormat *fmt1, *fmt;
1337     int score, score_max;
1338
1339     fmt = NULL;
1340     score_max = 0;
1341     for(fmt1 = first_image_format; fmt1 != NULL; fmt1 = fmt1->next) {
1342         if (fmt1->img_probe) {
1343             score = fmt1->img_probe(pd);
1344             if (score > score_max) {
1345                 score_max = score;
1346                 fmt = fmt1;
1347             }
1348         }
1349     }
1350     return fmt;
1351 }
1352
1353 AVImageFormat *guess_image_format(const char *filename)
1354 {
1355     AVImageFormat *fmt1;
1356
1357     for(fmt1 = first_image_format; fmt1 != NULL; fmt1 = fmt1->next) {
1358         if (fmt1->extensions && match_ext(filename, fmt1->extensions))
1359             return fmt1;
1360     }
1361     return NULL;
1362 }
1363
1364 /**
1365  * Read an image from a stream. 
1366  * @param gb byte stream containing the image
1367  * @param fmt image format, NULL if probing is required
1368  */
1369 int av_read_image(ByteIOContext *pb, const char *filename,
1370                   AVImageFormat *fmt,
1371                   int (*alloc_cb)(void *, AVImageInfo *info), void *opaque)
1372 {
1373     char buf[PROBE_BUF_SIZE];
1374     AVProbeData probe_data, *pd = &probe_data;
1375     offset_t pos;
1376     int ret;
1377
1378     if (!fmt) {
1379         pd->filename = (char *)filename;
1380         pd->buf = buf;
1381         pos = url_ftell(pb);
1382         pd->buf_size = get_buffer(pb, buf, PROBE_BUF_SIZE);
1383         url_fseek(pb, pos, SEEK_SET);
1384         fmt = av_probe_image_format(pd);
1385     }
1386     if (!fmt)
1387         return AVERROR_NOFMT;
1388     ret = fmt->img_read(pb, alloc_cb, opaque);
1389     return ret;
1390 }
1391
1392 /**
1393  * Write an image to a stream.
1394  * @param pb byte stream for the image output
1395  * @param fmt image format
1396  * @param img image data and informations
1397  */
1398 int av_write_image(ByteIOContext *pb, AVImageFormat *fmt, AVImageInfo *img)
1399 {
1400     return fmt->img_write(pb, img);
1401 }
1402