Statistics
| Branch: | Revision:

ffmpeg / libav / utils.c @ 50d5d129

History | View | Annotate | Download (32.5 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
    /* XXX: suppress this hack for redirectors */
357
    if (fmt == &redir_demux) {
358
        err = redir_open(ic_ptr, &ic->pb);
359
        url_fclose(&ic->pb);
360
        av_free(ic);
361
        return err;
362
    }
363

    
364
    ic->iformat = fmt;
365

    
366
    /* allocate private data */
367
    ic->priv_data = av_mallocz(fmt->priv_data_size);
368
    if (!ic->priv_data) {
369
        err = AVERROR_NOMEM;
370
        goto fail;
371
    }
372

    
373
    /* default pts settings is MPEG like */
374
    av_set_pts_info(ic, 33, 1, 90000);
375

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

    
402
/**
403
 * Read a packet from a media file
404
 * @param s media file handle
405
 * @param pkt is filled 
406
 * @return 0 if OK. AVERROR_xxx if error.
407
 */
408
int av_read_packet(AVFormatContext *s, AVPacket *pkt)
409
{
410
    AVPacketList *pktl;
411

    
412
    pktl = s->packet_buffer;
413
    if (pktl) {
414
        /* read packet from packet buffer, if there is data */
415
        *pkt = pktl->pkt;
416
        s->packet_buffer = pktl->next;
417
        av_free(pktl);
418
        return 0;
419
    } else {
420
        return s->iformat->read_packet(s, pkt);
421
    }
422
}
423

    
424
/* state for codec information */
425
#define CSTATE_NOTFOUND    0
426
#define CSTATE_DECODING    1
427
#define CSTATE_FOUND       2
428

    
429
static int has_codec_parameters(AVCodecContext *enc)
430
{
431
    int val;
432
    switch(enc->codec_type) {
433
    case CODEC_TYPE_AUDIO:
434
        val = enc->sample_rate;
435
        break;
436
    case CODEC_TYPE_VIDEO:
437
        val = enc->width;
438
        break;
439
    default:
440
        val = 1;
441
        break;
442
    }
443
    return (val != 0);
444
}
445

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

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

    
470
    /* XXX: base it on stream bitrate when possible */
471
    if (ic->iformat == &mpegts_demux) {
472
        /* maximum number of bytes we accept to read to find all the streams
473
           in a file */
474
        min_read_size = 3000000;
475
    } else {
476
        min_read_size = 125000;
477
    }
478
    /* max read size is 2 seconds of video max */
479
    max_read_size = min_read_size * 20;
480

    
481
    /* set initial codec state */
482
    for(i=0;i<ic->nb_streams;i++) {
483
        st = ic->streams[i];
484
        if (has_codec_parameters(&st->codec))
485
            st->codec_info_state = CSTATE_FOUND;
486
        else
487
            st->codec_info_state = CSTATE_NOTFOUND;
488
        st->codec_info_nb_repeat_frames = 0;
489
        st->codec_info_nb_real_frames = 0;
490
    }
491

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

    
520
        pktl = av_mallocz(sizeof(AVPacketList));
521
        if (!pktl) {
522
            ret = AVERROR_NOMEM;
523
            break;
524
        }
525

    
526
        /* add the packet in the buffered packet list */
527
        *ppktl = pktl;
528
        ppktl = &pktl->next;
529

    
530
        /* NOTE: a new stream can be added there if no header in file
531
           (AVFMT_NOHEADER) */
532
        pkt = &pktl->pkt;
533
        if (ic->iformat->read_packet(ic, pkt) < 0) {
534
            /* EOF or error */
535
            ret = -1; /* we could not have all the codec parameters before EOF */
536
            if ((ic->iformat->flags & AVFMT_NOHEADER) &&
537
                i == ic->nb_streams)
538
                ret = 0;
539
            break;
540
        }
541
        read_size += pkt->size;
542

    
543
        /* open new codecs */
544
        for(i=0;i<ic->nb_streams;i++) {
545
            st = ic->streams[i];
546
            if (st->codec_info_state == CSTATE_NOTFOUND) {
547
                /* set to found in case of error */
548
                st->codec_info_state = CSTATE_FOUND; 
549
                codec = avcodec_find_decoder(st->codec.codec_id);
550
                if (codec) {
551
                    if(codec->capabilities & CODEC_CAP_TRUNCATED)
552
                        st->codec.flags |= CODEC_FLAG_TRUNCATED;
553

    
554
                    ret = avcodec_open(&st->codec, codec);
555
                    if (ret >= 0)
556
                        st->codec_info_state = CSTATE_DECODING;
557
                }
558
            }
559
        }
560

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

    
627
    /* close each codec if there are opened */
628
    for(i=0;i<ic->nb_streams;i++) {
629
        st = ic->streams[i];
630
        if (st->codec_info_state == CSTATE_DECODING)
631
            avcodec_close(&st->codec);
632
    }
633

    
634
    /* set real frame rate info */
635
    for(i=0;i<ic->nb_streams;i++) {
636
        st = ic->streams[i];
637
        if (st->codec.codec_type == CODEC_TYPE_VIDEO) {
638
            if (!st->r_frame_rate)
639
                st->r_frame_rate = st->codec.frame_rate;
640
        }
641
    }
642

    
643
    return ret;
644
}
645

    
646
/**
647
 * Close a media file (but not its codecs)
648
 *
649
 * @param s media file handle
650
 */
651
void av_close_input_file(AVFormatContext *s)
652
{
653
    int i;
654

    
655
    if (s->iformat->read_close)
656
        s->iformat->read_close(s);
657
    for(i=0;i<s->nb_streams;i++) {
658
        av_free(s->streams[i]);
659
    }
660
    if (s->packet_buffer) {
661
        AVPacketList *p, *p1;
662
        p = s->packet_buffer;
663
        while (p != NULL) {
664
            p1 = p->next;
665
            av_free_packet(&p->pkt);
666
            av_free(p);
667
            p = p1;
668
        }
669
        s->packet_buffer = NULL;
670
    }
671
    if (!(s->iformat->flags & AVFMT_NOFILE)) {
672
        url_fclose(&s->pb);
673
    }
674
    av_freep(&s->priv_data);
675
    av_free(s);
676
}
677

    
678
/**
679
 * Add a new stream to a media file. Can only be called in the
680
 * read_header function. If the flag AVFMT_NOHEADER is in the format
681
 * description, then new streams can be added in read_packet too.
682
 *
683
 *
684
 * @param s media file handle
685
 * @param id file format dependent stream id
686
 */
687
AVStream *av_new_stream(AVFormatContext *s, int id)
688
{
689
    AVStream *st;
690

    
691
    if (s->nb_streams >= MAX_STREAMS)
692
        return NULL;
693

    
694
    st = av_mallocz(sizeof(AVStream));
695
    if (!st)
696
        return NULL;
697
    st->index = s->nb_streams;
698
    st->id = id;
699
    s->streams[s->nb_streams++] = st;
700
    return st;
701
}
702

    
703
/************************************************************/
704
/* output media file */
705

    
706
/**
707
 * allocate the stream private data and write the stream header to an
708
 * output media file
709
 *
710
 * @param s media file handle
711
 * @return 0 if OK. AVERROR_xxx if error.  
712
 */
713
int av_write_header(AVFormatContext *s)
714
{
715
    int ret, i;
716
    AVStream *st;
717

    
718
    s->priv_data = av_mallocz(s->oformat->priv_data_size);
719
    if (!s->priv_data)
720
        return AVERROR_NOMEM;
721
    /* default pts settings is MPEG like */
722
    av_set_pts_info(s, 33, 1, 90000);
723
    ret = s->oformat->write_header(s);
724
    if (ret < 0)
725
        return ret;
726

    
727
    /* init PTS generation */
728
    for(i=0;i<s->nb_streams;i++) {
729
        st = s->streams[i];
730

    
731
        switch (st->codec.codec_type) {
732
        case CODEC_TYPE_AUDIO:
733
            av_frac_init(&st->pts, 0, 0, 
734
                         (INT64)s->pts_num * st->codec.sample_rate);
735
            break;
736
        case CODEC_TYPE_VIDEO:
737
            av_frac_init(&st->pts, 0, 0, 
738
                         (INT64)s->pts_num * st->codec.frame_rate);
739
            break;
740
        default:
741
            break;
742
        }
743
    }
744
    return 0;
745
}
746

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

    
764
    st = s->streams[stream_index];
765
    pts_mask = (1LL << s->pts_wrap_bits) - 1;
766
    ret = s->oformat->write_packet(s, stream_index, (uint8_t *)buf, size, 
767
                                   st->pts.val & pts_mask);
768
    if (ret < 0)
769
        return ret;
770

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

    
803
/**
804
 * write the stream trailer to an output media file and and free the
805
 * file private data.
806
 *
807
 * @param s media file handle
808
 * @return 0 if OK. AVERROR_xxx if error.  */
809
int av_write_trailer(AVFormatContext *s)
810
{
811
    int ret;
812
    ret = s->oformat->write_trailer(s);
813
    av_freep(&s->priv_data);
814
    return ret;
815
}
816

    
817
/* "user interface" functions */
818

    
819
void dump_format(AVFormatContext *ic,
820
                 int index, 
821
                 const char *url,
822
                 int is_output)
823
{
824
    int i, flags;
825
    char buf[256];
826

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

    
849
typedef struct {
850
    const char *str;
851
    int width, height;
852
} SizeEntry;
853

    
854
static SizeEntry sizes[] = {
855
    { "sqcif", 128, 96 },
856
    { "qcif", 176, 144 },
857
    { "cif", 352, 288 },
858
    { "4cif", 704, 576 },
859
};
860
    
861
int parse_image_size(int *width_ptr, int *height_ptr, const char *str)
862
{
863
    int i;
864
    int n = sizeof(sizes) / sizeof(SizeEntry);
865
    const char *p;
866
    int frame_width = 0, frame_height = 0;
867

    
868
    for(i=0;i<n;i++) {
869
        if (!strcmp(sizes[i].str, str)) {
870
            frame_width = sizes[i].width;
871
            frame_height = sizes[i].height;
872
            break;
873
        }
874
    }
875
    if (i == n) {
876
        p = str;
877
        frame_width = strtol(p, (char **)&p, 10);
878
        if (*p)
879
            p++;
880
        frame_height = strtol(p, (char **)&p, 10);
881
    }
882
    if (frame_width <= 0 || frame_height <= 0)
883
        return -1;
884
    *width_ptr = frame_width;
885
    *height_ptr = frame_height;
886
    return 0;
887
}
888

    
889
INT64 av_gettime(void)
890
{
891
#ifdef CONFIG_WIN32
892
    struct _timeb tb;
893
    _ftime(&tb);
894
    return ((INT64)tb.time * INT64_C(1000) + (INT64)tb.millitm) * INT64_C(1000);
895
#else
896
    struct timeval tv;
897
    gettimeofday(&tv,NULL);
898
    return (INT64)tv.tv_sec * 1000000 + tv.tv_usec;
899
#endif
900
}
901

    
902
static time_t mktimegm(struct tm *tm)
903
{
904
    time_t t;
905

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

    
908
    if (m < 3) {
909
        m += 12;
910
        y--;
911
    }
912

    
913
    t = 86400 * 
914
        (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469);
915

    
916
    t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
917

    
918
    return t;
919
}
920

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

    
949
    len = strlen(datestr);
950
    if (len > 0)
951
        lastch = datestr[len - 1];
952
    else
953
        lastch = '\0';
954
    is_utc = (lastch == 'z' || lastch == 'Z');
955

    
956
    memset(&dt, 0, sizeof(dt));
957

    
958
    p = datestr;
959
    q = NULL;
960
    if (!duration) {
961
        for (i = 0; i < sizeof(date_fmt) / sizeof(date_fmt[0]); i++) {
962
            q = strptime(p, date_fmt[i], &dt);
963
            if (q) {
964
                break;
965
            }
966
        }
967

    
968
        if (!q) {
969
            if (is_utc) {
970
                dt = *gmtime(&now);
971
            } else {
972
                dt = *localtime(&now);
973
            }
974
            dt.tm_hour = dt.tm_min = dt.tm_sec = 0;
975
        } else {
976
            p = q;
977
        }
978

    
979
        if (*p == 'T' || *p == 't' || *p == ' ')
980
            p++;
981

    
982
        for (i = 0; i < sizeof(time_fmt) / sizeof(time_fmt[0]); i++) {
983
            q = strptime(p, time_fmt[i], &dt);
984
            if (q) {
985
                break;
986
            }
987
        }
988
    } else {
989
        q = strptime(p, time_fmt[0], &dt);
990
        if (!q) {
991
            dt.tm_sec = strtol(p, (char **)&q, 10);
992
            dt.tm_min = 0;
993
            dt.tm_hour = 0;
994
        }
995
    }
996

    
997
    /* Now we have all the fields that we can get */
998
    if (!q) {
999
        if (duration)
1000
            return 0;
1001
        else
1002
            return now * INT64_C(1000000);
1003
    }
1004

    
1005
    if (duration) {
1006
        t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
1007
    } else {
1008
        dt.tm_isdst = -1;       /* unknown */
1009
        if (is_utc) {
1010
            t = mktimegm(&dt);
1011
        } else {
1012
            t = mktime(&dt);
1013
        }
1014
    }
1015

    
1016
    t *= 1000000;
1017

    
1018
    if (*q == '.') {
1019
        int val, n;
1020
        q++;
1021
        for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
1022
            if (!isdigit(*q)) 
1023
                break;
1024
            val += n * (*q - '0');
1025
        }
1026
        t += val;
1027
    }
1028
    return t;
1029
}
1030

    
1031
/* syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done. Return
1032
   1 if found */
1033
int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
1034
{
1035
    const char *p;
1036
    char tag[128], *q;
1037

    
1038
    p = info;
1039
    if (*p == '?')
1040
        p++;
1041
    for(;;) {
1042
        q = tag;
1043
        while (*p != '\0' && *p != '=' && *p != '&') {
1044
            if ((q - tag) < sizeof(tag) - 1)
1045
                *q++ = *p;
1046
            p++;
1047
        }
1048
        *q = '\0';
1049
        q = arg;
1050
        if (*p == '=') {
1051
            p++;
1052
            while (*p != '&' && *p != '\0') {
1053
                if ((q - arg) < arg_size - 1) {
1054
                    if (*p == '+')
1055
                        *q++ = ' ';
1056
                    else
1057
                        *q++ = *p;
1058
                }
1059
                p++;
1060
            }
1061
            *q = '\0';
1062
        }
1063
        if (!strcmp(tag, tag1)) 
1064
            return 1;
1065
        if (*p != '&')
1066
            break;
1067
        p++;
1068
    }
1069
    return 0;
1070
}
1071

    
1072
/* Return in 'buf' the path with '%d' replaced by number. Also handles
1073
   the '%0nd' format where 'n' is the total number of digits and
1074
   '%%'. Return 0 if OK, and -1 if format error */
1075
int get_frame_filename(char *buf, int buf_size,
1076
                       const char *path, int number)
1077
{
1078
    const char *p;
1079
    char *q, buf1[20];
1080
    int nd, len, c, percentd_found;
1081

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

    
1127
/**
1128
 *
1129
 * Print on stdout a nice hexa dump of a buffer
1130
 * @param buf buffer
1131
 * @param size buffer size
1132
 */
1133
void av_hex_dump(UINT8 *buf, int size)
1134
{
1135
    int len, i, j, c;
1136

    
1137
    for(i=0;i<size;i+=16) {
1138
        len = size - i;
1139
        if (len > 16)
1140
            len = 16;
1141
        printf("%08x ", i);
1142
        for(j=0;j<16;j++) {
1143
            if (j < len)
1144
                printf(" %02x", buf[i+j]);
1145
            else
1146
                printf("   ");
1147
        }
1148
        printf(" ");
1149
        for(j=0;j<len;j++) {
1150
            c = buf[i+j];
1151
            if (c < ' ' || c > '~')
1152
                c = '.';
1153
            printf("%c", c);
1154
        }
1155
        printf("\n");
1156
    }
1157
}
1158

    
1159
void url_split(char *proto, int proto_size,
1160
               char *hostname, int hostname_size,
1161
               int *port_ptr,
1162
               char *path, int path_size,
1163
               const char *url)
1164
{
1165
    const char *p;
1166
    char *q;
1167
    int port;
1168

    
1169
    port = -1;
1170

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

    
1210
/**
1211
 * Set the pts for a given stream
1212
 * @param s stream 
1213
 * @param pts_wrap_bits number of bits effectively used by the pts
1214
 *        (used for wrap control, 33 is the value for MPEG) 
1215
 * @param pts_num numerator to convert to seconds (MPEG: 1) 
1216
 * @param pts_den denominator to convert to seconds (MPEG: 90000)
1217
 */
1218
void av_set_pts_info(AVFormatContext *s, int pts_wrap_bits,
1219
                     int pts_num, int pts_den)
1220
{
1221
    s->pts_wrap_bits = pts_wrap_bits;
1222
    s->pts_num = pts_num;
1223
    s->pts_den = pts_den;
1224
}
1225

    
1226
/* fraction handling */
1227

    
1228
/**
1229
 * f = val + (num / den) + 0.5. 'num' is normalized so that it is such
1230
 * as 0 <= num < den.
1231
 *
1232
 * @param f fractional number
1233
 * @param val integer value
1234
 * @param num must be >= 0
1235
 * @param den must be >= 1 
1236
 */
1237
void av_frac_init(AVFrac *f, INT64 val, INT64 num, INT64 den)
1238
{
1239
    num += (den >> 1);
1240
    if (num >= den) {
1241
        val += num / den;
1242
        num = num % den;
1243
    }
1244
    f->val = val;
1245
    f->num = num;
1246
    f->den = den;
1247
}
1248

    
1249
/* set f to (val + 0.5) */
1250
void av_frac_set(AVFrac *f, INT64 val)
1251
{
1252
    f->val = val;
1253
    f->num = f->den >> 1;
1254
}
1255

    
1256
/**
1257
 * Fractionnal addition to f: f = f + (incr / f->den)
1258
 *
1259
 * @param f fractional number
1260
 * @param incr increment, can be positive or negative
1261
 */
1262
void av_frac_add(AVFrac *f, INT64 incr)
1263
{
1264
    INT64 num, den;
1265

    
1266
    num = f->num + incr;
1267
    den = f->den;
1268
    if (num < 0) {
1269
        f->val += num / den;
1270
        num = num % den;
1271
        if (num < 0) {
1272
            num += den;
1273
            f->val--;
1274
        }
1275
    } else if (num >= den) {
1276
        f->val += num / den;
1277
        num = num % den;
1278
    }
1279
    f->num = num;
1280
}