Statistics
| Branch: | Revision:

ffmpeg / libavformat / utils.c @ 12f996ed

History | View | Annotate | Download (46.7 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
#ifdef CONFIG_WIN32
22
#define strcasecmp _stricmp
23
#include <sys/types.h>
24
#include <sys/timeb.h>
25
#elif defined(CONFIG_OS2)
26
#include <string.h>
27
#define strcasecmp stricmp
28
#include <sys/time.h>
29
#else
30
#include <unistd.h>
31
#include <fcntl.h>
32
#include <sys/time.h>
33
#endif
34
#include <time.h>
35

    
36
#ifndef HAVE_STRPTIME
37
#include "strptime.h"
38
#endif
39

    
40
AVInputFormat *first_iformat;
41
AVOutputFormat *first_oformat;
42
AVImageFormat *first_image_format;
43

    
44
void av_register_input_format(AVInputFormat *format)
45
{
46
    AVInputFormat **p;
47
    p = &first_iformat;
48
    while (*p != NULL) p = &(*p)->next;
49
    *p = format;
50
    format->next = NULL;
51
}
52

    
53
void av_register_output_format(AVOutputFormat *format)
54
{
55
    AVOutputFormat **p;
56
    p = &first_oformat;
57
    while (*p != NULL) p = &(*p)->next;
58
    *p = format;
59
    format->next = NULL;
60
}
61

    
62
int match_ext(const char *filename, const char *extensions)
63
{
64
    const char *ext, *p;
65
    char ext1[32], *q;
66

    
67
    ext = strrchr(filename, '.');
68
    if (ext) {
69
        ext++;
70
        p = extensions;
71
        for(;;) {
72
            q = ext1;
73
            while (*p != '\0' && *p != ',') 
74
                *q++ = *p++;
75
            *q = '\0';
76
            if (!strcasecmp(ext1, ext)) 
77
                return 1;
78
            if (*p == '\0') 
79
                break;
80
            p++;
81
        }
82
    }
83
    return 0;
84
}
85

    
86
AVOutputFormat *guess_format(const char *short_name, const char *filename, 
87
                             const char *mime_type)
88
{
89
    AVOutputFormat *fmt, *fmt_found;
90
    int score_max, score;
91

    
92
    /* specific test for image sequences */
93
    if (!short_name && filename && 
94
        filename_number_test(filename) >= 0 &&
95
        guess_image_format(filename)) {
96
        return guess_format("image", NULL, NULL);
97
    }
98

    
99
    /* find the proper file type */
100
    fmt_found = NULL;
101
    score_max = 0;
102
    fmt = first_oformat;
103
    while (fmt != NULL) {
104
        score = 0;
105
        if (fmt->name && short_name && !strcmp(fmt->name, short_name))
106
            score += 100;
107
        if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
108
            score += 10;
109
        if (filename && fmt->extensions && 
110
            match_ext(filename, fmt->extensions)) {
111
            score += 5;
112
        }
113
        if (score > score_max) {
114
            score_max = score;
115
            fmt_found = fmt;
116
        }
117
        fmt = fmt->next;
118
    }
119
    return fmt_found;
120
}   
121

    
122
AVOutputFormat *guess_stream_format(const char *short_name, const char *filename, 
123
                             const char *mime_type)
124
{
125
    AVOutputFormat *fmt = guess_format(short_name, filename, mime_type);
126

    
127
    if (fmt) {
128
        AVOutputFormat *stream_fmt;
129
        char stream_format_name[64];
130

    
131
        snprintf(stream_format_name, sizeof(stream_format_name), "%s_stream", fmt->name);
132
        stream_fmt = guess_format(stream_format_name, NULL, NULL);
133

    
134
        if (stream_fmt)
135
            fmt = stream_fmt;
136
    }
137

    
138
    return fmt;
139
}
140

    
141
AVInputFormat *av_find_input_format(const char *short_name)
142
{
143
    AVInputFormat *fmt;
144
    for(fmt = first_iformat; fmt != NULL; fmt = fmt->next) {
145
        if (!strcmp(fmt->name, short_name))
146
            return fmt;
147
    }
148
    return NULL;
149
}
150

    
151
/* memory handling */
152

    
153
/**
154
 * Default packet destructor 
155
 */
156
static void av_destruct_packet(AVPacket *pkt)
157
{
158
    av_free(pkt->data);
159
    pkt->data = NULL; pkt->size = 0;
160
}
161

    
162
/**
163
 * Allocate the payload of a packet and intialized its fields to default values.
164
 *
165
 * @param pkt packet
166
 * @param size wanted payload size
167
 * @return 0 if OK. AVERROR_xxx otherwise.
168
 */
169
int av_new_packet(AVPacket *pkt, int size)
170
{
171
    void *data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
172
    if (!data)
173
        return AVERROR_NOMEM;
174
    memset(data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
175

    
176
    av_init_packet(pkt);
177
    pkt->data = data; 
178
    pkt->size = size;
179
    pkt->destruct = av_destruct_packet;
180
    return 0;
181
}
182

    
183
/* fifo handling */
184

    
185
int fifo_init(FifoBuffer *f, int size)
186
{
187
    f->buffer = av_malloc(size);
188
    if (!f->buffer)
189
        return -1;
190
    f->end = f->buffer + size;
191
    f->wptr = f->rptr = f->buffer;
192
    return 0;
193
}
194

    
195
void fifo_free(FifoBuffer *f)
196
{
197
    av_free(f->buffer);
198
}
199

    
200
int fifo_size(FifoBuffer *f, uint8_t *rptr)
201
{
202
    int size;
203

    
204
    if (f->wptr >= rptr) {
205
        size = f->wptr - rptr;
206
    } else {
207
        size = (f->end - rptr) + (f->wptr - f->buffer);
208
    }
209
    return size;
210
}
211

    
212
/* get data from the fifo (return -1 if not enough data) */
213
int fifo_read(FifoBuffer *f, uint8_t *buf, int buf_size, uint8_t **rptr_ptr)
214
{
215
    uint8_t *rptr = *rptr_ptr;
216
    int size, len;
217

    
218
    if (f->wptr >= rptr) {
219
        size = f->wptr - rptr;
220
    } else {
221
        size = (f->end - rptr) + (f->wptr - f->buffer);
222
    }
223
    
224
    if (size < buf_size)
225
        return -1;
226
    while (buf_size > 0) {
227
        len = f->end - rptr;
228
        if (len > buf_size)
229
            len = buf_size;
230
        memcpy(buf, rptr, len);
231
        buf += len;
232
        rptr += len;
233
        if (rptr >= f->end)
234
            rptr = f->buffer;
235
        buf_size -= len;
236
    }
237
    *rptr_ptr = rptr;
238
    return 0;
239
}
240

    
241
void fifo_write(FifoBuffer *f, uint8_t *buf, int size, uint8_t **wptr_ptr)
242
{
243
    int len;
244
    uint8_t *wptr;
245
    wptr = *wptr_ptr;
246
    while (size > 0) {
247
        len = f->end - wptr;
248
        if (len > size)
249
            len = size;
250
        memcpy(wptr, buf, len);
251
        wptr += len;
252
        if (wptr >= f->end)
253
            wptr = f->buffer;
254
        buf += len;
255
        size -= len;
256
    }
257
    *wptr_ptr = wptr;
258
}
259

    
260
int filename_number_test(const char *filename)
261
{
262
    char buf[1024];
263
    return get_frame_filename(buf, sizeof(buf), filename, 1);
264
}
265

    
266
/* guess file format */
267
AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened)
268
{
269
    AVInputFormat *fmt1, *fmt;
270
    int score, score_max;
271

    
272
    fmt = NULL;
273
    score_max = 0;
274
    for(fmt1 = first_iformat; fmt1 != NULL; fmt1 = fmt1->next) {
275
        if (!is_opened && !(fmt1->flags & AVFMT_NOFILE))
276
            continue;
277
        score = 0;
278
        if (fmt1->read_probe) {
279
            score = fmt1->read_probe(pd);
280
        } else if (fmt1->extensions) {
281
            if (match_ext(pd->filename, fmt1->extensions)) {
282
                score = 50;
283
            }
284
        } 
285
        if (score > score_max) {
286
            score_max = score;
287
            fmt = fmt1;
288
        }
289
    }
290
    return fmt;
291
}
292

    
293
/************************************************************/
294
/* input media file */
295

    
296
#define PROBE_BUF_SIZE 2048
297

    
298
/**
299
 * Open a media file as input. The codec are not opened. Only the file
300
 * header (if present) is read.
301
 *
302
 * @param ic_ptr the opened media file handle is put here
303
 * @param filename filename to open.
304
 * @param fmt if non NULL, force the file format to use
305
 * @param buf_size optional buffer size (zero if default is OK)
306
 * @param ap additionnal parameters needed when opening the file (NULL if default)
307
 * @return 0 if OK. AVERROR_xxx otherwise.
308
 */
309
int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, 
310
                       AVInputFormat *fmt,
311
                       int buf_size,
312
                       AVFormatParameters *ap)
313
{
314
    AVFormatContext *ic = NULL;
315
    int err, must_open_file;
316
    char buf[PROBE_BUF_SIZE];
317
    AVProbeData probe_data, *pd = &probe_data;
318

    
319
    ic = av_mallocz(sizeof(AVFormatContext));
320
    if (!ic) {
321
        err = AVERROR_NOMEM;
322
        goto fail;
323
    }
324
    ic->duration = AV_NOPTS_VALUE;
325
    ic->start_time = AV_NOPTS_VALUE;
326
    pstrcpy(ic->filename, sizeof(ic->filename), filename);
327
    pd->filename = ic->filename;
328
    pd->buf = buf;
329
    pd->buf_size = 0;
330

    
331
    if (!fmt) {
332
        /* guess format if no file can be opened  */
333
        fmt = av_probe_input_format(pd, 0);
334
    }
335

    
336
    /* do not open file if the format does not need it. XXX: specific
337
       hack needed to handle RTSP/TCP */
338
    must_open_file = 1;
339
    if ((fmt && (fmt->flags & AVFMT_NOFILE)) ||
340
        (fmt == &rtp_demux && !strcmp(filename, "null"))) {
341
        must_open_file = 0;
342
    }
343

    
344
    if (!fmt || must_open_file) {
345
        /* if no file needed do not try to open one */
346
        if (url_fopen(&ic->pb, filename, URL_RDONLY) < 0) {
347
            err = AVERROR_IO;
348
            goto fail;
349
        }
350
        if (buf_size > 0) {
351
            url_setbufsize(&ic->pb, buf_size);
352
        }
353
        if (!fmt) {
354
            /* read probe data */
355
            pd->buf_size = get_buffer(&ic->pb, buf, PROBE_BUF_SIZE);
356
            url_fseek(&ic->pb, 0, SEEK_SET);
357
        }
358
    }
359
    
360
    /* guess file format */
361
    if (!fmt) {
362
        fmt = av_probe_input_format(pd, 1);
363
    }
364

    
365
    /* if still no format found, error */
366
    if (!fmt) {
367
        err = AVERROR_NOFMT;
368
        goto fail1;
369
    }
370
        
371
    /* XXX: suppress this hack for redirectors */
372
#ifdef CONFIG_NETWORK
373
    if (fmt == &redir_demux) {
374
        err = redir_open(ic_ptr, &ic->pb);
375
        url_fclose(&ic->pb);
376
        av_free(ic);
377
        return err;
378
    }
379
#endif
380

    
381
    ic->iformat = fmt;
382

    
383
    /* check filename in case of an image number is expected */
384
    if (ic->iformat->flags & AVFMT_NEEDNUMBER) {
385
        if (filename_number_test(ic->filename) < 0) { 
386
            err = AVERROR_NUMEXPECTED;
387
            goto fail1;
388
        }
389
    }
390
    
391
    /* allocate private data */
392
    if (fmt->priv_data_size > 0) {
393
        ic->priv_data = av_mallocz(fmt->priv_data_size);
394
        if (!ic->priv_data) {
395
            err = AVERROR_NOMEM;
396
        goto fail1;
397
        }
398
    } else
399
        ic->priv_data = NULL;
400

    
401
    /* default pts settings is MPEG like */
402
    av_set_pts_info(ic, 33, 1, 90000);
403

    
404
    err = ic->iformat->read_header(ic, ap);
405
    if (err < 0)
406
        goto fail1;
407
    *ic_ptr = ic;
408
    return 0;
409
 fail1:
410
    if (!fmt || must_open_file) {
411
        url_fclose(&ic->pb);
412
    }
413
 fail:
414
    if (ic) {
415
        av_freep(&ic->priv_data);
416
    }
417
    av_free(ic);
418
    *ic_ptr = NULL;
419
    return err;
420
}
421

    
422
/**
423
 * Read a packet from a media file
424
 * @param s media file handle
425
 * @param pkt is filled 
426
 * @return 0 if OK. AVERROR_xxx if error.
427
 */
428
int av_read_packet(AVFormatContext *s, AVPacket *pkt)
429
{
430
    AVPacketList *pktl;
431

    
432
    pktl = s->packet_buffer;
433
    if (pktl) {
434
        /* read packet from packet buffer, if there is data */
435
        *pkt = pktl->pkt;
436
        s->packet_buffer = pktl->next;
437
        av_free(pktl);
438
        return 0;
439
    } else {
440
        return s->iformat->read_packet(s, pkt);
441
    }
442
}
443

    
444

    
445
/* return TRUE if the stream has accurate timings for at least one component */
446
static int av_has_timings(AVFormatContext *ic)
447
{
448
    int i;
449
    AVStream *st;
450

    
451
    for(i = 0;i < ic->nb_streams; i++) {
452
        st = ic->streams[i];
453
        if (st->start_time != AV_NOPTS_VALUE &&
454
            st->duration != AV_NOPTS_VALUE)
455
            return 1;
456
    }
457
    return 0;
458
}
459

    
460
/* estimate the stream timings from the one of each components. Also
461
   compute the global bitrate if possible */
462
static void av_update_stream_timings(AVFormatContext *ic)
463
{
464
    int64_t start_time, end_time, end_time1;
465
    int i;
466
    AVStream *st;
467

    
468
    start_time = MAXINT64;
469
    end_time = MININT64;
470
    for(i = 0;i < ic->nb_streams; i++) {
471
        st = ic->streams[i];
472
        if (st->start_time != AV_NOPTS_VALUE) {
473
            if (st->start_time < start_time)
474
                start_time = st->start_time;
475
            if (st->duration != AV_NOPTS_VALUE) {
476
                end_time1 = st->start_time + st->duration;
477
                if (end_time1 > end_time)
478
                    end_time = end_time1;
479
            }
480
        }
481
    }
482
    if (start_time != MAXINT64) {
483
        ic->start_time = start_time;
484
        if (end_time != MAXINT64) {
485
            ic->duration = end_time - start_time;
486
            if (ic->file_size > 0) {
487
                /* compute the bit rate */
488
                ic->bit_rate = (double)ic->file_size * 8.0 * AV_TIME_BASE / 
489
                    (double)ic->duration;
490
            }
491
        }
492
    }
493

    
494
}
495

    
496
static void fill_all_stream_timings(AVFormatContext *ic)
497
{
498
    int i;
499
    AVStream *st;
500

    
501
    av_update_stream_timings(ic);
502
    for(i = 0;i < ic->nb_streams; i++) {
503
        st = ic->streams[i];
504
        if (st->start_time == AV_NOPTS_VALUE) {
505
            st->start_time = ic->start_time;
506
            st->duration = ic->duration;
507
        }
508
    }
509
}
510

    
511
static void av_estimate_timings_from_bit_rate(AVFormatContext *ic)
512
{
513
    int64_t filesize, duration;
514
    int bit_rate, i;
515
    AVStream *st;
516

    
517
    /* if bit_rate is already set, we believe it */
518
    if (ic->bit_rate == 0) {
519
        bit_rate = 0;
520
        for(i=0;i<ic->nb_streams;i++) {
521
            st = ic->streams[i];
522
            bit_rate += st->codec.bit_rate;
523
        }
524
        ic->bit_rate = bit_rate;
525
    }
526

    
527
    /* if duration is already set, we believe it */
528
    if (ic->duration == AV_NOPTS_VALUE && 
529
        ic->bit_rate != 0 && 
530
        ic->file_size != 0)  {
531
        filesize = ic->file_size;
532
        if (filesize > 0) {
533
            duration = (int64_t)((8 * AV_TIME_BASE * (double)filesize) / (double)ic->bit_rate);
534
            for(i = 0; i < ic->nb_streams; i++) {
535
                st = ic->streams[i];
536
                if (st->start_time == AV_NOPTS_VALUE ||
537
                    st->duration == AV_NOPTS_VALUE) {
538
                    st->start_time = 0;
539
                    st->duration = duration;
540
                }
541
            }
542
        }
543
    }
544
}
545

    
546
static void flush_packet_queue(AVFormatContext *s)
547
{
548
    AVPacketList *pktl;
549

    
550
    for(;;) {
551
        pktl = s->packet_buffer;
552
        if (!pktl) 
553
            break;
554
        s->packet_buffer = pktl->next;
555
        av_free(pktl);
556
    }
557
}
558

    
559
#define DURATION_MAX_READ_SIZE 250000
560

    
561
/* only usable for MPEG-PS streams */
562
static void av_estimate_timings_from_pts(AVFormatContext *ic)
563
{
564
    AVPacket pkt1, *pkt = &pkt1;
565
    AVStream *st;
566
    int read_size, i, ret;
567
    int64_t start_time, end_time, end_time1;
568
    int64_t filesize, offset, duration;
569
    
570
    /* we read the first packets to get the first PTS (not fully
571
       accurate, but it is enough now) */
572
    url_fseek(&ic->pb, 0, SEEK_SET);
573
    read_size = 0;
574
    for(;;) {
575
        if (read_size >= DURATION_MAX_READ_SIZE)
576
            break;
577
        /* if all info is available, we can stop */
578
        for(i = 0;i < ic->nb_streams; i++) {
579
            st = ic->streams[i];
580
            if (st->start_time == AV_NOPTS_VALUE)
581
                break;
582
        }
583
        if (i == ic->nb_streams)
584
            break;
585

    
586
        ret = av_read_packet(ic, pkt);
587
        if (ret != 0)
588
            break;
589
        read_size += pkt->size;
590
        st = ic->streams[pkt->stream_index];
591
        if (pkt->pts != AV_NOPTS_VALUE) {
592
            if (st->start_time == AV_NOPTS_VALUE)
593
                st->start_time = (int64_t)((double)pkt->pts * ic->pts_num * (double)AV_TIME_BASE / ic->pts_den);
594
         }
595
         av_free_packet(pkt);
596
     }
597

    
598
    /* we compute the minimum start_time and use it as default */
599
    start_time = MAXINT64;
600
    for(i = 0; i < ic->nb_streams; i++) {
601
        st = ic->streams[i];
602
        if (st->start_time != AV_NOPTS_VALUE &&
603
            st->start_time < start_time)
604
            start_time = st->start_time;
605
    }
606
    printf("start=%lld\n", start_time);
607
    if (start_time != MAXINT64)
608
        ic->start_time = start_time;
609
    
610
    /* estimate the end time (duration) */
611
    /* XXX: may need to support wrapping */
612
    filesize = ic->file_size;
613
    offset = filesize - DURATION_MAX_READ_SIZE;
614
    if (offset < 0)
615
        offset = 0;
616

    
617
    /* flush packet queue */
618
    flush_packet_queue(ic);
619

    
620
    url_fseek(&ic->pb, offset, SEEK_SET);
621
    read_size = 0;
622
    for(;;) {
623
        if (read_size >= DURATION_MAX_READ_SIZE)
624
            break;
625
        /* if all info is available, we can stop */
626
        for(i = 0;i < ic->nb_streams; i++) {
627
            st = ic->streams[i];
628
            if (st->duration == AV_NOPTS_VALUE)
629
                break;
630
        }
631
        if (i == ic->nb_streams)
632
            break;
633
        
634
        ret = av_read_packet(ic, pkt);
635
        if (ret != 0)
636
            break;
637
        read_size += pkt->size;
638
        st = ic->streams[pkt->stream_index];
639
        if (pkt->pts != AV_NOPTS_VALUE) {
640
            end_time = (int64_t)((double)pkt->pts * ic->pts_num * (double)AV_TIME_BASE / ic->pts_den);
641
            duration = end_time - st->start_time;
642
            if (duration > 0) {
643
                if (st->duration == AV_NOPTS_VALUE ||
644
                    st->duration < duration)
645
                    st->duration = duration;
646
            }
647
        }
648
        av_free_packet(pkt);
649
    }
650
    
651
    /* estimate total duration */
652
    end_time = MININT64;
653
    for(i = 0;i < ic->nb_streams; i++) {
654
        st = ic->streams[i];
655
        if (st->duration != AV_NOPTS_VALUE) {
656
            end_time1 = st->start_time + st->duration;
657
            if (end_time1 > end_time)
658
                end_time = end_time1;
659
        }
660
    }
661
    
662
    /* update start_time (new stream may have been created, so we do
663
       it at the end */
664
    if (ic->start_time != AV_NOPTS_VALUE) {
665
        for(i = 0; i < ic->nb_streams; i++) {
666
            st = ic->streams[i];
667
            if (st->start_time == AV_NOPTS_VALUE)
668
                st->start_time = ic->start_time;
669
        }
670
    }
671

    
672
    if (end_time != MININT64) {
673
        /* put dummy values for duration if needed */
674
        for(i = 0;i < ic->nb_streams; i++) {
675
            st = ic->streams[i];
676
            if (st->duration == AV_NOPTS_VALUE && 
677
                st->start_time != AV_NOPTS_VALUE)
678
                st->duration = end_time - st->start_time;
679
        }
680
        ic->duration = end_time - ic->start_time;
681
    }
682

    
683
    url_fseek(&ic->pb, 0, SEEK_SET);
684
}
685

    
686
static void av_estimate_timings(AVFormatContext *ic)
687
{
688
    URLContext *h;
689
    int64_t file_size;
690

    
691
    /* get the file size, if possible */
692
    if (ic->iformat->flags & AVFMT_NOFILE) {
693
        file_size = 0;
694
    } else {
695
        h = url_fileno(&ic->pb);
696
        file_size = url_filesize(h);
697
        if (file_size < 0)
698
            file_size = 0;
699
    }
700
    ic->file_size = file_size;
701

    
702
    if (ic->iformat == &mpegps_demux) {
703
        /* get accurate estimate from the PTSes */
704
        av_estimate_timings_from_pts(ic);
705
    } else if (av_has_timings(ic)) {
706
        /* at least one components has timings - we use them for all
707
           the components */
708
        fill_all_stream_timings(ic);
709
    } else {
710
        /* less precise: use bit rate info */
711
        av_estimate_timings_from_bit_rate(ic);
712
    }
713
    av_update_stream_timings(ic);
714

    
715
#if 0
716
    {
717
        int i;
718
        AVStream *st;
719
        for(i = 0;i < ic->nb_streams; i++) {
720
            st = ic->streams[i];
721
        printf("%d: start_time: %0.3f duration: %0.3f\n", 
722
               i, (double)st->start_time / AV_TIME_BASE, 
723
               (double)st->duration / AV_TIME_BASE);
724
        }
725
        printf("stream: start_time: %0.3f duration: %0.3f bitrate=%d kb/s\n", 
726
               (double)ic->start_time / AV_TIME_BASE, 
727
               (double)ic->duration / AV_TIME_BASE,
728
               ic->bit_rate / 1000);
729
    }
730
#endif
731
}
732

    
733
/* state for codec information */
734
#define CSTATE_NOTFOUND    0
735
#define CSTATE_DECODING    1
736
#define CSTATE_FOUND       2
737

    
738
static int has_codec_parameters(AVCodecContext *enc)
739
{
740
    int val;
741
    switch(enc->codec_type) {
742
    case CODEC_TYPE_AUDIO:
743
        val = enc->sample_rate;
744
        break;
745
    case CODEC_TYPE_VIDEO:
746
        val = enc->width;
747
        break;
748
    default:
749
        val = 1;
750
        break;
751
    }
752
    return (val != 0);
753
}
754

    
755
/**
756
 * Read the beginning of a media file to get stream information. This
757
 * is useful for file formats with no headers such as MPEG. This
758
 * function also compute the real frame rate in case of mpeg2 repeat
759
 * frame mode.
760
 *
761
 * @param ic media file handle
762
 * @return >=0 if OK. AVERROR_xxx if error.  
763
 */
764
int av_find_stream_info(AVFormatContext *ic)
765
{
766
    int i, count, ret, got_picture, size, read_size;
767
    AVCodec *codec;
768
    AVStream *st;
769
    AVPacket *pkt;
770
    AVFrame picture;
771
    AVPacketList *pktl=NULL, **ppktl;
772
    short samples[AVCODEC_MAX_AUDIO_FRAME_SIZE / 2];
773
    uint8_t *ptr;
774
    int min_read_size, max_read_size;
775

    
776
    /* typical mpeg ts rate is 40 Mbits. DVD rate is about 10
777
       Mbits. We read at most 0.2 second of file to find all streams */
778

    
779
    /* XXX: base it on stream bitrate when possible */
780
    if (ic->iformat == &mpegts_demux) {
781
        /* maximum number of bytes we accept to read to find all the streams
782
           in a file */
783
        min_read_size = 6000000;
784
    } else {
785
        min_read_size = 250000;
786
    }
787
    /* max read size is 2 seconds of video max */
788
    max_read_size = min_read_size * 10;
789

    
790
    /* set initial codec state */
791
    for(i=0;i<ic->nb_streams;i++) {
792
        st = ic->streams[i];
793
        if (has_codec_parameters(&st->codec))
794
            st->codec_info_state = CSTATE_FOUND;
795
        else
796
            st->codec_info_state = CSTATE_NOTFOUND;
797
        st->codec_info_nb_repeat_frames = 0;
798
        st->codec_info_nb_real_frames = 0;
799
    }
800

    
801
    count = 0;
802
    read_size = 0;
803
    ppktl = &ic->packet_buffer;
804
    for(;;) {
805
        /* check if one codec still needs to be handled */
806
        for(i=0;i<ic->nb_streams;i++) {
807
            st = ic->streams[i];
808
            if (st->codec_info_state != CSTATE_FOUND)
809
                break;
810
        }
811
        if (i == ic->nb_streams) {
812
            /* NOTE: if the format has no header, then we need to read
813
               some packets to get most of the streams, so we cannot
814
               stop here */
815
            if (!(ic->iformat->flags & AVFMT_NOHEADER) ||
816
                read_size >= min_read_size) {
817
                /* if we found the info for all the codecs, we can stop */
818
                ret = count;
819
                break;
820
            }
821
        } else {
822
            /* we did not get all the codec info, but we read too much data */
823
            if (read_size >= max_read_size) {
824
                ret = count;
825
                break;
826
            }
827
        }
828

    
829
        pktl = av_mallocz(sizeof(AVPacketList));
830
        if (!pktl) {
831
            ret = AVERROR_NOMEM;
832
            break;
833
        }
834

    
835
        /* add the packet in the buffered packet list */
836
        *ppktl = pktl;
837
        ppktl = &pktl->next;
838

    
839
        /* NOTE: a new stream can be added there if no header in file
840
           (AVFMT_NOHEADER) */
841
        pkt = &pktl->pkt;
842
        if (ic->iformat->read_packet(ic, pkt) < 0) {
843
            /* EOF or error */
844
            ret = -1; /* we could not have all the codec parameters before EOF */
845
            if ((ic->iformat->flags & AVFMT_NOHEADER) &&
846
                i == ic->nb_streams)
847
                ret = 0;
848
            break;
849
        }
850
        read_size += pkt->size;
851

    
852
        /* open new codecs */
853
        for(i=0;i<ic->nb_streams;i++) {
854
            st = ic->streams[i];
855
            if (st->codec_info_state == CSTATE_NOTFOUND) {
856
                /* set to found in case of error */
857
                st->codec_info_state = CSTATE_FOUND; 
858
                codec = avcodec_find_decoder(st->codec.codec_id);
859
                if (codec) {
860
                    if(codec->capabilities & CODEC_CAP_TRUNCATED)
861
                        st->codec.flags |= CODEC_FLAG_TRUNCATED;
862

    
863
                    ret = avcodec_open(&st->codec, codec);
864
                    if (ret >= 0)
865
                        st->codec_info_state = CSTATE_DECODING;
866
                }
867
            }
868
        }
869

    
870
        st = ic->streams[pkt->stream_index];
871
        if (st->codec_info_state == CSTATE_DECODING) {
872
            /* decode the data and update codec parameters */
873
            ptr = pkt->data;
874
            size = pkt->size;
875
            while (size > 0) {
876
                switch(st->codec.codec_type) {
877
                case CODEC_TYPE_VIDEO:
878
                    ret = avcodec_decode_video(&st->codec, &picture, 
879
                                               &got_picture, ptr, size);
880
                    break;
881
                case CODEC_TYPE_AUDIO:
882
                    ret = avcodec_decode_audio(&st->codec, samples, 
883
                                               &got_picture, ptr, size);
884
                    break;
885
                default:
886
                    ret = -1;
887
                    break;
888
                }
889
                if (ret < 0) {
890
                    /* if error, simply ignore because another packet
891
                       may be OK */
892
                    break;
893
                }
894
                if (got_picture) {
895
                    /* we got the parameters - now we can stop
896
                       examining this stream */
897
                    /* XXX: add a codec info so that we can decide if
898
                       the codec can repeat frames */
899
                    if (st->codec.codec_id == CODEC_ID_MPEG1VIDEO && 
900
                        ic->iformat != &mpegts_demux &&
901
                        st->codec.sub_id == 2) {
902
                        /* for mpeg2 video, we want to know the real
903
                           frame rate, so we decode 40 frames. In mpeg
904
                           TS case we do not do it because it would be
905
                           too long */
906
                        st->codec_info_nb_real_frames++;
907
                        st->codec_info_nb_repeat_frames += st->codec.coded_frame->repeat_pict;
908
#if 0
909
                        /* XXX: testing */
910
                        if ((st->codec_info_nb_real_frames % 24) == 23) {
911
                            st->codec_info_nb_repeat_frames += 2;
912
                        }
913
#endif
914
                        /* stop after 40 frames */
915
                        if (st->codec_info_nb_real_frames >= 40) {
916
                            av_reduce(
917
                                &st->r_frame_rate,
918
                                &st->r_frame_rate_base,
919
                                (int64_t)st->codec.frame_rate * st->codec_info_nb_real_frames,
920
                                (st->codec_info_nb_real_frames + (st->codec_info_nb_repeat_frames >> 1)) * st->codec.frame_rate_base,
921
                                1<<30);
922
                            goto close_codec;
923
                        }
924
                    } else {
925
                    close_codec:
926
                        st->codec_info_state = CSTATE_FOUND;
927
                        avcodec_close(&st->codec);
928
                        break;
929
                    }
930
                }
931
                ptr += ret;
932
                size -= ret;
933
            }
934
        }
935
        count++;
936
    }
937

    
938
    /* close each codec if there are opened */
939
    for(i=0;i<ic->nb_streams;i++) {
940
        st = ic->streams[i];
941
        if (st->codec_info_state == CSTATE_DECODING)
942
            avcodec_close(&st->codec);
943
    }
944

    
945
    /* set real frame rate info */
946
    for(i=0;i<ic->nb_streams;i++) {
947
        st = ic->streams[i];
948
        if (st->codec.codec_type == CODEC_TYPE_VIDEO) {
949
            if (!st->r_frame_rate){
950
                st->r_frame_rate      = st->codec.frame_rate;
951
                st->r_frame_rate_base = st->codec.frame_rate_base;
952
            }
953
        }
954
    }
955

    
956

    
957
    av_estimate_timings(ic);
958
    return ret;
959
}
960

    
961
/**
962
 * Close a media file (but not its codecs)
963
 *
964
 * @param s media file handle
965
 */
966
void av_close_input_file(AVFormatContext *s)
967
{
968
    int i, must_open_file;
969

    
970
    if (s->iformat->read_close)
971
        s->iformat->read_close(s);
972
    for(i=0;i<s->nb_streams;i++) {
973
        av_free(s->streams[i]);
974
    }
975
    if (s->packet_buffer) {
976
        AVPacketList *p, *p1;
977
        p = s->packet_buffer;
978
        while (p != NULL) {
979
            p1 = p->next;
980
            av_free_packet(&p->pkt);
981
            av_free(p);
982
            p = p1;
983
        }
984
        s->packet_buffer = NULL;
985
    }
986
    must_open_file = 1;
987
    if ((s->iformat->flags & AVFMT_NOFILE) ||
988
        (s->iformat == &rtp_demux && !strcmp(s->filename, "null"))) {
989
        must_open_file = 0;
990
    }
991
    if (must_open_file) {
992
        url_fclose(&s->pb);
993
    }
994
    av_freep(&s->priv_data);
995
    av_free(s);
996
}
997

    
998
/**
999
 * Add a new stream to a media file. Can only be called in the
1000
 * read_header function. If the flag AVFMT_NOHEADER is in the format
1001
 * description, then new streams can be added in read_packet too.
1002
 *
1003
 *
1004
 * @param s media file handle
1005
 * @param id file format dependent stream id
1006
 */
1007
AVStream *av_new_stream(AVFormatContext *s, int id)
1008
{
1009
    AVStream *st;
1010

    
1011
    if (s->nb_streams >= MAX_STREAMS)
1012
        return NULL;
1013

    
1014
    st = av_mallocz(sizeof(AVStream));
1015
    if (!st)
1016
        return NULL;
1017
    avcodec_get_context_defaults(&st->codec);
1018

    
1019
    st->index = s->nb_streams;
1020
    st->id = id;
1021
    st->start_time = AV_NOPTS_VALUE;
1022
    st->duration = AV_NOPTS_VALUE;
1023
    s->streams[s->nb_streams++] = st;
1024
    return st;
1025
}
1026

    
1027
/************************************************************/
1028
/* output media file */
1029

    
1030
int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap)
1031
{
1032
    int ret;
1033
    
1034
    if (s->oformat->priv_data_size > 0) {
1035
        s->priv_data = av_mallocz(s->oformat->priv_data_size);
1036
        if (!s->priv_data)
1037
            return AVERROR_NOMEM;
1038
    } else
1039
        s->priv_data = NULL;
1040
        
1041
    if (s->oformat->set_parameters) {
1042
        ret = s->oformat->set_parameters(s, ap);
1043
        if (ret < 0)
1044
            return ret;
1045
    }
1046
    return 0;
1047
}
1048

    
1049
/**
1050
 * allocate the stream private data and write the stream header to an
1051
 * output media file
1052
 *
1053
 * @param s media file handle
1054
 * @return 0 if OK. AVERROR_xxx if error.  
1055
 */
1056
int av_write_header(AVFormatContext *s)
1057
{
1058
    int ret, i;
1059
    AVStream *st;
1060

    
1061
    /* default pts settings is MPEG like */
1062
    av_set_pts_info(s, 33, 1, 90000);
1063
    ret = s->oformat->write_header(s);
1064
    if (ret < 0)
1065
        return ret;
1066

    
1067
    /* init PTS generation */
1068
    for(i=0;i<s->nb_streams;i++) {
1069
        st = s->streams[i];
1070

    
1071
        switch (st->codec.codec_type) {
1072
        case CODEC_TYPE_AUDIO:
1073
            av_frac_init(&st->pts, 0, 0, 
1074
                         (int64_t)s->pts_num * st->codec.sample_rate);
1075
            break;
1076
        case CODEC_TYPE_VIDEO:
1077
            av_frac_init(&st->pts, 0, 0, 
1078
                         (int64_t)s->pts_num * st->codec.frame_rate);
1079
            break;
1080
        default:
1081
            break;
1082
        }
1083
    }
1084
    return 0;
1085
}
1086

    
1087
/**
1088
 * Write a packet to an output media file. The packet shall contain
1089
 * one audio or video frame.
1090
 *
1091
 * @param s media file handle
1092
 * @param stream_index stream index
1093
 * @param buf buffer containing the frame data
1094
 * @param size size of buffer
1095
 * @return < 0 if error, = 0 if OK, 1 if end of stream wanted.
1096
 */
1097
int av_write_frame(AVFormatContext *s, int stream_index, const uint8_t *buf, 
1098
                   int size)
1099
{
1100
    AVStream *st;
1101
    int64_t pts_mask;
1102
    int ret, frame_size;
1103

    
1104
    st = s->streams[stream_index];
1105
    pts_mask = (1LL << s->pts_wrap_bits) - 1;
1106
    ret = s->oformat->write_packet(s, stream_index, (uint8_t *)buf, size, 
1107
                                   st->pts.val & pts_mask);
1108
    if (ret < 0)
1109
        return ret;
1110

    
1111
    /* update pts */
1112
    switch (st->codec.codec_type) {
1113
    case CODEC_TYPE_AUDIO:
1114
        if (st->codec.frame_size <= 1) {
1115
            frame_size = size / st->codec.channels;
1116
            /* specific hack for pcm codecs because no frame size is provided */
1117
            switch(st->codec.codec_id) {
1118
            case CODEC_ID_PCM_S16LE:
1119
            case CODEC_ID_PCM_S16BE:
1120
            case CODEC_ID_PCM_U16LE:
1121
            case CODEC_ID_PCM_U16BE:
1122
                frame_size >>= 1;
1123
                break;
1124
            default:
1125
                break;
1126
            }
1127
        } else {
1128
            frame_size = st->codec.frame_size;
1129
        }
1130
        av_frac_add(&st->pts, 
1131
                    (int64_t)s->pts_den * frame_size);
1132
        break;
1133
    case CODEC_TYPE_VIDEO:
1134
        av_frac_add(&st->pts, 
1135
                    (int64_t)s->pts_den * st->codec.frame_rate_base);
1136
        break;
1137
    default:
1138
        break;
1139
    }
1140
    return ret;
1141
}
1142

    
1143
/**
1144
 * write the stream trailer to an output media file and and free the
1145
 * file private data.
1146
 *
1147
 * @param s media file handle
1148
 * @return 0 if OK. AVERROR_xxx if error.  */
1149
int av_write_trailer(AVFormatContext *s)
1150
{
1151
    int ret;
1152
    ret = s->oformat->write_trailer(s);
1153
    av_freep(&s->priv_data);
1154
    return ret;
1155
}
1156

    
1157
/* "user interface" functions */
1158

    
1159
void dump_format(AVFormatContext *ic,
1160
                 int index, 
1161
                 const char *url,
1162
                 int is_output)
1163
{
1164
    int i, flags;
1165
    char buf[256];
1166

    
1167
    fprintf(stderr, "%s #%d, %s, %s '%s':\n", 
1168
            is_output ? "Output" : "Input",
1169
            index, 
1170
            is_output ? ic->oformat->name : ic->iformat->name, 
1171
            is_output ? "to" : "from", url);
1172
    if (!is_output) {
1173
        printf("  Duration: ");
1174
        if (ic->duration != AV_NOPTS_VALUE) {
1175
            int hours, mins, secs, us;
1176
            secs = ic->duration / AV_TIME_BASE;
1177
            us = ic->duration % AV_TIME_BASE;
1178
            mins = secs / 60;
1179
            secs %= 60;
1180
            hours = mins / 60;
1181
            mins %= 60;
1182
            printf("%02d:%02d:%02d.%01d", hours, mins, secs, 
1183
                   (10 * us) / AV_TIME_BASE);
1184
        } else {
1185
            printf("N/A");
1186
        }
1187
        printf(", bitrate: ");
1188
        if (ic->bit_rate) {
1189
            printf("%d kb/s", ic->bit_rate / 1000);
1190
        } else {
1191
            printf("N/A");
1192
        }
1193
        printf("\n");
1194
    }
1195
    for(i=0;i<ic->nb_streams;i++) {
1196
        AVStream *st = ic->streams[i];
1197
        avcodec_string(buf, sizeof(buf), &st->codec, is_output);
1198
        fprintf(stderr, "  Stream #%d.%d", index, i);
1199
        /* the pid is an important information, so we display it */
1200
        /* XXX: add a generic system */
1201
        if (is_output)
1202
            flags = ic->oformat->flags;
1203
        else
1204
            flags = ic->iformat->flags;
1205
        if (flags & AVFMT_SHOW_IDS) {
1206
            fprintf(stderr, "[0x%x]", st->id);
1207
        }
1208
        fprintf(stderr, ": %s\n", buf);
1209
    }
1210
}
1211

    
1212
typedef struct {
1213
    const char *abv;
1214
    int width, height;
1215
    int frame_rate, frame_rate_base;
1216
} AbvEntry;
1217

    
1218
static AbvEntry frame_abvs[] = {
1219
    { "ntsc",      352, 240, 30000, 1001 },
1220
    { "pal",       352, 288,    25,    1 },
1221
    { "film",      352, 240,    24,    1 },
1222
    { "ntsc-film", 352, 240, 24000, 1001 },
1223
    { "sqcif",     128,  96,     0,    0 },
1224
    { "qcif",      176, 144,     0,    0 },
1225
    { "cif",       352, 288,     0,    0 },
1226
    { "4cif",      704, 576,     0,    0 },
1227
};
1228

    
1229
int parse_image_size(int *width_ptr, int *height_ptr, const char *str)
1230
{
1231
    int i;
1232
    int n = sizeof(frame_abvs) / sizeof(AbvEntry);
1233
    const char *p;
1234
    int frame_width = 0, frame_height = 0;
1235

    
1236
    for(i=0;i<n;i++) {
1237
        if (!strcmp(frame_abvs[i].abv, str)) {
1238
            frame_width = frame_abvs[i].width;
1239
            frame_height = frame_abvs[i].height;
1240
            break;
1241
        }
1242
    }
1243
    if (i == n) {
1244
        p = str;
1245
        frame_width = strtol(p, (char **)&p, 10);
1246
        if (*p)
1247
            p++;
1248
        frame_height = strtol(p, (char **)&p, 10);
1249
    }
1250
    if (frame_width <= 0 || frame_height <= 0)
1251
        return -1;
1252
    *width_ptr = frame_width;
1253
    *height_ptr = frame_height;
1254
    return 0;
1255
}
1256

    
1257
int parse_frame_rate(int *frame_rate, int *frame_rate_base, const char *arg)
1258
{
1259
    int i;
1260
    char* cp;
1261
   
1262
    /* First, we check our abbreviation table */
1263
    for (i = 0; i < sizeof(frame_abvs)/sizeof(*frame_abvs); ++i)
1264
         if (!strcmp(frame_abvs[i].abv, arg)) {
1265
             *frame_rate = frame_abvs[i].frame_rate;
1266
             *frame_rate_base = frame_abvs[i].frame_rate_base;
1267
             return 0;
1268
         }
1269

    
1270
    /* Then, we try to parse it as fraction */
1271
    cp = strchr(arg, '/');
1272
    if (cp) {
1273
        char* cpp;
1274
        *frame_rate = strtol(arg, &cpp, 10);
1275
        if (cpp != arg || cpp == cp) 
1276
            *frame_rate_base = strtol(cp+1, &cpp, 10);
1277
        else
1278
           *frame_rate = 0;
1279
    } 
1280
    else {
1281
        /* Finally we give up and parse it as double */
1282
        *frame_rate_base = DEFAULT_FRAME_RATE_BASE;
1283
        *frame_rate = (int)(strtod(arg, 0) * (*frame_rate_base) + 0.5);
1284
    }
1285
    if (!*frame_rate || !*frame_rate_base)
1286
        return -1;
1287
    else
1288
        return 0;
1289
}
1290

    
1291
int64_t av_gettime(void)
1292
{
1293
#ifdef CONFIG_WIN32
1294
    struct _timeb tb;
1295
    _ftime(&tb);
1296
    return ((int64_t)tb.time * int64_t_C(1000) + (int64_t)tb.millitm) * int64_t_C(1000);
1297
#else
1298
    struct timeval tv;
1299
    gettimeofday(&tv,NULL);
1300
    return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
1301
#endif
1302
}
1303

    
1304
static time_t mktimegm(struct tm *tm)
1305
{
1306
    time_t t;
1307

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

    
1310
    if (m < 3) {
1311
        m += 12;
1312
        y--;
1313
    }
1314

    
1315
    t = 86400 * 
1316
        (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469);
1317

    
1318
    t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
1319

    
1320
    return t;
1321
}
1322

    
1323
/* Syntax:
1324
 * - If not a duration:
1325
 *  [{YYYY-MM-DD|YYYYMMDD}]{T| }{HH[:MM[:SS[.m...]]][Z]|HH[MM[SS[.m...]]][Z]}
1326
 * Time is localtime unless Z is suffixed to the end. In this case GMT
1327
 * Return the date in micro seconds since 1970 
1328
 * - If duration:
1329
 *  HH[:MM[:SS[.m...]]]
1330
 *  S+[.m...]
1331
 */
1332
int64_t parse_date(const char *datestr, int duration)
1333
{
1334
    const char *p;
1335
    int64_t t;
1336
    struct tm dt;
1337
    int i;
1338
    static const char *date_fmt[] = {
1339
        "%Y-%m-%d",
1340
        "%Y%m%d",
1341
    };
1342
    static const char *time_fmt[] = {
1343
        "%H:%M:%S",
1344
        "%H%M%S",
1345
    };
1346
    const char *q;
1347
    int is_utc, len;
1348
    char lastch;
1349
    time_t now = time(0);
1350

    
1351
    len = strlen(datestr);
1352
    if (len > 0)
1353
        lastch = datestr[len - 1];
1354
    else
1355
        lastch = '\0';
1356
    is_utc = (lastch == 'z' || lastch == 'Z');
1357

    
1358
    memset(&dt, 0, sizeof(dt));
1359

    
1360
    p = datestr;
1361
    q = NULL;
1362
    if (!duration) {
1363
        for (i = 0; i < sizeof(date_fmt) / sizeof(date_fmt[0]); i++) {
1364
            q = strptime(p, date_fmt[i], &dt);
1365
            if (q) {
1366
                break;
1367
            }
1368
        }
1369

    
1370
        if (!q) {
1371
            if (is_utc) {
1372
                dt = *gmtime(&now);
1373
            } else {
1374
                dt = *localtime(&now);
1375
            }
1376
            dt.tm_hour = dt.tm_min = dt.tm_sec = 0;
1377
        } else {
1378
            p = q;
1379
        }
1380

    
1381
        if (*p == 'T' || *p == 't' || *p == ' ')
1382
            p++;
1383

    
1384
        for (i = 0; i < sizeof(time_fmt) / sizeof(time_fmt[0]); i++) {
1385
            q = strptime(p, time_fmt[i], &dt);
1386
            if (q) {
1387
                break;
1388
            }
1389
        }
1390
    } else {
1391
        q = strptime(p, time_fmt[0], &dt);
1392
        if (!q) {
1393
            dt.tm_sec = strtol(p, (char **)&q, 10);
1394
            dt.tm_min = 0;
1395
            dt.tm_hour = 0;
1396
        }
1397
    }
1398

    
1399
    /* Now we have all the fields that we can get */
1400
    if (!q) {
1401
        if (duration)
1402
            return 0;
1403
        else
1404
            return now * int64_t_C(1000000);
1405
    }
1406

    
1407
    if (duration) {
1408
        t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
1409
    } else {
1410
        dt.tm_isdst = -1;       /* unknown */
1411
        if (is_utc) {
1412
            t = mktimegm(&dt);
1413
        } else {
1414
            t = mktime(&dt);
1415
        }
1416
    }
1417

    
1418
    t *= 1000000;
1419

    
1420
    if (*q == '.') {
1421
        int val, n;
1422
        q++;
1423
        for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
1424
            if (!isdigit(*q)) 
1425
                break;
1426
            val += n * (*q - '0');
1427
        }
1428
        t += val;
1429
    }
1430
    return t;
1431
}
1432

    
1433
/* syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done. Return
1434
   1 if found */
1435
int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
1436
{
1437
    const char *p;
1438
    char tag[128], *q;
1439

    
1440
    p = info;
1441
    if (*p == '?')
1442
        p++;
1443
    for(;;) {
1444
        q = tag;
1445
        while (*p != '\0' && *p != '=' && *p != '&') {
1446
            if ((q - tag) < sizeof(tag) - 1)
1447
                *q++ = *p;
1448
            p++;
1449
        }
1450
        *q = '\0';
1451
        q = arg;
1452
        if (*p == '=') {
1453
            p++;
1454
            while (*p != '&' && *p != '\0') {
1455
                if ((q - arg) < arg_size - 1) {
1456
                    if (*p == '+')
1457
                        *q++ = ' ';
1458
                    else
1459
                        *q++ = *p;
1460
                }
1461
                p++;
1462
            }
1463
            *q = '\0';
1464
        }
1465
        if (!strcmp(tag, tag1)) 
1466
            return 1;
1467
        if (*p != '&')
1468
            break;
1469
        p++;
1470
    }
1471
    return 0;
1472
}
1473

    
1474
/* Return in 'buf' the path with '%d' replaced by number. Also handles
1475
   the '%0nd' format where 'n' is the total number of digits and
1476
   '%%'. Return 0 if OK, and -1 if format error */
1477
int get_frame_filename(char *buf, int buf_size,
1478
                       const char *path, int number)
1479
{
1480
    const char *p;
1481
    char *q, buf1[20];
1482
    int nd, len, c, percentd_found;
1483

    
1484
    q = buf;
1485
    p = path;
1486
    percentd_found = 0;
1487
    for(;;) {
1488
        c = *p++;
1489
        if (c == '\0')
1490
            break;
1491
        if (c == '%') {
1492
            do {
1493
                nd = 0;
1494
                while (isdigit(*p)) {
1495
                    nd = nd * 10 + *p++ - '0';
1496
                }
1497
                c = *p++;
1498
                if (c == '*' && nd > 0) {
1499
                    // The nd field is actually the modulus
1500
                    number = number % nd;
1501
                    c = *p++;
1502
                    nd = 0;
1503
                }
1504
            } while (isdigit(c));
1505

    
1506
            switch(c) {
1507
            case '%':
1508
                goto addchar;
1509
            case 'd':
1510
                if (percentd_found)
1511
                    goto fail;
1512
                percentd_found = 1;
1513
                snprintf(buf1, sizeof(buf1), "%0*d", nd, number);
1514
                len = strlen(buf1);
1515
                if ((q - buf + len) > buf_size - 1)
1516
                    goto fail;
1517
                memcpy(q, buf1, len);
1518
                q += len;
1519
                break;
1520
            default:
1521
                goto fail;
1522
            }
1523
        } else {
1524
        addchar:
1525
            if ((q - buf) < buf_size - 1)
1526
                *q++ = c;
1527
        }
1528
    }
1529
    if (!percentd_found)
1530
        goto fail;
1531
    *q = '\0';
1532
    return 0;
1533
 fail:
1534
    *q = '\0';
1535
    return -1;
1536
}
1537

    
1538
/**
1539
 *
1540
 * Print on stdout a nice hexa dump of a buffer
1541
 * @param buf buffer
1542
 * @param size buffer size
1543
 */
1544
void av_hex_dump(uint8_t *buf, int size)
1545
{
1546
    int len, i, j, c;
1547

    
1548
    for(i=0;i<size;i+=16) {
1549
        len = size - i;
1550
        if (len > 16)
1551
            len = 16;
1552
        printf("%08x ", i);
1553
        for(j=0;j<16;j++) {
1554
            if (j < len)
1555
                printf(" %02x", buf[i+j]);
1556
            else
1557
                printf("   ");
1558
        }
1559
        printf(" ");
1560
        for(j=0;j<len;j++) {
1561
            c = buf[i+j];
1562
            if (c < ' ' || c > '~')
1563
                c = '.';
1564
            printf("%c", c);
1565
        }
1566
        printf("\n");
1567
    }
1568
}
1569

    
1570
void url_split(char *proto, int proto_size,
1571
               char *hostname, int hostname_size,
1572
               int *port_ptr,
1573
               char *path, int path_size,
1574
               const char *url)
1575
{
1576
    const char *p;
1577
    char *q;
1578
    int port;
1579

    
1580
    port = -1;
1581

    
1582
    p = url;
1583
    q = proto;
1584
    while (*p != ':' && *p != '\0') {
1585
        if ((q - proto) < proto_size - 1)
1586
            *q++ = *p;
1587
        p++;
1588
    }
1589
    if (proto_size > 0)
1590
        *q = '\0';
1591
    if (*p == '\0') {
1592
        if (proto_size > 0)
1593
            proto[0] = '\0';
1594
        if (hostname_size > 0)
1595
            hostname[0] = '\0';
1596
        p = url;
1597
    } else {
1598
        p++;
1599
        if (*p == '/')
1600
            p++;
1601
        if (*p == '/')
1602
            p++;
1603
        q = hostname;
1604
        while (*p != ':' && *p != '/' && *p != '?' && *p != '\0') {
1605
            if ((q - hostname) < hostname_size - 1)
1606
                *q++ = *p;
1607
            p++;
1608
        }
1609
        if (hostname_size > 0)
1610
            *q = '\0';
1611
        if (*p == ':') {
1612
            p++;
1613
            port = strtoul(p, (char **)&p, 10);
1614
        }
1615
    }
1616
    if (port_ptr)
1617
        *port_ptr = port;
1618
    pstrcpy(path, path_size, p);
1619
}
1620

    
1621
/**
1622
 * Set the pts for a given stream
1623
 * @param s stream 
1624
 * @param pts_wrap_bits number of bits effectively used by the pts
1625
 *        (used for wrap control, 33 is the value for MPEG) 
1626
 * @param pts_num numerator to convert to seconds (MPEG: 1) 
1627
 * @param pts_den denominator to convert to seconds (MPEG: 90000)
1628
 */
1629
void av_set_pts_info(AVFormatContext *s, int pts_wrap_bits,
1630
                     int pts_num, int pts_den)
1631
{
1632
    s->pts_wrap_bits = pts_wrap_bits;
1633
    s->pts_num = pts_num;
1634
    s->pts_den = pts_den;
1635
}
1636

    
1637
/* fraction handling */
1638

    
1639
/**
1640
 * f = val + (num / den) + 0.5. 'num' is normalized so that it is such
1641
 * as 0 <= num < den.
1642
 *
1643
 * @param f fractional number
1644
 * @param val integer value
1645
 * @param num must be >= 0
1646
 * @param den must be >= 1 
1647
 */
1648
void av_frac_init(AVFrac *f, int64_t val, int64_t num, int64_t den)
1649
{
1650
    num += (den >> 1);
1651
    if (num >= den) {
1652
        val += num / den;
1653
        num = num % den;
1654
    }
1655
    f->val = val;
1656
    f->num = num;
1657
    f->den = den;
1658
}
1659

    
1660
/* set f to (val + 0.5) */
1661
void av_frac_set(AVFrac *f, int64_t val)
1662
{
1663
    f->val = val;
1664
    f->num = f->den >> 1;
1665
}
1666

    
1667
/**
1668
 * Fractionnal addition to f: f = f + (incr / f->den)
1669
 *
1670
 * @param f fractional number
1671
 * @param incr increment, can be positive or negative
1672
 */
1673
void av_frac_add(AVFrac *f, int64_t incr)
1674
{
1675
    int64_t num, den;
1676

    
1677
    num = f->num + incr;
1678
    den = f->den;
1679
    if (num < 0) {
1680
        f->val += num / den;
1681
        num = num % den;
1682
        if (num < 0) {
1683
            num += den;
1684
            f->val--;
1685
        }
1686
    } else if (num >= den) {
1687
        f->val += num / den;
1688
        num = num % den;
1689
    }
1690
    f->num = num;
1691
}
1692

    
1693
/**
1694
 * register a new image format
1695
 * @param img_fmt Image format descriptor
1696
 */
1697
void av_register_image_format(AVImageFormat *img_fmt)
1698
{
1699
    AVImageFormat **p;
1700

    
1701
    p = &first_image_format;
1702
    while (*p != NULL) p = &(*p)->next;
1703
    *p = img_fmt;
1704
    img_fmt->next = NULL;
1705
}
1706

    
1707
/* guess image format */
1708
AVImageFormat *av_probe_image_format(AVProbeData *pd)
1709
{
1710
    AVImageFormat *fmt1, *fmt;
1711
    int score, score_max;
1712

    
1713
    fmt = NULL;
1714
    score_max = 0;
1715
    for(fmt1 = first_image_format; fmt1 != NULL; fmt1 = fmt1->next) {
1716
        if (fmt1->img_probe) {
1717
            score = fmt1->img_probe(pd);
1718
            if (score > score_max) {
1719
                score_max = score;
1720
                fmt = fmt1;
1721
            }
1722
        }
1723
    }
1724
    return fmt;
1725
}
1726

    
1727
AVImageFormat *guess_image_format(const char *filename)
1728
{
1729
    AVImageFormat *fmt1;
1730

    
1731
    for(fmt1 = first_image_format; fmt1 != NULL; fmt1 = fmt1->next) {
1732
        if (fmt1->extensions && match_ext(filename, fmt1->extensions))
1733
            return fmt1;
1734
    }
1735
    return NULL;
1736
}
1737

    
1738
/**
1739
 * Read an image from a stream. 
1740
 * @param gb byte stream containing the image
1741
 * @param fmt image format, NULL if probing is required
1742
 */
1743
int av_read_image(ByteIOContext *pb, const char *filename,
1744
                  AVImageFormat *fmt,
1745
                  int (*alloc_cb)(void *, AVImageInfo *info), void *opaque)
1746
{
1747
    char buf[PROBE_BUF_SIZE];
1748
    AVProbeData probe_data, *pd = &probe_data;
1749
    offset_t pos;
1750
    int ret;
1751

    
1752
    if (!fmt) {
1753
        pd->filename = filename;
1754
        pd->buf = buf;
1755
        pos = url_ftell(pb);
1756
        pd->buf_size = get_buffer(pb, buf, PROBE_BUF_SIZE);
1757
        url_fseek(pb, pos, SEEK_SET);
1758
        fmt = av_probe_image_format(pd);
1759
    }
1760
    if (!fmt)
1761
        return AVERROR_NOFMT;
1762
    ret = fmt->img_read(pb, alloc_cb, opaque);
1763
    return ret;
1764
}
1765

    
1766
/**
1767
 * Write an image to a stream.
1768
 * @param pb byte stream for the image output
1769
 * @param fmt image format
1770
 * @param img image data and informations
1771
 */
1772
int av_write_image(ByteIOContext *pb, AVImageFormat *fmt, AVImageInfo *img)
1773
{
1774
    return fmt->img_write(pb, img);
1775
}
1776