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(&mjpeg_format
);
136 register_avformat(&h263_format
);
137 register_avformat(&rm_format
);
138 register_avformat(&asf_format
);
139 register_avformat(&avi_format
);
140 register_avformat(&mpjpeg_format
);
141 register_avformat(&jpeg_format
);
142 register_avformat(&single_jpeg_format
);
143 register_avformat(&swf_format
);
144 register_avformat(&wav_format
);
145 register_avformat(&pcm_s16le_format
);
146 register_avformat(&pcm_s16be_format
);
147 register_avformat(&pcm_u16le_format
);
148 register_avformat(&pcm_u16be_format
);
149 register_avformat(&pcm_s8_format
);
150 register_avformat(&pcm_u8_format
);
151 register_avformat(&pcm_mulaw_format
);
152 register_avformat(&pcm_alaw_format
);
153 register_avformat(&rawvideo_format
);
155 register_avformat(&ffm_format
);
157 register_avformat(&pgm_format
);
158 register_avformat(&ppm_format
);
159 register_avformat(&pgmyuv_format
);
160 register_avformat(&imgyuv_format
);
161 register_avformat(&pgmpipe_format
);
162 register_avformat(&pgmyuvpipe_format
);
163 register_avformat(&ppmpipe_format
);
165 register_protocol(&file_protocol
);
166 register_protocol(&pipe_protocol
);
168 register_protocol(&audio_protocol
);
169 register_protocol(&video_protocol
);
172 register_protocol(&udp_protocol
);
173 register_protocol(&http_protocol
);
177 /* memory handling */
179 int av_new_packet(AVPacket
*pkt
, int size
)
181 pkt
->data
= malloc(size
);
187 pkt
->stream_index
= 0;
192 void av_free_packet(AVPacket
*pkt
)
202 int fifo_init(FifoBuffer
*f
, int size
)
204 f
->buffer
= malloc(size
);
207 f
->end
= f
->buffer
+ size
;
208 f
->wptr
= f
->rptr
= f
->buffer
;
212 void fifo_free(FifoBuffer
*f
)
217 int fifo_size(FifoBuffer
*f
, UINT8
*rptr
)
221 if (f
->wptr
>= rptr
) {
222 size
= f
->wptr
- rptr
;
224 size
= (f
->end
- rptr
) + (f
->wptr
- f
->buffer
);
229 /* get data from the fifo (return -1 if not enough data) */
230 int fifo_read(FifoBuffer
*f
, UINT8
*buf
, int buf_size
, UINT8
**rptr_ptr
)
232 UINT8
*rptr
= *rptr_ptr
;
235 if (f
->wptr
>= rptr
) {
236 size
= f
->wptr
- rptr
;
238 size
= (f
->end
- rptr
) + (f
->wptr
- f
->buffer
);
243 while (buf_size
> 0) {
247 memcpy(buf
, rptr
, len
);
258 void fifo_write(FifoBuffer
*f
, UINT8
*buf
, int size
, UINT8
**wptr_ptr
)
267 memcpy(wptr
, buf
, len
);
277 /* media file handling */
279 AVFormatContext
*av_open_input_file(const char *filename
, int buf_size
)
281 AVFormatParameters params
, *ap
;
283 AVFormatContext
*ic
= NULL
;
284 URLFormat url_format
;
287 ic
= av_mallocz(sizeof(AVFormatContext
));
290 if (url_fopen(&ic
->pb
, filename
, URL_RDONLY
) < 0)
294 url_setbufsize(&ic
->pb
, buf_size
);
298 err
= url_getformat(url_fileno(&ic
->pb
), &url_format
);
300 fmt
= guess_format(url_format
.format_name
, NULL
, NULL
);
302 ap
->sample_rate
= url_format
.sample_rate
;
303 ap
->frame_rate
= url_format
.frame_rate
;
304 ap
->channels
= url_format
.channels
;
305 ap
->width
= url_format
.width
;
306 ap
->height
= url_format
.height
;
307 ap
->pix_fmt
= url_format
.pix_fmt
;
309 fmt
= guess_format(NULL
, filename
, NULL
);
312 if (!fmt
|| !fmt
->read_header
) {
317 err
= ic
->format
->read_header(ic
, ap
);
331 int av_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
335 pktl
= s
->packet_buffer
;
337 /* read packet from packet buffer, if there is data */
339 s
->packet_buffer
= pktl
->next
;
343 return s
->format
->read_packet(s
, pkt
);
347 void av_close_input_file(AVFormatContext
*s
)
351 if (s
->format
->read_close
)
352 s
->format
->read_close(s
);
353 for(i
=0;i
<s
->nb_streams
;i
++) {
356 if (s
->packet_buffer
) {
357 AVPacketList
*p
, *p1
;
358 p
= s
->packet_buffer
;
361 av_free_packet(&p
->pkt
);
365 s
->packet_buffer
= NULL
;
372 int av_write_packet(AVFormatContext
*s
, AVPacket
*pkt
)
374 /* XXX: currently, an emulation because internal API must change */
375 return s
->format
->write_packet(s
, pkt
->stream_index
, pkt
->data
, pkt
->size
);
378 /* "user interface" functions */
380 void dump_format(AVFormatContext
*ic
,
388 fprintf(stderr
, "%s #%d, %s, %s '%s':\n",
389 is_output ?
"Output" : "Input",
390 index
, ic
->format
->name
,
391 is_output ?
"to" : "from", url
);
392 for(i
=0;i
<ic
->nb_streams
;i
++) {
393 AVStream
*st
= ic
->streams
[i
];
394 avcodec_string(buf
, sizeof(buf
), &st
->codec
, is_output
);
395 fprintf(stderr
, " Stream #%d.%d: %s\n", index
, i
, buf
);
404 static SizeEntry sizes
[] = {
405 { "sqcif", 128, 96 },
406 { "qcif", 176, 144 },
408 { "4cif", 704, 576 },
411 int parse_image_size(int *width_ptr
, int *height_ptr
, const char *str
)
414 int n
= sizeof(sizes
) / sizeof(SizeEntry
);
416 int frame_width
= 0, frame_height
= 0;
419 if (!strcmp(sizes
[i
].str
, str
)) {
420 frame_width
= sizes
[i
].width
;
421 frame_height
= sizes
[i
].height
;
427 frame_width
= strtol(p
, (char **)&p
, 10);
430 frame_height
= strtol(p
, (char **)&p
, 10);
432 if (frame_width
<= 0 || frame_height
<= 0)
434 *width_ptr
= frame_width
;
435 *height_ptr
= frame_height
;
444 return ((INT64
)tb
.time
* INT64_C(1000) + (INT64
)tb
.millitm
) * INT64_C(1000);
447 gettimeofday(&tv
,NULL
);
448 return (INT64
)tv
.tv_sec
* 1000000 + tv
.tv_usec
;
452 /* syntax: [YYYY-MM-DD ][[HH:]MM:]SS[.m...] . Return the date in micro seconds since 1970 */
453 INT64
parse_date(const char *datestr
, int duration
)
461 static const UINT8 months
[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
462 int year
, month
, day
, i
;
464 if (strlen(p
) >= 5 && p
[4] == '-') {
466 year
= strtol(p
, (char **)&p
, 10);
469 month
= strtol(p
, (char **)&p
, 10) - 1;
472 day
= strtol(p
, (char **)&p
, 10) - 1;
475 day
+= (year
- 1970) * 365;
476 /* if >= March, take February of current year into account too */
479 for(i
=1970;i
<year
;i
++) {
480 if ((i
% 100) == 0) {
481 if ((i
% 400) == 0) day
++;
482 } else if ((i
% 4) == 0) {
489 day
= (time(NULL
) / (3600 * 24));
491 t
= day
* (3600 * 24);
499 val
= strtol(p
, (char **)&p
, 10);
500 sec
= sec
* 60 + val
;
505 t
= (t
+ sec
) * 1000000;
512 val
= strtol(p
, NULL
, 10);
522 /* syntax: '?tag1=val1&tag2=val2...'. No URL decoding is done. Return
524 int find_info_tag(char *arg
, int arg_size
, const char *tag1
, const char *info
)
534 while (*p
!= '\0' && *p
!= '=' && *p
!= '&') {
535 if ((q
- tag
) < sizeof(tag
) - 1)
543 while (*p
!= '&' && *p
!= '\0') {
544 if ((q
- arg
) < arg_size
- 1)
550 if (!strcmp(tag
, tag1
))
558 /* Return in 'buf' the path with '%d' replaced by number. Also handles
559 the '%0nd' format where 'n' is the total number of digits and
560 '%%'. Return 0 if OK, and -1 if format error */
561 int get_frame_filename(char *buf
, int buf_size
,
562 const char *path
, int number
)
566 int nd
, len
, c
, percentd_found
;
577 while (*p
>= '0' && *p
<= '9') {
578 nd
= nd
* 10 + *p
++ - '0';
588 snprintf(buf1
, sizeof(buf1
), "%0*d", nd
, number
);
590 if ((q
- buf
+ len
) > buf_size
- 1)
592 memcpy(q
, buf1
, len
);
600 if ((q
- buf
) < buf_size
- 1)