new video grab device for ATI All-In-Wonder cards based on the GATOS km driver patch...
[libav.git] / libav / utils.c
CommitLineData
de6d9b64
FB
1/*
2 * Various utilities for ffmpeg system
19720f15 3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
de6d9b64 4 *
19720f15
FB
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.
de6d9b64 9 *
19720f15 10 * This library is distributed in the hope that it will be useful,
de6d9b64 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19720f15
FB
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
de6d9b64 14 *
19720f15
FB
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
de6d9b64 18 */
8be1c656 19#include "avformat.h"
af469427 20#include "tick.h"
c5510dd6 21#include <ctype.h>
8be1c656 22#ifndef CONFIG_WIN32
de6d9b64
FB
23#include <unistd.h>
24#include <fcntl.h>
de6d9b64 25#include <sys/time.h>
8be1c656
FB
26#else
27#define strcasecmp _stricmp
28#include <sys/types.h>
29#include <sys/timeb.h>
30#endif
9235088f 31#include <time.h>
de6d9b64 32
c5510dd6
PG
33#ifndef HAVE_STRPTIME
34#include "strptime.h"
35#endif
36
b9a281db
FB
37AVInputFormat *first_iformat;
38AVOutputFormat *first_oformat;
de6d9b64 39
b9a281db 40void av_register_input_format(AVInputFormat *format)
de6d9b64 41{
b9a281db
FB
42 AVInputFormat **p;
43 p = &first_iformat;
44 while (*p != NULL) p = &(*p)->next;
45 *p = format;
46 format->next = NULL;
47}
48
49void av_register_output_format(AVOutputFormat *format)
50{
51 AVOutputFormat **p;
52 p = &first_oformat;
de6d9b64
FB
53 while (*p != NULL) p = &(*p)->next;
54 *p = format;
55 format->next = NULL;
56}
57
58int match_ext(const char *filename, const char *extensions)
59{
60 const char *ext, *p;
61 char ext1[32], *q;
62
63 ext = strrchr(filename, '.');
64 if (ext) {
65 ext++;
66 p = extensions;
67 for(;;) {
68 q = ext1;
69 while (*p != '\0' && *p != ',')
70 *q++ = *p++;
71 *q = '\0';
72 if (!strcasecmp(ext1, ext))
73 return 1;
74 if (*p == '\0')
75 break;
76 p++;
77 }
78 }
79 return 0;
80}
81
b9a281db
FB
82AVOutputFormat *guess_format(const char *short_name, const char *filename,
83 const char *mime_type)
de6d9b64 84{
b9a281db 85 AVOutputFormat *fmt, *fmt_found;
de6d9b64
FB
86 int score_max, score;
87
88 /* find the proper file type */
89 fmt_found = NULL;
90 score_max = 0;
b9a281db 91 fmt = first_oformat;
de6d9b64
FB
92 while (fmt != NULL) {
93 score = 0;
94 if (fmt->name && short_name && !strcmp(fmt->name, short_name))
95 score += 100;
96 if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
97 score += 10;
98 if (filename && fmt->extensions &&
99 match_ext(filename, fmt->extensions)) {
100 score += 5;
101 }
102 if (score > score_max) {
103 score_max = score;
104 fmt_found = fmt;
105 }
106 fmt = fmt->next;
107 }
108 return fmt_found;
109}
110
c5510dd6
PG
111AVOutputFormat *guess_stream_format(const char *short_name, const char *filename,
112 const char *mime_type)
113{
114 AVOutputFormat *fmt = guess_format(short_name, filename, mime_type);
115
116 if (fmt) {
117 AVOutputFormat *stream_fmt;
118 char stream_format_name[64];
119
120 snprintf(stream_format_name, sizeof(stream_format_name), "%s_stream", fmt->name);
121 stream_fmt = guess_format(stream_format_name, NULL, NULL);
122
123 if (stream_fmt)
124 fmt = stream_fmt;
125 }
126
127 return fmt;
128}
129
b9a281db
FB
130AVInputFormat *av_find_input_format(const char *short_name)
131{
132 AVInputFormat *fmt;
133 for(fmt = first_iformat; fmt != NULL; fmt = fmt->next) {
134 if (!strcmp(fmt->name, short_name))
135 return fmt;
136 }
137 return NULL;
138}
139
de6d9b64
FB
140/* memory handling */
141
b9a281db
FB
142/**
143 * Allocate the payload of a packet and intialized its fields to default values.
144 *
145 * @param pkt packet
146 * @param size wanted payload size
147 * @return 0 if OK. AVERROR_xxx otherwise.
148 */
de6d9b64
FB
149int av_new_packet(AVPacket *pkt, int size)
150{
1ea4f593 151 pkt->data = av_malloc(size);
de6d9b64 152 if (!pkt->data)
b9a281db 153 return AVERROR_NOMEM;
de6d9b64
FB
154 pkt->size = size;
155 /* sane state */
156 pkt->pts = 0;
157 pkt->stream_index = 0;
158 pkt->flags = 0;
159 return 0;
160}
161
b9a281db
FB
162/**
163 * Free a packet
164 *
165 * @param pkt packet to free
166 */
de6d9b64
FB
167void av_free_packet(AVPacket *pkt)
168{
1ea4f593 169 av_freep(&pkt->data);
de6d9b64 170 /* fail safe */
de6d9b64
FB
171 pkt->size = 0;
172}
173
174/* fifo handling */
175
176int fifo_init(FifoBuffer *f, int size)
177{
1ea4f593 178 f->buffer = av_malloc(size);
de6d9b64
FB
179 if (!f->buffer)
180 return -1;
181 f->end = f->buffer + size;
182 f->wptr = f->rptr = f->buffer;
183 return 0;
184}
185
186void fifo_free(FifoBuffer *f)
187{
1ea4f593 188 av_free(f->buffer);
de6d9b64
FB
189}
190
191int fifo_size(FifoBuffer *f, UINT8 *rptr)
192{
193 int size;
194
195 if (f->wptr >= rptr) {
196 size = f->wptr - rptr;
197 } else {
198 size = (f->end - rptr) + (f->wptr - f->buffer);
199 }
200 return size;
201}
202
203/* get data from the fifo (return -1 if not enough data) */
204int fifo_read(FifoBuffer *f, UINT8 *buf, int buf_size, UINT8 **rptr_ptr)
205{
206 UINT8 *rptr = *rptr_ptr;
207 int size, len;
208
209 if (f->wptr >= rptr) {
210 size = f->wptr - rptr;
211 } else {
212 size = (f->end - rptr) + (f->wptr - f->buffer);
213 }
214
215 if (size < buf_size)
216 return -1;
217 while (buf_size > 0) {
218 len = f->end - rptr;
219 if (len > buf_size)
220 len = buf_size;
221 memcpy(buf, rptr, len);
222 buf += len;
223 rptr += len;
224 if (rptr >= f->end)
225 rptr = f->buffer;
226 buf_size -= len;
227 }
228 *rptr_ptr = rptr;
229 return 0;
230}
231
232void fifo_write(FifoBuffer *f, UINT8 *buf, int size, UINT8 **wptr_ptr)
233{
234 int len;
235 UINT8 *wptr;
236 wptr = *wptr_ptr;
237 while (size > 0) {
238 len = f->end - wptr;
239 if (len > size)
240 len = size;
241 memcpy(wptr, buf, len);
242 wptr += len;
243 if (wptr >= f->end)
244 wptr = f->buffer;
245 buf += len;
246 size -= len;
247 }
248 *wptr_ptr = wptr;
249}
250
b9a281db
FB
251int filename_number_test(const char *filename)
252{
253 char buf[1024];
254 return get_frame_filename(buf, sizeof(buf), filename, 1);
255}
256
257/* guess file format */
a25e098d 258AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened)
b9a281db
FB
259{
260 AVInputFormat *fmt1, *fmt;
261 int score, score_max;
262
263 fmt = NULL;
264 score_max = 0;
265 for(fmt1 = first_iformat; fmt1 != NULL; fmt1 = fmt1->next) {
266 if (!is_opened && !(fmt1->flags & AVFMT_NOFILE))
267 continue;
268 score = 0;
a8dbe951
PG
269 if (fmt1->read_probe) {
270 score = fmt1->read_probe(pd);
271 } else if (fmt1->extensions) {
b9a281db
FB
272 if (match_ext(pd->filename, fmt1->extensions)) {
273 score = 50;
274 }
a8dbe951 275 }
b9a281db
FB
276 if (score > score_max) {
277 score_max = score;
278 fmt = fmt1;
279 }
280 }
281 return fmt;
282}
283
284/************************************************************/
285/* input media file */
96baaa6a 286
b9a281db
FB
287#define PROBE_BUF_SIZE 2048
288
289/**
290 * Open a media file as input. The codec are not opened. Only the file
291 * header (if present) is read.
292 *
293 * @param ic_ptr the opened media file handle is put here
294 * @param filename filename to open.
295 * @param fmt if non NULL, force the file format to use
296 * @param buf_size optional buffer size (zero if default is OK)
297 * @param ap additionnal parameters needed when opening the file (NULL if default)
298 * @return 0 if OK. AVERROR_xxx otherwise.
299 */
300int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,
301 AVInputFormat *fmt,
302 int buf_size,
303 AVFormatParameters *ap)
de6d9b64 304{
de6d9b64 305 AVFormatContext *ic = NULL;
de6d9b64 306 int err;
b9a281db
FB
307 char buf[PROBE_BUF_SIZE];
308 AVProbeData probe_data, *pd = &probe_data;
de6d9b64
FB
309
310 ic = av_mallocz(sizeof(AVFormatContext));
b9a281db
FB
311 if (!ic) {
312 err = AVERROR_NOMEM;
de6d9b64 313 goto fail;
de6d9b64 314 }
b9a281db
FB
315 pstrcpy(ic->filename, sizeof(ic->filename), filename);
316 pd->filename = ic->filename;
317 pd->buf = buf;
318 pd->buf_size = 0;
319
320 if (!fmt) {
321 /* guess format if no file can be opened */
a25e098d 322 fmt = av_probe_input_format(pd, 0);
de6d9b64 323 }
de6d9b64 324
96baaa6a 325 /* if no file needed do not try to open one */
b9a281db
FB
326 if (!fmt || !(fmt->flags & AVFMT_NOFILE)) {
327 if (url_fopen(&ic->pb, filename, URL_RDONLY) < 0) {
328 err = AVERROR_IO;
96baaa6a 329 goto fail;
b9a281db 330 }
96baaa6a
FB
331 if (buf_size > 0) {
332 url_setbufsize(&ic->pb, buf_size);
333 }
b9a281db
FB
334 /* read probe data */
335 pd->buf_size = get_buffer(&ic->pb, buf, PROBE_BUF_SIZE);
336 url_fseek(&ic->pb, 0, SEEK_SET);
96baaa6a
FB
337 }
338
b9a281db
FB
339 /* guess file format */
340 if (!fmt) {
a25e098d 341 fmt = av_probe_input_format(pd, 1);
b9a281db
FB
342 }
343
344 /* if still no format found, error */
345 if (!fmt) {
346 err = AVERROR_NOFMT;
de6d9b64
FB
347 goto fail;
348 }
b9a281db
FB
349
350 ic->iformat = fmt;
de6d9b64 351
b9a281db
FB
352 /* allocate private data */
353 ic->priv_data = av_mallocz(fmt->priv_data_size);
354 if (!ic->priv_data) {
355 err = AVERROR_NOMEM;
356 goto fail;
357 }
358
359 /* check filename in case of an image number is expected */
360 if (ic->iformat->flags & AVFMT_NEEDNUMBER) {
361 if (filename_number_test(ic->filename) < 0) {
362 err = AVERROR_NUMEXPECTED;
363 goto fail1;
364 }
365 }
366
367 err = ic->iformat->read_header(ic, ap);
368 if (err < 0)
369 goto fail1;
370 *ic_ptr = ic;
371 return 0;
372 fail1:
373 if (!(fmt->flags & AVFMT_NOFILE)) {
374 url_fclose(&ic->pb);
375 }
de6d9b64 376 fail:
b9a281db 377 if (ic) {
a8dbe951 378 av_freep(&ic->priv_data);
b9a281db 379 }
1ea4f593 380 av_free(ic);
b9a281db
FB
381 *ic_ptr = NULL;
382 return err;
de6d9b64
FB
383}
384
b9a281db
FB
385/**
386 * Read a packet from a media file
387 * @param s media file handle
388 * @param pkt is filled
389 * @return 0 if OK. AVERROR_xxx if error.
390 */
de6d9b64
FB
391int av_read_packet(AVFormatContext *s, AVPacket *pkt)
392{
393 AVPacketList *pktl;
394
395 pktl = s->packet_buffer;
396 if (pktl) {
397 /* read packet from packet buffer, if there is data */
398 *pkt = pktl->pkt;
399 s->packet_buffer = pktl->next;
1ea4f593 400 av_free(pktl);
de6d9b64
FB
401 return 0;
402 } else {
b9a281db
FB
403 return s->iformat->read_packet(s, pkt);
404 }
405}
406
407/* state for codec information */
408#define CSTATE_NOTFOUND 0
409#define CSTATE_DECODING 1
410#define CSTATE_FOUND 2
411
412static int has_codec_parameters(AVCodecContext *enc)
413{
414 int val;
415 switch(enc->codec_type) {
416 case CODEC_TYPE_AUDIO:
417 val = enc->sample_rate;
418 break;
419 case CODEC_TYPE_VIDEO:
420 val = enc->width;
421 break;
422 default:
423 val = 1;
424 break;
425 }
426 return (val != 0);
427}
428
429/**
430 * Read the beginning of a media file to get stream information. This
431 * is useful for file formats with no headers such as MPEG. This
432 * function also compute the real frame rate in case of mpeg2 repeat
433 * frame mode.
434 *
435 * @param ic media file handle
436 * @return >=0 if OK. AVERROR_xxx if error.
437 */
438int av_find_stream_info(AVFormatContext *ic)
439{
440 int i, count, ret, got_picture, size, read_size;
441 AVCodec *codec;
442 AVStream *st;
443 AVPacket *pkt;
444 AVPicture picture;
445 AVPacketList *pktl=NULL, **ppktl;
446 short samples[AVCODEC_MAX_AUDIO_FRAME_SIZE / 2];
447 UINT8 *ptr;
448 int min_read_size, max_read_size;
449
450 /* typical mpeg ts rate is 40 Mbits. DVD rate is about 10
451 Mbits. We read at most 0.1 second of file to find all streams */
452
453 /* XXX: base it on stream bitrate when possible */
454 if (ic->iformat == &mpegts_demux) {
455 /* maximum number of bytes we accept to read to find all the streams
456 in a file */
457 min_read_size = 3000000;
458 } else {
459 min_read_size = 125000;
460 }
461 /* max read size is 2 seconds of video max */
462 max_read_size = min_read_size * 20;
463
464 /* set initial codec state */
465 for(i=0;i<ic->nb_streams;i++) {
466 st = ic->streams[i];
467 if (has_codec_parameters(&st->codec))
468 st->codec_info_state = CSTATE_FOUND;
469 else
470 st->codec_info_state = CSTATE_NOTFOUND;
471 st->codec_info_nb_repeat_frames = 0;
472 st->codec_info_nb_real_frames = 0;
473 }
474
475 count = 0;
476 read_size = 0;
477 ppktl = &ic->packet_buffer;
478 for(;;) {
479 /* check if one codec still needs to be handled */
480 for(i=0;i<ic->nb_streams;i++) {
481 st = ic->streams[i];
482 if (st->codec_info_state != CSTATE_FOUND)
483 break;
484 }
485 if (i == ic->nb_streams) {
486 /* NOTE: if the format has no header, then we need to read
487 some packets to get most of the streams, so we cannot
488 stop here */
489 if (!(ic->iformat->flags & AVFMT_NOHEADER) ||
490 read_size >= min_read_size) {
491 /* if we found the info for all the codecs, we can stop */
492 ret = count;
493 break;
494 }
495 } else {
496 /* we did not get all the codec info, but we read too much data */
497 if (read_size >= max_read_size) {
498 ret = count;
499 break;
500 }
501 }
502
503 pktl = av_mallocz(sizeof(AVPacketList));
504 if (!pktl) {
505 ret = AVERROR_NOMEM;
506 break;
507 }
508
509 /* add the packet in the buffered packet list */
510 *ppktl = pktl;
511 ppktl = &pktl->next;
512
513 /* NOTE: a new stream can be added there if no header in file
514 (AVFMT_NOHEADER) */
515 pkt = &pktl->pkt;
516 if (ic->iformat->read_packet(ic, pkt) < 0) {
517 /* EOF or error */
518 ret = -1; /* we could not have all the codec parameters before EOF */
519 if ((ic->iformat->flags & AVFMT_NOHEADER) &&
520 i == ic->nb_streams)
521 ret = 0;
522 break;
523 }
524 read_size += pkt->size;
525
526 /* open new codecs */
527 for(i=0;i<ic->nb_streams;i++) {
528 st = ic->streams[i];
529 if (st->codec_info_state == CSTATE_NOTFOUND) {
530 /* set to found in case of error */
531 st->codec_info_state = CSTATE_FOUND;
532 codec = avcodec_find_decoder(st->codec.codec_id);
533 if (codec) {
534 ret = avcodec_open(&st->codec, codec);
535 if (ret >= 0)
536 st->codec_info_state = CSTATE_DECODING;
537 }
538 }
539 }
540
541 st = ic->streams[pkt->stream_index];
542 if (st->codec_info_state == CSTATE_DECODING) {
543 /* decode the data and update codec parameters */
544 ptr = pkt->data;
545 size = pkt->size;
546 while (size > 0) {
547 switch(st->codec.codec_type) {
548 case CODEC_TYPE_VIDEO:
549 ret = avcodec_decode_video(&st->codec, &picture,
550 &got_picture, ptr, size);
551 break;
552 case CODEC_TYPE_AUDIO:
553 ret = avcodec_decode_audio(&st->codec, samples,
554 &got_picture, ptr, size);
555 break;
556 default:
557 ret = -1;
558 break;
559 }
560 if (ret < 0) {
561 /* if error, simply ignore because another packet
562 may be OK */
563 break;
564 }
565 if (got_picture) {
566 /* we got the parameters - now we can stop
567 examining this stream */
568 /* XXX: add a codec info so that we can decide if
569 the codec can repeat frames */
570 if (st->codec.codec_id == CODEC_ID_MPEG1VIDEO &&
571 ic->iformat != &mpegts_demux &&
572 st->codec.sub_id == 2) {
573 /* for mpeg2 video, we want to know the real
574 frame rate, so we decode 40 frames. In mpeg
575 TS case we do not do it because it would be
576 too long */
577 st->codec_info_nb_real_frames++;
578 st->codec_info_nb_repeat_frames += st->codec.repeat_pict;
579#if 0
580 /* XXX: testing */
581 if ((st->codec_info_nb_real_frames % 24) == 23) {
582 st->codec_info_nb_repeat_frames += 2;
583 }
584#endif
585 /* stop after 40 frames */
586 if (st->codec_info_nb_real_frames >= 40) {
587 st->r_frame_rate = (st->codec.frame_rate *
588 st->codec_info_nb_real_frames) /
589 (st->codec_info_nb_real_frames +
590 (st->codec_info_nb_repeat_frames >> 1));
591 goto close_codec;
592 }
593 } else {
594 close_codec:
595 st->codec_info_state = CSTATE_FOUND;
596 avcodec_close(&st->codec);
24f9709b 597 break;
b9a281db 598 }
b9a281db
FB
599 }
600 ptr += ret;
601 size -= ret;
602 }
603 }
604 count++;
605 }
606
607 /* close each codec if there are opened */
608 for(i=0;i<ic->nb_streams;i++) {
609 st = ic->streams[i];
610 if (st->codec_info_state == CSTATE_DECODING)
611 avcodec_close(&st->codec);
612 }
613
614 /* set real frame rate info */
615 for(i=0;i<ic->nb_streams;i++) {
616 st = ic->streams[i];
617 if (st->codec.codec_type == CODEC_TYPE_VIDEO) {
618 if (!st->r_frame_rate)
619 st->r_frame_rate = st->codec.frame_rate;
620 }
de6d9b64 621 }
b9a281db
FB
622
623 return ret;
de6d9b64
FB
624}
625
b9a281db
FB
626/**
627 * Close a media file (but not its codecs)
628 *
629 * @param s media file handle
630 */
de6d9b64
FB
631void av_close_input_file(AVFormatContext *s)
632{
633 int i;
634
b9a281db
FB
635 if (s->iformat->read_close)
636 s->iformat->read_close(s);
de6d9b64 637 for(i=0;i<s->nb_streams;i++) {
1ea4f593 638 av_free(s->streams[i]);
de6d9b64
FB
639 }
640 if (s->packet_buffer) {
641 AVPacketList *p, *p1;
642 p = s->packet_buffer;
643 while (p != NULL) {
644 p1 = p->next;
645 av_free_packet(&p->pkt);
1ea4f593 646 av_free(p);
de6d9b64
FB
647 p = p1;
648 }
649 s->packet_buffer = NULL;
650 }
b9a281db 651 if (!(s->iformat->flags & AVFMT_NOFILE)) {
96baaa6a
FB
652 url_fclose(&s->pb);
653 }
a8dbe951 654 av_freep(&s->priv_data);
1ea4f593 655 av_free(s);
de6d9b64
FB
656}
657
b9a281db
FB
658/**
659 * Add a new stream to a media file. Can only be called in the
660 * read_header function. If the flag AVFMT_NOHEADER is in the format
661 * description, then new streams can be added in read_packet too.
662 *
663 *
664 * @param s media file handle
665 * @param id file format dependent stream id
666 */
667AVStream *av_new_stream(AVFormatContext *s, int id)
668{
669 AVStream *st;
670
671 if (s->nb_streams >= MAX_STREAMS)
672 return NULL;
673
674 st = av_mallocz(sizeof(AVStream));
675 if (!st)
676 return NULL;
677 st->index = s->nb_streams;
678 st->id = id;
679 s->streams[s->nb_streams++] = st;
680 return st;
681}
682
683/************************************************************/
684/* output media file */
de6d9b64 685
b9a281db
FB
686/**
687 * allocate the stream private data and write the stream header to an
688 * output media file
689 *
690 * @param s media file handle
691 * @return 0 if OK. AVERROR_xxx if error.
692 */
693int av_write_header(AVFormatContext *s)
694{
695 s->priv_data = av_mallocz(s->oformat->priv_data_size);
696 if (!s->priv_data)
697 return AVERROR_NOMEM;
698 return s->oformat->write_header(s);
699}
700
701/**
702 * write a packet to an output media file
703 *
704 * @param s media file handle
705 * @param pkt packet to write
706 * @param force_pts XXX: need to suppress that
707 */
10bb7023 708int av_write_packet(AVFormatContext *s, AVPacket *pkt, int force_pts)
de6d9b64
FB
709{
710 /* XXX: currently, an emulation because internal API must change */
b9a281db
FB
711 return s->oformat->write_packet(s, pkt->stream_index, pkt->data, pkt->size, force_pts);
712}
713
714/**
715 * write the stream trailer to an output media file and and free the
716 * file private data.
717 *
718 * @param s media file handle
719 * @return 0 if OK. AVERROR_xxx if error. */
720int av_write_trailer(AVFormatContext *s)
721{
722 int ret;
723 ret = s->oformat->write_trailer(s);
724 av_freep(&s->priv_data);
725 return ret;
de6d9b64
FB
726}
727
728/* "user interface" functions */
729
730void dump_format(AVFormatContext *ic,
731 int index,
732 const char *url,
733 int is_output)
734{
b9a281db 735 int i, flags;
de6d9b64
FB
736 char buf[256];
737
738 fprintf(stderr, "%s #%d, %s, %s '%s':\n",
739 is_output ? "Output" : "Input",
b9a281db
FB
740 index,
741 is_output ? ic->oformat->name : ic->iformat->name,
de6d9b64
FB
742 is_output ? "to" : "from", url);
743 for(i=0;i<ic->nb_streams;i++) {
744 AVStream *st = ic->streams[i];
745 avcodec_string(buf, sizeof(buf), &st->codec, is_output);
b9a281db
FB
746 fprintf(stderr, " Stream #%d.%d", index, i);
747 /* the pid is an important information, so we display it */
748 /* XXX: add a generic system */
749 if (is_output)
750 flags = ic->oformat->flags;
751 else
752 flags = ic->iformat->flags;
753 if (flags & AVFMT_SHOW_IDS) {
754 fprintf(stderr, "[0x%x]", st->id);
755 }
756 fprintf(stderr, ": %s\n", buf);
de6d9b64
FB
757 }
758}
759
760typedef struct {
761 const char *str;
762 int width, height;
763} SizeEntry;
764
765static SizeEntry sizes[] = {
766 { "sqcif", 128, 96 },
767 { "qcif", 176, 144 },
768 { "cif", 352, 288 },
769 { "4cif", 704, 576 },
770};
771
772int parse_image_size(int *width_ptr, int *height_ptr, const char *str)
773{
774 int i;
775 int n = sizeof(sizes) / sizeof(SizeEntry);
776 const char *p;
777 int frame_width = 0, frame_height = 0;
778
779 for(i=0;i<n;i++) {
780 if (!strcmp(sizes[i].str, str)) {
781 frame_width = sizes[i].width;
782 frame_height = sizes[i].height;
783 break;
784 }
785 }
786 if (i == n) {
787 p = str;
788 frame_width = strtol(p, (char **)&p, 10);
789 if (*p)
790 p++;
791 frame_height = strtol(p, (char **)&p, 10);
792 }
793 if (frame_width <= 0 || frame_height <= 0)
794 return -1;
795 *width_ptr = frame_width;
796 *height_ptr = frame_height;
797 return 0;
798}
799
a25e098d 800INT64 av_gettime(void)
de6d9b64 801{
8be1c656
FB
802#ifdef CONFIG_WIN32
803 struct _timeb tb;
804 _ftime(&tb);
805 return ((INT64)tb.time * INT64_C(1000) + (INT64)tb.millitm) * INT64_C(1000);
806#else
de6d9b64
FB
807 struct timeval tv;
808 gettimeofday(&tv,NULL);
809 return (INT64)tv.tv_sec * 1000000 + tv.tv_usec;
8be1c656 810#endif
de6d9b64
FB
811}
812
c5510dd6
PG
813static time_t mktimegm(struct tm *tm)
814{
815 time_t t;
816
817 int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
818
819 if (m < 3) {
820 m += 12;
821 y--;
822 }
823
824 t = 86400 *
825 (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469);
826
827 t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
828
829 return t;
830}
831
832/* syntax:
833 * [YYYY-MM-DD]{T| }HH[:MM[:SS[.m...]]][Z] .
834 * [YYYYMMDD]{T| }HH[MM[SS[.m...]]][Z] .
835 * Time is localtime unless Z is suffixed to the end. In this case GMT
836 * Return the date in micro seconds since 1970 */
de6d9b64
FB
837INT64 parse_date(const char *datestr, int duration)
838{
839 const char *p;
840 INT64 t;
2dbceb9f 841 struct tm dt;
c5510dd6
PG
842 int i;
843 static const char *date_fmt[] = {
844 "%Y-%m-%d",
845 "%Y%m%d",
846 };
847 static const char *time_fmt[] = {
848 "%H:%M:%S",
849 "%H%M%S",
850 };
851 const char *q;
852 int is_utc;
853 char lastch;
854 time_t now = time(0);
855
856 lastch = datestr[strlen(datestr)-1];
857
858 is_utc = (lastch == 'z' || lastch == 'Z');
2dbceb9f
PG
859
860 memset(&dt, 0, sizeof(dt));
de6d9b64
FB
861
862 p = datestr;
c5510dd6
PG
863 q = 0;
864
de6d9b64 865 if (!duration) {
c5510dd6
PG
866 for (i = 0; i < sizeof(date_fmt) / sizeof(date_fmt[0]); i++) {
867 q = strptime(p, date_fmt[i], &dt);
868 if (q) {
869 break;
870 }
871 }
872
873 if (!q) {
874 if (is_utc) {
875 dt = *gmtime(&now);
876 } else {
877 dt = *localtime(&now);
878 }
879 dt.tm_hour = dt.tm_min = dt.tm_sec = 0;
de6d9b64 880 } else {
c5510dd6 881 p = q;
de6d9b64 882 }
c5510dd6
PG
883
884 if (*p == 'T' || *p == 't' || *p == ' ')
885 p++;
886 }
887
888 for (i = 0; i < sizeof(time_fmt) / sizeof(time_fmt[0]); i++) {
889 q = strptime(p, time_fmt[i], &dt);
890 if (q) {
891 break;
892 }
893 }
894
895 /* Now we have all the fields that we can get */
896 if (!q) {
897 if (duration)
898 return 0;
899 else
900 return now * INT64_C(1000000);
de6d9b64 901 }
2dbceb9f
PG
902
903 if (duration) {
c5510dd6 904 t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
2dbceb9f 905 } else {
c5510dd6
PG
906 dt.tm_isdst = -1; /* unknown */
907 if (is_utc) {
908 t = mktimegm(&dt);
909 } else {
910 t = mktime(&dt);
911 }
de6d9b64 912 }
2dbceb9f 913
c5510dd6
PG
914 t *= 1000000;
915
916 if (*q == '.') {
de6d9b64 917 int val, n;
c5510dd6
PG
918 q++;
919 for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
920 if (!isdigit(*q))
921 break;
922 val += n * (*q - '0');
de6d9b64
FB
923 }
924 t += val;
925 }
926 return t;
927}
928
2dbceb9f 929/* syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done. Return
de6d9b64
FB
930 1 if found */
931int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
932{
933 const char *p;
934 char tag[128], *q;
935
936 p = info;
937 if (*p == '?')
938 p++;
939 for(;;) {
940 q = tag;
941 while (*p != '\0' && *p != '=' && *p != '&') {
942 if ((q - tag) < sizeof(tag) - 1)
943 *q++ = *p;
944 p++;
945 }
946 *q = '\0';
947 q = arg;
948 if (*p == '=') {
949 p++;
950 while (*p != '&' && *p != '\0') {
2dbceb9f
PG
951 if ((q - arg) < arg_size - 1) {
952 if (*p == '+')
953 *q++ = ' ';
954 else
955 *q++ = *p;
956 }
de6d9b64
FB
957 p++;
958 }
959 *q = '\0';
960 }
961 if (!strcmp(tag, tag1))
962 return 1;
963 if (*p != '&')
964 break;
8d1335ea 965 p++;
de6d9b64
FB
966 }
967 return 0;
968}
969
9150f42e
FB
970/* Return in 'buf' the path with '%d' replaced by number. Also handles
971 the '%0nd' format where 'n' is the total number of digits and
972 '%%'. Return 0 if OK, and -1 if format error */
973int get_frame_filename(char *buf, int buf_size,
974 const char *path, int number)
975{
976 const char *p;
977 char *q, buf1[20];
978 int nd, len, c, percentd_found;
979
980 q = buf;
981 p = path;
982 percentd_found = 0;
983 for(;;) {
984 c = *p++;
985 if (c == '\0')
986 break;
987 if (c == '%') {
988 nd = 0;
989 while (*p >= '0' && *p <= '9') {
990 nd = nd * 10 + *p++ - '0';
991 }
992 c = *p++;
993 switch(c) {
994 case '%':
995 goto addchar;
996 case 'd':
997 if (percentd_found)
998 goto fail;
999 percentd_found = 1;
1000 snprintf(buf1, sizeof(buf1), "%0*d", nd, number);
1001 len = strlen(buf1);
1002 if ((q - buf + len) > buf_size - 1)
1003 goto fail;
1004 memcpy(q, buf1, len);
1005 q += len;
1006 break;
1007 default:
1008 goto fail;
1009 }
1010 } else {
1011 addchar:
1012 if ((q - buf) < buf_size - 1)
1013 *q++ = c;
1014 }
1015 }
1016 if (!percentd_found)
1017 goto fail;
1018 *q = '\0';
1019 return 0;
1020 fail:
1021 *q = '\0';
1022 return -1;
1023}
1024
af469427
J
1025static int gcd(INT64 a, INT64 b)
1026{
1027 INT64 c;
1028
1029 while (1) {
1030 c = a % b;
1031 if (c == 0)
1032 return b;
1033 a = b;
1034 b = c;
1035 }
1036}
1037
1038void ticker_init(Ticker *tick, INT64 inrate, INT64 outrate)
1039{
1040 int g;
1041
1042 g = gcd(inrate, outrate);
1043 inrate /= g;
1044 outrate /= g;
9150f42e 1045
af469427
J
1046 tick->value = -outrate/2;
1047
1048 tick->inrate = inrate;
1049 tick->outrate = outrate;
1050 tick->div = tick->outrate / tick->inrate;
1051 tick->mod = tick->outrate % tick->inrate;
1052}
b9a281db
FB
1053
1054/**
1055 *
1056 * Print on stdout a nice hexa dump of a buffer
1057 * @param buf buffer
1058 * @param size buffer size
1059 */
1060void av_hex_dump(UINT8 *buf, int size)
1061{
1062 int len, i, j, c;
1063
1064 for(i=0;i<size;i+=16) {
1065 len = size - i;
1066 if (len > 16)
1067 len = 16;
1068 printf("%08x ", i);
1069 for(j=0;j<16;j++) {
1070 if (j < len)
1071 printf(" %02x", buf[i+j]);
1072 else
1073 printf(" ");
1074 }
1075 printf(" ");
1076 for(j=0;j<len;j++) {
1077 c = buf[i+j];
1078 if (c < ' ' || c > '~')
1079 c = '.';
1080 printf("%c", c);
1081 }
1082 printf("\n");
1083 }
1084}
1085
a9a721da
FB
1086void url_split(char *proto, int proto_size,
1087 char *hostname, int hostname_size,
1088 int *port_ptr,
1089 char *path, int path_size,
1090 const char *url)
1091{
1092 const char *p;
1093 char *q;
1094 int port;
1095
1096 port = -1;
1097
1098 p = url;
1099 q = proto;
1100 while (*p != ':' && *p != '\0') {
1101 if ((q - proto) < proto_size - 1)
1102 *q++ = *p;
1103 p++;
1104 }
1105 if (proto_size > 0)
1106 *q = '\0';
1107 if (*p == '\0') {
1108 if (proto_size > 0)
1109 proto[0] = '\0';
1110 if (hostname_size > 0)
1111 hostname[0] = '\0';
1112 p = url;
1113 } else {
1114 p++;
1115 if (*p == '/')
1116 p++;
1117 if (*p == '/')
1118 p++;
1119 q = hostname;
1120 while (*p != ':' && *p != '/' && *p != '?' && *p != '\0') {
1121 if ((q - hostname) < hostname_size - 1)
1122 *q++ = *p;
1123 p++;
1124 }
1125 if (hostname_size > 0)
1126 *q = '\0';
1127 if (*p == ':') {
1128 p++;
1129 port = strtoul(p, (char **)&p, 10);
1130 }
1131 }
1132 if (port_ptr)
1133 *port_ptr = port;
1134 pstrcpy(path, path_size, p);
1135}
1136