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
))