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