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.
26 #define strcasecmp _stricmp
27 #include <sys/types.h>
28 #include <sys/timeb.h>
31 AVFormat *first_format;
33 void register_avformat(AVFormat *format)
37 while (*p != NULL) p = &(*p)->next;
42 int match_ext(const char *filename, const char *extensions)
47 ext = strrchr(filename, '.');
53 while (*p != '\0' && *p != ',')
56 if (!strcasecmp(ext1, ext))
66 AVFormat *guess_format(const char *short_name, const char *filename, const char *mime_type)
68 AVFormat *fmt, *fmt_found;
71 /* find the proper file type */
77 if (fmt->name && short_name && !strcmp(fmt->name, short_name))
79 if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
81 if (filename && fmt->extensions &&
82 match_ext(filename, fmt->extensions)) {
85 if (score > score_max) {
94 /* return TRUE if val is a prefix of str. If it returns TRUE, ptr is
95 set to the next character in 'str' after the prefix */
96 int strstart(const char *str, const char *val, const char **ptr)
112 void nstrcpy(char *buf, int buf_size, const char *str)
119 if (c == 0 || q >= buf + buf_size - 1)
126 void register_all(void)
129 avcodec_register_all();
131 register_avformat(&mp2_format);
132 register_avformat(&ac3_format);
133 register_avformat(&mpeg_mux_format);
134 register_avformat(&mpeg1video_format);
135 register_avformat(&h263_format);
136 register_avformat(&rm_format);
137 register_avformat(&asf_format);
138 register_avformat(&avi_format);
139 register_avformat(&mpjpeg_format);
140 register_avformat(&jpeg_format);
141 register_avformat(&swf_format);
142 register_avformat(&wav_format);
143 register_avformat(&pcm_format);
144 register_avformat(&rawvideo_format);
146 register_avformat(&ffm_format);
148 register_avformat(&pgm_format);
149 register_avformat(&ppm_format);
150 register_avformat(&pgmyuv_format);
151 register_avformat(&imgyuv_format);
152 register_avformat(&pgmpipe_format);
153 register_avformat(&pgmyuvpipe_format);
154 register_avformat(&ppmpipe_format);
156 register_protocol(&file_protocol);
157 register_protocol(&pipe_protocol);
159 register_protocol(&audio_protocol);
160 register_protocol(&video_protocol);
163 register_protocol(&udp_protocol);
164 register_protocol(&http_protocol);
168 /* memory handling */
170 int av_new_packet(AVPacket *pkt, int size)
172 pkt->data = malloc(size);
178 pkt->stream_index = 0;
183 void av_free_packet(AVPacket *pkt)
193 int fifo_init(FifoBuffer *f, int size)
195 f->buffer = malloc(size);
198 f->end = f->buffer + size;
199 f->wptr = f->rptr = f->buffer;
203 void fifo_free(FifoBuffer *f)
208 int fifo_size(FifoBuffer *f, UINT8 *rptr)
212 if (f->wptr >= rptr) {
213 size = f->wptr - rptr;
215 size = (f->end - rptr) + (f->wptr - f->buffer);
220 /* get data from the fifo (return -1 if not enough data) */
221 int fifo_read(FifoBuffer *f, UINT8 *buf, int buf_size, UINT8 **rptr_ptr)
223 UINT8 *rptr = *rptr_ptr;
226 if (f->wptr >= rptr) {
227 size = f->wptr - rptr;
229 size = (f->end - rptr) + (f->wptr - f->buffer);
234 while (buf_size > 0) {
238 memcpy(buf, rptr, len);
249 void fifo_write(FifoBuffer *f, UINT8 *buf, int size, UINT8 **wptr_ptr)
258 memcpy(wptr, buf, len);
268 /* media file handling */
270 AVFormatContext *av_open_input_file(const char *filename, int buf_size)
272 AVFormatParameters params, *ap;
274 AVFormatContext *ic = NULL;
275 URLFormat url_format;
278 ic = av_mallocz(sizeof(AVFormatContext));
281 if (url_fopen(&ic->pb, filename, URL_RDONLY) < 0)
285 url_setbufsize(&ic->pb, buf_size);
289 err = url_getformat(url_fileno(&ic->pb), &url_format);
291 fmt = guess_format(url_format.format_name, NULL, NULL);
293 ap->sample_rate = url_format.sample_rate;
294 ap->frame_rate = url_format.frame_rate;
295 ap->channels = url_format.channels;
296 ap->width = url_format.width;
297 ap->height = url_format.height;
298 ap->pix_fmt = url_format.pix_fmt;
300 fmt = guess_format(NULL, filename, NULL);
303 if (!fmt || !fmt->read_header) {
308 err = ic->format->read_header(ic, ap);
322 int av_read_packet(AVFormatContext *s, AVPacket *pkt)
326 pktl = s->packet_buffer;
328 /* read packet from packet buffer, if there is data */
330 s->packet_buffer = pktl->next;
334 return s->format->read_packet(s, pkt);
338 void av_close_input_file(AVFormatContext *s)
342 if (s->format->read_close)
343 s->format->read_close(s);
344 for(i=0;i<s->nb_streams;i++) {
347 if (s->packet_buffer) {
348 AVPacketList *p, *p1;
349 p = s->packet_buffer;
352 av_free_packet(&p->pkt);
356 s->packet_buffer = NULL;
363 int av_write_packet(AVFormatContext *s, AVPacket *pkt)
365 /* XXX: currently, an emulation because internal API must change */
366 return s->format->write_packet(s, pkt->stream_index, pkt->data, pkt->size);
369 /* "user interface" functions */
371 void dump_format(AVFormatContext *ic,
379 fprintf(stderr, "%s #%d, %s, %s '%s':\n",
380 is_output ? "Output" : "Input",
381 index, ic->format->name,
382 is_output ? "to" : "from", url);
383 for(i=0;i<ic->nb_streams;i++) {
384 AVStream *st = ic->streams[i];
385 avcodec_string(buf, sizeof(buf), &st->codec, is_output);
386 fprintf(stderr, " Stream #%d.%d: %s\n", index, i, buf);
395 static SizeEntry sizes[] = {
396 { "sqcif", 128, 96 },
397 { "qcif", 176, 144 },
399 { "4cif", 704, 576 },
402 int parse_image_size(int *width_ptr, int *height_ptr, const char *str)
405 int n = sizeof(sizes) / sizeof(SizeEntry);
407 int frame_width = 0, frame_height = 0;
410 if (!strcmp(sizes[i].str, str)) {
411 frame_width = sizes[i].width;
412 frame_height = sizes[i].height;
418 frame_width = strtol(p, (char **)&p, 10);
421 frame_height = strtol(p, (char **)&p, 10);
423 if (frame_width <= 0 || frame_height <= 0)
425 *width_ptr = frame_width;
426 *height_ptr = frame_height;
435 return ((INT64)tb.time * INT64_C(1000) + (INT64)tb.millitm) * INT64_C(1000);
438 gettimeofday(&tv,NULL);
439 return (INT64)tv.tv_sec * 1000000 + tv.tv_usec;
443 /* syntax: [YYYY-MM-DD ][[HH:]MM:]SS[.m...] . Return the date in micro seconds since 1970 */
444 INT64 parse_date(const char *datestr, int duration)
452 static const UINT8 months[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
453 int year, month, day, i;
455 if (strlen(p) >= 5 && p[4] == '-') {
457 year = strtol(p, (char **)&p, 10);
460 month = strtol(p, (char **)&p, 10) - 1;
463 day = strtol(p, (char **)&p, 10) - 1;
466 day += (year - 1970) * 365;
467 /* if >= March, take February of current year into account too */
470 for(i=1970;i<year;i++) {
471 if ((i % 100) == 0) {
472 if ((i % 400) == 0) day++;
473 } else if ((i % 4) == 0) {
480 day = (time(NULL) / (3600 * 24));
482 t = day * (3600 * 24);
490 val = strtol(p, (char **)&p, 10);
491 sec = sec * 60 + val;
496 t = (t + sec) * 1000000;
503 val = strtol(p, NULL, 10);
513 /* syntax: '?tag1=val1&tag2=val2...'. No URL decoding is done. Return
515 int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
525 while (*p != '\0' && *p != '=' && *p != '&') {
526 if ((q - tag) < sizeof(tag) - 1)
534 while (*p != '&' && *p != '\0') {
535 if ((q - arg) < arg_size - 1)
541 if (!strcmp(tag, tag1))