Statistics
| Branch: | Revision:

ffmpeg / libav / utils.c @ 7feb950a

History | View | Annotate | Download (32.3 KB)

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
    ic->iformat = fmt;
357

    
358
    /* allocate private data */
359
    ic->priv_data = av_mallocz(fmt->priv_data_size);
360
    if (!ic->priv_data) {
361
        err = AVERROR_NOMEM;
362
        goto fail;
363
    }
364

    
365
    /* default pts settings is MPEG like */
366
    av_set_pts_info(ic, 33, 1, 90000);
367

    
368
    /* check filename in case of an image number is expected */
369
    if (ic->iformat->flags & AVFMT_NEEDNUMBER) {
370
        if (filename_number_test(ic->filename) < 0) { 
371
            err = AVERROR_NUMEXPECTED;
372
            goto fail1;
373
        }
374
    }
375
    
376
    err = ic->iformat->read_header(ic, ap);
377
    if (err < 0)
378
        goto fail1;
379
    *ic_ptr = ic;
380
    return 0;
381
 fail1:
382
    if (!(fmt->flags & AVFMT_NOFILE)) {
383
        url_fclose(&ic->pb);
384
    }
385
 fail:
386
    if (ic) {
387
        av_freep(&ic->priv_data);
388
    }
389
    av_free(ic);
390
    *ic_ptr = NULL;
391
    return err;
392
}
393

    
394
/**
395
 * Read a packet from a media file
396
 * @param s media file handle
397
 * @param pkt is filled 
398
 * @return 0 if OK. AVERROR_xxx if error.
399
 */
400
int av_read_packet(AVFormatContext *s, AVPacket *pkt)
401
{
402
    AVPacketList *pktl;
403

    
404
    pktl = s->packet_buffer;
405
    if (pktl) {
406
        /* read packet from packet buffer, if there is data */
407
        *pkt = pktl->pkt;
408
        s->packet_buffer = pktl->next;
409
        av_free(pktl);
410
        return 0;
411
    } else {
412
        return s->iformat->read_packet(s, pkt);
413
    }
414
}
415

    
416
/* state for codec information */
417
#define CSTATE_NOTFOUND    0
418
#define CSTATE_DECODING    1
419
#define CSTATE_FOUND       2
420

    
421
static int has_codec_parameters(AVCodecContext *enc)
422
{
423
    int val;
424
    switch(enc->codec_type) {
425
    case CODEC_TYPE_AUDIO:
426
        val = enc->sample_rate;
427
        break;
428
    case CODEC_TYPE_VIDEO:
429
        val = enc->width;
430
        break;
431
    default:
432
        val = 1;
433
        break;
434
    }
435
    return (val != 0);
436
}
437

    
438
/**
439
 * Read the beginning of a media file to get stream information. This
440
 * is useful for file formats with no headers such as MPEG. This
441
 * function also compute the real frame rate in case of mpeg2 repeat
442
 * frame mode.
443
 *
444
 * @param ic media file handle
445
 * @return >=0 if OK. AVERROR_xxx if error.  
446
 */
447
int av_find_stream_info(AVFormatContext *ic)
448
{
449
    int i, count, ret, got_picture, size, read_size;
450
    AVCodec *codec;
451
    AVStream *st;
452
    AVPacket *pkt;
453
    AVPicture picture;
454
    AVPacketList *pktl=NULL, **ppktl;
455
    short samples[AVCODEC_MAX_AUDIO_FRAME_SIZE / 2];
456
    UINT8 *ptr;
457
    int min_read_size, max_read_size;
458

    
459
    /* typical mpeg ts rate is 40 Mbits. DVD rate is about 10
460
       Mbits. We read at most 0.1 second of file to find all streams */
461

    
462
    /* XXX: base it on stream bitrate when possible */
463
    if (ic->iformat == &mpegts_demux) {
464
        /* maximum number of bytes we accept to read to find all the streams
465
           in a file */
466
        min_read_size = 3000000;
467
    } else {
468
        min_read_size = 125000;
469
    }
470
    /* max read size is 2 seconds of video max */
471
    max_read_size = min_read_size * 20;
472

    
473
    /* set initial codec state */
474
    for(i=0;i<ic->nb_streams;i++) {
475
        st = ic->streams[i];
476
        if (has_codec_parameters(&st->codec))
477
            st->codec_info_state = CSTATE_FOUND;
478
        else
479
            st->codec_info_state = CSTATE_NOTFOUND;
480
        st->codec_info_nb_repeat_frames = 0;
481
        st->codec_info_nb_real_frames = 0;
482
    }
483

    
484
    count = 0;
485
    read_size = 0;
486
    ppktl = &ic->packet_buffer;
487
    for(;;) {
488
        /* check if one codec still needs to be handled */
489
        for(i=0;i<ic->nb_streams;i++) {
490
            st = ic->streams[i];
491
            if (st->codec_info_state != CSTATE_FOUND)
492
                break;
493
        }
494
        if (i == ic->nb_streams) {
495
            /* NOTE: if the format has no header, then we need to read
496
               some packets to get most of the streams, so we cannot
497
               stop here */
498
            if (!(ic->iformat->flags & AVFMT_NOHEADER) ||
499
                read_size >= min_read_size) {
500
                /* if we found the info for all the codecs, we can stop */
501
                ret = count;
502
                break;
503
            }
504
        } else {
505
            /* we did not get all the codec info, but we read too much data */
506
            if (read_size >= max_read_size) {
507
                ret = count;
508
                break;
509
            }
510
        }
511

    
512
        pktl = av_mallocz(sizeof(AVPacketList));
513
        if (!pktl) {
514
            ret = AVERROR_NOMEM;
515
            break;
516
        }
517

    
518
        /* add the packet in the buffered packet list */
519
        *ppktl = pktl;
520
        ppktl = &pktl->next;
521

    
522
        /* NOTE: a new stream can be added there if no header in file
523
           (AVFMT_NOHEADER) */
524
        pkt = &pktl->pkt;
525
        if (ic->iformat->read_packet(ic, pkt) < 0) {
526
            /* EOF or error */
527
            ret = -1; /* we could not have all the codec parameters before EOF */
528
            if ((ic->iformat->flags & AVFMT_NOHEADER) &&
529
                i == ic->nb_streams)
530
                ret = 0;
531
            break;
532
        }
533
        read_size += pkt->size;
534

    
535
        /* open new codecs */
536
        for(i=0;i<ic->nb_streams;i++) {
537
            st = ic->streams[i];
538
            if (st->codec_info_state == CSTATE_NOTFOUND) {
539
                /* set to found in case of error */
540
                st->codec_info_state = CSTATE_FOUND; 
541
                codec = avcodec_find_decoder(st->codec.codec_id);
542
                if (codec) {
543
                    if(codec->capabilities & CODEC_CAP_TRUNCATED)
544
                        st->codec.flags |= CODEC_FLAG_TRUNCATED;
545

    
546
                    ret = avcodec_open(&st->codec, codec);
547
                    if (ret >= 0)
548
                        st->codec_info_state = CSTATE_DECODING;
549
                }
550
            }
551
        }
552

    
553
        st = ic->streams[pkt->stream_index];
554
        if (st->codec_info_state == CSTATE_DECODING) {
555
            /* decode the data and update codec parameters */
556
            ptr = pkt->data;
557
            size = pkt->size;
558
            while (size > 0) {
559
                switch(st->codec.codec_type) {
560
                case CODEC_TYPE_VIDEO:
561
                    ret = avcodec_decode_video(&st->codec, &picture, 
562
                                               &got_picture, ptr, size);
563
                    break;
564
                case CODEC_TYPE_AUDIO:
565
                    ret = avcodec_decode_audio(&st->codec, samples, 
566
                                               &got_picture, ptr, size);
567
                    break;
568
                default:
569
                    ret = -1;
570
                    break;
571
                }
572
                if (ret < 0) {
573
                    /* if error, simply ignore because another packet
574
                       may be OK */
575
                    break;
576
                }
577
                if (got_picture) {
578
                    /* we got the parameters - now we can stop
579
                       examining this stream */
580
                    /* XXX: add a codec info so that we can decide if
581
                       the codec can repeat frames */
582
                    if (st->codec.codec_id == CODEC_ID_MPEG1VIDEO && 
583
                        ic->iformat != &mpegts_demux &&
584
                        st->codec.sub_id == 2) {
585
                        /* for mpeg2 video, we want to know the real
586
                           frame rate, so we decode 40 frames. In mpeg
587
                           TS case we do not do it because it would be
588
                           too long */
589
                        st->codec_info_nb_real_frames++;
590
                        st->codec_info_nb_repeat_frames += st->codec.repeat_pict;
591
#if 0
592
                        /* XXX: testing */
593
                        if ((st->codec_info_nb_real_frames % 24) == 23) {
594
                            st->codec_info_nb_repeat_frames += 2;
595
                        }
596
#endif
597
                        /* stop after 40 frames */
598
                        if (st->codec_info_nb_real_frames >= 40) {
599
                            st->r_frame_rate = (st->codec.frame_rate * 
600
                                                st->codec_info_nb_real_frames) /
601
                                (st->codec_info_nb_real_frames + 
602
                                 (st->codec_info_nb_repeat_frames >> 1));
603
                            goto close_codec;
604
                        }
605
                    } else {
606
                    close_codec:
607
                        st->codec_info_state = CSTATE_FOUND;
608
                        avcodec_close(&st->codec);
609
                        break;
610
                    }
611
                }
612
                ptr += ret;
613
                size -= ret;
614
            }
615
        }
616
        count++;
617
    }
618

    
619
    /* close each codec if there are opened */
620
    for(i=0;i<ic->nb_streams;i++) {
621
        st = ic->streams[i];
622
        if (st->codec_info_state == CSTATE_DECODING)
623
            avcodec_close(&st->codec);
624
    }
625

    
626
    /* set real frame rate info */
627
    for(i=0;i<ic->nb_streams;i++) {
628
        st = ic->streams[i];
629
        if (st->codec.codec_type == CODEC_TYPE_VIDEO) {
630
            if (!st->r_frame_rate)
631
                st->r_frame_rate = st->codec.frame_rate;
632
        }
633
    }
634

    
635
    return ret;
636
}
637

    
638
/**
639
 * Close a media file (but not its codecs)
640
 *
641
 * @param s media file handle
642
 */
643
void av_close_input_file(AVFormatContext *s)
644
{
645
    int i;
646

    
647
    if (s->iformat->read_close)
648
        s->iformat->read_close(s);
649
    for(i=0;i<s->nb_streams;i++) {
650
        av_free(s->streams[i]);
651
    }
652
    if (s->packet_buffer) {
653
        AVPacketList *p, *p1;
654
        p = s->packet_buffer;
655
        while (p != NULL) {
656
            p1 = p->next;
657
            av_free_packet(&p->pkt);
658
            av_free(p);
659
            p = p1;
660
        }
661
        s->packet_buffer = NULL;
662
    }
663
    if (!(s->iformat->flags & AVFMT_NOFILE)) {
664
        url_fclose(&s->pb);
665
    }
666
    av_freep(&s->priv_data);
667
    av_free(s);
668
}
669

    
670
/**
671
 * Add a new stream to a media file. Can only be called in the
672
 * read_header function. If the flag AVFMT_NOHEADER is in the format
673
 * description, then new streams can be added in read_packet too.
674
 *
675
 *
676
 * @param s media file handle
677
 * @param id file format dependent stream id
678
 */
679
AVStream *av_new_stream(AVFormatContext *s, int id)
680
{
681
    AVStream *st;
682

    
683
    if (s->nb_streams >= MAX_STREAMS)
684
        return NULL;
685

    
686
    st = av_mallocz(sizeof(AVStream));
687
    if (!st)
688
        return NULL;
689
    st->index = s->nb_streams;
690
    st->id = id;
691
    s->streams[s->nb_streams++] = st;
692
    return st;
693
}
694

    
695
/************************************************************/
696
/* output media file */
697

    
698
/**
699
 * allocate the stream private data and write the stream header to an
700
 * output media file
701
 *
702
 * @param s media file handle
703
 * @return 0 if OK. AVERROR_xxx if error.  
704
 */
705
int av_write_header(AVFormatContext *s)
706
{
707
    int ret, i;
708
    AVStream *st;
709

    
710
    s->priv_data = av_mallocz(s->oformat->priv_data_size);
711
    if (!s->priv_data)
712
        return AVERROR_NOMEM;
713
    /* default pts settings is MPEG like */
714
    av_set_pts_info(s, 33, 1, 90000);
715
    ret = s->oformat->write_header(s);
716
    if (ret < 0)
717
        return ret;
718

    
719
    /* init PTS generation */
720
    for(i=0;i<s->nb_streams;i++) {
721
        st = s->streams[i];
722

    
723
        switch (st->codec.codec_type) {
724
        case CODEC_TYPE_AUDIO:
725
            av_frac_init(&st->pts, 0, 0, 
726
                         (INT64)s->pts_num * st->codec.sample_rate);
727
            break;
728
        case CODEC_TYPE_VIDEO:
729
            av_frac_init(&st->pts, 0, 0, 
730
                         (INT64)s->pts_num * st->codec.frame_rate);
731
            break;
732
        default:
733
            break;
734
        }
735
    }
736
    return 0;
737
}
738

    
739
/**
740
 * Write a packet to an output media file. The packet shall contain
741
 * one audio or video frame.
742
 *
743
 * @param s media file handle
744
 * @param stream_index stream index
745
 * @param buf buffer containing the frame data
746
 * @param size size of buffer
747
 * @return < 0 if error, = 0 if OK, 1 if end of stream wanted.
748
 */
749
int av_write_frame(AVFormatContext *s, int stream_index, const uint8_t *buf, 
750
                   int size)
751
{
752
    AVStream *st;
753
    INT64 pts_mask;
754
    int ret, frame_size;
755

    
756
    st = s->streams[stream_index];
757
    pts_mask = (1LL << s->pts_wrap_bits) - 1;
758
    ret = s->oformat->write_packet(s, stream_index, (uint8_t *)buf, size, 
759
                                   st->pts.val & pts_mask);
760
    if (ret < 0)
761
        return ret;
762

    
763
    /* update pts */
764
    switch (st->codec.codec_type) {
765
    case CODEC_TYPE_AUDIO:
766
        if (st->codec.frame_size <= 1) {
767
            frame_size = size / st->codec.channels;
768
            /* specific hack for pcm codecs because no frame size is provided */
769
            switch(st->codec.codec->id) {
770
            case CODEC_ID_PCM_S16LE:
771
            case CODEC_ID_PCM_S16BE:
772
            case CODEC_ID_PCM_U16LE:
773
            case CODEC_ID_PCM_U16BE:
774
                frame_size >>= 1;
775
                break;
776
            default:
777
                break;
778
            }
779
        } else {
780
            frame_size = st->codec.frame_size;
781
        }
782
        av_frac_add(&st->pts, 
783
                    (INT64)s->pts_den * frame_size);
784
        break;
785
    case CODEC_TYPE_VIDEO:
786
        av_frac_add(&st->pts, 
787
                    (INT64)s->pts_den * FRAME_RATE_BASE);
788
        break;
789
    default:
790
        break;
791
    }
792
    return ret;
793
}
794

    
795
/**
796
 * write the stream trailer to an output media file and and free the
797
 * file private data.
798
 *
799
 * @param s media file handle
800
 * @return 0 if OK. AVERROR_xxx if error.  */
801
int av_write_trailer(AVFormatContext *s)
802
{
803
    int ret;
804
    ret = s->oformat->write_trailer(s);
805
    av_freep(&s->priv_data);
806
    return ret;
807
}
808

    
809
/* "user interface" functions */
810

    
811
void dump_format(AVFormatContext *ic,
812
                 int index, 
813
                 const char *url,
814
                 int is_output)
815
{
816
    int i, flags;
817
    char buf[256];
818

    
819
    fprintf(stderr, "%s #%d, %s, %s '%s':\n", 
820
            is_output ? "Output" : "Input",
821
            index, 
822
            is_output ? ic->oformat->name : ic->iformat->name, 
823
            is_output ? "to" : "from", url);
824
    for(i=0;i<ic->nb_streams;i++) {
825
        AVStream *st = ic->streams[i];
826
        avcodec_string(buf, sizeof(buf), &st->codec, is_output);
827
        fprintf(stderr, "  Stream #%d.%d", index, i);
828
        /* the pid is an important information, so we display it */
829
        /* XXX: add a generic system */
830
        if (is_output)
831
            flags = ic->oformat->flags;
832
        else
833
            flags = ic->iformat->flags;
834
        if (flags & AVFMT_SHOW_IDS) {
835
            fprintf(stderr, "[0x%x]", st->id);
836
        }
837
        fprintf(stderr, ": %s\n", buf);
838
    }
839
}
840

    
841
typedef struct {
842
    const char *str;
843
    int width, height;
844
} SizeEntry;
845

    
846
static SizeEntry sizes[] = {
847
    { "sqcif", 128, 96 },
848
    { "qcif", 176, 144 },
849
    { "cif", 352, 288 },
850
    { "4cif", 704, 576 },
851
};
852
    
853
int parse_image_size(int *width_ptr, int *height_ptr, const char *str)
854
{
855
    int i;
856
    int n = sizeof(sizes) / sizeof(SizeEntry);
857
    const char *p;
858
    int frame_width = 0, frame_height = 0;
859

    
860
    for(i=0;i<n;i++) {
861
        if (!strcmp(sizes[i].str, str)) {
862
            frame_width = sizes[i].width;
863
            frame_height = sizes[i].height;
864
            break;
865
        }
866
    }
867
    if (i == n) {
868
        p = str;
869
        frame_width = strtol(p, (char **)&p, 10);
870
        if (*p)
871
            p++;
872
        frame_height = strtol(p, (char **)&p, 10);
873
    }
874
    if (frame_width <= 0 || frame_height <= 0)
875
        return -1;
876
    *width_ptr = frame_width;
877
    *height_ptr = frame_height;
878
    return 0;
879
}
880

    
881
INT64 av_gettime(void)
882
{
883
#ifdef CONFIG_WIN32
884
    struct _timeb tb;
885
    _ftime(&tb);
886
    return ((INT64)tb.time * INT64_C(1000) + (INT64)tb.millitm) * INT64_C(1000);
887
#else
888
    struct timeval tv;
889
    gettimeofday(&tv,NULL);
890
    return (INT64)tv.tv_sec * 1000000 + tv.tv_usec;
891
#endif
892
}
893

    
894
static time_t mktimegm(struct tm *tm)
895
{
896
    time_t t;
897

    
898
    int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
899

    
900
    if (m < 3) {
901
        m += 12;
902
        y--;
903
    }
904

    
905
    t = 86400 * 
906
        (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469);
907

    
908
    t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
909

    
910
    return t;
911
}
912

    
913
/* Syntax:
914
 * - If not a duration:
915
 *  [{YYYY-MM-DD|YYYYMMDD}]{T| }{HH[:MM[:SS[.m...]]][Z]|HH[MM[SS[.m...]]][Z]}
916
 * Time is localtime unless Z is suffixed to the end. In this case GMT
917
 * Return the date in micro seconds since 1970 
918
 * - If duration:
919
 *  HH[:MM[:SS[.m...]]]
920
 *  S+[.m...]
921
 */
922
INT64 parse_date(const char *datestr, int duration)
923
{
924
    const char *p;
925
    INT64 t;
926
    struct tm dt;
927
    int i;
928
    static const char *date_fmt[] = {
929
        "%Y-%m-%d",
930
        "%Y%m%d",
931
    };
932
    static const char *time_fmt[] = {
933
        "%H:%M:%S",
934
        "%H%M%S",
935
    };
936
    const char *q;
937
    int is_utc, len;
938
    char lastch;
939
    time_t now = time(0);
940

    
941
    len = strlen(datestr);
942
    if (len > 0)
943
        lastch = datestr[len - 1];
944
    else
945
        lastch = '\0';
946
    is_utc = (lastch == 'z' || lastch == 'Z');
947

    
948
    memset(&dt, 0, sizeof(dt));
949

    
950
    p = datestr;
951
    q = NULL;
952
    if (!duration) {
953
        for (i = 0; i < sizeof(date_fmt) / sizeof(date_fmt[0]); i++) {
954
            q = strptime(p, date_fmt[i], &dt);
955
            if (q) {
956
                break;
957
            }
958
        }
959

    
960
        if (!q) {
961
            if (is_utc) {
962
                dt = *gmtime(&now);
963
            } else {
964
                dt = *localtime(&now);
965
            }
966
            dt.tm_hour = dt.tm_min = dt.tm_sec = 0;
967
        } else {
968
            p = q;
969
        }
970

    
971
        if (*p == 'T' || *p == 't' || *p == ' ')
972
            p++;
973

    
974
        for (i = 0; i < sizeof(time_fmt) / sizeof(time_fmt[0]); i++) {
975
            q = strptime(p, time_fmt[i], &dt);
976
            if (q) {
977
                break;
978
            }
979
        }
980
    } else {
981
        q = strptime(p, time_fmt[0], &dt);
982
        if (!q) {
983
            dt.tm_sec = strtol(p, (char **)&q, 10);
984
            dt.tm_min = 0;
985
            dt.tm_hour = 0;
986
        }
987
    }
988

    
989
    /* Now we have all the fields that we can get */
990
    if (!q) {
991
        if (duration)
992
            return 0;
993
        else
994
            return now * INT64_C(1000000);
995
    }
996

    
997
    if (duration) {
998
        t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
999
    } else {
1000
        dt.tm_isdst = -1;       /* unknown */
1001
        if (is_utc) {
1002
            t = mktimegm(&dt);
1003
        } else {
1004
            t = mktime(&dt);
1005
        }
1006
    }
1007

    
1008
    t *= 1000000;
1009

    
1010
    if (*q == '.') {
1011
        int val, n;
1012
        q++;
1013
        for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
1014
            if (!isdigit(*q)) 
1015
                break;
1016
            val += n * (*q - '0');
1017
        }
1018
        t += val;
1019
    }
1020
    return t;
1021
}
1022

    
1023
/* syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done. Return
1024
   1 if found */
1025
int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
1026
{
1027
    const char *p;
1028
    char tag[128], *q;
1029

    
1030
    p = info;
1031
    if (*p == '?')
1032
        p++;
1033
    for(;;) {
1034
        q = tag;
1035
        while (*p != '\0' && *p != '=' && *p != '&') {
1036
            if ((q - tag) < sizeof(tag) - 1)
1037
                *q++ = *p;
1038
            p++;
1039
        }
1040
        *q = '\0';
1041
        q = arg;
1042
        if (*p == '=') {
1043
            p++;
1044
            while (*p != '&' && *p != '\0') {
1045
                if ((q - arg) < arg_size - 1) {
1046
                    if (*p == '+')
1047
                        *q++ = ' ';
1048
                    else
1049
                        *q++ = *p;
1050
                }
1051
                p++;
1052
            }
1053
            *q = '\0';
1054
        }
1055
        if (!strcmp(tag, tag1)) 
1056
            return 1;
1057
        if (*p != '&')
1058
            break;
1059
        p++;
1060
    }
1061
    return 0;
1062
}
1063

    
1064
/* Return in 'buf' the path with '%d' replaced by number. Also handles
1065
   the '%0nd' format where 'n' is the total number of digits and
1066
   '%%'. Return 0 if OK, and -1 if format error */
1067
int get_frame_filename(char *buf, int buf_size,
1068
                       const char *path, int number)
1069
{
1070
    const char *p;
1071
    char *q, buf1[20];
1072
    int nd, len, c, percentd_found;
1073

    
1074
    q = buf;
1075
    p = path;
1076
    percentd_found = 0;
1077
    for(;;) {
1078
        c = *p++;
1079
        if (c == '\0')
1080
            break;
1081
        if (c == '%') {
1082
            nd = 0;
1083
            while (*p >= '0' && *p <= '9') {
1084
                nd = nd * 10 + *p++ - '0';
1085
            }
1086
            c = *p++;
1087
            switch(c) {
1088
            case '%':
1089
                goto addchar;
1090
            case 'd':
1091
                if (percentd_found)
1092
                    goto fail;
1093
                percentd_found = 1;
1094
                snprintf(buf1, sizeof(buf1), "%0*d", nd, number);
1095
                len = strlen(buf1);
1096
                if ((q - buf + len) > buf_size - 1)
1097
                    goto fail;
1098
                memcpy(q, buf1, len);
1099
                q += len;
1100
                break;
1101
            default:
1102
                goto fail;
1103
            }
1104
        } else {
1105
        addchar:
1106
            if ((q - buf) < buf_size - 1)
1107
                *q++ = c;
1108
        }
1109
    }
1110
    if (!percentd_found)
1111
        goto fail;
1112
    *q = '\0';
1113
    return 0;
1114
 fail:
1115
    *q = '\0';
1116
    return -1;
1117
}
1118

    
1119
/**
1120
 *
1121
 * Print on stdout a nice hexa dump of a buffer
1122
 * @param buf buffer
1123
 * @param size buffer size
1124
 */
1125
void av_hex_dump(UINT8 *buf, int size)
1126
{
1127
    int len, i, j, c;
1128

    
1129
    for(i=0;i<size;i+=16) {
1130
        len = size - i;
1131
        if (len > 16)
1132
            len = 16;
1133
        printf("%08x ", i);
1134
        for(j=0;j<16;j++) {
1135
            if (j < len)
1136
                printf(" %02x", buf[i+j]);
1137
            else
1138
                printf("   ");
1139
        }
1140
        printf(" ");
1141
        for(j=0;j<len;j++) {
1142
            c = buf[i+j];
1143
            if (c < ' ' || c > '~')
1144
                c = '.';
1145
            printf("%c", c);
1146
        }
1147
        printf("\n");
1148
    }
1149
}
1150

    
1151
void url_split(char *proto, int proto_size,
1152
               char *hostname, int hostname_size,
1153
               int *port_ptr,
1154
               char *path, int path_size,
1155
               const char *url)
1156
{
1157
    const char *p;
1158
    char *q;
1159
    int port;
1160

    
1161
    port = -1;
1162

    
1163
    p = url;
1164
    q = proto;
1165
    while (*p != ':' && *p != '\0') {
1166
        if ((q - proto) < proto_size - 1)
1167
            *q++ = *p;
1168
        p++;
1169
    }
1170
    if (proto_size > 0)
1171
        *q = '\0';
1172
    if (*p == '\0') {
1173
        if (proto_size > 0)
1174
            proto[0] = '\0';
1175
        if (hostname_size > 0)
1176
            hostname[0] = '\0';
1177
        p = url;
1178
    } else {
1179
        p++;
1180
        if (*p == '/')
1181
            p++;
1182
        if (*p == '/')
1183
            p++;
1184
        q = hostname;
1185
        while (*p != ':' && *p != '/' && *p != '?' && *p != '\0') {
1186
            if ((q - hostname) < hostname_size - 1)
1187
                *q++ = *p;
1188
            p++;
1189
        }
1190
        if (hostname_size > 0)
1191
            *q = '\0';
1192
        if (*p == ':') {
1193
            p++;
1194
            port = strtoul(p, (char **)&p, 10);
1195
        }
1196
    }
1197
    if (port_ptr)
1198
        *port_ptr = port;
1199
    pstrcpy(path, path_size, p);
1200
}
1201

    
1202
/**
1203
 * Set the pts for a given stream
1204
 * @param s stream 
1205
 * @param pts_wrap_bits number of bits effectively used by the pts
1206
 *        (used for wrap control, 33 is the value for MPEG) 
1207
 * @param pts_num numerator to convert to seconds (MPEG: 1) 
1208
 * @param pts_den denominator to convert to seconds (MPEG: 90000)
1209
 */
1210
void av_set_pts_info(AVFormatContext *s, int pts_wrap_bits,
1211
                     int pts_num, int pts_den)
1212
{
1213
    s->pts_wrap_bits = pts_wrap_bits;
1214
    s->pts_num = pts_num;
1215
    s->pts_den = pts_den;
1216
}
1217

    
1218
/* fraction handling */
1219

    
1220
/**
1221
 * f = val + (num / den) + 0.5. 'num' is normalized so that it is such
1222
 * as 0 <= num < den.
1223
 *
1224
 * @param f fractional number
1225
 * @param val integer value
1226
 * @param num must be >= 0
1227
 * @param den must be >= 1 
1228
 */
1229
void av_frac_init(AVFrac *f, INT64 val, INT64 num, INT64 den)
1230
{
1231
    num += (den >> 1);
1232
    if (num >= den) {
1233
        val += num / den;
1234
        num = num % den;
1235
    }
1236
    f->val = val;
1237
    f->num = num;
1238
    f->den = den;
1239
}
1240

    
1241
/* set f to (val + 0.5) */
1242
void av_frac_set(AVFrac *f, INT64 val)
1243
{
1244
    f->val = val;
1245
    f->num = f->den >> 1;
1246
}
1247

    
1248
/**
1249
 * Fractionnal addition to f: f = f + (incr / f->den)
1250
 *
1251
 * @param f fractional number
1252
 * @param incr increment, can be positive or negative
1253
 */
1254
void av_frac_add(AVFrac *f, INT64 incr)
1255
{
1256
    INT64 num, den;
1257

    
1258
    num = f->num + incr;
1259
    den = f->den;
1260
    if (num < 0) {
1261
        f->val += num / den;
1262
        num = num % den;
1263
        if (num < 0) {
1264
            num += den;
1265
            f->val--;
1266
        }
1267
    } else if (num >= den) {
1268
        f->val += num / den;
1269
        num = num % den;
1270
    }
1271
    f->num = num;
1272
}