2 * Various utilities for ffmpeg system
3 * Copyright (c) 2000,2001 Gerard Lantau
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.
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.
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.
27 #define strcasecmp _stricmp
28 #include <sys/types.h>
29 #include <sys/timeb.h>
32 AVFormat *first_format;
34 void register_avformat(AVFormat *format)
38 while (*p != NULL) p = &(*p)->next;
43 int match_ext(const char *filename, const char *extensions)
48 ext = strrchr(filename, '.');
54 while (*p != '\0' && *p != ',')
57 if (!strcasecmp(ext1, ext))
67 AVFormat *guess_format(const char *short_name, const char *filename, const char *mime_type)
69 AVFormat *fmt, *fmt_found;
72 /* find the proper file type */
78 if (fmt->name && short_name && !strcmp(fmt->name, short_name))
80 if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
82 if (filename && fmt->extensions &&
83 match_ext(filename, fmt->extensions)) {
86 if (score > score_max) {
95 /* return TRUE if val is a prefix of str. If it returns TRUE, ptr is
96 set to the next character in 'str' after the prefix */
97 int strstart(const char *str, const char *val, const char **ptr)
113 void nstrcpy(char *buf, int buf_size, const char *str)
120 if (c == 0 || q >= buf + buf_size - 1)
127 void register_all(void)
130 avcodec_register_all();
132 register_avformat(&mp2_format);
133 register_avformat(&ac3_format);
134 register_avformat(&mpeg_mux_format);
135 register_avformat(&mpeg1video_format);
136 register_avformat(&mjpeg_format);
137 register_avformat(&h263_format);
138 register_avformat(&rm_format);
139 register_avformat(&asf_format);
140 register_avformat(&avi_format);
141 register_avformat(&mpjpeg_format);
142 register_avformat(&jpeg_format);
143 register_avformat(&single_jpeg_format);
144 register_avformat(&swf_format);
145 register_avformat(&wav_format);
146 register_avformat(&pcm_s16le_format);
147 register_avformat(&pcm_s16be_format);
148 register_avformat(&pcm_u16le_format);
149 register_avformat(&pcm_u16be_format);
150 register_avformat(&pcm_s8_format);
151 register_avformat(&pcm_u8_format);
152 register_avformat(&pcm_mulaw_format);
153 register_avformat(&pcm_alaw_format);
154 register_avformat(&rawvideo_format);
156 register_avformat(&ffm_format);
158 register_avformat(&pgm_format);
159 register_avformat(&ppm_format);
160 register_avformat(&pgmyuv_format);
161 register_avformat(&imgyuv_format);
162 register_avformat(&pgmpipe_format);
163 register_avformat(&pgmyuvpipe_format);
164 register_avformat(&ppmpipe_format);
166 register_avformat(&video_grab_device_format);
167 register_avformat(&audio_device_format);
171 register_protocol(&file_protocol);
172 register_protocol(&pipe_protocol);
174 register_protocol(&udp_protocol);
175 register_protocol(&http_protocol);
179 /* memory handling */
181 int av_new_packet(AVPacket *pkt, int size)
183 pkt->data = malloc(size);
189 pkt->stream_index = 0;
194 void av_free_packet(AVPacket *pkt)
204 int fifo_init(FifoBuffer *f, int size)
206 f->buffer = malloc(size);
209 f->end = f->buffer + size;
210 f->wptr = f->rptr = f->buffer;
214 void fifo_free(FifoBuffer *f)
219 int fifo_size(FifoBuffer *f, UINT8 *rptr)
223 if (f->wptr >= rptr) {
224 size = f->wptr - rptr;
226 size = (f->end - rptr) + (f->wptr - f->buffer);
231 /* get data from the fifo (return -1 if not enough data) */
232 int fifo_read(FifoBuffer *f, UINT8 *buf, int buf_size, UINT8 **rptr_ptr)
234 UINT8 *rptr = *rptr_ptr;
237 if (f->wptr >= rptr) {
238 size = f->wptr - rptr;
240 size = (f->end - rptr) + (f->wptr - f->buffer);
245 while (buf_size > 0) {
249 memcpy(buf, rptr, len);
260 void fifo_write(FifoBuffer *f, UINT8 *buf, int size, UINT8 **wptr_ptr)
269 memcpy(wptr, buf, len);
279 /* media file handling.
280 'filename' is the filename to open.
281 'format_name' is used to force the file format (NULL if auto guess).
282 'buf_size' is the optional buffer size (zero if default is OK).
283 'ap' are additionnal parameters needed when opening the file (NULL if default).
286 AVFormatContext *av_open_input_file(const char *filename,
287 const char *format_name,
289 AVFormatParameters *ap)
292 AVFormatContext *ic = NULL;
295 ic = av_mallocz(sizeof(AVFormatContext));
300 if (format_name != NULL) {
301 fmt = guess_format(format_name, NULL, NULL);
303 fmt = guess_format(NULL, filename, NULL);
305 if (!fmt || !fmt->read_header) {
310 /* if no file needed do not try to open one */
311 if (!(fmt->flags & AVFMT_NOFILE)) {
312 if (url_fopen(&ic->pb, filename, URL_RDONLY) < 0)
315 url_setbufsize(&ic->pb, buf_size);
319 err = ic->format->read_header(ic, ap);
321 if (!(fmt->flags & AVFMT_NOFILE)) {
335 int av_read_packet(AVFormatContext *s, AVPacket *pkt)
339 pktl = s->packet_buffer;
341 /* read packet from packet buffer, if there is data */
343 s->packet_buffer = pktl->next;
347 return s->format->read_packet(s, pkt);
351 void av_close_input_file(AVFormatContext *s)
355 if (s->format->read_close)
356 s->format->read_close(s);
357 for(i=0;i<s->nb_streams;i++) {
360 if (s->packet_buffer) {
361 AVPacketList *p, *p1;
362 p = s->packet_buffer;
365 av_free_packet(&p->pkt);
369 s->packet_buffer = NULL;
371 if (!(s->format->flags & AVFMT_NOFILE)) {
378 int av_write_packet(AVFormatContext *s, AVPacket *pkt)
380 /* XXX: currently, an emulation because internal API must change */
381 return s->format->write_packet(s, pkt->stream_index, pkt->data, pkt->size);
384 /* "user interface" functions */
386 void dump_format(AVFormatContext *ic,
394 fprintf(stderr, "%s #%d, %s, %s '%s':\n",
395 is_output ? "Output" : "Input",
396 index, ic->format->name,
397 is_output ? "to" : "from", url);
398 for(i=0;i<ic->nb_streams;i++) {
399 AVStream *st = ic->streams[i];
400 avcodec_string(buf, sizeof(buf), &st->codec, is_output);
401 fprintf(stderr, " Stream #%d.%d: %s\n", index, i, buf);
410 static SizeEntry sizes[] = {
411 { "sqcif", 128, 96 },
412 { "qcif", 176, 144 },
414 { "4cif", 704, 576 },
417 int parse_image_size(int *width_ptr, int *height_ptr, const char *str)
420 int n = sizeof(sizes) / sizeof(SizeEntry);
422 int frame_width = 0, frame_height = 0;
425 if (!strcmp(sizes[i].str, str)) {
426 frame_width = sizes[i].width;
427 frame_height = sizes[i].height;
433 frame_width = strtol(p, (char **)&p, 10);
436 frame_height = strtol(p, (char **)&p, 10);
438 if (frame_width <= 0 || frame_height <= 0)
440 *width_ptr = frame_width;
441 *height_ptr = frame_height;
450 return ((INT64)tb.time * INT64_C(1000) + (INT64)tb.millitm) * INT64_C(1000);
453 gettimeofday(&tv,NULL);
454 return (INT64)tv.tv_sec * 1000000 + tv.tv_usec;
458 /* syntax: [YYYY-MM-DD ][[HH:]MM:]SS[.m...] . Return the date in micro seconds since 1970 */
459 INT64 parse_date(const char *datestr, int duration)
467 static const UINT8 months[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
468 int year, month, day, i;
470 if (strlen(p) >= 5 && p[4] == '-') {
472 year = strtol(p, (char **)&p, 10);
475 month = strtol(p, (char **)&p, 10) - 1;
478 day = strtol(p, (char **)&p, 10) - 1;
481 day += (year - 1970) * 365;
482 /* if >= March, take February of current year into account too */
485 for(i=1970;i<year;i++) {
486 if ((i % 100) == 0) {
487 if ((i % 400) == 0) day++;
488 } else if ((i % 4) == 0) {
495 day = (time(NULL) / (3600 * 24));
497 t = day * (3600 * 24);
505 val = strtol(p, (char **)&p, 10);
506 sec = sec * 60 + val;
511 t = (t + sec) * 1000000;
518 val = strtol(p, NULL, 10);
528 /* syntax: '?tag1=val1&tag2=val2...'. No URL decoding is done. Return
530 int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
540 while (*p != '\0' && *p != '=' && *p != '&') {
541 if ((q - tag) < sizeof(tag) - 1)
549 while (*p != '&' && *p != '\0') {
550 if ((q - arg) < arg_size - 1)
556 if (!strcmp(tag, tag1))
564 /* Return in 'buf' the path with '%d' replaced by number. Also handles
565 the '%0nd' format where 'n' is the total number of digits and
566 '%%'. Return 0 if OK, and -1 if format error */
567 int get_frame_filename(char *buf, int buf_size,
568 const char *path, int number)
572 int nd, len, c, percentd_found;
583 while (*p >= '0' && *p <= '9') {
584 nd = nd * 10 + *p++ - '0';
594 snprintf(buf1, sizeof(buf1), "%0*d", nd, number);
596 if ((q - buf + len) > buf_size - 1)
598 memcpy(q, buf1, len);
606 if ((q - buf) < buf_size - 1)
619 static int gcd(INT64 a, INT64 b)
632 void ticker_init(Ticker *tick, INT64 inrate, INT64 outrate)
636 g = gcd(inrate, outrate);
640 tick->value = -outrate/2;
642 tick->inrate = inrate;
643 tick->outrate = outrate;
644 tick->div = tick->outrate / tick->inrate;
645 tick->mod = tick->outrate % tick->inrate;