Commit | Line | Data |
---|---|---|
de6d9b64 FB |
1 | /* |
2 | * Various utilities for ffmpeg system | |
19720f15 | 3 | * Copyright (c) 2000, 2001, 2002 Fabrice Bellard |
de6d9b64 | 4 | * |
19720f15 FB |
5 | * This library is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU Lesser General Public | |
7 | * License as published by the Free Software Foundation; either | |
8 | * version 2 of the License, or (at your option) any later version. | |
de6d9b64 | 9 | * |
19720f15 | 10 | * This library is distributed in the hope that it will be useful, |
de6d9b64 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
19720f15 FB |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | * Lesser General Public License for more details. | |
de6d9b64 | 14 | * |
19720f15 FB |
15 | * You should have received a copy of the GNU Lesser General Public |
16 | * License along with this library; if not, write to the Free Software | |
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
de6d9b64 | 18 | */ |
8be1c656 | 19 | #include "avformat.h" |
c5510dd6 | 20 | #include <ctype.h> |
f3ec2d46 | 21 | #ifdef CONFIG_WIN32 |
8be1c656 FB |
22 | #define strcasecmp _stricmp |
23 | #include <sys/types.h> | |
24 | #include <sys/timeb.h> | |
f3ec2d46 SG |
25 | #elif defined(CONFIG_OS2) |
26 | #include <string.h> | |
27 | #define strcasecmp stricmp | |
28 | #include <sys/time.h> | |
29 | #else | |
30 | #include <unistd.h> | |
31 | #include <fcntl.h> | |
32 | #include <sys/time.h> | |
8be1c656 | 33 | #endif |
9235088f | 34 | #include <time.h> |
de6d9b64 | 35 | |
c5510dd6 PG |
36 | #ifndef HAVE_STRPTIME |
37 | #include "strptime.h" | |
38 | #endif | |
39 | ||
b9a281db FB |
40 | AVInputFormat *first_iformat; |
41 | AVOutputFormat *first_oformat; | |
87a0a681 | 42 | AVImageFormat *first_image_format; |
de6d9b64 | 43 | |
b9a281db | 44 | void av_register_input_format(AVInputFormat *format) |
de6d9b64 | 45 | { |
b9a281db FB |
46 | AVInputFormat **p; |
47 | p = &first_iformat; | |
48 | while (*p != NULL) p = &(*p)->next; | |
49 | *p = format; | |
50 | format->next = NULL; | |
51 | } | |
52 | ||
53 | void av_register_output_format(AVOutputFormat *format) | |
54 | { | |
55 | AVOutputFormat **p; | |
56 | p = &first_oformat; | |
de6d9b64 FB |
57 | while (*p != NULL) p = &(*p)->next; |
58 | *p = format; | |
59 | format->next = NULL; | |
60 | } | |
61 | ||
5b25dfa7 | 62 | int match_ext(const char *filename, const char *extensions) |
de6d9b64 FB |
63 | { |
64 | const char *ext, *p; | |
65 | char ext1[32], *q; | |
66 | ||
67 | ext = strrchr(filename, '.'); | |
68 | if (ext) { | |
69 | ext++; | |
70 | p = extensions; | |
71 | for(;;) { | |
72 | q = ext1; | |
73 | while (*p != '\0' && *p != ',') | |
74 | *q++ = *p++; | |
75 | *q = '\0'; | |
76 | if (!strcasecmp(ext1, ext)) | |
77 | return 1; | |
78 | if (*p == '\0') | |
79 | break; | |
80 | p++; | |
81 | } | |
82 | } | |
83 | return 0; | |
84 | } | |
85 | ||
b9a281db FB |
86 | AVOutputFormat *guess_format(const char *short_name, const char *filename, |
87 | const char *mime_type) | |
de6d9b64 | 88 | { |
b9a281db | 89 | AVOutputFormat *fmt, *fmt_found; |
de6d9b64 FB |
90 | int score_max, score; |
91 | ||
87a0a681 | 92 | /* specific test for image sequences */ |
94d883e8 FB |
93 | if (!short_name && filename && |
94 | filename_number_test(filename) >= 0 && | |
95 | guess_image_format(filename)) { | |
87a0a681 FB |
96 | return guess_format("image", NULL, NULL); |
97 | } | |
98 | ||
de6d9b64 FB |
99 | /* find the proper file type */ |
100 | fmt_found = NULL; | |
101 | score_max = 0; | |
b9a281db | 102 | fmt = first_oformat; |
de6d9b64 FB |
103 | while (fmt != NULL) { |
104 | score = 0; | |
105 | if (fmt->name && short_name && !strcmp(fmt->name, short_name)) | |
106 | score += 100; | |
107 | if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type)) | |
108 | score += 10; | |
109 | if (filename && fmt->extensions && | |
110 | match_ext(filename, fmt->extensions)) { | |
111 | score += 5; | |
112 | } | |
113 | if (score > score_max) { | |
114 | score_max = score; | |
115 | fmt_found = fmt; | |
116 | } | |
117 | fmt = fmt->next; | |
118 | } | |
119 | return fmt_found; | |
120 | } | |
121 | ||
c5510dd6 PG |
122 | AVOutputFormat *guess_stream_format(const char *short_name, const char *filename, |
123 | const char *mime_type) | |
124 | { | |
125 | AVOutputFormat *fmt = guess_format(short_name, filename, mime_type); | |
126 | ||
127 | if (fmt) { | |
128 | AVOutputFormat *stream_fmt; | |
129 | char stream_format_name[64]; | |
130 | ||
131 | snprintf(stream_format_name, sizeof(stream_format_name), "%s_stream", fmt->name); | |
132 | stream_fmt = guess_format(stream_format_name, NULL, NULL); | |
133 | ||
134 | if (stream_fmt) | |
135 | fmt = stream_fmt; | |
136 | } | |
137 | ||
138 | return fmt; | |
139 | } | |
140 | ||
b9a281db FB |
141 | AVInputFormat *av_find_input_format(const char *short_name) |
142 | { | |
143 | AVInputFormat *fmt; | |
144 | for(fmt = first_iformat; fmt != NULL; fmt = fmt->next) { | |
145 | if (!strcmp(fmt->name, short_name)) | |
146 | return fmt; | |
147 | } | |
148 | return NULL; | |
149 | } | |
150 | ||
de6d9b64 FB |
151 | /* memory handling */ |
152 | ||
b9a281db | 153 | /** |
6fa5a56c FB |
154 | * Default packet destructor |
155 | */ | |
156 | static void av_destruct_packet(AVPacket *pkt) | |
157 | { | |
158 | av_free(pkt->data); | |
159 | pkt->data = NULL; pkt->size = 0; | |
160 | } | |
161 | ||
162 | /** | |
b9a281db FB |
163 | * Allocate the payload of a packet and intialized its fields to default values. |
164 | * | |
165 | * @param pkt packet | |
166 | * @param size wanted payload size | |
167 | * @return 0 if OK. AVERROR_xxx otherwise. | |
168 | */ | |
de6d9b64 FB |
169 | int av_new_packet(AVPacket *pkt, int size) |
170 | { | |
6fa5a56c FB |
171 | void *data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); |
172 | if (!data) | |
b9a281db | 173 | return AVERROR_NOMEM; |
6fa5a56c | 174 | memset(data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE); |
8cd5be98 | 175 | |
6fa5a56c FB |
176 | av_init_packet(pkt); |
177 | pkt->data = data; | |
178 | pkt->size = size; | |
179 | pkt->destruct = av_destruct_packet; | |
de6d9b64 FB |
180 | return 0; |
181 | } | |
182 | ||
de6d9b64 FB |
183 | /* fifo handling */ |
184 | ||
185 | int fifo_init(FifoBuffer *f, int size) | |
186 | { | |
1ea4f593 | 187 | f->buffer = av_malloc(size); |
de6d9b64 FB |
188 | if (!f->buffer) |
189 | return -1; | |
190 | f->end = f->buffer + size; | |
191 | f->wptr = f->rptr = f->buffer; | |
192 | return 0; | |
193 | } | |
194 | ||
195 | void fifo_free(FifoBuffer *f) | |
196 | { | |
1ea4f593 | 197 | av_free(f->buffer); |
de6d9b64 FB |
198 | } |
199 | ||
0c1a9eda | 200 | int fifo_size(FifoBuffer *f, uint8_t *rptr) |
de6d9b64 FB |
201 | { |
202 | int size; | |
203 | ||
204 | if (f->wptr >= rptr) { | |
205 | size = f->wptr - rptr; | |
206 | } else { | |
207 | size = (f->end - rptr) + (f->wptr - f->buffer); | |
208 | } | |
209 | return size; | |
210 | } | |
211 | ||
212 | /* get data from the fifo (return -1 if not enough data) */ | |
0c1a9eda | 213 | int fifo_read(FifoBuffer *f, uint8_t *buf, int buf_size, uint8_t **rptr_ptr) |
de6d9b64 | 214 | { |
0c1a9eda | 215 | uint8_t *rptr = *rptr_ptr; |
de6d9b64 FB |
216 | int size, len; |
217 | ||
218 | if (f->wptr >= rptr) { | |
219 | size = f->wptr - rptr; | |
220 | } else { | |
221 | size = (f->end - rptr) + (f->wptr - f->buffer); | |
222 | } | |
223 | ||
224 | if (size < buf_size) | |
225 | return -1; | |
226 | while (buf_size > 0) { | |
227 | len = f->end - rptr; | |
228 | if (len > buf_size) | |
229 | len = buf_size; | |
230 | memcpy(buf, rptr, len); | |
231 | buf += len; | |
232 | rptr += len; | |
233 | if (rptr >= f->end) | |
234 | rptr = f->buffer; | |
235 | buf_size -= len; | |
236 | } | |
237 | *rptr_ptr = rptr; | |
238 | return 0; | |
239 | } | |
240 | ||
0c1a9eda | 241 | void fifo_write(FifoBuffer *f, uint8_t *buf, int size, uint8_t **wptr_ptr) |
de6d9b64 FB |
242 | { |
243 | int len; | |
0c1a9eda | 244 | uint8_t *wptr; |
de6d9b64 FB |
245 | wptr = *wptr_ptr; |
246 | while (size > 0) { | |
247 | len = f->end - wptr; | |
248 | if (len > size) | |
249 | len = size; | |
250 | memcpy(wptr, buf, len); | |
251 | wptr += len; | |
252 | if (wptr >= f->end) | |
253 | wptr = f->buffer; | |
254 | buf += len; | |
255 | size -= len; | |
256 | } | |
257 | *wptr_ptr = wptr; | |
258 | } | |
259 | ||
b9a281db FB |
260 | int filename_number_test(const char *filename) |
261 | { | |
262 | char buf[1024]; | |
263 | return get_frame_filename(buf, sizeof(buf), filename, 1); | |
264 | } | |
265 | ||
266 | /* guess file format */ | |
a25e098d | 267 | AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened) |
b9a281db FB |
268 | { |
269 | AVInputFormat *fmt1, *fmt; | |
270 | int score, score_max; | |
271 | ||
272 | fmt = NULL; | |
273 | score_max = 0; | |
274 | for(fmt1 = first_iformat; fmt1 != NULL; fmt1 = fmt1->next) { | |
275 | if (!is_opened && !(fmt1->flags & AVFMT_NOFILE)) | |
276 | continue; | |
277 | score = 0; | |
a8dbe951 PG |
278 | if (fmt1->read_probe) { |
279 | score = fmt1->read_probe(pd); | |
280 | } else if (fmt1->extensions) { | |
b9a281db FB |
281 | if (match_ext(pd->filename, fmt1->extensions)) { |
282 | score = 50; | |
283 | } | |
a8dbe951 | 284 | } |
b9a281db FB |
285 | if (score > score_max) { |
286 | score_max = score; | |
287 | fmt = fmt1; | |
288 | } | |
289 | } | |
290 | return fmt; | |
291 | } | |
292 | ||
293 | /************************************************************/ | |
294 | /* input media file */ | |
96baaa6a | 295 | |
b9a281db FB |
296 | #define PROBE_BUF_SIZE 2048 |
297 | ||
298 | /** | |
299 | * Open a media file as input. The codec are not opened. Only the file | |
300 | * header (if present) is read. | |
301 | * | |
302 | * @param ic_ptr the opened media file handle is put here | |
303 | * @param filename filename to open. | |
304 | * @param fmt if non NULL, force the file format to use | |
305 | * @param buf_size optional buffer size (zero if default is OK) | |
306 | * @param ap additionnal parameters needed when opening the file (NULL if default) | |
307 | * @return 0 if OK. AVERROR_xxx otherwise. | |
308 | */ | |
309 | int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, | |
310 | AVInputFormat *fmt, | |
311 | int buf_size, | |
312 | AVFormatParameters *ap) | |
de6d9b64 | 313 | { |
de6d9b64 | 314 | AVFormatContext *ic = NULL; |
b6892136 | 315 | int err, must_open_file; |
b9a281db FB |
316 | char buf[PROBE_BUF_SIZE]; |
317 | AVProbeData probe_data, *pd = &probe_data; | |
de6d9b64 FB |
318 | |
319 | ic = av_mallocz(sizeof(AVFormatContext)); | |
b9a281db FB |
320 | if (!ic) { |
321 | err = AVERROR_NOMEM; | |
de6d9b64 | 322 | goto fail; |
de6d9b64 | 323 | } |
b9a281db FB |
324 | pstrcpy(ic->filename, sizeof(ic->filename), filename); |
325 | pd->filename = ic->filename; | |
326 | pd->buf = buf; | |
327 | pd->buf_size = 0; | |
328 | ||
329 | if (!fmt) { | |
330 | /* guess format if no file can be opened */ | |
a25e098d | 331 | fmt = av_probe_input_format(pd, 0); |
de6d9b64 | 332 | } |
de6d9b64 | 333 | |
b6892136 FB |
334 | /* do not open file if the format does not need it. XXX: specific |
335 | hack needed to handle RTSP/TCP */ | |
336 | must_open_file = 1; | |
afdd82bb | 337 | if ((fmt && (fmt->flags & AVFMT_NOFILE)) || |
b6892136 FB |
338 | (fmt == &rtp_demux && !strcmp(filename, "null"))) { |
339 | must_open_file = 0; | |
340 | } | |
341 | ||
342 | if (!fmt || must_open_file) { | |
87a0a681 | 343 | /* if no file needed do not try to open one */ |
b9a281db FB |
344 | if (url_fopen(&ic->pb, filename, URL_RDONLY) < 0) { |
345 | err = AVERROR_IO; | |
96baaa6a | 346 | goto fail; |
b9a281db | 347 | } |
96baaa6a FB |
348 | if (buf_size > 0) { |
349 | url_setbufsize(&ic->pb, buf_size); | |
350 | } | |
5b25dfa7 FB |
351 | if (!fmt) { |
352 | /* read probe data */ | |
353 | pd->buf_size = get_buffer(&ic->pb, buf, PROBE_BUF_SIZE); | |
354 | url_fseek(&ic->pb, 0, SEEK_SET); | |
355 | } | |
96baaa6a FB |
356 | } |
357 | ||
b9a281db FB |
358 | /* guess file format */ |
359 | if (!fmt) { | |
a25e098d | 360 | fmt = av_probe_input_format(pd, 1); |
b9a281db FB |
361 | } |
362 | ||
363 | /* if still no format found, error */ | |
364 | if (!fmt) { | |
365 | err = AVERROR_NOFMT; | |
a05c8d71 | 366 | goto fail1; |
de6d9b64 | 367 | } |
b9a281db | 368 | |
67d06418 | 369 | /* XXX: suppress this hack for redirectors */ |
f3ec2d46 | 370 | #ifdef CONFIG_NETWORK |
67d06418 FB |
371 | if (fmt == &redir_demux) { |
372 | err = redir_open(ic_ptr, &ic->pb); | |
373 | url_fclose(&ic->pb); | |
374 | av_free(ic); | |
375 | return err; | |
376 | } | |
9b2e001f | 377 | #endif |
67d06418 | 378 | |
b9a281db | 379 | ic->iformat = fmt; |
de6d9b64 | 380 | |
87a0a681 FB |
381 | /* check filename in case of an image number is expected */ |
382 | if (ic->iformat->flags & AVFMT_NEEDNUMBER) { | |
383 | if (filename_number_test(ic->filename) < 0) { | |
384 | err = AVERROR_NUMEXPECTED; | |
385 | goto fail1; | |
386 | } | |
387 | } | |
388 | ||
b9a281db | 389 | /* allocate private data */ |
98486a6b RS |
390 | if (fmt->priv_data_size > 0) { |
391 | ic->priv_data = av_mallocz(fmt->priv_data_size); | |
392 | if (!ic->priv_data) { | |
393 | err = AVERROR_NOMEM; | |
a05c8d71 | 394 | goto fail1; |
98486a6b RS |
395 | } |
396 | } else | |
397 | ic->priv_data = NULL; | |
b9a281db | 398 | |
916c80e9 FB |
399 | /* default pts settings is MPEG like */ |
400 | av_set_pts_info(ic, 33, 1, 90000); | |
401 | ||
b9a281db FB |
402 | err = ic->iformat->read_header(ic, ap); |
403 | if (err < 0) | |
404 | goto fail1; | |
405 | *ic_ptr = ic; | |
406 | return 0; | |
407 | fail1: | |
b6892136 | 408 | if (!fmt || must_open_file) { |
b9a281db FB |
409 | url_fclose(&ic->pb); |
410 | } | |
de6d9b64 | 411 | fail: |
b9a281db | 412 | if (ic) { |
a8dbe951 | 413 | av_freep(&ic->priv_data); |
b9a281db | 414 | } |
1ea4f593 | 415 | av_free(ic); |
b9a281db FB |
416 | *ic_ptr = NULL; |
417 | return err; | |
de6d9b64 FB |
418 | } |
419 | ||
b9a281db FB |
420 | /** |
421 | * Read a packet from a media file | |
422 | * @param s media file handle | |
423 | * @param pkt is filled | |
424 | * @return 0 if OK. AVERROR_xxx if error. | |
425 | */ | |
de6d9b64 FB |
426 | int av_read_packet(AVFormatContext *s, AVPacket *pkt) |
427 | { | |
428 | AVPacketList *pktl; | |
429 | ||
430 | pktl = s->packet_buffer; | |
431 | if (pktl) { | |
432 | /* read packet from packet buffer, if there is data */ | |
433 | *pkt = pktl->pkt; | |
434 | s->packet_buffer = pktl->next; | |
1ea4f593 | 435 | av_free(pktl); |
de6d9b64 FB |
436 | return 0; |
437 | } else { | |
b9a281db FB |
438 | return s->iformat->read_packet(s, pkt); |
439 | } | |
440 | } | |
441 | ||
442 | /* state for codec information */ | |
443 | #define CSTATE_NOTFOUND 0 | |
444 | #define CSTATE_DECODING 1 | |
445 | #define CSTATE_FOUND 2 | |
446 | ||
447 | static int has_codec_parameters(AVCodecContext *enc) | |
448 | { | |
449 | int val; | |
450 | switch(enc->codec_type) { | |
451 | case CODEC_TYPE_AUDIO: | |
452 | val = enc->sample_rate; | |
453 | break; | |
454 | case CODEC_TYPE_VIDEO: | |
455 | val = enc->width; | |
456 | break; | |
457 | default: | |
458 | val = 1; | |
459 | break; | |
460 | } | |
461 | return (val != 0); | |
462 | } | |
463 | ||
464 | /** | |
465 | * Read the beginning of a media file to get stream information. This | |
466 | * is useful for file formats with no headers such as MPEG. This | |
467 | * function also compute the real frame rate in case of mpeg2 repeat | |
468 | * frame mode. | |
469 | * | |
470 | * @param ic media file handle | |
471 | * @return >=0 if OK. AVERROR_xxx if error. | |
472 | */ | |
473 | int av_find_stream_info(AVFormatContext *ic) | |
474 | { | |
475 | int i, count, ret, got_picture, size, read_size; | |
476 | AVCodec *codec; | |
477 | AVStream *st; | |
478 | AVPacket *pkt; | |
492cd3a9 | 479 | AVFrame picture; |
b9a281db FB |
480 | AVPacketList *pktl=NULL, **ppktl; |
481 | short samples[AVCODEC_MAX_AUDIO_FRAME_SIZE / 2]; | |
0c1a9eda | 482 | uint8_t *ptr; |
b9a281db FB |
483 | int min_read_size, max_read_size; |
484 | ||
485 | /* typical mpeg ts rate is 40 Mbits. DVD rate is about 10 | |
b530f842 | 486 | Mbits. We read at most 0.2 second of file to find all streams */ |
b9a281db FB |
487 | |
488 | /* XXX: base it on stream bitrate when possible */ | |
489 | if (ic->iformat == &mpegts_demux) { | |
490 | /* maximum number of bytes we accept to read to find all the streams | |
491 | in a file */ | |
b530f842 | 492 | min_read_size = 6000000; |
b9a281db | 493 | } else { |
b530f842 | 494 | min_read_size = 250000; |
b9a281db FB |
495 | } |
496 | /* max read size is 2 seconds of video max */ | |
b530f842 | 497 | max_read_size = min_read_size * 10; |
b9a281db FB |
498 | |
499 | /* set initial codec state */ | |
500 | for(i=0;i<ic->nb_streams;i++) { | |
501 | st = ic->streams[i]; | |
502 | if (has_codec_parameters(&st->codec)) | |
503 | st->codec_info_state = CSTATE_FOUND; | |
504 | else | |
505 | st->codec_info_state = CSTATE_NOTFOUND; | |
506 | st->codec_info_nb_repeat_frames = 0; | |
507 | st->codec_info_nb_real_frames = 0; | |
508 | } | |
509 | ||
510 | count = 0; | |
511 | read_size = 0; | |
512 | ppktl = &ic->packet_buffer; | |
513 | for(;;) { | |
514 | /* check if one codec still needs to be handled */ | |
515 | for(i=0;i<ic->nb_streams;i++) { | |
516 | st = ic->streams[i]; | |
517 | if (st->codec_info_state != CSTATE_FOUND) | |
518 | break; | |
519 | } | |
520 | if (i == ic->nb_streams) { | |
521 | /* NOTE: if the format has no header, then we need to read | |
522 | some packets to get most of the streams, so we cannot | |
523 | stop here */ | |
524 | if (!(ic->iformat->flags & AVFMT_NOHEADER) || | |
525 | read_size >= min_read_size) { | |
526 | /* if we found the info for all the codecs, we can stop */ | |
527 | ret = count; | |
528 | break; | |
529 | } | |
530 | } else { | |
531 | /* we did not get all the codec info, but we read too much data */ | |
532 | if (read_size >= max_read_size) { | |
533 | ret = count; | |
534 | break; | |
535 | } | |
536 | } | |
537 | ||
538 | pktl = av_mallocz(sizeof(AVPacketList)); | |
539 | if (!pktl) { | |
540 | ret = AVERROR_NOMEM; | |
541 | break; | |
542 | } | |
543 | ||
544 | /* add the packet in the buffered packet list */ | |
545 | *ppktl = pktl; | |
546 | ppktl = &pktl->next; | |
547 | ||
548 | /* NOTE: a new stream can be added there if no header in file | |
549 | (AVFMT_NOHEADER) */ | |
550 | pkt = &pktl->pkt; | |
551 | if (ic->iformat->read_packet(ic, pkt) < 0) { | |
552 | /* EOF or error */ | |
553 | ret = -1; /* we could not have all the codec parameters before EOF */ | |
554 | if ((ic->iformat->flags & AVFMT_NOHEADER) && | |
555 | i == ic->nb_streams) | |
556 | ret = 0; | |
557 | break; | |
558 | } | |
559 | read_size += pkt->size; | |
560 | ||
561 | /* open new codecs */ | |
562 | for(i=0;i<ic->nb_streams;i++) { | |
563 | st = ic->streams[i]; | |
564 | if (st->codec_info_state == CSTATE_NOTFOUND) { | |
565 | /* set to found in case of error */ | |
566 | st->codec_info_state = CSTATE_FOUND; | |
567 | codec = avcodec_find_decoder(st->codec.codec_id); | |
568 | if (codec) { | |
d7425f59 MN |
569 | if(codec->capabilities & CODEC_CAP_TRUNCATED) |
570 | st->codec.flags |= CODEC_FLAG_TRUNCATED; | |
571 | ||
b9a281db FB |
572 | ret = avcodec_open(&st->codec, codec); |
573 | if (ret >= 0) | |
574 | st->codec_info_state = CSTATE_DECODING; | |
575 | } | |
576 | } | |
577 | } | |
578 | ||
579 | st = ic->streams[pkt->stream_index]; | |
580 | if (st->codec_info_state == CSTATE_DECODING) { | |
581 | /* decode the data and update codec parameters */ | |
582 | ptr = pkt->data; | |
583 | size = pkt->size; | |
584 | while (size > 0) { | |
585 | switch(st->codec.codec_type) { | |
586 | case CODEC_TYPE_VIDEO: | |
587 | ret = avcodec_decode_video(&st->codec, &picture, | |
588 | &got_picture, ptr, size); | |
589 | break; | |
590 | case CODEC_TYPE_AUDIO: | |
591 | ret = avcodec_decode_audio(&st->codec, samples, | |
592 | &got_picture, ptr, size); | |
593 | break; | |
594 | default: | |
595 | ret = -1; | |
596 | break; | |
597 | } | |
598 | if (ret < 0) { | |
599 | /* if error, simply ignore because another packet | |
600 | may be OK */ | |
601 | break; | |
602 | } | |
603 | if (got_picture) { | |
604 | /* we got the parameters - now we can stop | |
605 | examining this stream */ | |
606 | /* XXX: add a codec info so that we can decide if | |
607 | the codec can repeat frames */ | |
608 | if (st->codec.codec_id == CODEC_ID_MPEG1VIDEO && | |
609 | ic->iformat != &mpegts_demux && | |
610 | st->codec.sub_id == 2) { | |
611 | /* for mpeg2 video, we want to know the real | |
612 | frame rate, so we decode 40 frames. In mpeg | |
613 | TS case we do not do it because it would be | |
614 | too long */ | |
615 | st->codec_info_nb_real_frames++; | |
2ec23b6d | 616 | st->codec_info_nb_repeat_frames += st->codec.coded_frame->repeat_pict; |
b9a281db FB |
617 | #if 0 |
618 | /* XXX: testing */ | |
619 | if ((st->codec_info_nb_real_frames % 24) == 23) { | |
620 | st->codec_info_nb_repeat_frames += 2; | |
621 | } | |
622 | #endif | |
623 | /* stop after 40 frames */ | |
624 | if (st->codec_info_nb_real_frames >= 40) { | |
14bea432 MN |
625 | av_reduce( |
626 | &st->r_frame_rate, | |
627 | &st->r_frame_rate_base, | |
628 | (int64_t)st->codec.frame_rate * st->codec_info_nb_real_frames, | |
e71ea8b2 | 629 | (st->codec_info_nb_real_frames + (st->codec_info_nb_repeat_frames >> 1)) * st->codec.frame_rate_base, |
14bea432 | 630 | 1<<30); |
b9a281db FB |
631 | goto close_codec; |
632 | } | |
633 | } else { | |
634 | close_codec: | |
635 | st->codec_info_state = CSTATE_FOUND; | |
636 | avcodec_close(&st->codec); | |
24f9709b | 637 | break; |
b9a281db | 638 | } |
b9a281db FB |
639 | } |
640 | ptr += ret; | |
641 | size -= ret; | |
642 | } | |
643 | } | |
644 | count++; | |
645 | } | |
646 | ||
647 | /* close each codec if there are opened */ | |
648 | for(i=0;i<ic->nb_streams;i++) { | |
649 | st = ic->streams[i]; | |
650 | if (st->codec_info_state == CSTATE_DECODING) | |
651 | avcodec_close(&st->codec); | |
652 | } | |
653 | ||
654 | /* set real frame rate info */ | |
655 | for(i=0;i<ic->nb_streams;i++) { | |
656 | st = ic->streams[i]; | |
657 | if (st->codec.codec_type == CODEC_TYPE_VIDEO) { | |
14bea432 MN |
658 | if (!st->r_frame_rate){ |
659 | st->r_frame_rate = st->codec.frame_rate; | |
660 | st->r_frame_rate_base = st->codec.frame_rate_base; | |
661 | } | |
b9a281db | 662 | } |
de6d9b64 | 663 | } |
b9a281db FB |
664 | |
665 | return ret; | |
de6d9b64 FB |
666 | } |
667 | ||
b9a281db FB |
668 | /** |
669 | * Close a media file (but not its codecs) | |
670 | * | |
671 | * @param s media file handle | |
672 | */ | |
de6d9b64 FB |
673 | void av_close_input_file(AVFormatContext *s) |
674 | { | |
b6892136 | 675 | int i, must_open_file; |
de6d9b64 | 676 | |
b9a281db FB |
677 | if (s->iformat->read_close) |
678 | s->iformat->read_close(s); | |
de6d9b64 | 679 | for(i=0;i<s->nb_streams;i++) { |
1ea4f593 | 680 | av_free(s->streams[i]); |
de6d9b64 FB |
681 | } |
682 | if (s->packet_buffer) { | |
683 | AVPacketList *p, *p1; | |
684 | p = s->packet_buffer; | |
685 | while (p != NULL) { | |
686 | p1 = p->next; | |
687 | av_free_packet(&p->pkt); | |
1ea4f593 | 688 | av_free(p); |
de6d9b64 FB |
689 | p = p1; |
690 | } | |
691 | s->packet_buffer = NULL; | |
692 | } | |
b6892136 FB |
693 | must_open_file = 1; |
694 | if ((s->iformat->flags & AVFMT_NOFILE) || | |
695 | (s->iformat == &rtp_demux && !strcmp(s->filename, "null"))) { | |
696 | must_open_file = 0; | |
697 | } | |
698 | if (must_open_file) { | |
96baaa6a FB |
699 | url_fclose(&s->pb); |
700 | } | |
a8dbe951 | 701 | av_freep(&s->priv_data); |
1ea4f593 | 702 | av_free(s); |
de6d9b64 FB |
703 | } |
704 | ||
b9a281db FB |
705 | /** |
706 | * Add a new stream to a media file. Can only be called in the | |
707 | * read_header function. If the flag AVFMT_NOHEADER is in the format | |
708 | * description, then new streams can be added in read_packet too. | |
709 | * | |
710 | * | |
711 | * @param s media file handle | |
712 | * @param id file format dependent stream id | |
713 | */ | |
714 | AVStream *av_new_stream(AVFormatContext *s, int id) | |
715 | { | |
716 | AVStream *st; | |
717 | ||
718 | if (s->nb_streams >= MAX_STREAMS) | |
719 | return NULL; | |
720 | ||
721 | st = av_mallocz(sizeof(AVStream)); | |
722 | if (!st) | |
723 | return NULL; | |
1e491e29 MN |
724 | avcodec_get_context_defaults(&st->codec); |
725 | ||
b9a281db FB |
726 | st->index = s->nb_streams; |
727 | st->id = id; | |
728 | s->streams[s->nb_streams++] = st; | |
729 | return st; | |
730 | } | |
731 | ||
732 | /************************************************************/ | |
733 | /* output media file */ | |
de6d9b64 | 734 | |
87a0a681 FB |
735 | int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap) |
736 | { | |
737 | int ret; | |
98486a6b RS |
738 | |
739 | if (s->oformat->priv_data_size > 0) { | |
740 | s->priv_data = av_mallocz(s->oformat->priv_data_size); | |
741 | if (!s->priv_data) | |
742 | return AVERROR_NOMEM; | |
743 | } else | |
744 | s->priv_data = NULL; | |
745 | ||
87a0a681 FB |
746 | if (s->oformat->set_parameters) { |
747 | ret = s->oformat->set_parameters(s, ap); | |
748 | if (ret < 0) | |
749 | return ret; | |
750 | } | |
751 | return 0; | |
752 | } | |
753 | ||
b9a281db FB |
754 | /** |
755 | * allocate the stream private data and write the stream header to an | |
756 | * output media file | |
757 | * | |
758 | * @param s media file handle | |
759 | * @return 0 if OK. AVERROR_xxx if error. | |
760 | */ | |
761 | int av_write_header(AVFormatContext *s) | |
762 | { | |
1e51d801 FB |
763 | int ret, i; |
764 | AVStream *st; | |
765 | ||
916c80e9 FB |
766 | /* default pts settings is MPEG like */ |
767 | av_set_pts_info(s, 33, 1, 90000); | |
1e51d801 FB |
768 | ret = s->oformat->write_header(s); |
769 | if (ret < 0) | |
770 | return ret; | |
771 | ||
772 | /* init PTS generation */ | |
773 | for(i=0;i<s->nb_streams;i++) { | |
774 | st = s->streams[i]; | |
775 | ||
776 | switch (st->codec.codec_type) { | |
777 | case CODEC_TYPE_AUDIO: | |
778 | av_frac_init(&st->pts, 0, 0, | |
0c1a9eda | 779 | (int64_t)s->pts_num * st->codec.sample_rate); |
1e51d801 FB |
780 | break; |
781 | case CODEC_TYPE_VIDEO: | |
782 | av_frac_init(&st->pts, 0, 0, | |
0c1a9eda | 783 | (int64_t)s->pts_num * st->codec.frame_rate); |
1e51d801 FB |
784 | break; |
785 | default: | |
786 | break; | |
787 | } | |
788 | } | |
789 | return 0; | |
b9a281db FB |
790 | } |
791 | ||
792 | /** | |
1e51d801 FB |
793 | * Write a packet to an output media file. The packet shall contain |
794 | * one audio or video frame. | |
b9a281db FB |
795 | * |
796 | * @param s media file handle | |
1e51d801 FB |
797 | * @param stream_index stream index |
798 | * @param buf buffer containing the frame data | |
799 | * @param size size of buffer | |
d4c0ff91 | 800 | * @return < 0 if error, = 0 if OK, 1 if end of stream wanted. |
b9a281db | 801 | */ |
1e51d801 FB |
802 | int av_write_frame(AVFormatContext *s, int stream_index, const uint8_t *buf, |
803 | int size) | |
de6d9b64 | 804 | { |
1e51d801 | 805 | AVStream *st; |
0c1a9eda | 806 | int64_t pts_mask; |
7feb950a | 807 | int ret, frame_size; |
1e51d801 FB |
808 | |
809 | st = s->streams[stream_index]; | |
810 | pts_mask = (1LL << s->pts_wrap_bits) - 1; | |
811 | ret = s->oformat->write_packet(s, stream_index, (uint8_t *)buf, size, | |
812 | st->pts.val & pts_mask); | |
813 | if (ret < 0) | |
814 | return ret; | |
815 | ||
816 | /* update pts */ | |
817 | switch (st->codec.codec_type) { | |
818 | case CODEC_TYPE_AUDIO: | |
7feb950a FB |
819 | if (st->codec.frame_size <= 1) { |
820 | frame_size = size / st->codec.channels; | |
821 | /* specific hack for pcm codecs because no frame size is provided */ | |
50d5d129 | 822 | switch(st->codec.codec_id) { |
7feb950a FB |
823 | case CODEC_ID_PCM_S16LE: |
824 | case CODEC_ID_PCM_S16BE: | |
825 | case CODEC_ID_PCM_U16LE: | |
826 | case CODEC_ID_PCM_U16BE: | |
827 | frame_size >>= 1; | |
828 | break; | |
829 | default: | |
830 | break; | |
831 | } | |
832 | } else { | |
833 | frame_size = st->codec.frame_size; | |
834 | } | |
1e51d801 | 835 | av_frac_add(&st->pts, |
0c1a9eda | 836 | (int64_t)s->pts_den * frame_size); |
1e51d801 FB |
837 | break; |
838 | case CODEC_TYPE_VIDEO: | |
839 | av_frac_add(&st->pts, | |
14bea432 | 840 | (int64_t)s->pts_den * st->codec.frame_rate_base); |
1e51d801 FB |
841 | break; |
842 | default: | |
843 | break; | |
844 | } | |
d4c0ff91 | 845 | return ret; |
b9a281db FB |
846 | } |
847 | ||
848 | /** | |
849 | * write the stream trailer to an output media file and and free the | |
850 | * file private data. | |
851 | * | |
852 | * @param s media file handle | |
853 | * @return 0 if OK. AVERROR_xxx if error. */ | |
854 | int av_write_trailer(AVFormatContext *s) | |
855 | { | |
856 | int ret; | |
857 | ret = s->oformat->write_trailer(s); | |
858 | av_freep(&s->priv_data); | |
859 | return ret; | |
de6d9b64 FB |
860 | } |
861 | ||
862 | /* "user interface" functions */ | |
863 | ||
864 | void dump_format(AVFormatContext *ic, | |
865 | int index, | |
866 | const char *url, | |
867 | int is_output) | |
868 | { | |
b9a281db | 869 | int i, flags; |
de6d9b64 FB |
870 | char buf[256]; |
871 | ||
872 | fprintf(stderr, "%s #%d, %s, %s '%s':\n", | |
873 | is_output ? "Output" : "Input", | |
b9a281db FB |
874 | index, |
875 | is_output ? ic->oformat->name : ic->iformat->name, | |
de6d9b64 FB |
876 | is_output ? "to" : "from", url); |
877 | for(i=0;i<ic->nb_streams;i++) { | |
878 | AVStream *st = ic->streams[i]; | |
879 | avcodec_string(buf, sizeof(buf), &st->codec, is_output); | |
b9a281db FB |
880 | fprintf(stderr, " Stream #%d.%d", index, i); |
881 | /* the pid is an important information, so we display it */ | |
882 | /* XXX: add a generic system */ | |
883 | if (is_output) | |
884 | flags = ic->oformat->flags; | |
885 | else | |
886 | flags = ic->iformat->flags; | |
887 | if (flags & AVFMT_SHOW_IDS) { | |
888 | fprintf(stderr, "[0x%x]", st->id); | |
889 | } | |
890 | fprintf(stderr, ": %s\n", buf); | |
de6d9b64 FB |
891 | } |
892 | } | |
893 | ||
894 | typedef struct { | |
445f1b83 | 895 | const char *abv; |
de6d9b64 | 896 | int width, height; |
445f1b83 RS |
897 | int frame_rate, frame_rate_base; |
898 | } AbvEntry; | |
899 | ||
900 | static AbvEntry frame_abvs[] = { | |
901 | { "ntsc", 352, 240, 30000, 1001 }, | |
902 | { "pal", 352, 288, 25, 1 }, | |
903 | { "film", 352, 240, 24, 1 }, | |
904 | { "ntsc-film", 352, 240, 24000, 1001 }, | |
905 | { "sqcif", 128, 96, 0, 0 }, | |
906 | { "qcif", 176, 144, 0, 0 }, | |
907 | { "cif", 352, 288, 0, 0 }, | |
908 | { "4cif", 704, 576, 0, 0 }, | |
de6d9b64 | 909 | }; |
445f1b83 | 910 | |
de6d9b64 FB |
911 | int parse_image_size(int *width_ptr, int *height_ptr, const char *str) |
912 | { | |
913 | int i; | |
445f1b83 | 914 | int n = sizeof(frame_abvs) / sizeof(AbvEntry); |
de6d9b64 FB |
915 | const char *p; |
916 | int frame_width = 0, frame_height = 0; | |
917 | ||
918 | for(i=0;i<n;i++) { | |
445f1b83 RS |
919 | if (!strcmp(frame_abvs[i].abv, str)) { |
920 | frame_width = frame_abvs[i].width; | |
921 | frame_height = frame_abvs[i].height; | |
de6d9b64 FB |
922 | break; |
923 | } | |
924 | } | |
925 | if (i == n) { | |
926 | p = str; | |
927 | frame_width = strtol(p, (char **)&p, 10); | |
928 | if (*p) | |
929 | p++; | |
930 | frame_height = strtol(p, (char **)&p, 10); | |
931 | } | |
932 | if (frame_width <= 0 || frame_height <= 0) | |
933 | return -1; | |
934 | *width_ptr = frame_width; | |
935 | *height_ptr = frame_height; | |
936 | return 0; | |
937 | } | |
938 | ||
445f1b83 RS |
939 | int parse_frame_rate(int *frame_rate, int *frame_rate_base, const char *arg) |
940 | { | |
941 | int i; | |
942 | char* cp; | |
943 | ||
944 | /* First, we check our abbreviation table */ | |
945 | for (i = 0; i < sizeof(frame_abvs)/sizeof(*frame_abvs); ++i) | |
946 | if (!strcmp(frame_abvs[i].abv, arg)) { | |
947 | *frame_rate = frame_abvs[i].frame_rate; | |
948 | *frame_rate_base = frame_abvs[i].frame_rate_base; | |
949 | return 0; | |
950 | } | |
951 | ||
952 | /* Then, we try to parse it as fraction */ | |
953 | cp = strchr(arg, '/'); | |
954 | if (cp) { | |
955 | char* cpp; | |
956 | *frame_rate = strtol(arg, &cpp, 10); | |
957 | if (cpp != arg || cpp == cp) | |
958 | *frame_rate_base = strtol(cp+1, &cpp, 10); | |
959 | else | |
960 | *frame_rate = 0; | |
961 | } | |
962 | else { | |
963 | /* Finally we give up and parse it as double */ | |
964 | *frame_rate_base = DEFAULT_FRAME_RATE_BASE; | |
965 | *frame_rate = (int)(strtod(arg, 0) * (*frame_rate_base) + 0.5); | |
966 | } | |
967 | if (!*frame_rate || !*frame_rate_base) | |
968 | return -1; | |
969 | else | |
970 | return 0; | |
971 | } | |
972 | ||
0c1a9eda | 973 | int64_t av_gettime(void) |
de6d9b64 | 974 | { |
8be1c656 FB |
975 | #ifdef CONFIG_WIN32 |
976 | struct _timeb tb; | |
977 | _ftime(&tb); | |
0c1a9eda | 978 | return ((int64_t)tb.time * int64_t_C(1000) + (int64_t)tb.millitm) * int64_t_C(1000); |
8be1c656 | 979 | #else |
de6d9b64 FB |
980 | struct timeval tv; |
981 | gettimeofday(&tv,NULL); | |
0c1a9eda | 982 | return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec; |
8be1c656 | 983 | #endif |
de6d9b64 FB |
984 | } |
985 | ||
c5510dd6 PG |
986 | static time_t mktimegm(struct tm *tm) |
987 | { | |
988 | time_t t; | |
989 | ||
990 | int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday; | |
991 | ||
992 | if (m < 3) { | |
993 | m += 12; | |
994 | y--; | |
995 | } | |
996 | ||
997 | t = 86400 * | |
998 | (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469); | |
999 | ||
1000 | t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec; | |
1001 | ||
1002 | return t; | |
1003 | } | |
1004 | ||
916c80e9 FB |
1005 | /* Syntax: |
1006 | * - If not a duration: | |
1007 | * [{YYYY-MM-DD|YYYYMMDD}]{T| }{HH[:MM[:SS[.m...]]][Z]|HH[MM[SS[.m...]]][Z]} | |
c5510dd6 | 1008 | * Time is localtime unless Z is suffixed to the end. In this case GMT |
916c80e9 FB |
1009 | * Return the date in micro seconds since 1970 |
1010 | * - If duration: | |
1011 | * HH[:MM[:SS[.m...]]] | |
1012 | * S+[.m...] | |
1013 | */ | |
0c1a9eda | 1014 | int64_t parse_date(const char *datestr, int duration) |
de6d9b64 FB |
1015 | { |
1016 | const char *p; | |
0c1a9eda | 1017 | int64_t t; |
2dbceb9f | 1018 | struct tm dt; |
c5510dd6 PG |
1019 | int i; |
1020 | static const char *date_fmt[] = { | |
1021 | "%Y-%m-%d", | |
1022 | "%Y%m%d", | |
1023 | }; | |
1024 | static const char *time_fmt[] = { | |
1025 | "%H:%M:%S", | |
1026 | "%H%M%S", | |
1027 | }; | |
1028 | const char *q; | |
916c80e9 | 1029 | int is_utc, len; |
c5510dd6 PG |
1030 | char lastch; |
1031 | time_t now = time(0); | |
1032 | ||
916c80e9 FB |
1033 | len = strlen(datestr); |
1034 | if (len > 0) | |
1035 | lastch = datestr[len - 1]; | |
1036 | else | |
1037 | lastch = '\0'; | |
c5510dd6 | 1038 | is_utc = (lastch == 'z' || lastch == 'Z'); |
2dbceb9f PG |
1039 | |
1040 | memset(&dt, 0, sizeof(dt)); | |
de6d9b64 FB |
1041 | |
1042 | p = datestr; | |
916c80e9 | 1043 | q = NULL; |
de6d9b64 | 1044 | if (!duration) { |
c5510dd6 PG |
1045 | for (i = 0; i < sizeof(date_fmt) / sizeof(date_fmt[0]); i++) { |
1046 | q = strptime(p, date_fmt[i], &dt); | |
1047 | if (q) { | |
1048 | break; | |
1049 | } | |
1050 | } | |
1051 | ||
1052 | if (!q) { | |
1053 | if (is_utc) { | |
1054 | dt = *gmtime(&now); | |
1055 | } else { | |
1056 | dt = *localtime(&now); | |
1057 | } | |
1058 | dt.tm_hour = dt.tm_min = dt.tm_sec = 0; | |
de6d9b64 | 1059 | } else { |
c5510dd6 | 1060 | p = q; |
de6d9b64 | 1061 | } |
c5510dd6 PG |
1062 | |
1063 | if (*p == 'T' || *p == 't' || *p == ' ') | |
1064 | p++; | |
c5510dd6 | 1065 | |
916c80e9 FB |
1066 | for (i = 0; i < sizeof(time_fmt) / sizeof(time_fmt[0]); i++) { |
1067 | q = strptime(p, time_fmt[i], &dt); | |
1068 | if (q) { | |
1069 | break; | |
1070 | } | |
1071 | } | |
1072 | } else { | |
1073 | q = strptime(p, time_fmt[0], &dt); | |
1074 | if (!q) { | |
1075 | dt.tm_sec = strtol(p, (char **)&q, 10); | |
1076 | dt.tm_min = 0; | |
1077 | dt.tm_hour = 0; | |
c5510dd6 PG |
1078 | } |
1079 | } | |
1080 | ||
1081 | /* Now we have all the fields that we can get */ | |
1082 | if (!q) { | |
1083 | if (duration) | |
1084 | return 0; | |
1085 | else | |
0c1a9eda | 1086 | return now * int64_t_C(1000000); |
de6d9b64 | 1087 | } |
2dbceb9f PG |
1088 | |
1089 | if (duration) { | |
c5510dd6 | 1090 | t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec; |
2dbceb9f | 1091 | } else { |
c5510dd6 PG |
1092 | dt.tm_isdst = -1; /* unknown */ |
1093 | if (is_utc) { | |
1094 | t = mktimegm(&dt); | |
1095 | } else { | |
1096 | t = mktime(&dt); | |
1097 | } | |
de6d9b64 | 1098 | } |
2dbceb9f | 1099 | |
c5510dd6 PG |
1100 | t *= 1000000; |
1101 | ||
1102 | if (*q == '.') { | |
de6d9b64 | 1103 | int val, n; |
c5510dd6 PG |
1104 | q++; |
1105 | for (val = 0, n = 100000; n >= 1; n /= 10, q++) { | |
1106 | if (!isdigit(*q)) | |
1107 | break; | |
1108 | val += n * (*q - '0'); | |
de6d9b64 FB |
1109 | } |
1110 | t += val; | |
1111 | } | |
1112 | return t; | |
1113 | } | |
1114 | ||
2dbceb9f | 1115 | /* syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done. Return |
de6d9b64 FB |
1116 | 1 if found */ |
1117 | int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info) | |
1118 | { | |
1119 | const char *p; | |
1120 | char tag[128], *q; | |
1121 | ||
1122 | p = info; | |
1123 | if (*p == '?') | |
1124 | p++; | |
1125 | for(;;) { | |
1126 | q = tag; | |
1127 | while (*p != '\0' && *p != '=' && *p != '&') { | |
1128 | if ((q - tag) < sizeof(tag) - 1) | |
1129 | *q++ = *p; | |
1130 | p++; | |
1131 | } | |
1132 | *q = '\0'; | |
1133 | q = arg; | |
1134 | if (*p == '=') { | |
1135 | p++; | |
1136 | while (*p != '&' && *p != '\0') { | |
2dbceb9f PG |
1137 | if ((q - arg) < arg_size - 1) { |
1138 | if (*p == '+') | |
1139 | *q++ = ' '; | |
1140 | else | |
1141 | *q++ = *p; | |
1142 | } | |
de6d9b64 FB |
1143 | p++; |
1144 | } | |
1145 | *q = '\0'; | |
1146 | } | |
1147 | if (!strcmp(tag, tag1)) | |
1148 | return 1; | |
1149 | if (*p != '&') | |
1150 | break; | |
8d1335ea | 1151 | p++; |
de6d9b64 FB |
1152 | } |
1153 | return 0; | |
1154 | } | |
1155 | ||
9150f42e FB |
1156 | /* Return in 'buf' the path with '%d' replaced by number. Also handles |
1157 | the '%0nd' format where 'n' is the total number of digits and | |
1158 | '%%'. Return 0 if OK, and -1 if format error */ | |
1159 | int get_frame_filename(char *buf, int buf_size, | |
1160 | const char *path, int number) | |
1161 | { | |
1162 | const char *p; | |
1163 | char *q, buf1[20]; | |
1164 | int nd, len, c, percentd_found; | |
1165 | ||
1166 | q = buf; | |
1167 | p = path; | |
1168 | percentd_found = 0; | |
1169 | for(;;) { | |
1170 | c = *p++; | |
1171 | if (c == '\0') | |
1172 | break; | |
1173 | if (c == '%') { | |
c9646fda PG |
1174 | do { |
1175 | nd = 0; | |
1176 | while (isdigit(*p)) { | |
1177 | nd = nd * 10 + *p++ - '0'; | |
1178 | } | |
1179 | c = *p++; | |
1180 | if (c == '*' && nd > 0) { | |
1181 | // The nd field is actually the modulus | |
1182 | number = number % nd; | |
1183 | c = *p++; | |
1184 | nd = 0; | |
1185 | } | |
1186 | } while (isdigit(c)); | |
1187 | ||
9150f42e FB |
1188 | switch(c) { |
1189 | case '%': | |
1190 | goto addchar; | |
1191 | case 'd': | |
1192 | if (percentd_found) | |
1193 | goto fail; | |
1194 | percentd_found = 1; | |
1195 | snprintf(buf1, sizeof(buf1), "%0*d", nd, number); | |
1196 | len = strlen(buf1); | |
1197 | if ((q - buf + len) > buf_size - 1) | |
1198 | goto fail; | |
1199 | memcpy(q, buf1, len); | |
1200 | q += len; | |
1201 | break; | |
1202 | default: | |
1203 | goto fail; | |
1204 | } | |
1205 | } else { | |
1206 | addchar: | |
1207 | if ((q - buf) < buf_size - 1) | |
1208 | *q++ = c; | |
1209 | } | |
1210 | } | |
1211 | if (!percentd_found) | |
1212 | goto fail; | |
1213 | *q = '\0'; | |
1214 | return 0; | |
1215 | fail: | |
1216 | *q = '\0'; | |
1217 | return -1; | |
1218 | } | |
1219 | ||
b9a281db FB |
1220 | /** |
1221 | * | |
1222 | * Print on stdout a nice hexa dump of a buffer | |
1223 | * @param buf buffer | |
1224 | * @param size buffer size | |
1225 | */ | |
0c1a9eda | 1226 | void av_hex_dump(uint8_t *buf, int size) |
b9a281db FB |
1227 | { |
1228 | int len, i, j, c; | |
1229 | ||
1230 | for(i=0;i<size;i+=16) { | |
1231 | len = size - i; | |
1232 | if (len > 16) | |
1233 | len = 16; | |
1234 | printf("%08x ", i); | |
1235 | for(j=0;j<16;j++) { | |
1236 | if (j < len) | |
1237 | printf(" %02x", buf[i+j]); | |
1238 | else | |
1239 | printf(" "); | |
1240 | } | |
1241 | printf(" "); | |
1242 | for(j=0;j<len;j++) { | |
1243 | c = buf[i+j]; | |
1244 | if (c < ' ' || c > '~') | |
1245 | c = '.'; | |
1246 | printf("%c", c); | |
1247 | } | |
1248 | printf("\n"); | |
1249 | } | |
1250 | } | |
1251 | ||
a9a721da FB |
1252 | void url_split(char *proto, int proto_size, |
1253 | char *hostname, int hostname_size, | |
1254 | int *port_ptr, | |
1255 | char *path, int path_size, | |
1256 | const char *url) | |
1257 | { | |
1258 | const char *p; | |
1259 | char *q; | |
1260 | int port; | |
1261 | ||
1262 | port = -1; | |
1263 | ||
1264 | p = url; | |
1265 | q = proto; | |
1266 | while (*p != ':' && *p != '\0') { | |
1267 | if ((q - proto) < proto_size - 1) | |
1268 | *q++ = *p; | |
1269 | p++; | |
1270 | } | |
1271 | if (proto_size > 0) | |
1272 | *q = '\0'; | |
1273 | if (*p == '\0') { | |
1274 | if (proto_size > 0) | |
1275 | proto[0] = '\0'; | |
1276 | if (hostname_size > 0) | |
1277 | hostname[0] = '\0'; | |
1278 | p = url; | |
1279 | } else { | |
1280 | p++; | |
1281 | if (*p == '/') | |
1282 | p++; | |
1283 | if (*p == '/') | |
1284 | p++; | |
1285 | q = hostname; | |
1286 | while (*p != ':' && *p != '/' && *p != '?' && *p != '\0') { | |
1287 | if ((q - hostname) < hostname_size - 1) | |
1288 | *q++ = *p; | |
1289 | p++; | |
1290 | } | |
1291 | if (hostname_size > 0) | |
1292 | *q = '\0'; | |
1293 | if (*p == ':') { | |
1294 | p++; | |
1295 | port = strtoul(p, (char **)&p, 10); | |
1296 | } | |
1297 | } | |
1298 | if (port_ptr) | |
1299 | *port_ptr = port; | |
1300 | pstrcpy(path, path_size, p); | |
1301 | } | |
1302 | ||
916c80e9 FB |
1303 | /** |
1304 | * Set the pts for a given stream | |
1305 | * @param s stream | |
1306 | * @param pts_wrap_bits number of bits effectively used by the pts | |
1307 | * (used for wrap control, 33 is the value for MPEG) | |
1308 | * @param pts_num numerator to convert to seconds (MPEG: 1) | |
1309 | * @param pts_den denominator to convert to seconds (MPEG: 90000) | |
1310 | */ | |
1311 | void av_set_pts_info(AVFormatContext *s, int pts_wrap_bits, | |
1312 | int pts_num, int pts_den) | |
1313 | { | |
1314 | s->pts_wrap_bits = pts_wrap_bits; | |
1315 | s->pts_num = pts_num; | |
1316 | s->pts_den = pts_den; | |
1317 | } | |
1318 | ||
1319 | /* fraction handling */ | |
1320 | ||
1321 | /** | |
1322 | * f = val + (num / den) + 0.5. 'num' is normalized so that it is such | |
1323 | * as 0 <= num < den. | |
1324 | * | |
1325 | * @param f fractional number | |
1326 | * @param val integer value | |
1327 | * @param num must be >= 0 | |
1328 | * @param den must be >= 1 | |
1329 | */ | |
0c1a9eda | 1330 | void av_frac_init(AVFrac *f, int64_t val, int64_t num, int64_t den) |
916c80e9 FB |
1331 | { |
1332 | num += (den >> 1); | |
1333 | if (num >= den) { | |
1334 | val += num / den; | |
1335 | num = num % den; | |
1336 | } | |
1337 | f->val = val; | |
1338 | f->num = num; | |
1339 | f->den = den; | |
1340 | } | |
1341 | ||
1342 | /* set f to (val + 0.5) */ | |
0c1a9eda | 1343 | void av_frac_set(AVFrac *f, int64_t val) |
916c80e9 FB |
1344 | { |
1345 | f->val = val; | |
1346 | f->num = f->den >> 1; | |
1347 | } | |
1348 | ||
1349 | /** | |
1350 | * Fractionnal addition to f: f = f + (incr / f->den) | |
1351 | * | |
1352 | * @param f fractional number | |
1353 | * @param incr increment, can be positive or negative | |
1354 | */ | |
0c1a9eda | 1355 | void av_frac_add(AVFrac *f, int64_t incr) |
916c80e9 | 1356 | { |
0c1a9eda | 1357 | int64_t num, den; |
916c80e9 FB |
1358 | |
1359 | num = f->num + incr; | |
1360 | den = f->den; | |
1361 | if (num < 0) { | |
1362 | f->val += num / den; | |
1363 | num = num % den; | |
1364 | if (num < 0) { | |
1365 | num += den; | |
1366 | f->val--; | |
1367 | } | |
1368 | } else if (num >= den) { | |
1369 | f->val += num / den; | |
1370 | num = num % den; | |
1371 | } | |
1372 | f->num = num; | |
1373 | } | |
87a0a681 FB |
1374 | |
1375 | /** | |
1376 | * register a new image format | |
1377 | * @param img_fmt Image format descriptor | |
1378 | */ | |
1379 | void av_register_image_format(AVImageFormat *img_fmt) | |
1380 | { | |
1381 | AVImageFormat **p; | |
1382 | ||
1383 | p = &first_image_format; | |
1384 | while (*p != NULL) p = &(*p)->next; | |
1385 | *p = img_fmt; | |
1386 | img_fmt->next = NULL; | |
1387 | } | |
1388 | ||
1389 | /* guess image format */ | |
1390 | AVImageFormat *av_probe_image_format(AVProbeData *pd) | |
1391 | { | |
1392 | AVImageFormat *fmt1, *fmt; | |
1393 | int score, score_max; | |
1394 | ||
1395 | fmt = NULL; | |
1396 | score_max = 0; | |
1397 | for(fmt1 = first_image_format; fmt1 != NULL; fmt1 = fmt1->next) { | |
1398 | if (fmt1->img_probe) { | |
1399 | score = fmt1->img_probe(pd); | |
1400 | if (score > score_max) { | |
1401 | score_max = score; | |
1402 | fmt = fmt1; | |
1403 | } | |
1404 | } | |
1405 | } | |
1406 | return fmt; | |
1407 | } | |
1408 | ||
1409 | AVImageFormat *guess_image_format(const char *filename) | |
1410 | { | |
1411 | AVImageFormat *fmt1; | |
1412 | ||
1413 | for(fmt1 = first_image_format; fmt1 != NULL; fmt1 = fmt1->next) { | |
1414 | if (fmt1->extensions && match_ext(filename, fmt1->extensions)) | |
1415 | return fmt1; | |
1416 | } | |
1417 | return NULL; | |
1418 | } | |
1419 | ||
1420 | /** | |
1421 | * Read an image from a stream. | |
1422 | * @param gb byte stream containing the image | |
1423 | * @param fmt image format, NULL if probing is required | |
1424 | */ | |
1425 | int av_read_image(ByteIOContext *pb, const char *filename, | |
1426 | AVImageFormat *fmt, | |
1427 | int (*alloc_cb)(void *, AVImageInfo *info), void *opaque) | |
1428 | { | |
1429 | char buf[PROBE_BUF_SIZE]; | |
1430 | AVProbeData probe_data, *pd = &probe_data; | |
1431 | offset_t pos; | |
1432 | int ret; | |
1433 | ||
1434 | if (!fmt) { | |
5c91a675 | 1435 | pd->filename = filename; |
87a0a681 FB |
1436 | pd->buf = buf; |
1437 | pos = url_ftell(pb); | |
1438 | pd->buf_size = get_buffer(pb, buf, PROBE_BUF_SIZE); | |
1439 | url_fseek(pb, pos, SEEK_SET); | |
1440 | fmt = av_probe_image_format(pd); | |
1441 | } | |
1442 | if (!fmt) | |
1443 | return AVERROR_NOFMT; | |
1444 | ret = fmt->img_read(pb, alloc_cb, opaque); | |
1445 | return ret; | |
1446 | } | |
1447 | ||
1448 | /** | |
1449 | * Write an image to a stream. | |
1450 | * @param pb byte stream for the image output | |
1451 | * @param fmt image format | |
1452 | * @param img image data and informations | |
1453 | */ | |
1454 | int av_write_image(ByteIOContext *pb, AVImageFormat *fmt, AVImageInfo *img) | |
1455 | { | |
1456 | return fmt->img_write(pb, img); | |
1457 | } | |
1458 |