a314ec4e2752d7cda78e876202a828fb2140cdeb
[libav.git] / libav / utils.c
1 /*
2 * Various utilities for ffmpeg system
3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
4 *
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.
9 *
10 * This library 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 GNU
13 * Lesser General Public License for more details.
14 *
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
18 */
19 #include "avformat.h"
20 #include "tick.h"
21 #ifndef CONFIG_WIN32
22 #include <unistd.h>
23 #include <fcntl.h>
24 #include <sys/time.h>
25 #include <time.h>
26 #else
27 #define strcasecmp _stricmp
28 #include <sys/types.h>
29 #include <sys/timeb.h>
30 #endif
31
32 AVInputFormat *first_iformat;
33 AVOutputFormat *first_oformat;
34
35 void av_register_input_format(AVInputFormat *format)
36 {
37 AVInputFormat **p;
38 p = &first_iformat;
39 while (*p != NULL) p = &(*p)->next;
40 *p = format;
41 format->next = NULL;
42 }
43
44 void av_register_output_format(AVOutputFormat *format)
45 {
46 AVOutputFormat **p;
47 p = &first_oformat;
48 while (*p != NULL) p = &(*p)->next;
49 *p = format;
50 format->next = NULL;
51 }
52
53 int match_ext(const char *filename, const char *extensions)
54 {
55 const char *ext, *p;
56 char ext1[32], *q;
57
58 ext = strrchr(filename, '.');
59 if (ext) {
60 ext++;
61 p = extensions;
62 for(;;) {
63 q = ext1;
64 while (*p != '\0' && *p != ',')
65 *q++ = *p++;
66 *q = '\0';
67 if (!strcasecmp(ext1, ext))
68 return 1;
69 if (*p == '\0')
70 break;
71 p++;
72 }
73 }
74 return 0;
75 }
76
77 AVOutputFormat *guess_format(const char *short_name, const char *filename,
78 const char *mime_type)
79 {
80 AVOutputFormat *fmt, *fmt_found;
81 int score_max, score;
82
83 /* find the proper file type */
84 fmt_found = NULL;
85 score_max = 0;
86 fmt = first_oformat;
87 while (fmt != NULL) {
88 score = 0;
89 if (fmt->name && short_name && !strcmp(fmt->name, short_name))
90 score += 100;
91 if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
92 score += 10;
93 if (filename && fmt->extensions &&
94 match_ext(filename, fmt->extensions)) {
95 score += 5;
96 }
97 if (score > score_max) {
98 score_max = score;
99 fmt_found = fmt;
100 }
101 fmt = fmt->next;
102 }
103 return fmt_found;
104 }
105
106 AVInputFormat *av_find_input_format(const char *short_name)
107 {
108 AVInputFormat *fmt;
109 for(fmt = first_iformat; fmt != NULL; fmt = fmt->next) {
110 if (!strcmp(fmt->name, short_name))
111 return fmt;
112 }
113 return NULL;
114 }
115
116
117 /**
118 * Return TRUE if val is a prefix of str. If it returns TRUE, ptr is
119 * set to the next character in 'str' after the prefix.
120 *
121 * @param str input string
122 * @param val prefix to test
123 * @param ptr updated after the prefix in str in there is a match
124 * @return TRUE if there is a match
125 */
126 int strstart(const char *str, const char *val, const char **ptr)
127 {
128 const char *p, *q;
129 p = str;
130 q = val;
131 while (*q != '\0') {
132 if (*p != *q)
133 return 0;
134 p++;
135 q++;
136 }
137 if (ptr)
138 *ptr = p;
139 return 1;
140 }
141
142 /**
143 * Copy the string str to buf. If str length is bigger than buf_size -
144 * 1 then it is clamped to buf_size - 1.
145 * NOTE: this function does what strncpy should have done to be
146 * useful. NEVER use strncpy.
147 *
148 * @param buf destination buffer
149 * @param buf_size size of destination buffer
150 * @param str source string
151 */
152 void pstrcpy(char *buf, int buf_size, const char *str)
153 {
154 int c;
155 char *q = buf;
156
157 for(;;) {
158 c = *str++;
159 if (c == 0 || q >= buf + buf_size - 1)
160 break;
161 *q++ = c;
162 }
163 *q = '\0';
164 }
165
166 void register_all(void)
167 {
168 avcodec_init();
169 avcodec_register_all();
170
171 mpegps_init();
172 mpegts_init();
173 crc_init();
174 img_init();
175 raw_init();
176 rm_init();
177 asf_init();
178 avienc_init();
179 avidec_init();
180 wav_init();
181 swf_init();
182 au_init();
183 gif_init();
184 mov_init();
185 jpeg_init();
186
187 #ifndef CONFIG_WIN32
188 ffm_init();
189 #endif
190 #ifdef CONFIG_VIDEO4LINUX
191 video_grab_init();
192 #endif
193 #ifdef CONFIG_AUDIO_OSS
194 audio_init();
195 #endif
196 /* file protocols */
197 register_protocol(&file_protocol);
198 register_protocol(&pipe_protocol);
199 #ifdef CONFIG_NETWORK
200 register_protocol(&udp_protocol);
201 register_protocol(&http_protocol);
202 #endif
203 }
204
205 /* memory handling */
206
207 /**
208 * Allocate the payload of a packet and intialized its fields to default values.
209 *
210 * @param pkt packet
211 * @param size wanted payload size
212 * @return 0 if OK. AVERROR_xxx otherwise.
213 */
214 int av_new_packet(AVPacket *pkt, int size)
215 {
216 pkt->data = av_malloc(size);
217 if (!pkt->data)
218 return AVERROR_NOMEM;
219 pkt->size = size;
220 /* sane state */
221 pkt->pts = 0;
222 pkt->stream_index = 0;
223 pkt->flags = 0;
224 return 0;
225 }
226
227 /**
228 * Free a packet
229 *
230 * @param pkt packet to free
231 */
232 void av_free_packet(AVPacket *pkt)
233 {
234 av_freep(&pkt->data);
235 /* fail safe */
236 pkt->size = 0;
237 }
238
239 /* fifo handling */
240
241 int fifo_init(FifoBuffer *f, int size)
242 {
243 f->buffer = av_malloc(size);
244 if (!f->buffer)
245 return -1;
246 f->end = f->buffer + size;
247 f->wptr = f->rptr = f->buffer;
248 return 0;
249 }
250
251 void fifo_free(FifoBuffer *f)
252 {
253 av_free(f->buffer);
254 }
255
256 int fifo_size(FifoBuffer *f, UINT8 *rptr)
257 {
258 int size;
259
260 if (f->wptr >= rptr) {
261 size = f->wptr - rptr;
262 } else {
263 size = (f->end - rptr) + (f->wptr - f->buffer);
264 }
265 return size;
266 }
267
268 /* get data from the fifo (return -1 if not enough data) */
269 int fifo_read(FifoBuffer *f, UINT8 *buf, int buf_size, UINT8 **rptr_ptr)
270 {
271 UINT8 *rptr = *rptr_ptr;
272 int size, len;
273
274 if (f->wptr >= rptr) {
275 size = f->wptr - rptr;
276 } else {
277 size = (f->end - rptr) + (f->wptr - f->buffer);
278 }
279
280 if (size < buf_size)
281 return -1;
282 while (buf_size > 0) {
283 len = f->end - rptr;
284 if (len > buf_size)
285 len = buf_size;
286 memcpy(buf, rptr, len);
287 buf += len;
288 rptr += len;
289 if (rptr >= f->end)
290 rptr = f->buffer;
291 buf_size -= len;
292 }
293 *rptr_ptr = rptr;
294 return 0;
295 }
296
297 void fifo_write(FifoBuffer *f, UINT8 *buf, int size, UINT8 **wptr_ptr)
298 {
299 int len;
300 UINT8 *wptr;
301 wptr = *wptr_ptr;
302 while (size > 0) {
303 len = f->end - wptr;
304 if (len > size)
305 len = size;
306 memcpy(wptr, buf, len);
307 wptr += len;
308 if (wptr >= f->end)
309 wptr = f->buffer;
310 buf += len;
311 size -= len;
312 }
313 *wptr_ptr = wptr;
314 }
315
316 int filename_number_test(const char *filename)
317 {
318 char buf[1024];
319 return get_frame_filename(buf, sizeof(buf), filename, 1);
320 }
321
322 /* guess file format */
323 static AVInputFormat *probe_input_format(AVProbeData *pd, int is_opened)
324 {
325 AVInputFormat *fmt1, *fmt;
326 int score, score_max;
327
328 fmt = NULL;
329 score_max = 0;
330 for(fmt1 = first_iformat; fmt1 != NULL; fmt1 = fmt1->next) {
331 if (!is_opened && !(fmt1->flags & AVFMT_NOFILE))
332 continue;
333 score = 0;
334 if (fmt1->read_probe) {
335 score = fmt1->read_probe(pd);
336 } else if (fmt1->extensions) {
337 if (match_ext(pd->filename, fmt1->extensions)) {
338 score = 50;
339 }
340 }
341 if (score > score_max) {
342 score_max = score;
343 fmt = fmt1;
344 }
345 }
346 return fmt;
347 }
348
349 /************************************************************/
350 /* input media file */
351
352 #define PROBE_BUF_SIZE 2048
353
354 /**
355 * Open a media file as input. The codec are not opened. Only the file
356 * header (if present) is read.
357 *
358 * @param ic_ptr the opened media file handle is put here
359 * @param filename filename to open.
360 * @param fmt if non NULL, force the file format to use
361 * @param buf_size optional buffer size (zero if default is OK)
362 * @param ap additionnal parameters needed when opening the file (NULL if default)
363 * @return 0 if OK. AVERROR_xxx otherwise.
364 */
365 int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,
366 AVInputFormat *fmt,
367 int buf_size,
368 AVFormatParameters *ap)
369 {
370 AVFormatContext *ic = NULL;
371 int err;
372 char buf[PROBE_BUF_SIZE];
373 AVProbeData probe_data, *pd = &probe_data;
374
375 ic = av_mallocz(sizeof(AVFormatContext));
376 if (!ic) {
377 err = AVERROR_NOMEM;
378 goto fail;
379 }
380 pstrcpy(ic->filename, sizeof(ic->filename), filename);
381 pd->filename = ic->filename;
382 pd->buf = buf;
383 pd->buf_size = 0;
384
385 if (!fmt) {
386 /* guess format if no file can be opened */
387 fmt = probe_input_format(pd, 0);
388 }
389
390 /* if no file needed do not try to open one */
391 if (!fmt || !(fmt->flags & AVFMT_NOFILE)) {
392 if (url_fopen(&ic->pb, filename, URL_RDONLY) < 0) {
393 err = AVERROR_IO;
394 goto fail;
395 }
396 if (buf_size > 0) {
397 url_setbufsize(&ic->pb, buf_size);
398 }
399 /* read probe data */
400 pd->buf_size = get_buffer(&ic->pb, buf, PROBE_BUF_SIZE);
401 url_fseek(&ic->pb, 0, SEEK_SET);
402 }
403
404 /* guess file format */
405 if (!fmt) {
406 fmt = probe_input_format(pd, 1);
407 }
408
409 /* if still no format found, error */
410 if (!fmt) {
411 err = AVERROR_NOFMT;
412 goto fail;
413 }
414
415 ic->iformat = fmt;
416
417 /* allocate private data */
418 ic->priv_data = av_mallocz(fmt->priv_data_size);
419 if (!ic->priv_data) {
420 err = AVERROR_NOMEM;
421 goto fail;
422 }
423
424 /* check filename in case of an image number is expected */
425 if (ic->iformat->flags & AVFMT_NEEDNUMBER) {
426 if (filename_number_test(ic->filename) < 0) {
427 err = AVERROR_NUMEXPECTED;
428 goto fail1;
429 }
430 }
431
432 err = ic->iformat->read_header(ic, ap);
433 if (err < 0)
434 goto fail1;
435 *ic_ptr = ic;
436 return 0;
437 fail1:
438 if (!(fmt->flags & AVFMT_NOFILE)) {
439 url_fclose(&ic->pb);
440 }
441 fail:
442 if (ic) {
443 av_freep(&ic->priv_data);
444 }
445 av_free(ic);
446 *ic_ptr = NULL;
447 return err;
448 }
449
450 /**
451 * Read a packet from a media file
452 * @param s media file handle
453 * @param pkt is filled
454 * @return 0 if OK. AVERROR_xxx if error.
455 */
456 int av_read_packet(AVFormatContext *s, AVPacket *pkt)
457 {
458 AVPacketList *pktl;
459
460 pktl = s->packet_buffer;
461 if (pktl) {
462 /* read packet from packet buffer, if there is data */
463 *pkt = pktl->pkt;
464 s->packet_buffer = pktl->next;
465 av_free(pktl);
466 return 0;
467 } else {
468 return s->iformat->read_packet(s, pkt);
469 }
470 }
471
472 /* state for codec information */
473 #define CSTATE_NOTFOUND 0
474 #define CSTATE_DECODING 1
475 #define CSTATE_FOUND 2
476
477 static int has_codec_parameters(AVCodecContext *enc)
478 {
479 int val;
480 switch(enc->codec_type) {
481 case CODEC_TYPE_AUDIO:
482 val = enc->sample_rate;
483 break;
484 case CODEC_TYPE_VIDEO:
485 val = enc->width;
486 break;
487 default:
488 val = 1;
489 break;
490 }
491 return (val != 0);
492 }
493
494 /**
495 * Read the beginning of a media file to get stream information. This
496 * is useful for file formats with no headers such as MPEG. This
497 * function also compute the real frame rate in case of mpeg2 repeat
498 * frame mode.
499 *
500 * @param ic media file handle
501 * @return >=0 if OK. AVERROR_xxx if error.
502 */
503 int av_find_stream_info(AVFormatContext *ic)
504 {
505 int i, count, ret, got_picture, size, read_size;
506 AVCodec *codec;
507 AVStream *st;
508 AVPacket *pkt;
509 AVPicture picture;
510 AVPacketList *pktl=NULL, **ppktl;
511 short samples[AVCODEC_MAX_AUDIO_FRAME_SIZE / 2];
512 UINT8 *ptr;
513 int min_read_size, max_read_size;
514
515 /* typical mpeg ts rate is 40 Mbits. DVD rate is about 10
516 Mbits. We read at most 0.1 second of file to find all streams */
517
518 /* XXX: base it on stream bitrate when possible */
519 if (ic->iformat == &mpegts_demux) {
520 /* maximum number of bytes we accept to read to find all the streams
521 in a file */
522 min_read_size = 3000000;
523 } else {
524 min_read_size = 125000;
525 }
526 /* max read size is 2 seconds of video max */
527 max_read_size = min_read_size * 20;
528
529 /* set initial codec state */
530 for(i=0;i<ic->nb_streams;i++) {
531 st = ic->streams[i];
532 if (has_codec_parameters(&st->codec))
533 st->codec_info_state = CSTATE_FOUND;
534 else
535 st->codec_info_state = CSTATE_NOTFOUND;
536 st->codec_info_nb_repeat_frames = 0;
537 st->codec_info_nb_real_frames = 0;
538 }
539
540 count = 0;
541 read_size = 0;
542 ppktl = &ic->packet_buffer;
543 for(;;) {
544 /* check if one codec still needs to be handled */
545 for(i=0;i<ic->nb_streams;i++) {
546 st = ic->streams[i];
547 if (st->codec_info_state != CSTATE_FOUND)
548 break;
549 }
550 if (i == ic->nb_streams) {
551 /* NOTE: if the format has no header, then we need to read
552 some packets to get most of the streams, so we cannot
553 stop here */
554 if (!(ic->iformat->flags & AVFMT_NOHEADER) ||
555 read_size >= min_read_size) {
556 /* if we found the info for all the codecs, we can stop */
557 ret = count;
558 break;
559 }
560 } else {
561 /* we did not get all the codec info, but we read too much data */
562 if (read_size >= max_read_size) {
563 ret = count;
564 break;
565 }
566 }
567
568 pktl = av_mallocz(sizeof(AVPacketList));
569 if (!pktl) {
570 ret = AVERROR_NOMEM;
571 break;
572 }
573
574 /* add the packet in the buffered packet list */
575 *ppktl = pktl;
576 ppktl = &pktl->next;
577
578 /* NOTE: a new stream can be added there if no header in file
579 (AVFMT_NOHEADER) */
580 pkt = &pktl->pkt;
581 if (ic->iformat->read_packet(ic, pkt) < 0) {
582 /* EOF or error */
583 ret = -1; /* we could not have all the codec parameters before EOF */
584 if ((ic->iformat->flags & AVFMT_NOHEADER) &&
585 i == ic->nb_streams)
586 ret = 0;
587 break;
588 }
589 read_size += pkt->size;
590
591 /* open new codecs */
592 for(i=0;i<ic->nb_streams;i++) {
593 st = ic->streams[i];
594 if (st->codec_info_state == CSTATE_NOTFOUND) {
595 /* set to found in case of error */
596 st->codec_info_state = CSTATE_FOUND;
597 codec = avcodec_find_decoder(st->codec.codec_id);
598 if (codec) {
599 ret = avcodec_open(&st->codec, codec);
600 if (ret >= 0)
601 st->codec_info_state = CSTATE_DECODING;
602 }
603 }
604 }
605
606 st = ic->streams[pkt->stream_index];
607 if (st->codec_info_state == CSTATE_DECODING) {
608 /* decode the data and update codec parameters */
609 ptr = pkt->data;
610 size = pkt->size;
611 while (size > 0) {
612 switch(st->codec.codec_type) {
613 case CODEC_TYPE_VIDEO:
614 ret = avcodec_decode_video(&st->codec, &picture,
615 &got_picture, ptr, size);
616 break;
617 case CODEC_TYPE_AUDIO:
618 ret = avcodec_decode_audio(&st->codec, samples,
619 &got_picture, ptr, size);
620 break;
621 default:
622 ret = -1;
623 break;
624 }
625 if (ret < 0) {
626 /* if error, simply ignore because another packet
627 may be OK */
628 break;
629 }
630 if (got_picture) {
631 /* we got the parameters - now we can stop
632 examining this stream */
633 /* XXX: add a codec info so that we can decide if
634 the codec can repeat frames */
635 if (st->codec.codec_id == CODEC_ID_MPEG1VIDEO &&
636 ic->iformat != &mpegts_demux &&
637 st->codec.sub_id == 2) {
638 /* for mpeg2 video, we want to know the real
639 frame rate, so we decode 40 frames. In mpeg
640 TS case we do not do it because it would be
641 too long */
642 st->codec_info_nb_real_frames++;
643 st->codec_info_nb_repeat_frames += st->codec.repeat_pict;
644 #if 0
645 /* XXX: testing */
646 if ((st->codec_info_nb_real_frames % 24) == 23) {
647 st->codec_info_nb_repeat_frames += 2;
648 }
649 #endif
650 /* stop after 40 frames */
651 if (st->codec_info_nb_real_frames >= 40) {
652 st->r_frame_rate = (st->codec.frame_rate *
653 st->codec_info_nb_real_frames) /
654 (st->codec_info_nb_real_frames +
655 (st->codec_info_nb_repeat_frames >> 1));
656 goto close_codec;
657 }
658 } else {
659 close_codec:
660 st->codec_info_state = CSTATE_FOUND;
661 avcodec_close(&st->codec);
662 }
663 break;
664 }
665 ptr += ret;
666 size -= ret;
667 }
668 }
669 count++;
670 }
671
672 /* close each codec if there are opened */
673 for(i=0;i<ic->nb_streams;i++) {
674 st = ic->streams[i];
675 if (st->codec_info_state == CSTATE_DECODING)
676 avcodec_close(&st->codec);
677 }
678
679 /* set real frame rate info */
680 for(i=0;i<ic->nb_streams;i++) {
681 st = ic->streams[i];
682 if (st->codec.codec_type == CODEC_TYPE_VIDEO) {
683 if (!st->r_frame_rate)
684 st->r_frame_rate = st->codec.frame_rate;
685 }
686 }
687
688 return ret;
689 }
690
691 /**
692 * Close a media file (but not its codecs)
693 *
694 * @param s media file handle
695 */
696 void av_close_input_file(AVFormatContext *s)
697 {
698 int i;
699
700 if (s->iformat->read_close)
701 s->iformat->read_close(s);
702 for(i=0;i<s->nb_streams;i++) {
703 av_free(s->streams[i]);
704 }
705 if (s->packet_buffer) {
706 AVPacketList *p, *p1;
707 p = s->packet_buffer;
708 while (p != NULL) {
709 p1 = p->next;
710 av_free_packet(&p->pkt);
711 av_free(p);
712 p = p1;
713 }
714 s->packet_buffer = NULL;
715 }
716 if (!(s->iformat->flags & AVFMT_NOFILE)) {
717 url_fclose(&s->pb);
718 }
719 av_freep(&s->priv_data);
720 av_free(s);
721 }
722
723 /**
724 * Add a new stream to a media file. Can only be called in the
725 * read_header function. If the flag AVFMT_NOHEADER is in the format
726 * description, then new streams can be added in read_packet too.
727 *
728 *
729 * @param s media file handle
730 * @param id file format dependent stream id
731 */
732 AVStream *av_new_stream(AVFormatContext *s, int id)
733 {
734 AVStream *st;
735
736 if (s->nb_streams >= MAX_STREAMS)
737 return NULL;
738
739 st = av_mallocz(sizeof(AVStream));
740 if (!st)
741 return NULL;
742 st->index = s->nb_streams;
743 st->id = id;
744 s->streams[s->nb_streams++] = st;
745 return st;
746 }
747
748 /************************************************************/
749 /* output media file */
750
751 /**
752 * allocate the stream private data and write the stream header to an
753 * output media file
754 *
755 * @param s media file handle
756 * @return 0 if OK. AVERROR_xxx if error.
757 */
758 int av_write_header(AVFormatContext *s)
759 {
760 s->priv_data = av_mallocz(s->oformat->priv_data_size);
761 if (!s->priv_data)
762 return AVERROR_NOMEM;
763 return s->oformat->write_header(s);
764 }
765
766 /**
767 * write a packet to an output media file
768 *
769 * @param s media file handle
770 * @param pkt packet to write
771 * @param force_pts XXX: need to suppress that
772 */
773 int av_write_packet(AVFormatContext *s, AVPacket *pkt, int force_pts)
774 {
775 /* XXX: currently, an emulation because internal API must change */
776 return s->oformat->write_packet(s, pkt->stream_index, pkt->data, pkt->size, force_pts);
777 }
778
779 /**
780 * write the stream trailer to an output media file and and free the
781 * file private data.
782 *
783 * @param s media file handle
784 * @return 0 if OK. AVERROR_xxx if error. */
785 int av_write_trailer(AVFormatContext *s)
786 {
787 int ret;
788 ret = s->oformat->write_trailer(s);
789 av_freep(&s->priv_data);
790 return ret;
791 }
792
793 /* "user interface" functions */
794
795 void dump_format(AVFormatContext *ic,
796 int index,
797 const char *url,
798 int is_output)
799 {
800 int i, flags;
801 char buf[256];
802
803 fprintf(stderr, "%s #%d, %s, %s '%s':\n",
804 is_output ? "Output" : "Input",
805 index,
806 is_output ? ic->oformat->name : ic->iformat->name,
807 is_output ? "to" : "from", url);
808 for(i=0;i<ic->nb_streams;i++) {
809 AVStream *st = ic->streams[i];
810 avcodec_string(buf, sizeof(buf), &st->codec, is_output);
811 fprintf(stderr, " Stream #%d.%d", index, i);
812 /* the pid is an important information, so we display it */
813 /* XXX: add a generic system */
814 if (is_output)
815 flags = ic->oformat->flags;
816 else
817 flags = ic->iformat->flags;
818 if (flags & AVFMT_SHOW_IDS) {
819 fprintf(stderr, "[0x%x]", st->id);
820 }
821 fprintf(stderr, ": %s\n", buf);
822 }
823 }
824
825 typedef struct {
826 const char *str;
827 int width, height;
828 } SizeEntry;
829
830 static SizeEntry sizes[] = {
831 { "sqcif", 128, 96 },
832 { "qcif", 176, 144 },
833 { "cif", 352, 288 },
834 { "4cif", 704, 576 },
835 };
836
837 int parse_image_size(int *width_ptr, int *height_ptr, const char *str)
838 {
839 int i;
840 int n = sizeof(sizes) / sizeof(SizeEntry);
841 const char *p;
842 int frame_width = 0, frame_height = 0;
843
844 for(i=0;i<n;i++) {
845 if (!strcmp(sizes[i].str, str)) {
846 frame_width = sizes[i].width;
847 frame_height = sizes[i].height;
848 break;
849 }
850 }
851 if (i == n) {
852 p = str;
853 frame_width = strtol(p, (char **)&p, 10);
854 if (*p)
855 p++;
856 frame_height = strtol(p, (char **)&p, 10);
857 }
858 if (frame_width <= 0 || frame_height <= 0)
859 return -1;
860 *width_ptr = frame_width;
861 *height_ptr = frame_height;
862 return 0;
863 }
864
865 INT64 gettime(void)
866 {
867 #ifdef CONFIG_WIN32
868 struct _timeb tb;
869 _ftime(&tb);
870 return ((INT64)tb.time * INT64_C(1000) + (INT64)tb.millitm) * INT64_C(1000);
871 #else
872 struct timeval tv;
873 gettimeofday(&tv,NULL);
874 return (INT64)tv.tv_sec * 1000000 + tv.tv_usec;
875 #endif
876 }
877
878 /* syntax: [YYYY-MM-DD ][[HH:]MM:]SS[.m...] . Return the date in micro seconds since 1970 */
879 INT64 parse_date(const char *datestr, int duration)
880 {
881 const char *p;
882 INT64 t;
883 struct tm dt;
884
885 memset(&dt, 0, sizeof(dt));
886
887 p = datestr;
888 if (!duration) {
889 if (strlen(p) >= 5 && p[4] == '-') {
890 dt.tm_year = strtol(p, (char **)&p, 10);
891 if (*p)
892 p++;
893 dt.tm_mon = strtol(p, (char **)&p, 10) - 1;
894 if (*p)
895 p++;
896 dt.tm_mday = strtol(p, (char **)&p, 10) - 1;
897 if (*p)
898 p++;
899 } else {
900 time_t now = time(0);
901 dt = *localtime(&now);
902 dt.tm_hour = 0;
903 dt.tm_min = 0;
904 dt.tm_sec = 0;
905 }
906 }
907
908 dt.tm_hour = strtol(p, (char **)&p, 10);
909 if (*p)
910 p++;
911 dt.tm_min = strtol(p, (char **)&p, 10);
912 if (*p)
913 p++;
914 dt.tm_sec = strtol(p, (char **)&p, 10);
915
916 if (duration) {
917 t = (INT64) 1000000 * (dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec);
918 } else {
919 t = (INT64) 1000000 * mktime(&dt);
920 }
921
922 if (*p == '.') {
923 int val, n;
924 p++;
925 n = strlen(p);
926 if (n > 6)
927 n = 6;
928 val = strtol(p, NULL, 10);
929 while (n < 6) {
930 val = val * 10;
931 n++;
932 }
933 t += val;
934 }
935 return t;
936 }
937
938 /* syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done. Return
939 1 if found */
940 int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
941 {
942 const char *p;
943 char tag[128], *q;
944
945 p = info;
946 if (*p == '?')
947 p++;
948 for(;;) {
949 q = tag;
950 while (*p != '\0' && *p != '=' && *p != '&') {
951 if ((q - tag) < sizeof(tag) - 1)
952 *q++ = *p;
953 p++;
954 }
955 *q = '\0';
956 q = arg;
957 if (*p == '=') {
958 p++;
959 while (*p != '&' && *p != '\0') {
960 if ((q - arg) < arg_size - 1) {
961 if (*p == '+')
962 *q++ = ' ';
963 else
964 *q++ = *p;
965 }
966 p++;
967 }
968 *q = '\0';
969 }
970 if (!strcmp(tag, tag1))
971 return 1;
972 if (*p != '&')
973 break;
974 p++;
975 }
976 return 0;
977 }
978
979 /* Return in 'buf' the path with '%d' replaced by number. Also handles
980 the '%0nd' format where 'n' is the total number of digits and
981 '%%'. Return 0 if OK, and -1 if format error */
982 int get_frame_filename(char *buf, int buf_size,
983 const char *path, int number)
984 {
985 const char *p;
986 char *q, buf1[20];
987 int nd, len, c, percentd_found;
988
989 q = buf;
990 p = path;
991 percentd_found = 0;
992 for(;;) {
993 c = *p++;
994 if (c == '\0')
995 break;
996 if (c == '%') {
997 nd = 0;
998 while (*p >= '0' && *p <= '9') {
999 nd = nd * 10 + *p++ - '0';
1000 }
1001 c = *p++;
1002 switch(c) {
1003 case '%':
1004 goto addchar;
1005 case 'd':
1006 if (percentd_found)
1007 goto fail;
1008 percentd_found = 1;
1009 snprintf(buf1, sizeof(buf1), "%0*d", nd, number);
1010 len = strlen(buf1);
1011 if ((q - buf + len) > buf_size - 1)
1012 goto fail;
1013 memcpy(q, buf1, len);
1014 q += len;
1015 break;
1016 default:
1017 goto fail;
1018 }
1019 } else {
1020 addchar:
1021 if ((q - buf) < buf_size - 1)
1022 *q++ = c;
1023 }
1024 }
1025 if (!percentd_found)
1026 goto fail;
1027 *q = '\0';
1028 return 0;
1029 fail:
1030 *q = '\0';
1031 return -1;
1032 }
1033
1034 static int gcd(INT64 a, INT64 b)
1035 {
1036 INT64 c;
1037
1038 while (1) {
1039 c = a % b;
1040 if (c == 0)
1041 return b;
1042 a = b;
1043 b = c;
1044 }
1045 }
1046
1047 void ticker_init(Ticker *tick, INT64 inrate, INT64 outrate)
1048 {
1049 int g;
1050
1051 g = gcd(inrate, outrate);
1052 inrate /= g;
1053 outrate /= g;
1054
1055 tick->value = -outrate/2;
1056
1057 tick->inrate = inrate;
1058 tick->outrate = outrate;
1059 tick->div = tick->outrate / tick->inrate;
1060 tick->mod = tick->outrate % tick->inrate;
1061 }
1062
1063 /**
1064 *
1065 * Print on stdout a nice hexa dump of a buffer
1066 * @param buf buffer
1067 * @param size buffer size
1068 */
1069 void av_hex_dump(UINT8 *buf, int size)
1070 {
1071 int len, i, j, c;
1072
1073 for(i=0;i<size;i+=16) {
1074 len = size - i;
1075 if (len > 16)
1076 len = 16;
1077 printf("%08x ", i);
1078 for(j=0;j<16;j++) {
1079 if (j < len)
1080 printf(" %02x", buf[i+j]);
1081 else
1082 printf(" ");
1083 }
1084 printf(" ");
1085 for(j=0;j<len;j++) {
1086 c = buf[i+j];
1087 if (c < ' ' || c > '~')
1088 c = '.';
1089 printf("%c", c);
1090 }
1091 printf("\n");
1092 }
1093 }
1094