Statistics
| Branch: | Revision:

ffmpeg / libavformat / utils.c @ 8509fc7b

History | View | Annotate | Download (85.4 KB)

1 de6d9b64 Fabrice Bellard
/*
2
 * Various utilities for ffmpeg system
3 19720f15 Fabrice Bellard
 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
4 de6d9b64 Fabrice Bellard
 *
5 b78e7197 Diego Biurrun
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8 19720f15 Fabrice Bellard
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10 b78e7197 Diego Biurrun
 * version 2.1 of the License, or (at your option) any later version.
11 de6d9b64 Fabrice Bellard
 *
12 b78e7197 Diego Biurrun
 * FFmpeg is distributed in the hope that it will be useful,
13 de6d9b64 Fabrice Bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 19720f15 Fabrice Bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16 de6d9b64 Fabrice Bellard
 *
17 19720f15 Fabrice Bellard
 * You should have received a copy of the GNU Lesser General Public
18 b78e7197 Diego Biurrun
 * License along with FFmpeg; if not, write to the Free Software
19 5509bffa Diego Biurrun
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 de6d9b64 Fabrice Bellard
 */
21 8be1c656 Fabrice Bellard
#include "avformat.h"
22 e006c307 Diego Pettenò
#include "allformats.h"
23 4eb72c6b Nico Sabbi
#include "opt.h"
24 c5510dd6 Philip Gladstone
25 b754978a Michael Niedermayer
#undef NDEBUG
26
#include <assert.h>
27
28 e36bdf8b Daniel Kristjansson
/**
29
 * @file libavformat/utils.c
30
 * Various utility functions for using ffmpeg library.
31
 */
32
33 f3a30e3a Luca Barbato
static void av_frac_init(AVFrac *f, int64_t val, int64_t num, int64_t den);
34
static void av_frac_add(AVFrac *f, int64_t incr);
35
36 e36bdf8b Daniel Kristjansson
/** head of registered input format linked list. */
37 8b69867f Michael Niedermayer
AVInputFormat *first_iformat = NULL;
38 e36bdf8b Daniel Kristjansson
/** head of registered output format linked list. */
39 8b69867f Michael Niedermayer
AVOutputFormat *first_oformat = NULL;
40 de6d9b64 Fabrice Bellard
41 b9a281db Fabrice Bellard
void av_register_input_format(AVInputFormat *format)
42 de6d9b64 Fabrice Bellard
{
43 b9a281db Fabrice Bellard
    AVInputFormat **p;
44
    p = &first_iformat;
45
    while (*p != NULL) p = &(*p)->next;
46
    *p = format;
47
    format->next = NULL;
48
}
49
50
void av_register_output_format(AVOutputFormat *format)
51
{
52
    AVOutputFormat **p;
53
    p = &first_oformat;
54 de6d9b64 Fabrice Bellard
    while (*p != NULL) p = &(*p)->next;
55
    *p = format;
56
    format->next = NULL;
57
}
58
59 5b25dfa7 Fabrice Bellard
int match_ext(const char *filename, const char *extensions)
60 de6d9b64 Fabrice Bellard
{
61
    const char *ext, *p;
62
    char ext1[32], *q;
63
64 293ed23f Michael Niedermayer
    if(!filename)
65
        return 0;
66 115329f1 Diego Biurrun
67 de6d9b64 Fabrice Bellard
    ext = strrchr(filename, '.');
68
    if (ext) {
69
        ext++;
70
        p = extensions;
71
        for(;;) {
72
            q = ext1;
73 115329f1 Diego Biurrun
            while (*p != '\0' && *p != ',' && q-ext1<sizeof(ext1)-1)
74 de6d9b64 Fabrice Bellard
                *q++ = *p++;
75
            *q = '\0';
76 115329f1 Diego Biurrun
            if (!strcasecmp(ext1, ext))
77 de6d9b64 Fabrice Bellard
                return 1;
78 115329f1 Diego Biurrun
            if (*p == '\0')
79 de6d9b64 Fabrice Bellard
                break;
80
            p++;
81
        }
82
    }
83
    return 0;
84
}
85
86 115329f1 Diego Biurrun
AVOutputFormat *guess_format(const char *short_name, const char *filename,
87 b9a281db Fabrice Bellard
                             const char *mime_type)
88 de6d9b64 Fabrice Bellard
{
89 b9a281db Fabrice Bellard
    AVOutputFormat *fmt, *fmt_found;
90 de6d9b64 Fabrice Bellard
    int score_max, score;
91
92 87a0a681 Fabrice Bellard
    /* specific test for image sequences */
93 ff70e601 Måns Rullgård
#ifdef CONFIG_IMAGE2_MUXER
94 115329f1 Diego Biurrun
    if (!short_name && filename &&
95 5c07cf53 Michel Bardiaux
        av_filename_number_test(filename) &&
96 5b6d5596 Michael Niedermayer
        av_guess_image2_codec(filename) != CODEC_ID_NONE) {
97
        return guess_format("image2", NULL, NULL);
98
    }
99 ff70e601 Måns Rullgård
#endif
100 de6d9b64 Fabrice Bellard
    /* find the proper file type */
101
    fmt_found = NULL;
102
    score_max = 0;
103 b9a281db Fabrice Bellard
    fmt = first_oformat;
104 de6d9b64 Fabrice Bellard
    while (fmt != NULL) {
105
        score = 0;
106
        if (fmt->name && short_name && !strcmp(fmt->name, short_name))
107
            score += 100;
108
        if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
109
            score += 10;
110 115329f1 Diego Biurrun
        if (filename && fmt->extensions &&
111 de6d9b64 Fabrice Bellard
            match_ext(filename, fmt->extensions)) {
112
            score += 5;
113
        }
114
        if (score > score_max) {
115
            score_max = score;
116
            fmt_found = fmt;
117
        }
118
        fmt = fmt->next;
119
    }
120
    return fmt_found;
121 115329f1 Diego Biurrun
}
122 de6d9b64 Fabrice Bellard
123 115329f1 Diego Biurrun
AVOutputFormat *guess_stream_format(const char *short_name, const char *filename,
124 c5510dd6 Philip Gladstone
                             const char *mime_type)
125
{
126
    AVOutputFormat *fmt = guess_format(short_name, filename, mime_type);
127
128
    if (fmt) {
129
        AVOutputFormat *stream_fmt;
130
        char stream_format_name[64];
131
132
        snprintf(stream_format_name, sizeof(stream_format_name), "%s_stream", fmt->name);
133
        stream_fmt = guess_format(stream_format_name, NULL, NULL);
134
135
        if (stream_fmt)
136
            fmt = stream_fmt;
137
    }
138
139
    return fmt;
140
}
141
142 115329f1 Diego Biurrun
enum CodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name,
143 5b6d5596 Michael Niedermayer
                            const char *filename, const char *mime_type, enum CodecType type){
144
    if(type == CODEC_TYPE_VIDEO){
145
        enum CodecID codec_id= CODEC_ID_NONE;
146
147 ff70e601 Måns Rullgård
#ifdef CONFIG_IMAGE2_MUXER
148 ae214ac3 Michael Niedermayer
        if(!strcmp(fmt->name, "image2") || !strcmp(fmt->name, "image2pipe")){
149 5b6d5596 Michael Niedermayer
            codec_id= av_guess_image2_codec(filename);
150
        }
151 ff70e601 Måns Rullgård
#endif
152 5b6d5596 Michael Niedermayer
        if(codec_id == CODEC_ID_NONE)
153
            codec_id= fmt->video_codec;
154
        return codec_id;
155
    }else if(type == CODEC_TYPE_AUDIO)
156
        return fmt->audio_codec;
157
    else
158
        return CODEC_ID_NONE;
159
}
160
161 b9a281db Fabrice Bellard
AVInputFormat *av_find_input_format(const char *short_name)
162
{
163
    AVInputFormat *fmt;
164
    for(fmt = first_iformat; fmt != NULL; fmt = fmt->next) {
165
        if (!strcmp(fmt->name, short_name))
166
            return fmt;
167
    }
168
    return NULL;
169
}
170
171 de6d9b64 Fabrice Bellard
/* memory handling */
172
173 90ad92b3 Michael Niedermayer
void av_destruct_packet(AVPacket *pkt)
174 6fa5a56c Fabrice Bellard
{
175
    av_free(pkt->data);
176
    pkt->data = NULL; pkt->size = 0;
177
}
178
179 de6d9b64 Fabrice Bellard
int av_new_packet(AVPacket *pkt, int size)
180
{
181 55bdd34d Baptiste Coudurier
    uint8_t *data;
182 568e18b1 Michael Niedermayer
    if((unsigned)size > (unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE)
183 115329f1 Diego Biurrun
        return AVERROR_NOMEM;
184 568e18b1 Michael Niedermayer
    data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
185 6fa5a56c Fabrice Bellard
    if (!data)
186 b9a281db Fabrice Bellard
        return AVERROR_NOMEM;
187 6fa5a56c Fabrice Bellard
    memset(data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
188 8cd5be98 Michael Niedermayer
189 6fa5a56c Fabrice Bellard
    av_init_packet(pkt);
190 115329f1 Diego Biurrun
    pkt->data = data;
191 6fa5a56c Fabrice Bellard
    pkt->size = size;
192
    pkt->destruct = av_destruct_packet;
193 de6d9b64 Fabrice Bellard
    return 0;
194
}
195
196 2692067a Michael Niedermayer
int av_get_packet(ByteIOContext *s, AVPacket *pkt, int size)
197
{
198
    int ret= av_new_packet(pkt, size);
199
200
    if(ret<0)
201
        return ret;
202
203
    pkt->pos= url_ftell(s);
204
205
    ret= get_buffer(s, pkt->data, size);
206
    if(ret<=0)
207
        av_free_packet(pkt);
208
    else
209
        pkt->size= ret;
210
211
    return ret;
212
}
213
214 fb2758c8 Fabrice Bellard
int av_dup_packet(AVPacket *pkt)
215
{
216
    if (pkt->destruct != av_destruct_packet) {
217
        uint8_t *data;
218 8a56ac7b Fabrice Bellard
        /* we duplicate the packet and don't forget to put the padding
219
           again */
220 568e18b1 Michael Niedermayer
        if((unsigned)pkt->size > (unsigned)pkt->size + FF_INPUT_BUFFER_PADDING_SIZE)
221 115329f1 Diego Biurrun
            return AVERROR_NOMEM;
222 8a56ac7b Fabrice Bellard
        data = av_malloc(pkt->size + FF_INPUT_BUFFER_PADDING_SIZE);
223 fb2758c8 Fabrice Bellard
        if (!data) {
224
            return AVERROR_NOMEM;
225
        }
226
        memcpy(data, pkt->data, pkt->size);
227 8a56ac7b Fabrice Bellard
        memset(data + pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
228 fb2758c8 Fabrice Bellard
        pkt->data = data;
229
        pkt->destruct = av_destruct_packet;
230
    }
231
    return 0;
232
}
233
234 5c07cf53 Michel Bardiaux
int av_filename_number_test(const char *filename)
235 b9a281db Fabrice Bellard
{
236
    char buf[1024];
237 5c07cf53 Michel Bardiaux
    return filename && (av_get_frame_filename(buf, sizeof(buf), filename, 1)>=0);
238 b9a281db Fabrice Bellard
}
239
240 a25e098d Fabrice Bellard
AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened)
241 b9a281db Fabrice Bellard
{
242
    AVInputFormat *fmt1, *fmt;
243
    int score, score_max;
244
245
    fmt = NULL;
246
    score_max = 0;
247
    for(fmt1 = first_iformat; fmt1 != NULL; fmt1 = fmt1->next) {
248 b8e705ec Reimar Döffinger
        if (!is_opened == !(fmt1->flags & AVFMT_NOFILE))
249 b9a281db Fabrice Bellard
            continue;
250
        score = 0;
251 a8dbe951 Philip Gladstone
        if (fmt1->read_probe) {
252
            score = fmt1->read_probe(pd);
253
        } else if (fmt1->extensions) {
254 b9a281db Fabrice Bellard
            if (match_ext(pd->filename, fmt1->extensions)) {
255
                score = 50;
256
            }
257 115329f1 Diego Biurrun
        }
258 b9a281db Fabrice Bellard
        if (score > score_max) {
259
            score_max = score;
260
            fmt = fmt1;
261
        }
262
    }
263
    return fmt;
264
}
265
266
/************************************************************/
267
/* input media file */
268 96baaa6a Fabrice Bellard
269 da24c5e3 Fabrice Bellard
/**
270 e36bdf8b Daniel Kristjansson
 * Open a media file from an IO stream. 'fmt' must be specified.
271 da24c5e3 Fabrice Bellard
 */
272 43465395 Michael Niedermayer
static const char* format_to_name(void* ptr)
273 bc874dae Michel Bardiaux
{
274 43465395 Michael Niedermayer
    AVFormatContext* fc = (AVFormatContext*) ptr;
275 bc874dae Michel Bardiaux
    if(fc->iformat) return fc->iformat->name;
276
    else if(fc->oformat) return fc->oformat->name;
277
    else return "NULL";
278
}
279
280 66acccf0 Panagiotis Issaris
#define OFFSET(x) offsetof(AVFormatContext,x)
281 4eb72c6b Nico Sabbi
#define DEFAULT 0 //should be NAN but it doesnt work as its not a constant in glibc as required by ANSI/ISO C
282
//these names are too long to be readable
283
#define E AV_OPT_FLAG_ENCODING_PARAM
284
#define D AV_OPT_FLAG_DECODING_PARAM
285
286
static const AVOption options[]={
287 8c3dd5dc Panagiotis Issaris
{"probesize", NULL, OFFSET(probesize), FF_OPT_TYPE_INT, 32000, 32, INT_MAX, D}, /* 32000 from mpegts.c: 1.0 second at 24Mbit/s */
288 09a45576 Panagiotis Issaris
{"muxrate", "set mux rate", OFFSET(mux_rate), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, E},
289 4ff8fcef Panagiotis Issaris
{"packetsize", "set packet size", OFFSET(packet_size), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, E},
290 18de0b81 Baptiste Coudurier
{"fflags", NULL, OFFSET(flags), FF_OPT_TYPE_FLAGS, DEFAULT, INT_MIN, INT_MAX, D|E, "fflags"},
291 2c00106c Michael Niedermayer
{"ignidx", "ignore index", 0, FF_OPT_TYPE_CONST, AVFMT_FLAG_IGNIDX, INT_MIN, INT_MAX, D, "fflags"},
292
{"genpts", "generate pts", 0, FF_OPT_TYPE_CONST, AVFMT_FLAG_GENPTS, INT_MIN, INT_MAX, D, "fflags"},
293 8c3dd5dc Panagiotis Issaris
{"track", " set the track number", OFFSET(track), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, E},
294 ec1b10f4 Panagiotis Issaris
{"year", "set the year", OFFSET(year), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, E},
295 a44b3c4d Michael Niedermayer
{"analyzeduration", NULL, OFFSET(max_analyze_duration), FF_OPT_TYPE_INT, 3*AV_TIME_BASE, 0, INT_MAX, D},
296 4eb72c6b Nico Sabbi
{NULL},
297
};
298
299 5e89b50b Panagiotis Issaris
#undef E
300
#undef D
301
#undef DEFAULT
302
303 4eb72c6b Nico Sabbi
static const AVClass av_format_context_class = { "AVFormatContext", format_to_name, options };
304
305 702dfe01 Baptiste Coudurier
static void avformat_get_context_defaults(AVFormatContext *s)
306
{
307 4eb72c6b Nico Sabbi
    memset(s, 0, sizeof(AVFormatContext));
308 9e6c9470 Nico Sabbi
309 73a8ceaa Panagiotis Issaris
    s->av_class = &av_format_context_class;
310
311
    av_opt_set_defaults(s);
312 4eb72c6b Nico Sabbi
}
313 bc874dae Michel Bardiaux
314
AVFormatContext *av_alloc_format_context(void)
315
{
316
    AVFormatContext *ic;
317 5894991f Panagiotis Issaris
    ic = av_malloc(sizeof(AVFormatContext));
318 bc874dae Michel Bardiaux
    if (!ic) return ic;
319 4eb72c6b Nico Sabbi
    avformat_get_context_defaults(ic);
320 43465395 Michael Niedermayer
    ic->av_class = &av_format_context_class;
321 bc874dae Michel Bardiaux
    return ic;
322
}
323
324 115329f1 Diego Biurrun
int av_open_input_stream(AVFormatContext **ic_ptr,
325
                         ByteIOContext *pb, const char *filename,
326 da24c5e3 Fabrice Bellard
                         AVInputFormat *fmt, AVFormatParameters *ap)
327
{
328
    int err;
329
    AVFormatContext *ic;
330 c04c3282 Michael Niedermayer
    AVFormatParameters default_ap;
331
332
    if(!ap){
333
        ap=&default_ap;
334
        memset(ap, 0, sizeof(default_ap));
335
    }
336 da24c5e3 Fabrice Bellard
337 4eb72c6b Nico Sabbi
    if(!ap->prealloced_context)
338
        ic = av_alloc_format_context();
339
    else
340
        ic = *ic_ptr;
341 da24c5e3 Fabrice Bellard
    if (!ic) {
342
        err = AVERROR_NOMEM;
343
        goto fail;
344
    }
345
    ic->iformat = fmt;
346
    if (pb)
347
        ic->pb = *pb;
348
    ic->duration = AV_NOPTS_VALUE;
349
    ic->start_time = AV_NOPTS_VALUE;
350
    pstrcpy(ic->filename, sizeof(ic->filename), filename);
351
352
    /* allocate private data */
353
    if (fmt->priv_data_size > 0) {
354
        ic->priv_data = av_mallocz(fmt->priv_data_size);
355
        if (!ic->priv_data) {
356
            err = AVERROR_NOMEM;
357
            goto fail;
358
        }
359
    } else {
360
        ic->priv_data = NULL;
361
    }
362
363
    err = ic->iformat->read_header(ic, ap);
364
    if (err < 0)
365
        goto fail;
366 fb2758c8 Fabrice Bellard
367 faf7cbf1 Michael Niedermayer
    if (pb && !ic->data_offset)
368 fb2758c8 Fabrice Bellard
        ic->data_offset = url_ftell(&ic->pb);
369
370 da24c5e3 Fabrice Bellard
    *ic_ptr = ic;
371
    return 0;
372
 fail:
373
    if (ic) {
374
        av_freep(&ic->priv_data);
375
    }
376
    av_free(ic);
377
    *ic_ptr = NULL;
378
    return err;
379
}
380
381 e36bdf8b Daniel Kristjansson
/** Size of probe buffer, for guessing file type from file contents. */
382 a877eedc Michael Niedermayer
#define PROBE_BUF_MIN 2048
383 329b1e75 Michael Niedermayer
#define PROBE_BUF_MAX (1<<20)
384 b9a281db Fabrice Bellard
385 115329f1 Diego Biurrun
int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,
386 b9a281db Fabrice Bellard
                       AVInputFormat *fmt,
387
                       int buf_size,
388
                       AVFormatParameters *ap)
389 de6d9b64 Fabrice Bellard
{
390 a877eedc Michael Niedermayer
    int err, must_open_file, file_opened, probe_size;
391 b9a281db Fabrice Bellard
    AVProbeData probe_data, *pd = &probe_data;
392 da24c5e3 Fabrice Bellard
    ByteIOContext pb1, *pb = &pb1;
393 115329f1 Diego Biurrun
394 da24c5e3 Fabrice Bellard
    file_opened = 0;
395
    pd->filename = "";
396
    if (filename)
397
        pd->filename = filename;
398 a877eedc Michael Niedermayer
    pd->buf = NULL;
399 b9a281db Fabrice Bellard
    pd->buf_size = 0;
400
401
    if (!fmt) {
402
        /* guess format if no file can be opened  */
403 a25e098d Fabrice Bellard
        fmt = av_probe_input_format(pd, 0);
404 de6d9b64 Fabrice Bellard
    }
405
406 b6892136 Fabrice Bellard
    /* do not open file if the format does not need it. XXX: specific
407
       hack needed to handle RTSP/TCP */
408
    must_open_file = 1;
409 da24c5e3 Fabrice Bellard
    if (fmt && (fmt->flags & AVFMT_NOFILE)) {
410 b6892136 Fabrice Bellard
        must_open_file = 0;
411 63dd1377 Michael Niedermayer
        pb= NULL; //FIXME this or memset(pb, 0, sizeof(ByteIOContext)); otherwise its uninitalized
412 b6892136 Fabrice Bellard
    }
413
414
    if (!fmt || must_open_file) {
415 87a0a681 Fabrice Bellard
        /* if no file needed do not try to open one */
416 da24c5e3 Fabrice Bellard
        if (url_fopen(pb, filename, URL_RDONLY) < 0) {
417 b9a281db Fabrice Bellard
            err = AVERROR_IO;
418 96baaa6a Fabrice Bellard
            goto fail;
419 b9a281db Fabrice Bellard
        }
420 da24c5e3 Fabrice Bellard
        file_opened = 1;
421 96baaa6a Fabrice Bellard
        if (buf_size > 0) {
422 da24c5e3 Fabrice Bellard
            url_setbufsize(pb, buf_size);
423 96baaa6a Fabrice Bellard
        }
424 a877eedc Michael Niedermayer
425
        for(probe_size= PROBE_BUF_MIN; probe_size<=PROBE_BUF_MAX && !fmt; probe_size<<=1){
426 5b25dfa7 Fabrice Bellard
            /* read probe data */
427 a877eedc Michael Niedermayer
            pd->buf= av_realloc(pd->buf, probe_size);
428
            pd->buf_size = get_buffer(pb, pd->buf, probe_size);
429 497244a8 Baptiste Coudurier
            if (url_fseek(pb, 0, SEEK_SET) < 0) {
430 53e2f9ca Michael Niedermayer
                url_fclose(pb);
431
                if (url_fopen(pb, filename, URL_RDONLY) < 0) {
432 5e43b17e Michael Niedermayer
                    file_opened = 0;
433 53e2f9ca Michael Niedermayer
                    err = AVERROR_IO;
434
                    goto fail;
435
                }
436
            }
437 a877eedc Michael Niedermayer
            /* guess file format */
438
            fmt = av_probe_input_format(pd, 1);
439 5b25dfa7 Fabrice Bellard
        }
440 a877eedc Michael Niedermayer
        av_freep(&pd->buf);
441 b9a281db Fabrice Bellard
    }
442
443
    /* if still no format found, error */
444
    if (!fmt) {
445
        err = AVERROR_NOFMT;
446 da24c5e3 Fabrice Bellard
        goto fail;
447 de6d9b64 Fabrice Bellard
    }
448 115329f1 Diego Biurrun
449 67d06418 Fabrice Bellard
    /* XXX: suppress this hack for redirectors */
450 f3ec2d46 Slavik Gnatenko
#ifdef CONFIG_NETWORK
451 d2a067d1 Måns Rullgård
    if (fmt == &redir_demuxer) {
452 da24c5e3 Fabrice Bellard
        err = redir_open(ic_ptr, pb);
453
        url_fclose(pb);
454 67d06418 Fabrice Bellard
        return err;
455
    }
456 9b2e001f Bill Eldridge
#endif
457 67d06418 Fabrice Bellard
458 87a0a681 Fabrice Bellard
    /* check filename in case of an image number is expected */
459 da24c5e3 Fabrice Bellard
    if (fmt->flags & AVFMT_NEEDNUMBER) {
460 5c07cf53 Michel Bardiaux
        if (!av_filename_number_test(filename)) {
461 87a0a681 Fabrice Bellard
            err = AVERROR_NUMEXPECTED;
462 da24c5e3 Fabrice Bellard
            goto fail;
463 87a0a681 Fabrice Bellard
        }
464
    }
465 da24c5e3 Fabrice Bellard
    err = av_open_input_stream(ic_ptr, pb, filename, fmt, ap);
466
    if (err)
467
        goto fail;
468 b9a281db Fabrice Bellard
    return 0;
469 de6d9b64 Fabrice Bellard
 fail:
470 a877eedc Michael Niedermayer
    av_freep(&pd->buf);
471 da24c5e3 Fabrice Bellard
    if (file_opened)
472
        url_fclose(pb);
473 b9a281db Fabrice Bellard
    *ic_ptr = NULL;
474
    return err;
475 115329f1 Diego Biurrun
476 de6d9b64 Fabrice Bellard
}
477
478 da24c5e3 Fabrice Bellard
/*******************************************************/
479
480 de6d9b64 Fabrice Bellard
int av_read_packet(AVFormatContext *s, AVPacket *pkt)
481
{
482 fb2758c8 Fabrice Bellard
    return s->iformat->read_packet(s, pkt);
483
}
484
485
/**********************************************************/
486
487 e36bdf8b Daniel Kristjansson
/**
488
 * Get the number of samples of an audio frame. Return (-1) if error.
489
 */
490 fb2758c8 Fabrice Bellard
static int get_audio_frame_size(AVCodecContext *enc, int size)
491
{
492
    int frame_size;
493
494
    if (enc->frame_size <= 1) {
495 ac3e1834 Baptiste Coudurier
        int bits_per_sample = av_get_bits_per_sample(enc->codec_id);
496
497
        if (bits_per_sample) {
498 fb2758c8 Fabrice Bellard
            if (enc->channels == 0)
499
                return -1;
500 f1b163e0 Aurelien Jacobs
            frame_size = (size << 3) / (bits_per_sample * enc->channels);
501 ac3e1834 Baptiste Coudurier
        } else {
502 fb2758c8 Fabrice Bellard
            /* used for example by ADPCM codecs */
503
            if (enc->bit_rate == 0)
504
                return -1;
505
            frame_size = (size * 8 * enc->sample_rate) / enc->bit_rate;
506
        }
507
    } else {
508
        frame_size = enc->frame_size;
509
    }
510
    return frame_size;
511
}
512
513
514 e36bdf8b Daniel Kristjansson
/**
515
 * Return the frame duration in seconds, return 0 if not available.
516
 */
517 115329f1 Diego Biurrun
static void compute_frame_duration(int *pnum, int *pden, AVStream *st,
518 fb2758c8 Fabrice Bellard
                                   AVCodecParserContext *pc, AVPacket *pkt)
519
{
520
    int frame_size;
521
522
    *pnum = 0;
523
    *pden = 0;
524 01f4895c Michael Niedermayer
    switch(st->codec->codec_type) {
525 fb2758c8 Fabrice Bellard
    case CODEC_TYPE_VIDEO:
526 1677155d Michael Niedermayer
        if(st->time_base.num*1000LL > st->time_base.den){
527 c0df9d75 Michael Niedermayer
            *pnum = st->time_base.num;
528
            *pden = st->time_base.den;
529 01f4895c Michael Niedermayer
        }else if(st->codec->time_base.num*1000LL > st->codec->time_base.den){
530
            *pnum = st->codec->time_base.num;
531
            *pden = st->codec->time_base.den;
532 327c4076 Michael Niedermayer
            if (pc && pc->repeat_pict) {
533
                *pden *= 2;
534
                *pnum = (*pnum) * (2 + pc->repeat_pict);
535
            }
536 fb2758c8 Fabrice Bellard
        }
537
        break;
538
    case CODEC_TYPE_AUDIO:
539 01f4895c Michael Niedermayer
        frame_size = get_audio_frame_size(st->codec, pkt->size);
540 fb2758c8 Fabrice Bellard
        if (frame_size < 0)
541
            break;
542
        *pnum = frame_size;
543 01f4895c Michael Niedermayer
        *pden = st->codec->sample_rate;
544 fb2758c8 Fabrice Bellard
        break;
545
    default:
546
        break;
547
    }
548
}
549
550 5ba7c3d7 Michael Niedermayer
static int is_intra_only(AVCodecContext *enc){
551
    if(enc->codec_type == CODEC_TYPE_AUDIO){
552
        return 1;
553
    }else if(enc->codec_type == CODEC_TYPE_VIDEO){
554
        switch(enc->codec_id){
555
        case CODEC_ID_MJPEG:
556
        case CODEC_ID_MJPEGB:
557
        case CODEC_ID_LJPEG:
558
        case CODEC_ID_RAWVIDEO:
559
        case CODEC_ID_DVVIDEO:
560
        case CODEC_ID_HUFFYUV:
561 f37b9768 Loren Merritt
        case CODEC_ID_FFVHUFF:
562 5ba7c3d7 Michael Niedermayer
        case CODEC_ID_ASV1:
563
        case CODEC_ID_ASV2:
564
        case CODEC_ID_VCR1:
565
            return 1;
566
        default: break;
567
        }
568
    }
569
    return 0;
570
}
571
572 77405fc8 Michael Niedermayer
static int64_t lsb2full(int64_t lsb, int64_t last_ts, int lsb_bits){
573 4fc2c644 Michael Niedermayer
    int64_t mask = lsb_bits < 64 ? (1LL<<lsb_bits)-1 : -1LL;
574 77405fc8 Michael Niedermayer
    int64_t delta= last_ts - mask/2;
575
    return  ((lsb - delta)&mask) + delta;
576
}
577
578 115329f1 Diego Biurrun
static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
579 fb2758c8 Fabrice Bellard
                               AVCodecParserContext *pc, AVPacket *pkt)
580
{
581 d9e1efb7 Michael Niedermayer
    int num, den, presentation_delayed, delay, i;
582 77405fc8 Michael Niedermayer
    /* handle wrapping */
583 e928649b Michael Niedermayer
    if(st->cur_dts != AV_NOPTS_VALUE){
584
        if(pkt->pts != AV_NOPTS_VALUE)
585
            pkt->pts= lsb2full(pkt->pts, st->cur_dts, st->pts_wrap_bits);
586
        if(pkt->dts != AV_NOPTS_VALUE)
587
            pkt->dts= lsb2full(pkt->dts, st->cur_dts, st->pts_wrap_bits);
588
    }
589 115329f1 Diego Biurrun
590 fb2758c8 Fabrice Bellard
    if (pkt->duration == 0) {
591 3c895fc0 Michael Niedermayer
        compute_frame_duration(&num, &den, st, pc, pkt);
592 fb2758c8 Fabrice Bellard
        if (den && num) {
593 77405fc8 Michael Niedermayer
            pkt->duration = av_rescale(1, num * (int64_t)st->time_base.den, den * (int64_t)st->time_base.num);
594 fb2758c8 Fabrice Bellard
        }
595
    }
596
597 01f4895c Michael Niedermayer
    if(is_intra_only(st->codec))
598 5ba7c3d7 Michael Niedermayer
        pkt->flags |= PKT_FLAG_KEY;
599
600 fb2758c8 Fabrice Bellard
    /* do we have a video B frame ? */
601 befe3b05 Michael Niedermayer
    delay= st->codec->has_b_frames;
602 fb2758c8 Fabrice Bellard
    presentation_delayed = 0;
603 7e4baa66 Michael Niedermayer
    /* XXX: need has_b_frame, but cannot get it if the codec is
604
        not initialized */
605
    if (delay &&
606
        pc && pc->pict_type != FF_B_TYPE)
607
        presentation_delayed = 1;
608
    /* this may be redundant, but it shouldnt hurt */
609
    if(pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts > pkt->dts)
610
        presentation_delayed = 1;
611 115329f1 Diego Biurrun
612 e928649b Michael Niedermayer
    if(st->cur_dts == AV_NOPTS_VALUE){
613 befe3b05 Michael Niedermayer
        st->cur_dts = -delay * pkt->duration;
614 e928649b Michael Niedermayer
    }
615 fb2758c8 Fabrice Bellard
616 949b1a13 Steve L'Homme
//    av_log(NULL, AV_LOG_DEBUG, "IN delayed:%d pts:%"PRId64", dts:%"PRId64" cur_dts:%"PRId64" st:%d pc:%p\n", presentation_delayed, pkt->pts, pkt->dts, st->cur_dts, pkt->stream_index, pc);
617 fb2758c8 Fabrice Bellard
    /* interpolate PTS and DTS if they are not present */
618 7e4baa66 Michael Niedermayer
    if(delay <=1){
619
        if (presentation_delayed) {
620
            /* DTS = decompression time stamp */
621
            /* PTS = presentation time stamp */
622
            if (pkt->dts == AV_NOPTS_VALUE)
623
                pkt->dts = st->last_IP_pts;
624
            if (pkt->dts == AV_NOPTS_VALUE)
625
                pkt->dts = st->cur_dts;
626
627
            /* this is tricky: the dts must be incremented by the duration
628
            of the frame we are displaying, i.e. the last I or P frame */
629
            if (st->last_IP_duration == 0)
630
                st->last_IP_duration = pkt->duration;
631
            st->cur_dts = pkt->dts + st->last_IP_duration;
632
            st->last_IP_duration  = pkt->duration;
633
            st->last_IP_pts= pkt->pts;
634
            /* cannot compute PTS if not present (we can compute it only
635
            by knowing the futur */
636 028d6f3e Michael Niedermayer
        } else if(pkt->pts != AV_NOPTS_VALUE || pkt->dts != AV_NOPTS_VALUE || pkt->duration){
637 7e4baa66 Michael Niedermayer
            if(pkt->pts != AV_NOPTS_VALUE && pkt->duration){
638
                int64_t old_diff= FFABS(st->cur_dts - pkt->duration - pkt->pts);
639
                int64_t new_diff= FFABS(st->cur_dts - pkt->pts);
640
                if(old_diff < new_diff && old_diff < (pkt->duration>>3)){
641
                    pkt->pts += pkt->duration;
642
    //                av_log(NULL, AV_LOG_DEBUG, "id:%d old:%"PRId64" new:%"PRId64" dur:%d cur:%"PRId64" size:%d\n", pkt->stream_index, old_diff, new_diff, pkt->duration, st->cur_dts, pkt->size);
643
                }
644 90bb394d Michael Niedermayer
            }
645 115329f1 Diego Biurrun
646 7e4baa66 Michael Niedermayer
            /* presentation is not delayed : PTS and DTS are the same */
647
            if(pkt->pts == AV_NOPTS_VALUE)
648
                pkt->pts = pkt->dts;
649
            if(pkt->pts == AV_NOPTS_VALUE)
650
                pkt->pts = st->cur_dts;
651
            pkt->dts = pkt->pts;
652
            st->cur_dts = pkt->pts + pkt->duration;
653
        }
654 fb2758c8 Fabrice Bellard
    }
655 d9e1efb7 Michael Niedermayer
656
    if(pkt->pts != AV_NOPTS_VALUE){
657
        st->pts_buffer[0]= pkt->pts;
658
        for(i=1; i<delay+1 && st->pts_buffer[i] == AV_NOPTS_VALUE; i++)
659
            st->pts_buffer[i]= (i-delay-1) * pkt->duration;
660
        for(i=0; i<delay && st->pts_buffer[i] > st->pts_buffer[i+1]; i++)
661
            FFSWAP(int64_t, st->pts_buffer[i], st->pts_buffer[i+1]);
662
        if(pkt->dts == AV_NOPTS_VALUE)
663
            pkt->dts= st->pts_buffer[0];
664
        if(pkt->dts > st->cur_dts)
665
            st->cur_dts = pkt->dts;
666
    }
667
668
//    av_log(NULL, AV_LOG_ERROR, "OUTdelayed:%d/%d pts:%"PRId64", dts:%"PRId64" cur_dts:%"PRId64"\n", presentation_delayed, delay, pkt->pts, pkt->dts, st->cur_dts);
669 115329f1 Diego Biurrun
670 fb2758c8 Fabrice Bellard
    /* update flags */
671
    if (pc) {
672
        pkt->flags = 0;
673
        /* key frame computation */
674
            if (pc->pict_type == FF_I_TYPE)
675
                pkt->flags |= PKT_FLAG_KEY;
676
    }
677
}
678
679 63dd1377 Michael Niedermayer
void av_destruct_packet_nofree(AVPacket *pkt)
680 fb2758c8 Fabrice Bellard
{
681
    pkt->data = NULL; pkt->size = 0;
682
}
683
684
static int av_read_frame_internal(AVFormatContext *s, AVPacket *pkt)
685
{
686
    AVStream *st;
687 37353960 Fabrice Bellard
    int len, ret, i;
688 fb2758c8 Fabrice Bellard
689
    for(;;) {
690
        /* select current input stream component */
691
        st = s->cur_st;
692
        if (st) {
693 90ad92b3 Michael Niedermayer
            if (!st->need_parsing || !st->parser) {
694 fb2758c8 Fabrice Bellard
                /* no parsing needed: we just output the packet as is */
695
                /* raw data support */
696
                *pkt = s->cur_pkt;
697
                compute_pkt_fields(s, st, NULL, pkt);
698
                s->cur_st = NULL;
699 434cab9e Michael Niedermayer
                break;
700 f3356e9c Michael Niedermayer
            } else if (s->cur_len > 0 && st->discard < AVDISCARD_ALL) {
701 115329f1 Diego Biurrun
                len = av_parser_parse(st->parser, st->codec, &pkt->data, &pkt->size,
702 6ec87caa Fabrice Bellard
                                      s->cur_ptr, s->cur_len,
703
                                      s->cur_pkt.pts, s->cur_pkt.dts);
704
                s->cur_pkt.pts = AV_NOPTS_VALUE;
705
                s->cur_pkt.dts = AV_NOPTS_VALUE;
706 fb2758c8 Fabrice Bellard
                /* increment read pointer */
707
                s->cur_ptr += len;
708
                s->cur_len -= len;
709 115329f1 Diego Biurrun
710 fb2758c8 Fabrice Bellard
                /* return packet if any */
711
                if (pkt->size) {
712 37353960 Fabrice Bellard
                got_packet:
713 fb2758c8 Fabrice Bellard
                    pkt->duration = 0;
714
                    pkt->stream_index = st->index;
715 6ec87caa Fabrice Bellard
                    pkt->pts = st->parser->pts;
716
                    pkt->dts = st->parser->dts;
717 fb2758c8 Fabrice Bellard
                    pkt->destruct = av_destruct_packet_nofree;
718
                    compute_pkt_fields(s, st, st->parser, pkt);
719 e9b78eeb Michael Niedermayer
720
                    if((s->iformat->flags & AVFMT_GENERIC_INDEX) && pkt->flags & PKT_FLAG_KEY){
721
                        av_add_index_entry(st, st->parser->frame_offset, pkt->dts,
722
                                           0, 0, AVINDEX_KEYFRAME);
723
                    }
724
725 434cab9e Michael Niedermayer
                    break;
726 fb2758c8 Fabrice Bellard
                }
727
            } else {
728 bcbecff1 Fabrice Bellard
                /* free packet */
729 115329f1 Diego Biurrun
                av_free_packet(&s->cur_pkt);
730 fb2758c8 Fabrice Bellard
                s->cur_st = NULL;
731
            }
732
        } else {
733
            /* read next packet */
734
            ret = av_read_packet(s, &s->cur_pkt);
735 37353960 Fabrice Bellard
            if (ret < 0) {
736 8fa36ae0 François Revol
                if (ret == AVERROR(EAGAIN))
737 37353960 Fabrice Bellard
                    return ret;
738
                /* return the last frames, if any */
739
                for(i = 0; i < s->nb_streams; i++) {
740
                    st = s->streams[i];
741 90ad92b3 Michael Niedermayer
                    if (st->parser && st->need_parsing) {
742 115329f1 Diego Biurrun
                        av_parser_parse(st->parser, st->codec,
743
                                        &pkt->data, &pkt->size,
744
                                        NULL, 0,
745 6ec87caa Fabrice Bellard
                                        AV_NOPTS_VALUE, AV_NOPTS_VALUE);
746 37353960 Fabrice Bellard
                        if (pkt->size)
747
                            goto got_packet;
748
                    }
749
                }
750
                /* no more packets: really terminates parsing */
751 fb2758c8 Fabrice Bellard
                return ret;
752 37353960 Fabrice Bellard
            }
753 115329f1 Diego Biurrun
754 9ee91c2f Michael Niedermayer
            st = s->streams[s->cur_pkt.stream_index];
755 434cab9e Michael Niedermayer
            if(st->codec->debug & FF_DEBUG_PTS)
756 ccd3228e Dominik Mierzejewski
                av_log(s, AV_LOG_DEBUG, "av_read_packet stream=%d, pts=%"PRId64", dts=%"PRId64", size=%d\n",
757 434cab9e Michael Niedermayer
                    s->cur_pkt.stream_index,
758
                    s->cur_pkt.pts,
759
                    s->cur_pkt.dts,
760
                    s->cur_pkt.size);
761 fb2758c8 Fabrice Bellard
762
            s->cur_st = st;
763
            s->cur_ptr = s->cur_pkt.data;
764
            s->cur_len = s->cur_pkt.size;
765
            if (st->need_parsing && !st->parser) {
766 01f4895c Michael Niedermayer
                st->parser = av_parser_init(st->codec->codec_id);
767 fb2758c8 Fabrice Bellard
                if (!st->parser) {
768
                    /* no parser available : just output the raw packets */
769
                    st->need_parsing = 0;
770 7cbaa7ba Michael Niedermayer
                }else if(st->need_parsing == 2){
771
                    st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
772 fb2758c8 Fabrice Bellard
                }
773 e9b78eeb Michael Niedermayer
                if(st->parser && (s->iformat->flags & AVFMT_GENERIC_INDEX)){
774
                    st->parser->last_frame_offset=
775
                    st->parser->cur_offset= s->cur_pkt.pos;
776
                }
777 fb2758c8 Fabrice Bellard
            }
778
        }
779
    }
780 434cab9e Michael Niedermayer
    if(st->codec->debug & FF_DEBUG_PTS)
781 ccd3228e Dominik Mierzejewski
        av_log(s, AV_LOG_DEBUG, "av_read_frame_internal stream=%d, pts=%"PRId64", dts=%"PRId64", size=%d\n",
782 434cab9e Michael Niedermayer
            pkt->stream_index,
783
            pkt->pts,
784
            pkt->dts,
785
            pkt->size);
786
787
    return 0;
788 fb2758c8 Fabrice Bellard
}
789
790
int av_read_frame(AVFormatContext *s, AVPacket *pkt)
791
{
792 de6d9b64 Fabrice Bellard
    AVPacketList *pktl;
793 30bc6613 Michael Niedermayer
    int eof=0;
794
    const int genpts= s->flags & AVFMT_FLAG_GENPTS;
795
796
    for(;;){
797
        pktl = s->packet_buffer;
798
        if (pktl) {
799
            AVPacket *next_pkt= &pktl->pkt;
800
801
            if(genpts && next_pkt->dts != AV_NOPTS_VALUE){
802
                while(pktl && next_pkt->pts == AV_NOPTS_VALUE){
803 115329f1 Diego Biurrun
                    if(   pktl->pkt.stream_index == next_pkt->stream_index
804 30bc6613 Michael Niedermayer
                       && next_pkt->dts < pktl->pkt.dts
805
                       && pktl->pkt.pts != pktl->pkt.dts //not b frame
806
                       /*&& pktl->pkt.dts != AV_NOPTS_VALUE*/){
807
                        next_pkt->pts= pktl->pkt.dts;
808
                    }
809
                    pktl= pktl->next;
810
                }
811
                pktl = s->packet_buffer;
812
            }
813 115329f1 Diego Biurrun
814
            if(   next_pkt->pts != AV_NOPTS_VALUE
815
               || next_pkt->dts == AV_NOPTS_VALUE
816 30bc6613 Michael Niedermayer
               || !genpts || eof){
817
                /* read packet from packet buffer, if there is data */
818
                *pkt = *next_pkt;
819
                s->packet_buffer = pktl->next;
820
                av_free(pktl);
821
                return 0;
822
            }
823
        }
824
        if(genpts){
825
            AVPacketList **plast_pktl= &s->packet_buffer;
826
            int ret= av_read_frame_internal(s, pkt);
827
            if(ret<0){
828 8fa36ae0 François Revol
                if(pktl && ret != AVERROR(EAGAIN)){
829 30bc6613 Michael Niedermayer
                    eof=1;
830
                    continue;
831
                }else
832
                    return ret;
833
            }
834 115329f1 Diego Biurrun
835 30bc6613 Michael Niedermayer
            /* duplicate the packet */
836
            if (av_dup_packet(pkt) < 0)
837
                return AVERROR_NOMEM;
838 de6d9b64 Fabrice Bellard
839 30bc6613 Michael Niedermayer
            while(*plast_pktl) plast_pktl= &(*plast_pktl)->next; //FIXME maybe maintain pointer to the last?
840 115329f1 Diego Biurrun
841 30bc6613 Michael Niedermayer
            pktl = av_mallocz(sizeof(AVPacketList));
842
            if (!pktl)
843
                return AVERROR_NOMEM;
844 115329f1 Diego Biurrun
845 30bc6613 Michael Niedermayer
            /* add the packet in the buffered packet list */
846
            *plast_pktl = pktl;
847 115329f1 Diego Biurrun
            pktl->pkt= *pkt;
848 30bc6613 Michael Niedermayer
        }else{
849
            assert(!s->packet_buffer);
850
            return av_read_frame_internal(s, pkt);
851
        }
852 fb2758c8 Fabrice Bellard
    }
853
}
854
855
/* XXX: suppress the packet queue */
856
static void flush_packet_queue(AVFormatContext *s)
857
{
858
    AVPacketList *pktl;
859
860
    for(;;) {
861
        pktl = s->packet_buffer;
862 115329f1 Diego Biurrun
        if (!pktl)
863 fb2758c8 Fabrice Bellard
            break;
864
        s->packet_buffer = pktl->next;
865
        av_free_packet(&pktl->pkt);
866
        av_free(pktl);
867 b9a281db Fabrice Bellard
    }
868
}
869
870 da24c5e3 Fabrice Bellard
/*******************************************************/
871 fb2758c8 Fabrice Bellard
/* seek support */
872
873 b754978a Michael Niedermayer
int av_find_default_stream_index(AVFormatContext *s)
874
{
875
    int i;
876
    AVStream *st;
877
878
    if (s->nb_streams <= 0)
879
        return -1;
880
    for(i = 0; i < s->nb_streams; i++) {
881
        st = s->streams[i];
882 01f4895c Michael Niedermayer
        if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
883 b754978a Michael Niedermayer
            return i;
884
        }
885
    }
886
    return 0;
887
}
888
889 e36bdf8b Daniel Kristjansson
/**
890
 * Flush the frame reader.
891
 */
892 fb2758c8 Fabrice Bellard
static void av_read_frame_flush(AVFormatContext *s)
893
{
894
    AVStream *st;
895
    int i;
896
897
    flush_packet_queue(s);
898
899
    /* free previous packet */
900
    if (s->cur_st) {
901
        if (s->cur_st->parser)
902
            av_free_packet(&s->cur_pkt);
903
        s->cur_st = NULL;
904
    }
905
    /* fail safe */
906
    s->cur_ptr = NULL;
907
    s->cur_len = 0;
908 115329f1 Diego Biurrun
909 fb2758c8 Fabrice Bellard
    /* for each stream, reset read state */
910
    for(i = 0; i < s->nb_streams; i++) {
911
        st = s->streams[i];
912 115329f1 Diego Biurrun
913 fb2758c8 Fabrice Bellard
        if (st->parser) {
914
            av_parser_close(st->parser);
915
            st->parser = NULL;
916
        }
917 77405fc8 Michael Niedermayer
        st->last_IP_pts = AV_NOPTS_VALUE;
918 a843d1ff Michael Niedermayer
        st->cur_dts = AV_NOPTS_VALUE; /* we set the current DTS to an unspecified origin */
919 fb2758c8 Fabrice Bellard
    }
920
}
921
922 22ffac70 Reimar Döffinger
void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp){
923 8bcb147f Michael Niedermayer
    int i;
924
925
    for(i = 0; i < s->nb_streams; i++) {
926 1a1dc611 Nathan Kurz
        AVStream *st = s->streams[i];
927 8bcb147f Michael Niedermayer
928 115329f1 Diego Biurrun
        st->cur_dts = av_rescale(timestamp,
929 1a1dc611 Nathan Kurz
                                 st->time_base.den * (int64_t)ref_st->time_base.num,
930
                                 st->time_base.num * (int64_t)ref_st->time_base.den);
931 8bcb147f Michael Niedermayer
    }
932
}
933
934 3e9245a9 Michael Niedermayer
int av_add_index_entry(AVStream *st,
935 30a43f2d Michael Niedermayer
                            int64_t pos, int64_t timestamp, int size, int distance, int flags)
936 fb2758c8 Fabrice Bellard
{
937
    AVIndexEntry *entries, *ie;
938 b754978a Michael Niedermayer
    int index;
939 115329f1 Diego Biurrun
940 568e18b1 Michael Niedermayer
    if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
941
        return -1;
942 115329f1 Diego Biurrun
943 fb2758c8 Fabrice Bellard
    entries = av_fast_realloc(st->index_entries,
944
                              &st->index_entries_allocated_size,
945 115329f1 Diego Biurrun
                              (st->nb_index_entries + 1) *
946 fb2758c8 Fabrice Bellard
                              sizeof(AVIndexEntry));
947 568e18b1 Michael Niedermayer
    if(!entries)
948
        return -1;
949
950 b754978a Michael Niedermayer
    st->index_entries= entries;
951
952 27a5fe5f Michael Niedermayer
    index= av_index_search_timestamp(st, timestamp, AVSEEK_FLAG_ANY);
953 b754978a Michael Niedermayer
954 3ba1438d Michael Niedermayer
    if(index<0){
955 3e9245a9 Michael Niedermayer
        index= st->nb_index_entries++;
956
        ie= &entries[index];
957 3ba1438d Michael Niedermayer
        assert(index==0 || ie[-1].timestamp < timestamp);
958
    }else{
959
        ie= &entries[index];
960
        if(ie->timestamp != timestamp){
961 528c2c73 Michael Niedermayer
            if(ie->timestamp <= timestamp)
962
                return -1;
963 3ba1438d Michael Niedermayer
            memmove(entries + index + 1, entries + index, sizeof(AVIndexEntry)*(st->nb_index_entries - index));
964
            st->nb_index_entries++;
965
        }else if(ie->pos == pos && distance < ie->min_distance) //dont reduce the distance
966
            distance= ie->min_distance;
967 3e9245a9 Michael Niedermayer
    }
968 3ba1438d Michael Niedermayer
969 b754978a Michael Niedermayer
    ie->pos = pos;
970
    ie->timestamp = timestamp;
971 3e9245a9 Michael Niedermayer
    ie->min_distance= distance;
972 30a43f2d Michael Niedermayer
    ie->size= size;
973 b754978a Michael Niedermayer
    ie->flags = flags;
974 115329f1 Diego Biurrun
975 3e9245a9 Michael Niedermayer
    return index;
976 fb2758c8 Fabrice Bellard
}
977
978 e36bdf8b Daniel Kristjansson
/**
979
 * build an index for raw streams using a parser.
980
 */
981 fb2758c8 Fabrice Bellard
static void av_build_index_raw(AVFormatContext *s)
982
{
983
    AVPacket pkt1, *pkt = &pkt1;
984
    int ret;
985
    AVStream *st;
986
987
    st = s->streams[0];
988
    av_read_frame_flush(s);
989
    url_fseek(&s->pb, s->data_offset, SEEK_SET);
990
991
    for(;;) {
992
        ret = av_read_frame(s, pkt);
993
        if (ret < 0)
994
            break;
995
        if (pkt->stream_index == 0 && st->parser &&
996
            (pkt->flags & PKT_FLAG_KEY)) {
997 115329f1 Diego Biurrun
            av_add_index_entry(st, st->parser->frame_offset, pkt->dts,
998 30a43f2d Michael Niedermayer
                            0, 0, AVINDEX_KEYFRAME);
999 fb2758c8 Fabrice Bellard
        }
1000
        av_free_packet(pkt);
1001
    }
1002
}
1003
1004 e36bdf8b Daniel Kristjansson
/**
1005
 * Returns TRUE if we deal with a raw stream.
1006
 *
1007
 * Raw codec data and parsing needed.
1008
 */
1009 fb2758c8 Fabrice Bellard
static int is_raw_stream(AVFormatContext *s)
1010
{
1011
    AVStream *st;
1012
1013
    if (s->nb_streams != 1)
1014
        return 0;
1015
    st = s->streams[0];
1016
    if (!st->need_parsing)
1017
        return 0;
1018
    return 1;
1019
}
1020
1021 dc56fc38 Michael Niedermayer
int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp,
1022 27a5fe5f Michael Niedermayer
                              int flags)
1023 fb2758c8 Fabrice Bellard
{
1024 b754978a Michael Niedermayer
    AVIndexEntry *entries= st->index_entries;
1025
    int nb_entries= st->nb_index_entries;
1026 fb2758c8 Fabrice Bellard
    int a, b, m;
1027
    int64_t timestamp;
1028
1029 3ba1438d Michael Niedermayer
    a = - 1;
1030
    b = nb_entries;
1031 b754978a Michael Niedermayer
1032 3ba1438d Michael Niedermayer
    while (b - a > 1) {
1033
        m = (a + b) >> 1;
1034 fb2758c8 Fabrice Bellard
        timestamp = entries[m].timestamp;
1035 3ba1438d Michael Niedermayer
        if(timestamp >= wanted_timestamp)
1036
            b = m;
1037
        if(timestamp <= wanted_timestamp)
1038 b754978a Michael Niedermayer
            a = m;
1039 fb2758c8 Fabrice Bellard
    }
1040 27a5fe5f Michael Niedermayer
    m= (flags & AVSEEK_FLAG_BACKWARD) ? a : b;
1041 115329f1 Diego Biurrun
1042 27a5fe5f Michael Niedermayer
    if(!(flags & AVSEEK_FLAG_ANY)){
1043
        while(m>=0 && m<nb_entries && !(entries[m].flags & AVINDEX_KEYFRAME)){
1044
            m += (flags & AVSEEK_FLAG_BACKWARD) ? -1 : 1;
1045
        }
1046
    }
1047 3ba1438d Michael Niedermayer
1048 115329f1 Diego Biurrun
    if(m == nb_entries)
1049 3ba1438d Michael Niedermayer
        return -1;
1050
    return  m;
1051 fb2758c8 Fabrice Bellard
}
1052
1053 8d14a25c Michael Niedermayer
#define DEBUG_SEEK
1054
1055 3ba1438d Michael Niedermayer
int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags){
1056 8d14a25c Michael Niedermayer
    AVInputFormat *avif= s->iformat;
1057
    int64_t pos_min, pos_max, pos, pos_limit;
1058
    int64_t ts_min, ts_max, ts;
1059 89ddd2a9 Michael Niedermayer
    int index;
1060 8d14a25c Michael Niedermayer
    AVStream *st;
1061
1062 cdd5034f Michael Niedermayer
    if (stream_index < 0)
1063
        return -1;
1064 115329f1 Diego Biurrun
1065 8d14a25c Michael Niedermayer
#ifdef DEBUG_SEEK
1066 4733abcb Måns Rullgård
    av_log(s, AV_LOG_DEBUG, "read_seek: %d %"PRId64"\n", stream_index, target_ts);
1067 8d14a25c Michael Niedermayer
#endif
1068
1069
    ts_max=
1070
    ts_min= AV_NOPTS_VALUE;
1071
    pos_limit= -1; //gcc falsely says it may be uninitalized
1072
1073
    st= s->streams[stream_index];
1074
    if(st->index_entries){
1075
        AVIndexEntry *e;
1076
1077 27a5fe5f Michael Niedermayer
        index= av_index_search_timestamp(st, target_ts, flags | AVSEEK_FLAG_BACKWARD); //FIXME whole func must be checked for non keyframe entries in index case, especially read_timestamp()
1078 3ba1438d Michael Niedermayer
        index= FFMAX(index, 0);
1079 8d14a25c Michael Niedermayer
        e= &st->index_entries[index];
1080
1081
        if(e->timestamp <= target_ts || e->pos == e->min_distance){
1082
            pos_min= e->pos;
1083
            ts_min= e->timestamp;
1084
#ifdef DEBUG_SEEK
1085 115329f1 Diego Biurrun
        av_log(s, AV_LOG_DEBUG, "using cached pos_min=0x%"PRIx64" dts_min=%"PRId64"\n",
1086 8d14a25c Michael Niedermayer
               pos_min,ts_min);
1087
#endif
1088
        }else{
1089
            assert(index==0);
1090
        }
1091 115329f1 Diego Biurrun
1092
        index= av_index_search_timestamp(st, target_ts, flags & ~AVSEEK_FLAG_BACKWARD);
1093 27a5fe5f Michael Niedermayer
        assert(index < st->nb_index_entries);
1094
        if(index >= 0){
1095 8d14a25c Michael Niedermayer
            e= &st->index_entries[index];
1096
            assert(e->timestamp >= target_ts);
1097
            pos_max= e->pos;
1098
            ts_max= e->timestamp;
1099
            pos_limit= pos_max - e->min_distance;
1100
#ifdef DEBUG_SEEK
1101 115329f1 Diego Biurrun
        av_log(s, AV_LOG_DEBUG, "using cached pos_max=0x%"PRIx64" pos_limit=0x%"PRIx64" dts_max=%"PRId64"\n",
1102 8d14a25c Michael Niedermayer
               pos_max,pos_limit, ts_max);
1103
#endif
1104
        }
1105
    }
1106
1107 89ddd2a9 Michael Niedermayer
    pos= av_gen_search(s, stream_index, target_ts, pos_min, pos_max, pos_limit, ts_min, ts_max, flags, &ts, avif->read_timestamp);
1108
    if(pos<0)
1109
        return -1;
1110
1111
    /* do the seek */
1112
    url_fseek(&s->pb, pos, SEEK_SET);
1113
1114
    av_update_cur_dts(s, st, ts);
1115
1116
    return 0;
1117
}
1118
1119
int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, int64_t pos_min, int64_t pos_max, int64_t pos_limit, int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret, int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t )){
1120
    int64_t pos, ts;
1121
    int64_t start_pos, filesize;
1122
    int no_change;
1123
1124
#ifdef DEBUG_SEEK
1125
    av_log(s, AV_LOG_DEBUG, "gen_seek: %d %"PRId64"\n", stream_index, target_ts);
1126
#endif
1127
1128 8d14a25c Michael Niedermayer
    if(ts_min == AV_NOPTS_VALUE){
1129
        pos_min = s->data_offset;
1130 89ddd2a9 Michael Niedermayer
        ts_min = read_timestamp(s, stream_index, &pos_min, INT64_MAX);
1131 8d14a25c Michael Niedermayer
        if (ts_min == AV_NOPTS_VALUE)
1132
            return -1;
1133
    }
1134
1135
    if(ts_max == AV_NOPTS_VALUE){
1136
        int step= 1024;
1137 6fd93ce2 Kenneth Aafløy
        filesize = url_fsize(&s->pb);
1138
        pos_max = filesize - 1;
1139 8d14a25c Michael Niedermayer
        do{
1140
            pos_max -= step;
1141 89ddd2a9 Michael Niedermayer
            ts_max = read_timestamp(s, stream_index, &pos_max, pos_max + step);
1142 8d14a25c Michael Niedermayer
            step += step;
1143
        }while(ts_max == AV_NOPTS_VALUE && pos_max >= step);
1144
        if (ts_max == AV_NOPTS_VALUE)
1145
            return -1;
1146 115329f1 Diego Biurrun
1147 8d14a25c Michael Niedermayer
        for(;;){
1148
            int64_t tmp_pos= pos_max + 1;
1149 89ddd2a9 Michael Niedermayer
            int64_t tmp_ts= read_timestamp(s, stream_index, &tmp_pos, INT64_MAX);
1150 8d14a25c Michael Niedermayer
            if(tmp_ts == AV_NOPTS_VALUE)
1151
                break;
1152
            ts_max= tmp_ts;
1153
            pos_max= tmp_pos;
1154 6fd93ce2 Kenneth Aafløy
            if(tmp_pos >= filesize)
1155
                break;
1156 8d14a25c Michael Niedermayer
        }
1157
        pos_limit= pos_max;
1158
    }
1159
1160 53f7c43f Michael Niedermayer
    if(ts_min > ts_max){
1161
        return -1;
1162
    }else if(ts_min == ts_max){
1163
        pos_limit= pos_min;
1164
    }
1165
1166 8d14a25c Michael Niedermayer
    no_change=0;
1167
    while (pos_min < pos_limit) {
1168
#ifdef DEBUG_SEEK
1169 115329f1 Diego Biurrun
        av_log(s, AV_LOG_DEBUG, "pos_min=0x%"PRIx64" pos_max=0x%"PRIx64" dts_min=%"PRId64" dts_max=%"PRId64"\n",
1170 8d14a25c Michael Niedermayer
               pos_min, pos_max,
1171
               ts_min, ts_max);
1172
#endif
1173
        assert(pos_limit <= pos_max);
1174
1175
        if(no_change==0){
1176
            int64_t approximate_keyframe_distance= pos_max - pos_limit;
1177
            // interpolate position (better than dichotomy)
1178 3ba1438d Michael Niedermayer
            pos = av_rescale(target_ts - ts_min, pos_max - pos_min, ts_max - ts_min)
1179
                + pos_min - approximate_keyframe_distance;
1180 8d14a25c Michael Niedermayer
        }else if(no_change==1){
1181
            // bisection, if interpolation failed to change min or max pos last time
1182
            pos = (pos_min + pos_limit)>>1;
1183
        }else{
1184
            // linear search if bisection failed, can only happen if there are very few or no keframes between min/max
1185
            pos=pos_min;
1186
        }
1187
        if(pos <= pos_min)
1188
            pos= pos_min + 1;
1189
        else if(pos > pos_limit)
1190
            pos= pos_limit;
1191
        start_pos= pos;
1192
1193 89ddd2a9 Michael Niedermayer
        ts = read_timestamp(s, stream_index, &pos, INT64_MAX); //may pass pos_limit instead of -1
1194 8d14a25c Michael Niedermayer
        if(pos == pos_max)
1195
            no_change++;
1196
        else
1197
            no_change=0;
1198
#ifdef DEBUG_SEEK
1199 4733abcb Måns Rullgård
av_log(s, AV_LOG_DEBUG, "%"PRId64" %"PRId64" %"PRId64" / %"PRId64" %"PRId64" %"PRId64" target:%"PRId64" limit:%"PRId64" start:%"PRId64" noc:%d\n", pos_min, pos, pos_max, ts_min, ts, ts_max, target_ts, pos_limit, start_pos, no_change);
1200 8d14a25c Michael Niedermayer
#endif
1201
        assert(ts != AV_NOPTS_VALUE);
1202 3ba1438d Michael Niedermayer
        if (target_ts <= ts) {
1203 8d14a25c Michael Niedermayer
            pos_limit = start_pos - 1;
1204
            pos_max = pos;
1205
            ts_max = ts;
1206 3ba1438d Michael Niedermayer
        }
1207
        if (target_ts >= ts) {
1208 8d14a25c Michael Niedermayer
            pos_min = pos;
1209
            ts_min = ts;
1210
        }
1211
    }
1212 115329f1 Diego Biurrun
1213 3ba1438d Michael Niedermayer
    pos = (flags & AVSEEK_FLAG_BACKWARD) ? pos_min : pos_max;
1214
    ts  = (flags & AVSEEK_FLAG_BACKWARD) ?  ts_min :  ts_max;
1215 8d14a25c Michael Niedermayer
#ifdef DEBUG_SEEK
1216
    pos_min = pos;
1217 89ddd2a9 Michael Niedermayer
    ts_min = read_timestamp(s, stream_index, &pos_min, INT64_MAX);
1218 8d14a25c Michael Niedermayer
    pos_min++;
1219 89ddd2a9 Michael Niedermayer
    ts_max = read_timestamp(s, stream_index, &pos_min, INT64_MAX);
1220 115329f1 Diego Biurrun
    av_log(s, AV_LOG_DEBUG, "pos=0x%"PRIx64" %"PRId64"<=%"PRId64"<=%"PRId64"\n",
1221 8d14a25c Michael Niedermayer
           pos, ts_min, target_ts, ts_max);
1222
#endif
1223 89ddd2a9 Michael Niedermayer
    *ts_ret= ts;
1224
    return pos;
1225 8d14a25c Michael Niedermayer
}
1226
1227 3ba1438d Michael Niedermayer
static int av_seek_frame_byte(AVFormatContext *s, int stream_index, int64_t pos, int flags){
1228
    int64_t pos_min, pos_max;
1229
#if 0
1230
    AVStream *st;
1231

1232
    if (stream_index < 0)
1233
        return -1;
1234

1235
    st= s->streams[stream_index];
1236
#endif
1237
1238
    pos_min = s->data_offset;
1239 a965c478 Aurelien Jacobs
    pos_max = url_fsize(&s->pb) - 1;
1240 3ba1438d Michael Niedermayer
1241
    if     (pos < pos_min) pos= pos_min;
1242
    else if(pos > pos_max) pos= pos_max;
1243
1244
    url_fseek(&s->pb, pos, SEEK_SET);
1245
1246
#if 0
1247 8bcb147f Michael Niedermayer
    av_update_cur_dts(s, st, ts);
1248 3ba1438d Michael Niedermayer
#endif
1249
    return 0;
1250
}
1251
1252 115329f1 Diego Biurrun
static int av_seek_frame_generic(AVFormatContext *s,
1253 3ba1438d Michael Niedermayer
                                 int stream_index, int64_t timestamp, int flags)
1254 fb2758c8 Fabrice Bellard
{
1255 8bcb147f Michael Niedermayer
    int index;
1256 fb2758c8 Fabrice Bellard
    AVStream *st;
1257
    AVIndexEntry *ie;
1258
1259
    st = s->streams[stream_index];
1260 e9b78eeb Michael Niedermayer
1261 27a5fe5f Michael Niedermayer
    index = av_index_search_timestamp(st, timestamp, flags);
1262 e9b78eeb Michael Niedermayer
1263
    if(index < 0){
1264
        int i;
1265
        AVPacket pkt;
1266
1267
        if(st->index_entries && st->nb_index_entries){
1268
            ie= &st->index_entries[st->nb_index_entries-1];
1269
            url_fseek(&s->pb, ie->pos, SEEK_SET);
1270
            av_update_cur_dts(s, st, ie->timestamp);
1271
        }else
1272
            url_fseek(&s->pb, 0, SEEK_SET);
1273
1274
        for(i=0;; i++) {
1275
            int ret = av_read_frame(s, &pkt);
1276
            if(ret<0)
1277
                break;
1278
            av_free_packet(&pkt);
1279
            if(stream_index == pkt.stream_index){
1280
                if((pkt.flags & PKT_FLAG_KEY) && pkt.dts > timestamp)
1281
                    break;
1282
            }
1283
        }
1284
        index = av_index_search_timestamp(st, timestamp, flags);
1285
    }
1286 fb2758c8 Fabrice Bellard
    if (index < 0)
1287
        return -1;
1288
1289
    av_read_frame_flush(s);
1290 e9b78eeb Michael Niedermayer
    if (s->iformat->read_seek){
1291
        if(s->iformat->read_seek(s, stream_index, timestamp, flags) >= 0)
1292
            return 0;
1293
    }
1294
    ie = &st->index_entries[index];
1295 fb2758c8 Fabrice Bellard
    url_fseek(&s->pb, ie->pos, SEEK_SET);
1296 3ba1438d Michael Niedermayer
1297 8bcb147f Michael Niedermayer
    av_update_cur_dts(s, st, ie->timestamp);
1298 cdd5034f Michael Niedermayer
1299 fb2758c8 Fabrice Bellard
    return 0;
1300
}
1301
1302 3ba1438d Michael Niedermayer
int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
1303 fb2758c8 Fabrice Bellard
{
1304
    int ret;
1305 cdd5034f Michael Niedermayer
    AVStream *st;
1306 115329f1 Diego Biurrun
1307 fb2758c8 Fabrice Bellard
    av_read_frame_flush(s);
1308 115329f1 Diego Biurrun
1309 3ba1438d Michael Niedermayer
    if(flags & AVSEEK_FLAG_BYTE)
1310
        return av_seek_frame_byte(s, stream_index, timestamp, flags);
1311 115329f1 Diego Biurrun
1312 cdd5034f Michael Niedermayer
    if(stream_index < 0){
1313
        stream_index= av_find_default_stream_index(s);
1314
        if(stream_index < 0)
1315
            return -1;
1316 115329f1 Diego Biurrun
1317 3ba1438d Michael Niedermayer
        st= s->streams[stream_index];
1318 eb497825 Nathan Kurz
       /* timestamp for default must be expressed in AV_TIME_BASE units */
1319 3ba1438d Michael Niedermayer
        timestamp = av_rescale(timestamp, st->time_base.den, AV_TIME_BASE * (int64_t)st->time_base.num);
1320 cdd5034f Michael Niedermayer
    }
1321
    st= s->streams[stream_index];
1322
1323 fb2758c8 Fabrice Bellard
    /* first, we try the format specific seek */
1324
    if (s->iformat->read_seek)
1325 3ba1438d Michael Niedermayer
        ret = s->iformat->read_seek(s, stream_index, timestamp, flags);
1326 fb2758c8 Fabrice Bellard
    else
1327
        ret = -1;
1328
    if (ret >= 0) {
1329
        return 0;
1330
    }
1331 8d14a25c Michael Niedermayer
1332
    if(s->iformat->read_timestamp)
1333 3ba1438d Michael Niedermayer
        return av_seek_frame_binary(s, stream_index, timestamp, flags);
1334 8d14a25c Michael Niedermayer
    else
1335 3ba1438d Michael Niedermayer
        return av_seek_frame_generic(s, stream_index, timestamp, flags);
1336 fb2758c8 Fabrice Bellard
}
1337
1338
/*******************************************************/
1339 12f996ed Fabrice Bellard
1340 e36bdf8b Daniel Kristjansson
/**
1341
 * Returns TRUE if the stream has accurate timings in any stream.
1342
 *
1343
 * @return TRUE if the stream has accurate timings for at least one component.
1344
 */
1345 12f996ed Fabrice Bellard
static int av_has_timings(AVFormatContext *ic)
1346
{
1347
    int i;
1348
    AVStream *st;
1349
1350
    for(i = 0;i < ic->nb_streams; i++) {
1351
        st = ic->streams[i];
1352
        if (st->start_time != AV_NOPTS_VALUE &&
1353
            st->duration != AV_NOPTS_VALUE)
1354
            return 1;
1355
    }
1356
    return 0;
1357
}
1358
1359 e36bdf8b Daniel Kristjansson
/**
1360
 * Estimate the stream timings from the one of each components.
1361
 *
1362
 * Also computes the global bitrate if possible.
1363
 */
1364 12f996ed Fabrice Bellard
static void av_update_stream_timings(AVFormatContext *ic)
1365
{
1366 c0df9d75 Michael Niedermayer
    int64_t start_time, start_time1, end_time, end_time1;
1367 12f996ed Fabrice Bellard
    int i;
1368
    AVStream *st;
1369
1370 f27a7268 Måns Rullgård
    start_time = INT64_MAX;
1371
    end_time = INT64_MIN;
1372 12f996ed Fabrice Bellard
    for(i = 0;i < ic->nb_streams; i++) {
1373
        st = ic->streams[i];
1374
        if (st->start_time != AV_NOPTS_VALUE) {
1375 c0df9d75 Michael Niedermayer
            start_time1= av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q);
1376
            if (start_time1 < start_time)
1377
                start_time = start_time1;
1378 12f996ed Fabrice Bellard
            if (st->duration != AV_NOPTS_VALUE) {
1379 c0df9d75 Michael Niedermayer
                end_time1 = start_time1
1380
                          + av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q);
1381 12f996ed Fabrice Bellard
                if (end_time1 > end_time)
1382
                    end_time = end_time1;
1383
            }
1384
        }
1385
    }
1386 f27a7268 Måns Rullgård
    if (start_time != INT64_MAX) {
1387 12f996ed Fabrice Bellard
        ic->start_time = start_time;
1388 f27a7268 Måns Rullgård
        if (end_time != INT64_MIN) {
1389 12f996ed Fabrice Bellard
            ic->duration = end_time - start_time;
1390
            if (ic->file_size > 0) {
1391
                /* compute the bit rate */
1392 115329f1 Diego Biurrun
                ic->bit_rate = (double)ic->file_size * 8.0 * AV_TIME_BASE /
1393 12f996ed Fabrice Bellard
                    (double)ic->duration;
1394
            }
1395
        }
1396
    }
1397
1398
}
1399
1400
static void fill_all_stream_timings(AVFormatContext *ic)
1401
{
1402
    int i;
1403
    AVStream *st;
1404
1405
    av_update_stream_timings(ic);
1406
    for(i = 0;i < ic->nb_streams; i++) {
1407
        st = ic->streams[i];
1408
        if (st->start_time == AV_NOPTS_VALUE) {
1409 c0df9d75 Michael Niedermayer
            if(ic->start_time != AV_NOPTS_VALUE)
1410
                st->start_time = av_rescale_q(ic->start_time, AV_TIME_BASE_Q, st->time_base);
1411
            if(ic->duration != AV_NOPTS_VALUE)
1412
                st->duration = av_rescale_q(ic->duration, AV_TIME_BASE_Q, st->time_base);
1413 12f996ed Fabrice Bellard
        }
1414
    }
1415
}
1416
1417
static void av_estimate_timings_from_bit_rate(AVFormatContext *ic)
1418
{
1419
    int64_t filesize, duration;
1420
    int bit_rate, i;
1421
    AVStream *st;
1422
1423
    /* if bit_rate is already set, we believe it */
1424
    if (ic->bit_rate == 0) {
1425
        bit_rate = 0;
1426
        for(i=0;i<ic->nb_streams;i++) {
1427
            st = ic->streams[i];
1428 01f4895c Michael Niedermayer
            bit_rate += st->codec->bit_rate;
1429 12f996ed Fabrice Bellard
        }
1430
        ic->bit_rate = bit_rate;
1431
    }
1432
1433
    /* if duration is already set, we believe it */
1434 115329f1 Diego Biurrun
    if (ic->duration == AV_NOPTS_VALUE &&
1435
        ic->bit_rate != 0 &&
1436 12f996ed Fabrice Bellard
        ic->file_size != 0)  {
1437
        filesize = ic->file_size;
1438
        if (filesize > 0) {
1439
            for(i = 0; i < ic->nb_streams; i++) {
1440
                st = ic->streams[i];
1441 c0df9d75 Michael Niedermayer
                duration= av_rescale(8*filesize, st->time_base.den, ic->bit_rate*(int64_t)st->time_base.num);
1442 12f996ed Fabrice Bellard
                if (st->start_time == AV_NOPTS_VALUE ||
1443
                    st->duration == AV_NOPTS_VALUE) {
1444
                    st->start_time = 0;
1445
                    st->duration = duration;
1446
                }
1447
            }
1448
        }
1449
    }
1450
}
1451
1452
#define DURATION_MAX_READ_SIZE 250000
1453
1454
/* only usable for MPEG-PS streams */
1455 9ecf7fad Wolfram Gloger
static void av_estimate_timings_from_pts(AVFormatContext *ic, offset_t old_offset)
1456 12f996ed Fabrice Bellard
{
1457
    AVPacket pkt1, *pkt = &pkt1;
1458
    AVStream *st;
1459
    int read_size, i, ret;
1460 bf4e3bd2 Måns Rullgård
    int64_t end_time;
1461 12f996ed Fabrice Bellard
    int64_t filesize, offset, duration;
1462 115329f1 Diego Biurrun
1463 df7625ed Wolfram Gloger
    av_read_frame_flush(ic);
1464 115329f1 Diego Biurrun
1465 12f996ed Fabrice Bellard
    /* we read the first packets to get the first PTS (not fully
1466
       accurate, but it is enough now) */
1467
    url_fseek(&ic->pb, 0, SEEK_SET);
1468
    read_size = 0;
1469
    for(;;) {
1470
        if (read_size >= DURATION_MAX_READ_SIZE)
1471
            break;
1472
        /* if all info is available, we can stop */
1473
        for(i = 0;i < ic->nb_streams; i++) {
1474
            st = ic->streams[i];
1475
            if (st->start_time == AV_NOPTS_VALUE)
1476
                break;
1477
        }
1478
        if (i == ic->nb_streams)
1479
            break;
1480
1481
        ret = av_read_packet(ic, pkt);
1482
        if (ret != 0)
1483
            break;
1484
        read_size += pkt->size;
1485
        st = ic->streams[pkt->stream_index];
1486
        if (pkt->pts != AV_NOPTS_VALUE) {
1487
            if (st->start_time == AV_NOPTS_VALUE)
1488 c0df9d75 Michael Niedermayer
                st->start_time = pkt->pts;
1489 0a5f92a1 Michael Niedermayer
        }
1490
        av_free_packet(pkt);
1491
    }
1492 12f996ed Fabrice Bellard
1493
    /* estimate the end time (duration) */
1494
    /* XXX: may need to support wrapping */
1495
    filesize = ic->file_size;
1496
    offset = filesize - DURATION_MAX_READ_SIZE;
1497
    if (offset < 0)
1498
        offset = 0;
1499
1500
    url_fseek(&ic->pb, offset, SEEK_SET);
1501
    read_size = 0;
1502
    for(;;) {
1503
        if (read_size >= DURATION_MAX_READ_SIZE)
1504
            break;
1505
        /* if all info is available, we can stop */
1506
        for(i = 0;i < ic->nb_streams; i++) {
1507
            st = ic->streams[i];
1508
            if (st->duration == AV_NOPTS_VALUE)
1509
                break;
1510
        }
1511
        if (i == ic->nb_streams)
1512
            break;
1513 115329f1 Diego Biurrun
1514 12f996ed Fabrice Bellard
        ret = av_read_packet(ic, pkt);
1515
        if (ret != 0)
1516
            break;
1517
        read_size += pkt->size;
1518
        st = ic->streams[pkt->stream_index];
1519
        if (pkt->pts != AV_NOPTS_VALUE) {
1520 c0df9d75 Michael Niedermayer
            end_time = pkt->pts;
1521 12f996ed Fabrice Bellard
            duration = end_time - st->start_time;
1522
            if (duration > 0) {
1523
                if (st->duration == AV_NOPTS_VALUE ||
1524
                    st->duration < duration)
1525
                    st->duration = duration;
1526
            }
1527
        }
1528
        av_free_packet(pkt);
1529
    }
1530 115329f1 Diego Biurrun
1531 c0df9d75 Michael Niedermayer
    fill_all_stream_timings(ic);
1532 12f996ed Fabrice Bellard
1533 9ecf7fad Wolfram Gloger
    url_fseek(&ic->pb, old_offset, SEEK_SET);
1534 12f996ed Fabrice Bellard
}
1535
1536 9ecf7fad Wolfram Gloger
static void av_estimate_timings(AVFormatContext *ic, offset_t old_offset)
1537 12f996ed Fabrice Bellard
{
1538
    int64_t file_size;
1539
1540
    /* get the file size, if possible */
1541
    if (ic->iformat->flags & AVFMT_NOFILE) {
1542
        file_size = 0;
1543
    } else {
1544 a965c478 Aurelien Jacobs
        file_size = url_fsize(&ic->pb);
1545 12f996ed Fabrice Bellard
        if (file_size < 0)
1546
            file_size = 0;
1547
    }
1548
    ic->file_size = file_size;
1549
1550 ff70e601 Måns Rullgård
    if ((!strcmp(ic->iformat->name, "mpeg") ||
1551
         !strcmp(ic->iformat->name, "mpegts")) &&
1552
        file_size && !ic->pb.is_streamed) {
1553 12f996ed Fabrice Bellard
        /* get accurate estimate from the PTSes */
1554 9ecf7fad Wolfram Gloger
        av_estimate_timings_from_pts(ic, old_offset);
1555 12f996ed Fabrice Bellard
    } else if (av_has_timings(ic)) {
1556
        /* at least one components has timings - we use them for all
1557
           the components */
1558
        fill_all_stream_timings(ic);
1559
    } else {
1560
        /* less precise: use bit rate info */
1561
        av_estimate_timings_from_bit_rate(ic);
1562
    }
1563
    av_update_stream_timings(ic);
1564
1565
#if 0
1566
    {
1567
        int i;
1568
        AVStream *st;
1569
        for(i = 0;i < ic->nb_streams; i++) {
1570
            st = ic->streams[i];
1571 115329f1 Diego Biurrun
        printf("%d: start_time: %0.3f duration: %0.3f\n",
1572
               i, (double)st->start_time / AV_TIME_BASE,
1573 12f996ed Fabrice Bellard
               (double)st->duration / AV_TIME_BASE);
1574
        }
1575 115329f1 Diego Biurrun
        printf("stream: start_time: %0.3f duration: %0.3f bitrate=%d kb/s\n",
1576
               (double)ic->start_time / AV_TIME_BASE,
1577 12f996ed Fabrice Bellard
               (double)ic->duration / AV_TIME_BASE,
1578
               ic->bit_rate / 1000);
1579
    }
1580
#endif
1581
}
1582
1583 b9a281db Fabrice Bellard
static int has_codec_parameters(AVCodecContext *enc)
1584
{
1585
    int val;
1586
    switch(enc->codec_type) {
1587
    case CODEC_TYPE_AUDIO:
1588
        val = enc->sample_rate;
1589
        break;
1590
    case CODEC_TYPE_VIDEO:
1591 644a9262 Michael Niedermayer
        val = enc->width && enc->pix_fmt != PIX_FMT_NONE;
1592 b9a281db Fabrice Bellard
        break;
1593
    default:
1594
        val = 1;
1595
        break;
1596
    }
1597
    return (val != 0);
1598
}
1599
1600 fb2758c8 Fabrice Bellard
static int try_decode_frame(AVStream *st, const uint8_t *data, int size)
1601
{
1602
    int16_t *samples;
1603
    AVCodec *codec;
1604 3fdb6af9 Baptiste Coudurier
    int got_picture, data_size, ret=0;
1605 fb2758c8 Fabrice Bellard
    AVFrame picture;
1606 115329f1 Diego Biurrun
1607 01f4895c Michael Niedermayer
  if(!st->codec->codec){
1608
    codec = avcodec_find_decoder(st->codec->codec_id);
1609 fb2758c8 Fabrice Bellard
    if (!codec)
1610
        return -1;
1611 01f4895c Michael Niedermayer
    ret = avcodec_open(st->codec, codec);
1612 fb2758c8 Fabrice Bellard
    if (ret < 0)
1613
        return ret;
1614 43c0040a Michael Niedermayer
  }
1615 644a9262 Michael Niedermayer
1616 01f4895c Michael Niedermayer
  if(!has_codec_parameters(st->codec)){
1617
    switch(st->codec->codec_type) {
1618 fb2758c8 Fabrice Bellard
    case CODEC_TYPE_VIDEO:
1619 115329f1 Diego Biurrun
        ret = avcodec_decode_video(st->codec, &picture,
1620 fb2758c8 Fabrice Bellard
                                   &got_picture, (uint8_t *)data, size);
1621
        break;
1622
    case CODEC_TYPE_AUDIO:
1623 3fdb6af9 Baptiste Coudurier
        data_size = FFMAX(size, AVCODEC_MAX_AUDIO_FRAME_SIZE);
1624
        samples = av_malloc(data_size);
1625 fb2758c8 Fabrice Bellard
        if (!samples)
1626
            goto fail;
1627 3fdb6af9 Baptiste Coudurier
        ret = avcodec_decode_audio2(st->codec, samples,
1628
                                    &data_size, (uint8_t *)data, size);
1629 fb2758c8 Fabrice Bellard
        av_free(samples);
1630
        break;
1631
    default:
1632
        break;
1633
    }
1634 644a9262 Michael Niedermayer
  }
1635 fb2758c8 Fabrice Bellard
 fail:
1636
    return ret;
1637
}
1638
1639
/* absolute maximum size we read until we abort */
1640
#define MAX_READ_SIZE        5000000
1641
1642 fd97f6a2 Michael Niedermayer
#define MAX_STD_TIMEBASES (60*12+5)
1643 4d43cbcc Michael Niedermayer
static int get_std_framerate(int i){
1644
    if(i<60*12) return i*1001;
1645 fd97f6a2 Michael Niedermayer
    else        return ((int[]){24,30,60,12,15})[i-60*12]*1000*12;
1646 4d43cbcc Michael Niedermayer
}
1647
1648 b9a281db Fabrice Bellard
int av_find_stream_info(AVFormatContext *ic)
1649
{
1650 9f75260e Michael Niedermayer
    int i, count, ret, read_size, j;
1651 b9a281db Fabrice Bellard
    AVStream *st;
1652 fb2758c8 Fabrice Bellard
    AVPacket pkt1, *pkt;
1653 b9a281db Fabrice Bellard
    AVPacketList *pktl=NULL, **ppktl;
1654 15bc38e5 Michael Niedermayer
    int64_t last_dts[MAX_STREAMS];
1655 3c150d16 Michael Niedermayer
    int duration_count[MAX_STREAMS]={0};
1656 0cbff027 Kristian Amlie
    double (*duration_error)[MAX_STD_TIMEBASES];
1657 9ecf7fad Wolfram Gloger
    offset_t old_offset = url_ftell(&ic->pb);
1658 ea486ab3 Baptiste Coudurier
    int64_t codec_info_duration[MAX_STREAMS]={0};
1659
    int codec_info_nb_frames[MAX_STREAMS]={0};
1660 b9a281db Fabrice Bellard
1661 0cbff027 Kristian Amlie
    duration_error = av_mallocz(MAX_STREAMS * sizeof(*duration_error));
1662
    if (!duration_error) return AVERROR_NOMEM;
1663
1664 c0df9d75 Michael Niedermayer
    for(i=0;i<ic->nb_streams;i++) {
1665
        st = ic->streams[i];
1666 01f4895c Michael Niedermayer
        if(st->codec->codec_type == CODEC_TYPE_VIDEO){
1667 c0df9d75 Michael Niedermayer
/*            if(!st->time_base.num)
1668
                st->time_base= */
1669 01f4895c Michael Niedermayer
            if(!st->codec->time_base.num)
1670
                st->codec->time_base= st->time_base;
1671 c0df9d75 Michael Niedermayer
        }
1672 90ad92b3 Michael Niedermayer
        //only for the split stuff
1673
        if (!st->parser) {
1674 01f4895c Michael Niedermayer
            st->parser = av_parser_init(st->codec->codec_id);
1675 7cbaa7ba Michael Niedermayer
            if(st->need_parsing == 2 && st->parser){
1676
                st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
1677
            }
1678 90ad92b3 Michael Niedermayer
        }
1679 c0df9d75 Michael Niedermayer
    }
1680
1681 15bc38e5 Michael Niedermayer
    for(i=0;i<MAX_STREAMS;i++){
1682
        last_dts[i]= AV_NOPTS_VALUE;
1683
    }
1684 115329f1 Diego Biurrun
1685 b9a281db Fabrice Bellard
    count = 0;
1686
    read_size = 0;
1687
    ppktl = &ic->packet_buffer;
1688
    for(;;) {
1689
        /* check if one codec still needs to be handled */
1690
        for(i=0;i<ic->nb_streams;i++) {
1691
            st = ic->streams[i];
1692 01f4895c Michael Niedermayer
            if (!has_codec_parameters(st->codec))
1693 b9a281db Fabrice Bellard
                break;
1694 3e76d1b5 Michael Niedermayer
            /* variable fps and no guess at the real fps */
1695 9f75260e Michael Niedermayer
            if(   st->codec->time_base.den >= 101LL*st->codec->time_base.num
1696 01f4895c Michael Niedermayer
               && duration_count[i]<20 && st->codec->codec_type == CODEC_TYPE_VIDEO)
1697 3e76d1b5 Michael Niedermayer
                break;
1698 01f4895c Michael Niedermayer
            if(st->parser && st->parser->parser->split && !st->codec->extradata)
1699 90ad92b3 Michael Niedermayer
                break;
1700 b9a281db Fabrice Bellard
        }
1701
        if (i == ic->nb_streams) {
1702
            /* NOTE: if the format has no header, then we need to read
1703
               some packets to get most of the streams, so we cannot
1704
               stop here */
1705 fb2758c8 Fabrice Bellard
            if (!(ic->ctx_flags & AVFMTCTX_NOHEADER)) {
1706 b9a281db Fabrice Bellard
                /* if we found the info for all the codecs, we can stop */
1707
                ret = count;
1708
                break;
1709
            }
1710 5fb83c38 Michael Niedermayer
        }
1711 35eab0c0 Michael Niedermayer
        /* we did not get all the codec info, but we read too much data */
1712
        if (read_size >= MAX_READ_SIZE) {
1713
            ret = count;
1714
            break;
1715
        }
1716 b9a281db Fabrice Bellard
1717 fb2758c8 Fabrice Bellard
        /* NOTE: a new stream can be added there if no header in file
1718
           (AVFMTCTX_NOHEADER) */
1719
        ret = av_read_frame_internal(ic, &pkt1);
1720
        if (ret < 0) {
1721
            /* EOF or error */
1722
            ret = -1; /* we could not have all the codec parameters before EOF */
1723 e19456e3 Michael Niedermayer
            for(i=0;i<ic->nb_streams;i++) {
1724
                st = ic->streams[i];
1725 305ee50f Michael Niedermayer
                if (!has_codec_parameters(st->codec)){
1726
                    char buf[256];
1727
                    avcodec_string(buf, sizeof(buf), st->codec, 0);
1728
                    av_log(ic, AV_LOG_INFO, "Could not find codec parameters (%s)\n", buf);
1729 344a18c3 Måns Rullgård
                } else {
1730
                    ret = 0;
1731 305ee50f Michael Niedermayer
                }
1732 e19456e3 Michael Niedermayer
            }
1733 fb2758c8 Fabrice Bellard
            break;
1734
        }
1735
1736 b9a281db Fabrice Bellard
        pktl = av_mallocz(sizeof(AVPacketList));
1737
        if (!pktl) {
1738
            ret = AVERROR_NOMEM;
1739
            break;
1740
        }
1741
1742
        /* add the packet in the buffered packet list */
1743
        *ppktl = pktl;
1744
        ppktl = &pktl->next;
1745
1746
        pkt = &pktl->pkt;
1747 fb2758c8 Fabrice Bellard
        *pkt = pkt1;
1748 115329f1 Diego Biurrun
1749 fb2758c8 Fabrice Bellard
        /* duplicate the packet */
1750
        if (av_dup_packet(pkt) < 0) {
1751 e344c1ea Steve L'Homme
            ret = AVERROR_NOMEM;
1752
            break;
1753 b9a281db Fabrice Bellard
        }
1754
1755 fb2758c8 Fabrice Bellard
        read_size += pkt->size;
1756 b9a281db Fabrice Bellard
1757
        st = ic->streams[pkt->stream_index];
1758 ea486ab3 Baptiste Coudurier
        if(codec_info_nb_frames[st->index]>1)
1759
            codec_info_duration[st->index] += pkt->duration;
1760 fb2758c8 Fabrice Bellard
        if (pkt->duration != 0)
1761 ea486ab3 Baptiste Coudurier
            codec_info_nb_frames[st->index]++;
1762 fb2758c8 Fabrice Bellard
1763 cefe0607 Michael Niedermayer
        {
1764 3c150d16 Michael Niedermayer
            int index= pkt->stream_index;
1765
            int64_t last= last_dts[index];
1766
            int64_t duration= pkt->dts - last;
1767
1768
            if(pkt->dts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && duration>0){
1769 4d43cbcc Michael Niedermayer
                double dur= duration * av_q2d(st->time_base);
1770
1771
//                if(st->codec->codec_type == CODEC_TYPE_VIDEO)
1772
//                    av_log(NULL, AV_LOG_ERROR, "%f\n", dur);
1773 1694118b Michael Niedermayer
                if(duration_count[index] < 2)
1774 0cbff027 Kristian Amlie
                    memset(duration_error, 0, MAX_STREAMS * sizeof(*duration_error));
1775 69c262d1 Michael Niedermayer
                for(i=1; i<MAX_STD_TIMEBASES; i++){
1776
                    int framerate= get_std_framerate(i);
1777
                    int ticks= lrintf(dur*framerate/(1001*12));
1778
                    double error= dur - ticks*1001*12/(double)framerate;
1779
                    duration_error[index][i] += error*error;
1780
                }
1781 4d43cbcc Michael Niedermayer
                duration_count[index]++;
1782 15bc38e5 Michael Niedermayer
            }
1783 fd97f6a2 Michael Niedermayer
            if(last == AV_NOPTS_VALUE || duration_count[index]<=1)
1784
                last_dts[pkt->stream_index]= pkt->dts;
1785 15bc38e5 Michael Niedermayer
        }
1786 01f4895c Michael Niedermayer
        if(st->parser && st->parser->parser->split && !st->codec->extradata){
1787
            int i= st->parser->parser->split(st->codec, pkt->data, pkt->size);
1788 90ad92b3 Michael Niedermayer
            if(i){
1789 01f4895c Michael Niedermayer
                st->codec->extradata_size= i;
1790 62c52121 Måns Rullgård
                st->codec->extradata= av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
1791 01f4895c Michael Niedermayer
                memcpy(st->codec->extradata, pkt->data, st->codec->extradata_size);
1792 62c52121 Måns Rullgård
                memset(st->codec->extradata + i, 0, FF_INPUT_BUFFER_PADDING_SIZE);
1793 90ad92b3 Michael Niedermayer
            }
1794
        }
1795 115329f1 Diego Biurrun
1796 fb2758c8 Fabrice Bellard
        /* if still no information, we try to open the codec and to
1797
           decompress the frame. We try to avoid that in most cases as
1798
           it takes longer and uses more memory. For MPEG4, we need to
1799
           decompress for Quicktime. */
1800 01f4895c Michael Niedermayer
        if (!has_codec_parameters(st->codec) /*&&
1801
            (st->codec->codec_id == CODEC_ID_FLV1 ||
1802
             st->codec->codec_id == CODEC_ID_H264 ||
1803
             st->codec->codec_id == CODEC_ID_H263 ||
1804
             st->codec->codec_id == CODEC_ID_H261 ||
1805
             st->codec->codec_id == CODEC_ID_VORBIS ||
1806
             st->codec->codec_id == CODEC_ID_MJPEG ||
1807
             st->codec->codec_id == CODEC_ID_PNG ||
1808
             st->codec->codec_id == CODEC_ID_PAM ||
1809
             st->codec->codec_id == CODEC_ID_PGM ||
1810
             st->codec->codec_id == CODEC_ID_PGMYUV ||
1811
             st->codec->codec_id == CODEC_ID_PBM ||
1812
             st->codec->codec_id == CODEC_ID_PPM ||
1813
             st->codec->codec_id == CODEC_ID_SHORTEN ||
1814
             (st->codec->codec_id == CODEC_ID_MPEG4 && !st->need_parsing))*/)
1815 fb2758c8 Fabrice Bellard
            try_decode_frame(st, pkt->data, pkt->size);
1816 115329f1 Diego Biurrun
1817 ea486ab3 Baptiste Coudurier
        if (av_rescale_q(codec_info_duration[st->index], st->time_base, AV_TIME_BASE_Q) >= ic->max_analyze_duration) {
1818 fb2758c8 Fabrice Bellard
            break;
1819 b9a281db Fabrice Bellard
        }
1820
        count++;
1821
    }
1822
1823 43c0040a Michael Niedermayer
    // close codecs which where opened in try_decode_frame()
1824
    for(i=0;i<ic->nb_streams;i++) {
1825
        st = ic->streams[i];
1826 01f4895c Michael Niedermayer
        if(st->codec->codec)
1827
            avcodec_close(st->codec);
1828 43c0040a Michael Niedermayer
    }
1829 b9a281db Fabrice Bellard
    for(i=0;i<ic->nb_streams;i++) {
1830
        st = ic->streams[i];
1831 01f4895c Michael Niedermayer
        if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
1832
            if(st->codec->codec_id == CODEC_ID_RAWVIDEO && !st->codec->codec_tag && !st->codec->bits_per_sample)
1833
                st->codec->codec_tag= avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);
1834 15bc38e5 Michael Niedermayer
1835 1694118b Michael Niedermayer
            if(duration_count[i]
1836 4d43cbcc Michael Niedermayer
               && (st->codec->time_base.num*101LL <= st->codec->time_base.den || st->codec->codec_id == CODEC_ID_MPEG2VIDEO) /*&&
1837 730ba406 Michael Niedermayer
               //FIXME we should not special case mpeg2, but this needs testing with non mpeg2 ...
1838 4d43cbcc Michael Niedermayer
               st->time_base.num*duration_sum[i]/duration_count[i]*101LL > st->time_base.den*/){
1839
                double best_error= 2*av_q2d(st->time_base);
1840
                best_error= best_error*best_error*duration_count[i]*1000*12*30;
1841
1842
                for(j=1; j<MAX_STD_TIMEBASES; j++){
1843
                    double error= duration_error[i][j] * get_std_framerate(j);
1844
//                    if(st->codec->codec_type == CODEC_TYPE_VIDEO)
1845
//                        av_log(NULL, AV_LOG_ERROR, "%f %f\n", get_std_framerate(j) / 12.0/1001, error);
1846 9f75260e Michael Niedermayer
                    if(error < best_error){
1847
                        best_error= error;
1848 4d43cbcc Michael Niedermayer
                        av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, get_std_framerate(j), 12*1001, INT_MAX);
1849 9f75260e Michael Niedermayer
                    }
1850 3c150d16 Michael Niedermayer
                }
1851 15bc38e5 Michael Niedermayer
            }
1852
1853 c0df9d75 Michael Niedermayer
            if (!st->r_frame_rate.num){
1854 5523d5f4 Michael Niedermayer
                if(    st->codec->time_base.den * (int64_t)st->time_base.num
1855
                    <= st->codec->time_base.num * (int64_t)st->time_base.den){
1856
                    st->r_frame_rate.num = st->codec->time_base.den;
1857
                    st->r_frame_rate.den = st->codec->time_base.num;
1858
                }else{
1859
                    st->r_frame_rate.num = st->time_base.den;
1860
                    st->r_frame_rate.den = st->time_base.num;
1861
                }
1862 14bea432 Michael Niedermayer
            }
1863 a185f52a Michael Niedermayer
        }else if(st->codec->codec_type == CODEC_TYPE_AUDIO) {
1864
            if(!st->codec->bits_per_sample)
1865
                st->codec->bits_per_sample= av_get_bits_per_sample(st->codec->codec_id);
1866 b9a281db Fabrice Bellard
        }
1867 de6d9b64 Fabrice Bellard
    }
1868 b9a281db Fabrice Bellard
1869 9ecf7fad Wolfram Gloger
    av_estimate_timings(ic, old_offset);
1870 e928649b Michael Niedermayer
#if 0
1871
    /* correct DTS for b frame streams with no timestamps */
1872
    for(i=0;i<ic->nb_streams;i++) {
1873
        st = ic->streams[i];
1874 01f4895c Michael Niedermayer
        if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
1875 e928649b Michael Niedermayer
            if(b-frames){
1876
                ppktl = &ic->packet_buffer;
1877
                while(ppkt1){
1878
                    if(ppkt1->stream_index != i)
1879
                        continue;
1880
                    if(ppkt1->pkt->dts < 0)
1881
                        break;
1882
                    if(ppkt1->pkt->pts != AV_NOPTS_VALUE)
1883
                        break;
1884
                    ppkt1->pkt->dts -= delta;
1885
                    ppkt1= ppkt1->next;
1886
                }
1887
                if(ppkt1)
1888
                    continue;
1889
                st->cur_dts -= delta;
1890
            }
1891
        }
1892
    }
1893
#endif
1894 0cbff027 Kristian Amlie
1895
    av_free(duration_error);
1896
1897 b9a281db Fabrice Bellard
    return ret;
1898 de6d9b64 Fabrice Bellard
}
1899
1900 fb2758c8 Fabrice Bellard
/*******************************************************/
1901
1902
int av_read_play(AVFormatContext *s)
1903
{
1904
    if (!s->iformat->read_play)
1905
        return AVERROR_NOTSUPP;
1906
    return s->iformat->read_play(s);
1907
}
1908
1909
int av_read_pause(AVFormatContext *s)
1910
{
1911
    if (!s->iformat->read_pause)
1912
        return AVERROR_NOTSUPP;
1913
    return s->iformat->read_pause(s);
1914
}
1915
1916 de6d9b64 Fabrice Bellard
void av_close_input_file(AVFormatContext *s)
1917
{
1918 b6892136 Fabrice Bellard
    int i, must_open_file;
1919 da24c5e3 Fabrice Bellard
    AVStream *st;
1920 de6d9b64 Fabrice Bellard
1921 fb2758c8 Fabrice Bellard
    /* free previous packet */
1922
    if (s->cur_st && s->cur_st->parser)
1923 115329f1 Diego Biurrun
        av_free_packet(&s->cur_pkt);
1924 fb2758c8 Fabrice Bellard
1925 b9a281db Fabrice Bellard
    if (s->iformat->read_close)
1926
        s->iformat->read_close(s);
1927 de6d9b64 Fabrice Bellard
    for(i=0;i<s->nb_streams;i++) {
1928 da24c5e3 Fabrice Bellard
        /* free all data in a stream component */
1929
        st = s->streams[i];
1930 fb2758c8 Fabrice Bellard
        if (st->parser) {
1931
            av_parser_close(st->parser);
1932 de6d9b64 Fabrice Bellard
        }
1933 fb2758c8 Fabrice Bellard
        av_free(st->index_entries);
1934 a5e9102b Måns Rullgård
        av_free(st->codec->extradata);
1935 01f4895c Michael Niedermayer
        av_free(st->codec);
1936 fb2758c8 Fabrice Bellard
        av_free(st);
1937 de6d9b64 Fabrice Bellard
    }
1938 fb2758c8 Fabrice Bellard
    flush_packet_queue(s);
1939 b6892136 Fabrice Bellard
    must_open_file = 1;
1940 da24c5e3 Fabrice Bellard
    if (s->iformat->flags & AVFMT_NOFILE) {
1941 b6892136 Fabrice Bellard
        must_open_file = 0;
1942
    }
1943
    if (must_open_file) {
1944 96baaa6a Fabrice Bellard
        url_fclose(&s->pb);
1945
    }
1946 a8dbe951 Philip Gladstone
    av_freep(&s->priv_data);
1947 1ea4f593 Fabrice Bellard
    av_free(s);
1948 de6d9b64 Fabrice Bellard
}
1949
1950 b9a281db Fabrice Bellard
AVStream *av_new_stream(AVFormatContext *s, int id)
1951
{
1952
    AVStream *st;
1953 504ee036 Michael Niedermayer
    int i;
1954 b9a281db Fabrice Bellard
1955
    if (s->nb_streams >= MAX_STREAMS)
1956
        return NULL;
1957
1958
    st = av_mallocz(sizeof(AVStream));
1959
    if (!st)
1960
        return NULL;
1961 115329f1 Diego Biurrun
1962 01f4895c Michael Niedermayer
    st->codec= avcodec_alloc_context();
1963 48091512 Fabrice Bellard
    if (s->iformat) {
1964
        /* no default bitrate if decoding */
1965 01f4895c Michael Niedermayer
        st->codec->bit_rate = 0;
1966 48091512 Fabrice Bellard
    }
1967 b9a281db Fabrice Bellard
    st->index = s->nb_streams;
1968
    st->id = id;
1969 12f996ed Fabrice Bellard
    st->start_time = AV_NOPTS_VALUE;
1970
    st->duration = AV_NOPTS_VALUE;
1971 e928649b Michael Niedermayer
    st->cur_dts = AV_NOPTS_VALUE;
1972 9ee91c2f Michael Niedermayer
1973
    /* default pts settings is MPEG like */
1974
    av_set_pts_info(st, 33, 1, 90000);
1975 77405fc8 Michael Niedermayer
    st->last_IP_pts = AV_NOPTS_VALUE;
1976 504ee036 Michael Niedermayer
    for(i=0; i<MAX_REORDER_DELAY+1; i++)
1977
        st->pts_buffer[i]= AV_NOPTS_VALUE;
1978 9ee91c2f Michael Niedermayer
1979 b9a281db Fabrice Bellard
    s->streams[s->nb_streams++] = st;
1980
    return st;
1981
}
1982
1983
/************************************************************/
1984
/* output media file */
1985 de6d9b64 Fabrice Bellard
1986 87a0a681 Fabrice Bellard
int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap)
1987
{
1988
    int ret;
1989 115329f1 Diego Biurrun
1990 98486a6b Roman Shaposhnik
    if (s->oformat->priv_data_size > 0) {
1991
        s->priv_data = av_mallocz(s->oformat->priv_data_size);
1992
        if (!s->priv_data)
1993
            return AVERROR_NOMEM;
1994
    } else
1995
        s->priv_data = NULL;
1996 115329f1 Diego Biurrun
1997 87a0a681 Fabrice Bellard
    if (s->oformat->set_parameters) {
1998
        ret = s->oformat->set_parameters(s, ap);
1999
        if (ret < 0)
2000
            return ret;
2001
    }
2002
    return 0;
2003
}
2004
2005 b9a281db Fabrice Bellard
int av_write_header(AVFormatContext *s)
2006
{
2007 1e51d801 Fabrice Bellard
    int ret, i;
2008
    AVStream *st;
2009
2010 9450118b Michael Niedermayer
    // some sanity checks
2011
    for(i=0;i<s->nb_streams;i++) {
2012
        st = s->streams[i];
2013
2014
        switch (st->codec->codec_type) {
2015
        case CODEC_TYPE_AUDIO:
2016
            if(st->codec->sample_rate<=0){
2017
                av_log(s, AV_LOG_ERROR, "sample rate not set\n");
2018
                return -1;
2019
            }
2020
            break;
2021
        case CODEC_TYPE_VIDEO:
2022
            if(st->codec->time_base.num<=0 || st->codec->time_base.den<=0){ //FIXME audio too?
2023
                av_log(s, AV_LOG_ERROR, "time base not set\n");
2024
                return -1;
2025
            }
2026
            if(st->codec->width<=0 || st->codec->height<=0){
2027
                av_log(s, AV_LOG_ERROR, "dimensions not set\n");
2028
                return -1;
2029
            }
2030
            break;
2031
        }
2032 5ecfa9f5 Michael Niedermayer
2033
        if(s->oformat->codec_tag){
2034
            if(st->codec->codec_tag){
2035
                //FIXME
2036
                //check that tag + id is in the table
2037
                //if neither is in the table -> ok
2038
                //if tag is in the table with another id -> FAIL
2039
                //if id is in the table with another tag -> FAIL unless strict < ?
2040
            }else
2041
                st->codec->codec_tag= av_codec_get_tag(s->oformat->codec_tag, st->codec->codec_id);
2042
        }
2043 9450118b Michael Niedermayer
    }
2044
2045 8fae2df5 Baptiste Coudurier
    if (!s->priv_data && s->oformat->priv_data_size > 0) {
2046 c6efa4b5 Baptiste Coudurier
        s->priv_data = av_mallocz(s->oformat->priv_data_size);
2047
        if (!s->priv_data)
2048
            return AVERROR_NOMEM;
2049 8fae2df5 Baptiste Coudurier
    }
2050 c6efa4b5 Baptiste Coudurier
2051 31e11451 Michael Niedermayer
    if(s->oformat->write_header){
2052
        ret = s->oformat->write_header(s);
2053
        if (ret < 0)
2054
            return ret;
2055
    }
2056 1e51d801 Fabrice Bellard
2057
    /* init PTS generation */
2058
    for(i=0;i<s->nb_streams;i++) {
2059 f0ff20a1 Wolfram Gloger
        int64_t den = AV_NOPTS_VALUE;
2060 1e51d801 Fabrice Bellard
        st = s->streams[i];
2061
2062 01f4895c Michael Niedermayer
        switch (st->codec->codec_type) {
2063 1e51d801 Fabrice Bellard
        case CODEC_TYPE_AUDIO:
2064 f0ff20a1 Wolfram Gloger
            den = (int64_t)st->time_base.num * st->codec->sample_rate;
2065 1e51d801 Fabrice Bellard
            break;
2066
        case CODEC_TYPE_VIDEO:
2067 f0ff20a1 Wolfram Gloger
            den = (int64_t)st->time_base.num * st->codec->time_base.den;
2068 1e51d801 Fabrice Bellard
            break;
2069
        default:
2070
            break;
2071
        }
2072 f0ff20a1 Wolfram Gloger
        if (den != AV_NOPTS_VALUE) {
2073
            if (den <= 0)
2074
                return AVERROR_INVALIDDATA;
2075
            av_frac_init(&st->pts, 0, 0, den);
2076
        }
2077 1e51d801 Fabrice Bellard
    }
2078
    return 0;
2079 b9a281db Fabrice Bellard
}
2080
2081 3c895fc0 Michael Niedermayer
//FIXME merge with compute_pkt_fields
2082 5edea431 Michael Niedermayer
static int compute_pkt_fields2(AVStream *st, AVPacket *pkt){
2083 504ee036 Michael Niedermayer
    int delay = FFMAX(st->codec->has_b_frames, !!st->codec->max_b_frames);
2084
    int num, den, frame_size, i;
2085 b0c7f5a9 Michael Niedermayer
2086 949b1a13 Steve L'Homme
//    av_log(st->codec, AV_LOG_DEBUG, "av_write_frame: pts:%"PRId64" dts:%"PRId64" cur_dts:%"PRId64" b:%d size:%d st:%d\n", pkt->pts, pkt->dts, st->cur_dts, delay, pkt->size, pkt->stream_index);
2087 115329f1 Diego Biurrun
2088 e928649b Michael Niedermayer
/*    if(pkt->pts == AV_NOPTS_VALUE && pkt->dts == AV_NOPTS_VALUE)
2089
        return -1;*/
2090 115329f1 Diego Biurrun
2091 e928649b Michael Niedermayer
    /* duration field */
2092 3c895fc0 Michael Niedermayer
    if (pkt->duration == 0) {
2093
        compute_frame_duration(&num, &den, st, NULL, pkt);
2094
        if (den && num) {
2095
            pkt->duration = av_rescale(1, num * (int64_t)st->time_base.den, den * (int64_t)st->time_base.num);
2096
        }
2097
    }
2098 e928649b Michael Niedermayer
2099
    //XXX/FIXME this is a temporary hack until all encoders output pts
2100 504ee036 Michael Niedermayer
    if((pkt->pts == 0 || pkt->pts == AV_NOPTS_VALUE) && pkt->dts == AV_NOPTS_VALUE && !delay){
2101 e928649b Michael Niedermayer
        pkt->dts=
2102
//        pkt->pts= st->cur_dts;
2103
        pkt->pts= st->pts.val;
2104
    }
2105
2106 115329f1 Diego Biurrun
    //calculate dts from pts
2107 e928649b Michael Niedermayer
    if(pkt->pts != AV_NOPTS_VALUE && pkt->dts == AV_NOPTS_VALUE){
2108 504ee036 Michael Niedermayer
        st->pts_buffer[0]= pkt->pts;
2109
        for(i=1; i<delay+1 && st->pts_buffer[i] == AV_NOPTS_VALUE; i++)
2110
            st->pts_buffer[i]= (i-delay-1) * pkt->duration;
2111
        for(i=0; i<delay && st->pts_buffer[i] > st->pts_buffer[i+1]; i++)
2112 1345f4ed Diego Biurrun
            FFSWAP(int64_t, st->pts_buffer[i], st->pts_buffer[i+1]);
2113 504ee036 Michael Niedermayer
2114
        pkt->dts= st->pts_buffer[0];
2115 e928649b Michael Niedermayer
    }
2116 115329f1 Diego Biurrun
2117 5edea431 Michael Niedermayer
    if(st->cur_dts && st->cur_dts != AV_NOPTS_VALUE && st->cur_dts >= pkt->dts){
2118 df7625ed Wolfram Gloger
        av_log(NULL, AV_LOG_ERROR, "error, non monotone timestamps %"PRId64" >= %"PRId64" st:%d\n", st->cur_dts, pkt->dts, st->index);
2119 5edea431 Michael Niedermayer
        return -1;
2120
    }
2121
    if(pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts < pkt->dts){
2122 df7625ed Wolfram Gloger
        av_log(NULL, AV_LOG_ERROR, "error, pts < dts (%"PRId64" < %"PRId64")\n",
2123
               pkt->pts, pkt->dts);
2124 5edea431 Michael Niedermayer
        return -1;
2125
    }
2126
2127 949b1a13 Steve L'Homme
//    av_log(NULL, AV_LOG_DEBUG, "av_write_frame: pts2:%"PRId64" dts2:%"PRId64"\n", pkt->pts, pkt->dts);
2128 e928649b Michael Niedermayer
    st->cur_dts= pkt->dts;
2129
    st->pts.val= pkt->dts;
2130
2131 1e51d801 Fabrice Bellard
    /* update pts */
2132 01f4895c Michael Niedermayer
    switch (st->codec->codec_type) {
2133 1e51d801 Fabrice Bellard
    case CODEC_TYPE_AUDIO:
2134 01f4895c Michael Niedermayer
        frame_size = get_audio_frame_size(st->codec, pkt->size);
2135 6d8f985e Michael Niedermayer
2136 b0c7f5a9 Michael Niedermayer
        /* HACK/FIXME, we skip the initial 0-size packets as they are most likely equal to the encoder delay,
2137 6d8f985e Michael Niedermayer
           but it would be better if we had the real timestamps from the encoder */
2138 e928649b Michael Niedermayer
        if (frame_size >= 0 && (pkt->size || st->pts.num!=st->pts.den>>1 || st->pts.val)) {
2139 9ee91c2f Michael Niedermayer
            av_frac_add(&st->pts, (int64_t)st->time_base.den * frame_size);
2140 7feb950a Fabrice Bellard
        }
2141 1e51d801 Fabrice Bellard
        break;
2142
    case CODEC_TYPE_VIDEO:
2143 01f4895c Michael Niedermayer
        av_frac_add(&st->pts, (int64_t)st->time_base.den * st->codec->time_base.num);
2144 1e51d801 Fabrice Bellard
        break;
2145
    default:
2146
        break;
2147
    }
2148 5edea431 Michael Niedermayer
    return 0;
2149 3c895fc0 Michael Niedermayer
}
2150
2151
static void truncate_ts(AVStream *st, AVPacket *pkt){
2152
    int64_t pts_mask = (2LL << (st->pts_wrap_bits-1)) - 1;
2153 115329f1 Diego Biurrun
2154 e0c91bc2 Michael Niedermayer
//    if(pkt->dts < 0)
2155
//        pkt->dts= 0;  //this happens for low_delay=0 and b frames, FIXME, needs further invstigation about what we should do here
2156 115329f1 Diego Biurrun
2157 68a432cf Baptiste Coudurier
    if (pkt->pts != AV_NOPTS_VALUE)
2158 8533284d Andy Parkins
        pkt->pts &= pts_mask;
2159 68a432cf Baptiste Coudurier
    if (pkt->dts != AV_NOPTS_VALUE)
2160 8533284d Andy Parkins
        pkt->dts &= pts_mask;
2161 3c895fc0 Michael Niedermayer
}
2162
2163
int av_write_frame(AVFormatContext *s, AVPacket *pkt)
2164
{
2165 576ae256 Michael Niedermayer
    int ret;
2166
2167 5edea431 Michael Niedermayer
    ret=compute_pkt_fields2(s->streams[pkt->stream_index], pkt);
2168 494bbf58 Michael Niedermayer
    if(ret<0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
2169 5edea431 Michael Niedermayer
        return ret;
2170 115329f1 Diego Biurrun
2171 3c895fc0 Michael Niedermayer
    truncate_ts(s->streams[pkt->stream_index], pkt);
2172
2173 576ae256 Michael Niedermayer
    ret= s->oformat->write_packet(s, pkt);
2174
    if(!ret)
2175
        ret= url_ferror(&s->pb);
2176
    return ret;
2177 3c895fc0 Michael Niedermayer
}
2178
2179 f21c0b4c Baptiste Coudurier
int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush){
2180 fe2d6fe2 Michael Niedermayer
    AVPacketList *pktl, **next_point, *this_pktl;
2181
    int stream_count=0;
2182
    int streams[MAX_STREAMS];
2183
2184
    if(pkt){
2185
        AVStream *st= s->streams[ pkt->stream_index];
2186
2187 2577897d Michael Niedermayer
//        assert(pkt->destruct != av_destruct_packet); //FIXME
2188 fe2d6fe2 Michael Niedermayer
2189
        this_pktl = av_mallocz(sizeof(AVPacketList));
2190
        this_pktl->pkt= *pkt;
2191 2577897d Michael Niedermayer
        if(pkt->destruct == av_destruct_packet)
2192
            pkt->destruct= NULL; // non shared -> must keep original from being freed
2193
        else
2194
            av_dup_packet(&this_pktl->pkt);  //shared -> must dup
2195 fe2d6fe2 Michael Niedermayer
2196
        next_point = &s->packet_buffer;
2197
        while(*next_point){
2198
            AVStream *st2= s->streams[ (*next_point)->pkt.stream_index];
2199
            int64_t left=  st2->time_base.num * (int64_t)st ->time_base.den;
2200
            int64_t right= st ->time_base.num * (int64_t)st2->time_base.den;
2201
            if((*next_point)->pkt.dts * left > pkt->dts * right) //FIXME this can overflow
2202
                break;
2203
            next_point= &(*next_point)->next;
2204
        }
2205
        this_pktl->next= *next_point;
2206
        *next_point= this_pktl;
2207
    }
2208 115329f1 Diego Biurrun
2209 fe2d6fe2 Michael Niedermayer
    memset(streams, 0, sizeof(streams));
2210
    pktl= s->packet_buffer;
2211
    while(pktl){
2212 949b1a13 Steve L'Homme
//av_log(s, AV_LOG_DEBUG, "show st:%d dts:%"PRId64"\n", pktl->pkt.stream_index, pktl->pkt.dts);
2213 fe2d6fe2 Michael Niedermayer
        if(streams[ pktl->pkt.stream_index ] == 0)
2214
            stream_count++;
2215
        streams[ pktl->pkt.stream_index ]++;
2216
        pktl= pktl->next;
2217
    }
2218 115329f1 Diego Biurrun
2219 fe2d6fe2 Michael Niedermayer
    if(s->nb_streams == stream_count || (flush && stream_count)){
2220
        pktl= s->packet_buffer;
2221
        *out= pktl->pkt;
2222 115329f1 Diego Biurrun
2223
        s->packet_buffer= pktl->next;
2224 fe2d6fe2 Michael Niedermayer
        av_freep(&pktl);
2225
        return 1;
2226
    }else{
2227
        av_init_packet(out);
2228
        return 0;
2229
    }
2230
}
2231
2232
/**
2233
 * Interleaves a AVPacket correctly so it can be muxed.
2234
 * @param out the interleaved packet will be output here
2235
 * @param in the input packet
2236
 * @param flush 1 if no further packets are available as input and all
2237
 *              remaining packets should be output
2238 115329f1 Diego Biurrun
 * @return 1 if a packet was output, 0 if no packet could be output,
2239 fe2d6fe2 Michael Niedermayer
 *         < 0 if an error occured
2240
 */
2241
static int av_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *in, int flush){
2242
    if(s->oformat->interleave_packet)
2243
        return s->oformat->interleave_packet(s, out, in, flush);
2244
    else
2245
        return av_interleave_packet_per_dts(s, out, in, flush);
2246
}
2247
2248 3c895fc0 Michael Niedermayer
int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt){
2249
    AVStream *st= s->streams[ pkt->stream_index];
2250
2251 6f824977 Michael Niedermayer
    //FIXME/XXX/HACK drop zero sized packets
2252 01f4895c Michael Niedermayer
    if(st->codec->codec_type == CODEC_TYPE_AUDIO && pkt->size==0)
2253 6f824977 Michael Niedermayer
        return 0;
2254 3ce16b30 Michael Niedermayer
2255 949b1a13 Steve L'Homme
//av_log(NULL, AV_LOG_DEBUG, "av_interleaved_write_frame %d %"PRId64" %"PRId64"\n", pkt->size, pkt->dts, pkt->pts);
2256 494bbf58 Michael Niedermayer
    if(compute_pkt_fields2(st, pkt) < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
2257 3ce16b30 Michael Niedermayer
        return -1;
2258 115329f1 Diego Biurrun
2259 3c895fc0 Michael Niedermayer
    if(pkt->dts == AV_NOPTS_VALUE)
2260
        return -1;
2261
2262 fe2d6fe2 Michael Niedermayer
    for(;;){
2263
        AVPacket opkt;
2264
        int ret= av_interleave_packet(s, &opkt, pkt, 0);
2265
        if(ret<=0) //FIXME cleanup needed for ret<0 ?
2266
            return ret;
2267 115329f1 Diego Biurrun
2268 fe2d6fe2 Michael Niedermayer
        truncate_ts(s->streams[opkt.stream_index], &opkt);
2269
        ret= s->oformat->write_packet(s, &opkt);
2270 115329f1 Diego Biurrun
2271 fe2d6fe2 Michael Niedermayer
        av_free_packet(&opkt);
2272
        pkt= NULL;
2273 115329f1 Diego Biurrun
2274 3c895fc0 Michael Niedermayer
        if(ret<0)
2275
            return ret;
2276 576ae256 Michael Niedermayer
        if(url_ferror(&s->pb))
2277
            return url_ferror(&s->pb);
2278 3c895fc0 Michael Niedermayer
    }
2279 b9a281db Fabrice Bellard
}
2280
2281
int av_write_trailer(AVFormatContext *s)
2282
{
2283 c40a3a42 Michael Niedermayer
    int ret, i;
2284 115329f1 Diego Biurrun
2285 fe2d6fe2 Michael Niedermayer
    for(;;){
2286
        AVPacket pkt;
2287
        ret= av_interleave_packet(s, &pkt, NULL, 1);
2288
        if(ret<0) //FIXME cleanup needed for ret<0 ?
2289 c40a3a42 Michael Niedermayer
            goto fail;
2290 fe2d6fe2 Michael Niedermayer
        if(!ret)
2291
            break;
2292 115329f1 Diego Biurrun
2293 fe2d6fe2 Michael Niedermayer
        truncate_ts(s->streams[pkt.stream_index], &pkt);
2294
        ret= s->oformat->write_packet(s, &pkt);
2295 115329f1 Diego Biurrun
2296 fe2d6fe2 Michael Niedermayer
        av_free_packet(&pkt);
2297 115329f1 Diego Biurrun
2298 3c895fc0 Michael Niedermayer
        if(ret<0)
2299 c40a3a42 Michael Niedermayer
            goto fail;
2300 576ae256 Michael Niedermayer
        if(url_ferror(&s->pb))
2301
            goto fail;
2302 3c895fc0 Michael Niedermayer
    }
2303
2304 31e11451 Michael Niedermayer
    if(s->oformat->write_trailer)
2305
        ret = s->oformat->write_trailer(s);
2306 c40a3a42 Michael Niedermayer
fail:
2307 576ae256 Michael Niedermayer
    if(ret == 0)
2308
       ret=url_ferror(&s->pb);
2309 c40a3a42 Michael Niedermayer
    for(i=0;i<s->nb_streams;i++)
2310
        av_freep(&s->streams[i]->priv_data);
2311 b9a281db Fabrice Bellard
    av_freep(&s->priv_data);
2312
    return ret;
2313 de6d9b64 Fabrice Bellard
}
2314
2315
/* "user interface" functions */
2316
2317
void dump_format(AVFormatContext *ic,
2318 115329f1 Diego Biurrun
                 int index,
2319 de6d9b64 Fabrice Bellard
                 const char *url,
2320
                 int is_output)
2321
{
2322 b9a281db Fabrice Bellard
    int i, flags;
2323 de6d9b64 Fabrice Bellard
    char buf[256];
2324
2325 115329f1 Diego Biurrun
    av_log(NULL, AV_LOG_INFO, "%s #%d, %s, %s '%s':\n",
2326 de6d9b64 Fabrice Bellard
            is_output ? "Output" : "Input",
2327 115329f1 Diego Biurrun
            index,
2328
            is_output ? ic->oformat->name : ic->iformat->name,
2329 de6d9b64 Fabrice Bellard
            is_output ? "to" : "from", url);
2330 12f996ed Fabrice Bellard
    if (!is_output) {
2331 2143116d Michael Niedermayer
        av_log(NULL, AV_LOG_INFO, "  Duration: ");
2332 12f996ed Fabrice Bellard
        if (ic->duration != AV_NOPTS_VALUE) {
2333
            int hours, mins, secs, us;
2334
            secs = ic->duration / AV_TIME_BASE;
2335
            us = ic->duration % AV_TIME_BASE;
2336
            mins = secs / 60;
2337
            secs %= 60;
2338
            hours = mins / 60;
2339
            mins %= 60;
2340 115329f1 Diego Biurrun
            av_log(NULL, AV_LOG_INFO, "%02d:%02d:%02d.%01d", hours, mins, secs,
2341 12f996ed Fabrice Bellard
                   (10 * us) / AV_TIME_BASE);
2342
        } else {
2343 2143116d Michael Niedermayer
            av_log(NULL, AV_LOG_INFO, "N/A");
2344 12f996ed Fabrice Bellard
        }
2345 d0f3f159 Wolfram Gloger
        if (ic->start_time != AV_NOPTS_VALUE) {
2346
            int secs, us;
2347 2143116d Michael Niedermayer
            av_log(NULL, AV_LOG_INFO, ", start: ");
2348 d0f3f159 Wolfram Gloger
            secs = ic->start_time / AV_TIME_BASE;
2349
            us = ic->start_time % AV_TIME_BASE;
2350 2143116d Michael Niedermayer
            av_log(NULL, AV_LOG_INFO, "%d.%06d",
2351 d0f3f159 Wolfram Gloger
                   secs, (int)av_rescale(us, 1000000, AV_TIME_BASE));
2352
        }
2353 2143116d Michael Niedermayer
        av_log(NULL, AV_LOG_INFO, ", bitrate: ");
2354 12f996ed Fabrice Bellard
        if (ic->bit_rate) {
2355 2143116d Michael Niedermayer
            av_log(NULL, AV_LOG_INFO,"%d kb/s", ic->bit_rate / 1000);
2356 12f996ed Fabrice Bellard
        } else {
2357 2143116d Michael Niedermayer
            av_log(NULL, AV_LOG_INFO, "N/A");
2358 12f996ed Fabrice Bellard
        }
2359 2143116d Michael Niedermayer
        av_log(NULL, AV_LOG_INFO, "\n");
2360 12f996ed Fabrice Bellard
    }
2361 de6d9b64 Fabrice Bellard
    for(i=0;i<ic->nb_streams;i++) {
2362
        AVStream *st = ic->streams[i];
2363 21189011 Michael Niedermayer
        int g= ff_gcd(st->time_base.num, st->time_base.den);
2364 01f4895c Michael Niedermayer
        avcodec_string(buf, sizeof(buf), st->codec, is_output);
2365 2143116d Michael Niedermayer
        av_log(NULL, AV_LOG_INFO, "  Stream #%d.%d", index, i);
2366 b9a281db Fabrice Bellard
        /* the pid is an important information, so we display it */
2367
        /* XXX: add a generic system */
2368
        if (is_output)
2369
            flags = ic->oformat->flags;
2370
        else
2371
            flags = ic->iformat->flags;
2372
        if (flags & AVFMT_SHOW_IDS) {
2373 2143116d Michael Niedermayer
            av_log(NULL, AV_LOG_INFO, "[0x%x]", st->id);
2374 b9a281db Fabrice Bellard
        }
2375 c6ec28b1 Michael Niedermayer
        if (strlen(st->language) > 0) {
2376
            av_log(NULL, AV_LOG_INFO, "(%s)", st->language);
2377
        }
2378 21189011 Michael Niedermayer
        av_log(NULL, AV_LOG_DEBUG, ", %d/%d", st->time_base.num/g, st->time_base.den/g);
2379 47dd81c7 Baptiste Coudurier
        av_log(NULL, AV_LOG_INFO, ": %s", buf);
2380 21189011 Michael Niedermayer
        if(st->codec->codec_type == CODEC_TYPE_VIDEO){
2381 780eb1c9 Michael Niedermayer
            if(st->r_frame_rate.den && st->r_frame_rate.num)
2382
                av_log(NULL, AV_LOG_INFO, ", %5.2f fps(r)", av_q2d(st->r_frame_rate));
2383
/*            else if(st->time_base.den && st->time_base.num)
2384
                av_log(NULL, AV_LOG_INFO, ", %5.2f fps(m)", 1/av_q2d(st->time_base));*/
2385
            else
2386
                av_log(NULL, AV_LOG_INFO, ", %5.2f fps(c)", 1/av_q2d(st->codec->time_base));
2387 21189011 Michael Niedermayer
        }
2388 47dd81c7 Baptiste Coudurier
        av_log(NULL, AV_LOG_INFO, "\n");
2389 de6d9b64 Fabrice Bellard
    }
2390
}
2391
2392
typedef struct {
2393 445f1b83 Roman Shaposhnik
    const char *abv;
2394 de6d9b64 Fabrice Bellard
    int width, height;
2395 445f1b83 Roman Shaposhnik
    int frame_rate, frame_rate_base;
2396
} AbvEntry;
2397
2398
static AbvEntry frame_abvs[] = {
2399 ba2a8cb4 Roman Shaposhnik
    { "ntsc",      720, 480, 30000, 1001 },
2400
    { "pal",       720, 576,    25,    1 },
2401
    { "qntsc",     352, 240, 30000, 1001 }, /* VCD compliant ntsc */
2402
    { "qpal",      352, 288,    25,    1 }, /* VCD compliant pal */
2403 904736b5 Roman Shaposhnik
    { "sntsc",     640, 480, 30000, 1001 }, /* square pixel ntsc */
2404
    { "spal",      768, 576,    25,    1 }, /* square pixel pal */
2405 445f1b83 Roman Shaposhnik
    { "film",      352, 240,    24,    1 },
2406
    { "ntsc-film", 352, 240, 24000, 1001 },
2407
    { "sqcif",     128,  96,     0,    0 },
2408
    { "qcif",      176, 144,     0,    0 },
2409
    { "cif",       352, 288,     0,    0 },
2410
    { "4cif",      704, 576,     0,    0 },
2411 de6d9b64 Fabrice Bellard
};
2412 445f1b83 Roman Shaposhnik
2413 de6d9b64 Fabrice Bellard
int parse_image_size(int *width_ptr, int *height_ptr, const char *str)
2414
{
2415
    int i;
2416 445f1b83 Roman Shaposhnik
    int n = sizeof(frame_abvs) / sizeof(AbvEntry);
2417 de6d9b64 Fabrice Bellard
    const char *p;
2418
    int frame_width = 0, frame_height = 0;
2419
2420
    for(i=0;i<n;i++) {
2421 445f1b83 Roman Shaposhnik
        if (!strcmp(frame_abvs[i].abv, str)) {
2422
            frame_width = frame_abvs[i].width;
2423
            frame_height = frame_abvs[i].height;
2424 de6d9b64 Fabrice Bellard
            break;
2425
        }
2426
    }
2427
    if (i == n) {
2428
        p = str;
2429
        frame_width = strtol(p, (char **)&p, 10);
2430
        if (*p)
2431
            p++;
2432
        frame_height = strtol(p, (char **)&p, 10);
2433
    }
2434
    if (frame_width <= 0 || frame_height <= 0)
2435
        return -1;
2436
    *width_ptr = frame_width;
2437
    *height_ptr = frame_height;
2438
    return 0;
2439
}
2440
2441 445f1b83 Roman Shaposhnik
int parse_frame_rate(int *frame_rate, int *frame_rate_base, const char *arg)
2442
{
2443
    int i;
2444
    char* cp;
2445 115329f1 Diego Biurrun
2446 445f1b83 Roman Shaposhnik
    /* First, we check our abbreviation table */
2447
    for (i = 0; i < sizeof(frame_abvs)/sizeof(*frame_abvs); ++i)
2448
         if (!strcmp(frame_abvs[i].abv, arg)) {
2449 bb270c08 Diego Biurrun
             *frame_rate = frame_abvs[i].frame_rate;
2450
             *frame_rate_base = frame_abvs[i].frame_rate_base;
2451
             return 0;
2452
         }
2453 445f1b83 Roman Shaposhnik
2454
    /* Then, we try to parse it as fraction */
2455
    cp = strchr(arg, '/');
2456 88805317 Roine Gustafsson
    if (!cp)
2457
        cp = strchr(arg, ':');
2458 445f1b83 Roman Shaposhnik
    if (cp) {
2459
        char* cpp;
2460 bb270c08 Diego Biurrun
        *frame_rate = strtol(arg, &cpp, 10);
2461
        if (cpp != arg || cpp == cp)
2462
            *frame_rate_base = strtol(cp+1, &cpp, 10);
2463
        else
2464
           *frame_rate = 0;
2465 115329f1 Diego Biurrun
    }
2466 445f1b83 Roman Shaposhnik
    else {
2467
        /* Finally we give up and parse it as double */
2468 67dd33f9 Baptiste Coudurier
        AVRational time_base = av_d2q(strtod(arg, 0), DEFAULT_FRAME_RATE_BASE);
2469
        *frame_rate_base = time_base.den;
2470
        *frame_rate = time_base.num;
2471 445f1b83 Roman Shaposhnik
    }
2472
    if (!*frame_rate || !*frame_rate_base)
2473
        return -1;
2474
    else
2475
        return 0;
2476
}
2477
2478 ac44871c Gildas Bazin
#ifndef CONFIG_WINCE
2479 0c1a9eda Zdenek Kabelac
int64_t parse_date(const char *datestr, int duration)
2480 de6d9b64 Fabrice Bellard
{
2481
    const char *p;
2482 0c1a9eda Zdenek Kabelac
    int64_t t;
2483 2dbceb9f Philip Gladstone
    struct tm dt;
2484 c5510dd6 Philip Gladstone
    int i;
2485
    static const char *date_fmt[] = {
2486
        "%Y-%m-%d",
2487
        "%Y%m%d",
2488
    };
2489
    static const char *time_fmt[] = {
2490
        "%H:%M:%S",
2491
        "%H%M%S",
2492
    };
2493
    const char *q;
2494 916c80e9 Fabrice Bellard
    int is_utc, len;
2495 c5510dd6 Philip Gladstone
    char lastch;
2496 a6a92a9a Wolfram Gloger
    int negative = 0;
2497 6d8f985e Michael Niedermayer
2498
#undef time
2499 c5510dd6 Philip Gladstone
    time_t now = time(0);
2500
2501 916c80e9 Fabrice Bellard
    len = strlen(datestr);
2502
    if (len > 0)
2503
        lastch = datestr[len - 1];
2504
    else
2505
        lastch = '\0';
2506 c5510dd6 Philip Gladstone
    is_utc = (lastch == 'z' || lastch == 'Z');
2507 2dbceb9f Philip Gladstone
2508
    memset(&dt, 0, sizeof(dt));
2509 de6d9b64 Fabrice Bellard
2510
    p = datestr;
2511 916c80e9 Fabrice Bellard
    q = NULL;
2512 de6d9b64 Fabrice Bellard
    if (!duration) {
2513 c5510dd6 Philip Gladstone
        for (i = 0; i < sizeof(date_fmt) / sizeof(date_fmt[0]); i++) {
2514 f71869a4 Fabrice Bellard
            q = small_strptime(p, date_fmt[i], &dt);
2515 c5510dd6 Philip Gladstone
            if (q) {
2516
                break;
2517
            }
2518
        }
2519
2520
        if (!q) {
2521
            if (is_utc) {
2522
                dt = *gmtime(&now);
2523
            } else {
2524
                dt = *localtime(&now);
2525
            }
2526
            dt.tm_hour = dt.tm_min = dt.tm_sec = 0;
2527 de6d9b64 Fabrice Bellard
        } else {
2528 c5510dd6 Philip Gladstone
            p = q;
2529 de6d9b64 Fabrice Bellard
        }
2530 c5510dd6 Philip Gladstone
2531
        if (*p == 'T' || *p == 't' || *p == ' ')
2532
            p++;
2533
2534 916c80e9 Fabrice Bellard
        for (i = 0; i < sizeof(time_fmt) / sizeof(time_fmt[0]); i++) {
2535 f71869a4 Fabrice Bellard
            q = small_strptime(p, time_fmt[i], &dt);
2536 916c80e9 Fabrice Bellard
            if (q) {
2537
                break;
2538
            }
2539
        }
2540
    } else {
2541 bb270c08 Diego Biurrun
        if (p[0] == '-') {
2542
            negative = 1;
2543
            ++p;
2544
        }
2545 f71869a4 Fabrice Bellard
        q = small_strptime(p, time_fmt[0], &dt);
2546 916c80e9 Fabrice Bellard
        if (!q) {
2547
            dt.tm_sec = strtol(p, (char **)&q, 10);
2548
            dt.tm_min = 0;
2549
            dt.tm_hour = 0;
2550 c5510dd6 Philip Gladstone
        }
2551
    }
2552
2553
    /* Now we have all the fields that we can get */
2554
    if (!q) {
2555
        if (duration)
2556
            return 0;
2557
        else
2558 8da9266c Måns Rullgård
            return now * INT64_C(1000000);
2559 de6d9b64 Fabrice Bellard
    }
2560 2dbceb9f Philip Gladstone
2561
    if (duration) {
2562 c5510dd6 Philip Gladstone
        t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
2563 2dbceb9f Philip Gladstone
    } else {
2564 c5510dd6 Philip Gladstone
        dt.tm_isdst = -1;       /* unknown */
2565
        if (is_utc) {
2566
            t = mktimegm(&dt);
2567
        } else {
2568
            t = mktime(&dt);
2569
        }
2570 de6d9b64 Fabrice Bellard
    }
2571 2dbceb9f Philip Gladstone
2572 c5510dd6 Philip Gladstone
    t *= 1000000;
2573
2574
    if (*q == '.') {
2575 de6d9b64 Fabrice Bellard
        int val, n;
2576 c5510dd6 Philip Gladstone
        q++;
2577
        for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
2578 115329f1 Diego Biurrun
            if (!isdigit(*q))
2579 c5510dd6 Philip Gladstone
                break;
2580
            val += n * (*q - '0');
2581 de6d9b64 Fabrice Bellard
        }
2582
        t += val;
2583
    }
2584 a6a92a9a Wolfram Gloger
    return negative ? -t : t;
2585 de6d9b64 Fabrice Bellard
}
2586 ac44871c Gildas Bazin
#endif /* CONFIG_WINCE */
2587 de6d9b64 Fabrice Bellard
2588
int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
2589
{
2590
    const char *p;
2591
    char tag[128], *q;
2592
2593
    p = info;
2594
    if (*p == '?')
2595
        p++;
2596
    for(;;) {
2597
        q = tag;
2598
        while (*p != '\0' && *p != '=' && *p != '&') {
2599
            if ((q - tag) < sizeof(tag) - 1)
2600
                *q++ = *p;
2601
            p++;
2602
        }
2603
        *q = '\0';
2604
        q = arg;
2605
        if (*p == '=') {
2606
            p++;
2607
            while (*p != '&' && *p != '\0') {
2608 2dbceb9f Philip Gladstone
                if ((q - arg) < arg_size - 1) {
2609
                    if (*p == '+')
2610
                        *q++ = ' ';
2611
                    else
2612
                        *q++ = *p;
2613
                }
2614 de6d9b64 Fabrice Bellard
                p++;
2615
            }
2616
            *q = '\0';
2617
        }
2618 115329f1 Diego Biurrun
        if (!strcmp(tag, tag1))
2619 de6d9b64 Fabrice Bellard
            return 1;
2620
        if (*p != '&')
2621
            break;
2622 8d1335ea Philip Gladstone
        p++;
2623 de6d9b64 Fabrice Bellard
    }
2624
    return 0;
2625
}
2626
2627 5c07cf53 Michel Bardiaux
int av_get_frame_filename(char *buf, int buf_size,
2628
                          const char *path, int number)
2629 9150f42e Fabrice Bellard
{
2630
    const char *p;
2631 0bf92f79 Panagiotis Issaris
    char *q, buf1[20], c;
2632
    int nd, len, percentd_found;
2633 9150f42e Fabrice Bellard
2634
    q = buf;
2635
    p = path;
2636
    percentd_found = 0;
2637
    for(;;) {
2638
        c = *p++;
2639
        if (c == '\0')
2640
            break;
2641
        if (c == '%') {
2642 c9646fda Philip Gladstone
            do {
2643
                nd = 0;
2644
                while (isdigit(*p)) {
2645
                    nd = nd * 10 + *p++ - '0';
2646
                }
2647
                c = *p++;
2648
            } while (isdigit(c));
2649
2650 9150f42e Fabrice Bellard
            switch(c) {
2651
            case '%':
2652
                goto addchar;
2653
            case 'd':
2654
                if (percentd_found)
2655
                    goto fail;
2656
                percentd_found = 1;
2657
                snprintf(buf1, sizeof(buf1), "%0*d", nd, number);
2658
                len = strlen(buf1);
2659
                if ((q - buf + len) > buf_size - 1)
2660
                    goto fail;
2661
                memcpy(q, buf1, len);
2662
                q += len;
2663
                break;
2664
            default:
2665
                goto fail;
2666
            }
2667
        } else {
2668
        addchar:
2669
            if ((q - buf) < buf_size - 1)
2670
                *q++ = c;
2671
        }
2672
    }
2673
    if (!percentd_found)
2674
        goto fail;
2675
    *q = '\0';
2676
    return 0;
2677
 fail:
2678
    *q = '\0';
2679
    return -1;
2680
}
2681
2682 750f0e1f Panagiotis Issaris
static void hex_dump_internal(void *avcl, FILE *f, int level, uint8_t *buf, int size)
2683 b9a281db Fabrice Bellard
{
2684
    int len, i, j, c;
2685 750f0e1f Panagiotis Issaris
#define PRINT(...) do { if (!f) av_log(avcl, level, __VA_ARGS__); else fprintf(f, __VA_ARGS__); } while(0)
2686 b9a281db Fabrice Bellard
2687
    for(i=0;i<size;i+=16) {
2688
        len = size - i;
2689
        if (len > 16)
2690
            len = 16;
2691 750f0e1f Panagiotis Issaris
        PRINT("%08x ", i);
2692 b9a281db Fabrice Bellard
        for(j=0;j<16;j++) {
2693
            if (j < len)
2694 750f0e1f Panagiotis Issaris
                PRINT(" %02x", buf[i+j]);
2695 b9a281db Fabrice Bellard
            else
2696 750f0e1f Panagiotis Issaris
                PRINT("   ");
2697 b9a281db Fabrice Bellard
        }
2698 750f0e1f Panagiotis Issaris
        PRINT(" ");
2699 b9a281db Fabrice Bellard
        for(j=0;j<len;j++) {
2700
            c = buf[i+j];
2701
            if (c < ' ' || c > '~')
2702
                c = '.';
2703 750f0e1f Panagiotis Issaris
            PRINT("%c", c);
2704 b9a281db Fabrice Bellard
        }
2705 750f0e1f Panagiotis Issaris
        PRINT("\n");
2706 b9a281db Fabrice Bellard
    }
2707 750f0e1f Panagiotis Issaris
#undef PRINT
2708
}
2709
2710
void av_hex_dump(FILE *f, uint8_t *buf, int size)
2711
{
2712
    hex_dump_internal(NULL, f, 0, buf, size);
2713
}
2714
2715
void av_hex_dump_log(void *avcl, int level, uint8_t *buf, int size)
2716
{
2717
    hex_dump_internal(avcl, NULL, level, buf, size);
2718 b9a281db Fabrice Bellard
}
2719
2720 c0df9d75 Michael Niedermayer
 //FIXME needs to know the time_base
2721 750f0e1f Panagiotis Issaris
static void pkt_dump_internal(void *avcl, FILE *f, int level, AVPacket *pkt, int dump_payload)
2722 fb2758c8 Fabrice Bellard
{
2723 750f0e1f Panagiotis Issaris
#define PRINT(...) do { if (!f) av_log(avcl, level, __VA_ARGS__); else fprintf(f, __VA_ARGS__); } while(0)
2724
    PRINT("stream #%d:\n", pkt->stream_index);
2725
    PRINT("  keyframe=%d\n", ((pkt->flags & PKT_FLAG_KEY) != 0));
2726
    PRINT("  duration=%0.3f\n", (double)pkt->duration / AV_TIME_BASE);
2727 37353960 Fabrice Bellard
    /* DTS is _always_ valid after av_read_frame() */
2728 750f0e1f Panagiotis Issaris
    PRINT("  dts=");
2729 37353960 Fabrice Bellard
    if (pkt->dts == AV_NOPTS_VALUE)
2730 750f0e1f Panagiotis Issaris
        PRINT("N/A");
2731 37353960 Fabrice Bellard
    else
2732 750f0e1f Panagiotis Issaris
        PRINT("%0.3f", (double)pkt->dts / AV_TIME_BASE);
2733 fb2758c8 Fabrice Bellard
    /* PTS may be not known if B frames are present */
2734 750f0e1f Panagiotis Issaris
    PRINT("  pts=");
2735 fb2758c8 Fabrice Bellard
    if (pkt->pts == AV_NOPTS_VALUE)
2736 750f0e1f Panagiotis Issaris
        PRINT("N/A");
2737 fb2758c8 Fabrice Bellard
    else
2738 750f0e1f Panagiotis Issaris
        PRINT("%0.3f", (double)pkt->pts / AV_TIME_BASE);
2739
    PRINT("\n");
2740
    PRINT("  size=%d\n", pkt->size);
2741
#undef PRINT
2742 fb2758c8 Fabrice Bellard
    if (dump_payload)
2743
        av_hex_dump(f, pkt->data, pkt->size);
2744
}
2745
2746 750f0e1f Panagiotis Issaris
void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload)
2747
{
2748
    pkt_dump_internal(NULL, f, 0, pkt, dump_payload);
2749
}
2750
2751
void av_pkt_dump_log(void *avcl, int level, AVPacket *pkt, int dump_payload)
2752
{
2753
    pkt_dump_internal(avcl, NULL, level, pkt, dump_payload);
2754
}
2755
2756 a9a721da Fabrice Bellard
void url_split(char *proto, int proto_size,
2757 6ba5cbc6 Petr Doubek
               char *authorization, int authorization_size,
2758 a9a721da Fabrice Bellard
               char *hostname, int hostname_size,
2759
               int *port_ptr,
2760
               char *path, int path_size,
2761
               const char *url)
2762
{
2763
    const char *p;
2764
    char *q;
2765
    int port;
2766
2767
    port = -1;
2768
2769
    p = url;
2770
    q = proto;
2771
    while (*p != ':' && *p != '\0') {
2772
        if ((q - proto) < proto_size - 1)
2773
            *q++ = *p;
2774
        p++;
2775
    }