comparison utils.c @ 0:05318cf2e886 libavformat

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