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