Browse code

avformat: split muxing functions from util.c

Luca Barbato authored on 2012/10/01 07:49:16
Showing 4 changed files
... ...
@@ -12,6 +12,7 @@ OBJS = allformats.o         \
12 12
        id3v1.o              \
13 13
        id3v2.o              \
14 14
        metadata.o           \
15
+       mux.o                \
15 16
        options.o            \
16 17
        os_support.o         \
17 18
        riff.o               \
... ...
@@ -345,4 +345,13 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt);
345 345
 int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
346 346
                                  AVPacket *pkt, int flush);
347 347
 
348
+/**
349
+ * Return the frame duration in seconds. Return 0 if not available.
350
+ */
351
+void ff_compute_frame_duration(int *pnum, int *pden, AVStream *st,
352
+                               AVCodecParserContext *pc, AVPacket *pkt);
353
+
354
+int ff_get_audio_frame_size(AVCodecContext *enc, int size, int mux);
355
+
356
+
348 357
 #endif /* AVFORMAT_INTERNAL_H */
349 358
new file mode 100644
... ...
@@ -0,0 +1,564 @@
0
+/*
1
+ * muxing functions for use within Libav
2
+ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
3
+ *
4
+ * This file is part of Libav.
5
+ *
6
+ * Libav is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * Libav is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with Libav; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+
21
+/* #define DEBUG */
22
+
23
+#include "avformat.h"
24
+#include "avio_internal.h"
25
+#include "internal.h"
26
+#include "libavcodec/internal.h"
27
+#include "libavcodec/bytestream.h"
28
+#include "libavutil/opt.h"
29
+#include "libavutil/dict.h"
30
+#include "libavutil/pixdesc.h"
31
+#include "metadata.h"
32
+#include "id3v2.h"
33
+#include "libavutil/avassert.h"
34
+#include "libavutil/avstring.h"
35
+#include "libavutil/mathematics.h"
36
+#include "libavutil/parseutils.h"
37
+#include "libavutil/time.h"
38
+#include "riff.h"
39
+#include "audiointerleave.h"
40
+#include "url.h"
41
+#include <stdarg.h>
42
+#if CONFIG_NETWORK
43
+#include "network.h"
44
+#endif
45
+
46
+#undef NDEBUG
47
+#include <assert.h>
48
+
49
+/**
50
+ * @file
51
+ * muxing functions for use within Libav
52
+ */
53
+
54
+/* fraction handling */
55
+
56
+/**
57
+ * f = val + (num / den) + 0.5.
58
+ *
59
+ * 'num' is normalized so that it is such as 0 <= num < den.
60
+ *
61
+ * @param f fractional number
62
+ * @param val integer value
63
+ * @param num must be >= 0
64
+ * @param den must be >= 1
65
+ */
66
+static void frac_init(AVFrac *f, int64_t val, int64_t num, int64_t den)
67
+{
68
+    num += (den >> 1);
69
+    if (num >= den) {
70
+        val += num / den;
71
+        num  = num % den;
72
+    }
73
+    f->val = val;
74
+    f->num = num;
75
+    f->den = den;
76
+}
77
+
78
+/**
79
+ * Fractional addition to f: f = f + (incr / f->den).
80
+ *
81
+ * @param f fractional number
82
+ * @param incr increment, can be positive or negative
83
+ */
84
+static void frac_add(AVFrac *f, int64_t incr)
85
+{
86
+    int64_t num, den;
87
+
88
+    num = f->num + incr;
89
+    den = f->den;
90
+    if (num < 0) {
91
+        f->val += num / den;
92
+        num     = num % den;
93
+        if (num < 0) {
94
+            num += den;
95
+            f->val--;
96
+        }
97
+    } else if (num >= den) {
98
+        f->val += num / den;
99
+        num     = num % den;
100
+    }
101
+    f->num = num;
102
+}
103
+
104
+static int validate_codec_tag(AVFormatContext *s, AVStream *st)
105
+{
106
+    const AVCodecTag *avctag;
107
+    int n;
108
+    enum AVCodecID id = AV_CODEC_ID_NONE;
109
+    unsigned int tag  = 0;
110
+
111
+    /**
112
+     * Check that tag + id is in the table
113
+     * If neither is in the table -> OK
114
+     * If tag is in the table with another id -> FAIL
115
+     * If id is in the table with another tag -> FAIL unless strict < normal
116
+     */
117
+    for (n = 0; s->oformat->codec_tag[n]; n++) {
118
+        avctag = s->oformat->codec_tag[n];
119
+        while (avctag->id != AV_CODEC_ID_NONE) {
120
+            if (avpriv_toupper4(avctag->tag) == avpriv_toupper4(st->codec->codec_tag)) {
121
+                id = avctag->id;
122
+                if (id == st->codec->codec_id)
123
+                    return 1;
124
+            }
125
+            if (avctag->id == st->codec->codec_id)
126
+                tag = avctag->tag;
127
+            avctag++;
128
+        }
129
+    }
130
+    if (id != AV_CODEC_ID_NONE)
131
+        return 0;
132
+    if (tag && (st->codec->strict_std_compliance >= FF_COMPLIANCE_NORMAL))
133
+        return 0;
134
+    return 1;
135
+}
136
+
137
+int avformat_write_header(AVFormatContext *s, AVDictionary **options)
138
+{
139
+    int ret = 0, i;
140
+    AVStream *st;
141
+    AVDictionary *tmp = NULL;
142
+
143
+    if (options)
144
+        av_dict_copy(&tmp, *options, 0);
145
+    if ((ret = av_opt_set_dict(s, &tmp)) < 0)
146
+        goto fail;
147
+
148
+    // some sanity checks
149
+    if (s->nb_streams == 0 && !(s->oformat->flags & AVFMT_NOSTREAMS)) {
150
+        av_log(s, AV_LOG_ERROR, "no streams\n");
151
+        ret = AVERROR(EINVAL);
152
+        goto fail;
153
+    }
154
+
155
+    for (i = 0; i < s->nb_streams; i++) {
156
+        st = s->streams[i];
157
+
158
+        switch (st->codec->codec_type) {
159
+        case AVMEDIA_TYPE_AUDIO:
160
+            if (st->codec->sample_rate <= 0) {
161
+                av_log(s, AV_LOG_ERROR, "sample rate not set\n");
162
+                ret = AVERROR(EINVAL);
163
+                goto fail;
164
+            }
165
+            if (!st->codec->block_align)
166
+                st->codec->block_align = st->codec->channels *
167
+                                         av_get_bits_per_sample(st->codec->codec_id) >> 3;
168
+            break;
169
+        case AVMEDIA_TYPE_VIDEO:
170
+            if (st->codec->time_base.num <= 0 || st->codec->time_base.den <= 0) { //FIXME audio too?
171
+                av_log(s, AV_LOG_ERROR, "time base not set\n");
172
+                ret = AVERROR(EINVAL);
173
+                goto fail;
174
+            }
175
+            if ((st->codec->width <= 0 || st->codec->height <= 0) && !(s->oformat->flags & AVFMT_NODIMENSIONS)) {
176
+                av_log(s, AV_LOG_ERROR, "dimensions not set\n");
177
+                ret = AVERROR(EINVAL);
178
+                goto fail;
179
+            }
180
+            if (av_cmp_q(st->sample_aspect_ratio, st->codec->sample_aspect_ratio)) {
181
+                av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between muxer "
182
+                                        "(%d/%d) and encoder layer (%d/%d)\n",
183
+                       st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
184
+                       st->codec->sample_aspect_ratio.num,
185
+                       st->codec->sample_aspect_ratio.den);
186
+                ret = AVERROR(EINVAL);
187
+                goto fail;
188
+            }
189
+            break;
190
+        }
191
+
192
+        if (s->oformat->codec_tag) {
193
+            if (st->codec->codec_tag && st->codec->codec_id == AV_CODEC_ID_RAWVIDEO && av_codec_get_tag(s->oformat->codec_tag, st->codec->codec_id) == 0 && !validate_codec_tag(s, st)) {
194
+                //the current rawvideo encoding system ends up setting the wrong codec_tag for avi, we override it here
195
+                st->codec->codec_tag = 0;
196
+            }
197
+            if (st->codec->codec_tag) {
198
+                if (!validate_codec_tag(s, st)) {
199
+                    char tagbuf[32];
200
+                    av_get_codec_tag_string(tagbuf, sizeof(tagbuf), st->codec->codec_tag);
201
+                    av_log(s, AV_LOG_ERROR,
202
+                           "Tag %s/0x%08x incompatible with output codec id '%d'\n",
203
+                           tagbuf, st->codec->codec_tag, st->codec->codec_id);
204
+                    ret = AVERROR_INVALIDDATA;
205
+                    goto fail;
206
+                }
207
+            } else
208
+                st->codec->codec_tag = av_codec_get_tag(s->oformat->codec_tag, st->codec->codec_id);
209
+        }
210
+
211
+        if (s->oformat->flags & AVFMT_GLOBALHEADER &&
212
+            !(st->codec->flags & CODEC_FLAG_GLOBAL_HEADER))
213
+            av_log(s, AV_LOG_WARNING, "Codec for stream %d does not use global headers but container format requires global headers\n", i);
214
+    }
215
+
216
+    if (!s->priv_data && s->oformat->priv_data_size > 0) {
217
+        s->priv_data = av_mallocz(s->oformat->priv_data_size);
218
+        if (!s->priv_data) {
219
+            ret = AVERROR(ENOMEM);
220
+            goto fail;
221
+        }
222
+        if (s->oformat->priv_class) {
223
+            *(const AVClass **)s->priv_data = s->oformat->priv_class;
224
+            av_opt_set_defaults(s->priv_data);
225
+            if ((ret = av_opt_set_dict(s->priv_data, &tmp)) < 0)
226
+                goto fail;
227
+        }
228
+    }
229
+
230
+    /* set muxer identification string */
231
+    if (s->nb_streams && !(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) {
232
+        av_dict_set(&s->metadata, "encoder", LIBAVFORMAT_IDENT, 0);
233
+    }
234
+
235
+    if (s->oformat->write_header) {
236
+        ret = s->oformat->write_header(s);
237
+        if (ret < 0)
238
+            goto fail;
239
+    }
240
+
241
+    /* init PTS generation */
242
+    for (i = 0; i < s->nb_streams; i++) {
243
+        int64_t den = AV_NOPTS_VALUE;
244
+        st = s->streams[i];
245
+
246
+        switch (st->codec->codec_type) {
247
+        case AVMEDIA_TYPE_AUDIO:
248
+            den = (int64_t)st->time_base.num * st->codec->sample_rate;
249
+            break;
250
+        case AVMEDIA_TYPE_VIDEO:
251
+            den = (int64_t)st->time_base.num * st->codec->time_base.den;
252
+            break;
253
+        default:
254
+            break;
255
+        }
256
+        if (den != AV_NOPTS_VALUE) {
257
+            if (den <= 0) {
258
+                ret = AVERROR_INVALIDDATA;
259
+                goto fail;
260
+            }
261
+            frac_init(&st->pts, 0, 0, den);
262
+        }
263
+    }
264
+
265
+    if (options) {
266
+        av_dict_free(options);
267
+        *options = tmp;
268
+    }
269
+    return 0;
270
+fail:
271
+    av_dict_free(&tmp);
272
+    return ret;
273
+}
274
+
275
+//FIXME merge with compute_pkt_fields
276
+static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt)
277
+{
278
+    int delay = FFMAX(st->codec->has_b_frames, !!st->codec->max_b_frames);
279
+    int num, den, frame_size, i;
280
+
281
+    av_dlog(s, "compute_pkt_fields2: pts:%" PRId64 " dts:%" PRId64 " cur_dts:%" PRId64 " b:%d size:%d st:%d\n",
282
+            pkt->pts, pkt->dts, st->cur_dts, delay, pkt->size, pkt->stream_index);
283
+
284
+/*    if(pkt->pts == AV_NOPTS_VALUE && pkt->dts == AV_NOPTS_VALUE)
285
+ *      return AVERROR(EINVAL);*/
286
+
287
+    /* duration field */
288
+    if (pkt->duration == 0) {
289
+        ff_compute_frame_duration(&num, &den, st, NULL, pkt);
290
+        if (den && num) {
291
+            pkt->duration = av_rescale(1, num * (int64_t)st->time_base.den * st->codec->ticks_per_frame, den * (int64_t)st->time_base.num);
292
+        }
293
+    }
294
+
295
+    if (pkt->pts == AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && delay == 0)
296
+        pkt->pts = pkt->dts;
297
+
298
+    //XXX/FIXME this is a temporary hack until all encoders output pts
299
+    if ((pkt->pts == 0 || pkt->pts == AV_NOPTS_VALUE) && pkt->dts == AV_NOPTS_VALUE && !delay) {
300
+        pkt->dts =
301
+//        pkt->pts= st->cur_dts;
302
+            pkt->pts = st->pts.val;
303
+    }
304
+
305
+    //calculate dts from pts
306
+    if (pkt->pts != AV_NOPTS_VALUE && pkt->dts == AV_NOPTS_VALUE && delay <= MAX_REORDER_DELAY) {
307
+        st->pts_buffer[0] = pkt->pts;
308
+        for (i = 1; i < delay + 1 && st->pts_buffer[i] == AV_NOPTS_VALUE; i++)
309
+            st->pts_buffer[i] = pkt->pts + (i - delay - 1) * pkt->duration;
310
+        for (i = 0; i<delay && st->pts_buffer[i] > st->pts_buffer[i + 1]; i++)
311
+            FFSWAP(int64_t, st->pts_buffer[i], st->pts_buffer[i + 1]);
312
+
313
+        pkt->dts = st->pts_buffer[0];
314
+    }
315
+
316
+    if (st->cur_dts && st->cur_dts != AV_NOPTS_VALUE &&
317
+        ((!(s->oformat->flags & AVFMT_TS_NONSTRICT) &&
318
+          st->cur_dts >= pkt->dts) || st->cur_dts > pkt->dts)) {
319
+        av_log(s, AV_LOG_ERROR,
320
+               "Application provided invalid, non monotonically increasing dts to muxer in stream %d: %" PRId64 " >= %" PRId64 "\n",
321
+               st->index, st->cur_dts, pkt->dts);
322
+        return AVERROR(EINVAL);
323
+    }
324
+    if (pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts < pkt->dts) {
325
+        av_log(s, AV_LOG_ERROR, "pts < dts in stream %d\n", st->index);
326
+        return AVERROR(EINVAL);
327
+    }
328
+
329
+    av_dlog(s, "av_write_frame: pts2:%"PRId64" dts2:%"PRId64"\n",
330
+            pkt->pts, pkt->dts);
331
+    st->cur_dts = pkt->dts;
332
+    st->pts.val = pkt->dts;
333
+
334
+    /* update pts */
335
+    switch (st->codec->codec_type) {
336
+    case AVMEDIA_TYPE_AUDIO:
337
+        frame_size = ff_get_audio_frame_size(st->codec, pkt->size, 1);
338
+
339
+        /* HACK/FIXME, we skip the initial 0 size packets as they are most
340
+         * likely equal to the encoder delay, but it would be better if we
341
+         * had the real timestamps from the encoder */
342
+        if (frame_size >= 0 && (pkt->size || st->pts.num != st->pts.den >> 1 || st->pts.val)) {
343
+            frac_add(&st->pts, (int64_t)st->time_base.den * frame_size);
344
+        }
345
+        break;
346
+    case AVMEDIA_TYPE_VIDEO:
347
+        frac_add(&st->pts, (int64_t)st->time_base.den * st->codec->time_base.num);
348
+        break;
349
+    default:
350
+        break;
351
+    }
352
+    return 0;
353
+}
354
+
355
+int av_write_frame(AVFormatContext *s, AVPacket *pkt)
356
+{
357
+    int ret;
358
+
359
+    if (!pkt) {
360
+        if (s->oformat->flags & AVFMT_ALLOW_FLUSH)
361
+            return s->oformat->write_packet(s, pkt);
362
+        return 1;
363
+    }
364
+
365
+    ret = compute_pkt_fields2(s, s->streams[pkt->stream_index], pkt);
366
+
367
+    if (ret < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
368
+        return ret;
369
+
370
+    ret = s->oformat->write_packet(s, pkt);
371
+
372
+    if (ret >= 0)
373
+        s->streams[pkt->stream_index]->nb_frames++;
374
+    return ret;
375
+}
376
+
377
+void ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt,
378
+                              int (*compare)(AVFormatContext *, AVPacket *, AVPacket *))
379
+{
380
+    AVPacketList **next_point, *this_pktl;
381
+
382
+    this_pktl      = av_mallocz(sizeof(AVPacketList));
383
+    this_pktl->pkt = *pkt;
384
+    pkt->destruct  = NULL;           // do not free original but only the copy
385
+    av_dup_packet(&this_pktl->pkt);  // duplicate the packet if it uses non-alloced memory
386
+
387
+    if (s->streams[pkt->stream_index]->last_in_packet_buffer) {
388
+        next_point = &(s->streams[pkt->stream_index]->last_in_packet_buffer->next);
389
+    } else
390
+        next_point = &s->packet_buffer;
391
+
392
+    if (*next_point) {
393
+        if (compare(s, &s->packet_buffer_end->pkt, pkt)) {
394
+            while (!compare(s, &(*next_point)->pkt, pkt))
395
+                next_point = &(*next_point)->next;
396
+            goto next_non_null;
397
+        } else {
398
+            next_point = &(s->packet_buffer_end->next);
399
+        }
400
+    }
401
+    assert(!*next_point);
402
+
403
+    s->packet_buffer_end = this_pktl;
404
+next_non_null:
405
+
406
+    this_pktl->next = *next_point;
407
+
408
+    s->streams[pkt->stream_index]->last_in_packet_buffer =
409
+        *next_point                                      = this_pktl;
410
+}
411
+
412
+static int ff_interleave_compare_dts(AVFormatContext *s, AVPacket *next, AVPacket *pkt)
413
+{
414
+    AVStream *st  = s->streams[pkt->stream_index];
415
+    AVStream *st2 = s->streams[next->stream_index];
416
+    int comp      = av_compare_ts(next->dts, st2->time_base, pkt->dts,
417
+                                  st->time_base);
418
+
419
+    if (comp == 0)
420
+        return pkt->stream_index < next->stream_index;
421
+    return comp > 0;
422
+}
423
+
424
+int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
425
+                                 AVPacket *pkt, int flush)
426
+{
427
+    AVPacketList *pktl;
428
+    int stream_count = 0;
429
+    int i;
430
+
431
+    if (pkt) {
432
+        ff_interleave_add_packet(s, pkt, ff_interleave_compare_dts);
433
+    }
434
+
435
+    for (i = 0; i < s->nb_streams; i++)
436
+        stream_count += !!s->streams[i]->last_in_packet_buffer;
437
+
438
+    if (stream_count && (s->nb_streams == stream_count || flush)) {
439
+        pktl = s->packet_buffer;
440
+        *out = pktl->pkt;
441
+
442
+        s->packet_buffer = pktl->next;
443
+        if (!s->packet_buffer)
444
+            s->packet_buffer_end = NULL;
445
+
446
+        if (s->streams[out->stream_index]->last_in_packet_buffer == pktl)
447
+            s->streams[out->stream_index]->last_in_packet_buffer = NULL;
448
+        av_freep(&pktl);
449
+        return 1;
450
+    } else {
451
+        av_init_packet(out);
452
+        return 0;
453
+    }
454
+}
455
+
456
+#if FF_API_INTERLEAVE_PACKET
457
+int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
458
+                                 AVPacket *pkt, int flush)
459
+{
460
+    return ff_interleave_packet_per_dts(s, out, pkt, flush);
461
+}
462
+
463
+#endif
464
+
465
+/**
466
+ * Interleave an AVPacket correctly so it can be muxed.
467
+ * @param out the interleaved packet will be output here
468
+ * @param in the input packet
469
+ * @param flush 1 if no further packets are available as input and all
470
+ *              remaining packets should be output
471
+ * @return 1 if a packet was output, 0 if no packet could be output,
472
+ *         < 0 if an error occurred
473
+ */
474
+static int interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *in, int flush)
475
+{
476
+    if (s->oformat->interleave_packet) {
477
+        int ret = s->oformat->interleave_packet(s, out, in, flush);
478
+        if (in)
479
+            av_free_packet(in);
480
+        return ret;
481
+    } else
482
+        return ff_interleave_packet_per_dts(s, out, in, flush);
483
+}
484
+
485
+int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt)
486
+{
487
+    int ret, flush = 0;
488
+
489
+    if (pkt) {
490
+        AVStream *st = s->streams[pkt->stream_index];
491
+
492
+        //FIXME/XXX/HACK drop zero sized packets
493
+        if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && pkt->size == 0)
494
+            return 0;
495
+
496
+        av_dlog(s, "av_interleaved_write_frame size:%d dts:%" PRId64 " pts:%" PRId64 "\n",
497
+                pkt->size, pkt->dts, pkt->pts);
498
+        if ((ret = compute_pkt_fields2(s, st, pkt)) < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
499
+            return ret;
500
+
501
+        if (pkt->dts == AV_NOPTS_VALUE && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
502
+            return AVERROR(EINVAL);
503
+    } else {
504
+        av_dlog(s, "av_interleaved_write_frame FLUSH\n");
505
+        flush = 1;
506
+    }
507
+
508
+    for (;; ) {
509
+        AVPacket opkt;
510
+        int ret = interleave_packet(s, &opkt, pkt, flush);
511
+        if (ret <= 0) //FIXME cleanup needed for ret<0 ?
512
+            return ret;
513
+
514
+        ret = s->oformat->write_packet(s, &opkt);
515
+        if (ret >= 0)
516
+            s->streams[opkt.stream_index]->nb_frames++;
517
+
518
+        av_free_packet(&opkt);
519
+        pkt = NULL;
520
+
521
+        if (ret < 0)
522
+            return ret;
523
+    }
524
+}
525
+
526
+int av_write_trailer(AVFormatContext *s)
527
+{
528
+    int ret, i;
529
+
530
+    for (;; ) {
531
+        AVPacket pkt;
532
+        ret = interleave_packet(s, &pkt, NULL, 1);
533
+        if (ret < 0) //FIXME cleanup needed for ret<0 ?
534
+            goto fail;
535
+        if (!ret)
536
+            break;
537
+
538
+        ret = s->oformat->write_packet(s, &pkt);
539
+        if (ret >= 0)
540
+            s->streams[pkt.stream_index]->nb_frames++;
541
+
542
+        av_free_packet(&pkt);
543
+
544
+        if (ret < 0)
545
+            goto fail;
546
+    }
547
+
548
+    if (s->oformat->write_trailer)
549
+        ret = s->oformat->write_trailer(s);
550
+
551
+    if (!(s->oformat->flags & AVFMT_NOFILE))
552
+        avio_flush(s->pb);
553
+
554
+fail:
555
+    for (i = 0; i < s->nb_streams; i++) {
556
+        av_freep(&s->streams[i]->priv_data);
557
+        av_freep(&s->streams[i]->index_entries);
558
+    }
559
+    if (s->oformat->priv_class)
560
+        av_opt_free(s->priv_data);
561
+    av_freep(&s->priv_data);
562
+    return ret;
563
+}
... ...
@@ -68,56 +68,6 @@ const char *avformat_license(void)
68 68
     return LICENSE_PREFIX LIBAV_LICENSE + sizeof(LICENSE_PREFIX) - 1;
69 69
 }
70 70
 
71
-/* fraction handling */
72
-
73
-/**
74
- * f = val + (num / den) + 0.5.
75
- *
76
- * 'num' is normalized so that it is such as 0 <= num < den.
77
- *
78
- * @param f fractional number
79
- * @param val integer value
80
- * @param num must be >= 0
81
- * @param den must be >= 1
82
- */
83
-static void frac_init(AVFrac *f, int64_t val, int64_t num, int64_t den)
84
-{
85
-    num += (den >> 1);
86
-    if (num >= den) {
87
-        val += num / den;
88
-        num = num % den;
89
-    }
90
-    f->val = val;
91
-    f->num = num;
92
-    f->den = den;
93
-}
94
-
95
-/**
96
- * Fractional addition to f: f = f + (incr / f->den).
97
- *
98
- * @param f fractional number
99
- * @param incr increment, can be positive or negative
100
- */
101
-static void frac_add(AVFrac *f, int64_t incr)
102
-{
103
-    int64_t num, den;
104
-
105
-    num = f->num + incr;
106
-    den = f->den;
107
-    if (num < 0) {
108
-        f->val += num / den;
109
-        num = num % den;
110
-        if (num < 0) {
111
-            num += den;
112
-            f->val--;
113
-        }
114
-    } else if (num >= den) {
115
-        f->val += num / den;
116
-        num = num % den;
117
-    }
118
-    f->num = num;
119
-}
120
-
121 71
 /** head of registered input format linked list */
122 72
 static AVInputFormat *first_iformat = NULL;
123 73
 /** head of registered output format linked list */
... ...
@@ -734,7 +684,7 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt)
734 734
 /**
735 735
  * Get the number of samples of an audio frame. Return -1 on error.
736 736
  */
737
-static int get_audio_frame_size(AVCodecContext *enc, int size, int mux)
737
+int ff_get_audio_frame_size(AVCodecContext *enc, int size, int mux)
738 738
 {
739 739
     int frame_size;
740 740
 
... ...
@@ -756,8 +706,8 @@ static int get_audio_frame_size(AVCodecContext *enc, int size, int mux)
756 756
 /**
757 757
  * Return the frame duration in seconds. Return 0 if not available.
758 758
  */
759
-static void compute_frame_duration(int *pnum, int *pden, AVStream *st,
760
-                                   AVCodecParserContext *pc, AVPacket *pkt)
759
+void ff_compute_frame_duration(int *pnum, int *pden, AVStream *st,
760
+                               AVCodecParserContext *pc, AVPacket *pkt)
761 761
 {
762 762
     int frame_size;
763 763
 
... ...
@@ -785,7 +735,7 @@ static void compute_frame_duration(int *pnum, int *pden, AVStream *st,
785 785
         }
786 786
         break;
787 787
     case AVMEDIA_TYPE_AUDIO:
788
-        frame_size = get_audio_frame_size(st->codec, pkt->size, 0);
788
+        frame_size = ff_get_audio_frame_size(st->codec, pkt->size, 0);
789 789
         if (frame_size <= 0 || st->codec->sample_rate <= 0)
790 790
             break;
791 791
         *pnum = frame_size;
... ...
@@ -909,7 +859,7 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
909 909
     }
910 910
 
911 911
     if (pkt->duration == 0 && st->codec->codec_type != AVMEDIA_TYPE_AUDIO) {
912
-        compute_frame_duration(&num, &den, st, pc, pkt);
912
+        ff_compute_frame_duration(&num, &den, st, pc, pkt);
913 913
         if (den && num) {
914 914
             pkt->duration = av_rescale_rnd(1, num * (int64_t)st->time_base.den, den * (int64_t)st->time_base.num, AV_ROUND_DOWN);
915 915
 
... ...
@@ -984,7 +934,7 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
984 984
                    st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
985 985
             int duration = pkt->duration;
986 986
             if (!duration && st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
987
-                compute_frame_duration(&num, &den, st, pc, pkt);
987
+                ff_compute_frame_duration(&num, &den, st, pc, pkt);
988 988
                 if (den && num) {
989 989
                     duration = av_rescale_rnd(1, num * (int64_t)st->time_base.den,
990 990
                                                  den * (int64_t)st->time_base.num,
... ...
@@ -2846,467 +2796,6 @@ AVChapter *avpriv_new_chapter(AVFormatContext *s, int id, AVRational time_base,
2846 2846
     return chapter;
2847 2847
 }
2848 2848
 
2849
-/************************************************************/
2850
-/* output media file */
2851
-
2852
-static int validate_codec_tag(AVFormatContext *s, AVStream *st)
2853
-{
2854
-    const AVCodecTag *avctag;
2855
-    int n;
2856
-    enum AVCodecID id = AV_CODEC_ID_NONE;
2857
-    unsigned int tag = 0;
2858
-
2859
-    /**
2860
-     * Check that tag + id is in the table
2861
-     * If neither is in the table -> OK
2862
-     * If tag is in the table with another id -> FAIL
2863
-     * If id is in the table with another tag -> FAIL unless strict < normal
2864
-     */
2865
-    for (n = 0; s->oformat->codec_tag[n]; n++) {
2866
-        avctag = s->oformat->codec_tag[n];
2867
-        while (avctag->id != AV_CODEC_ID_NONE) {
2868
-            if (avpriv_toupper4(avctag->tag) == avpriv_toupper4(st->codec->codec_tag)) {
2869
-                id = avctag->id;
2870
-                if (id == st->codec->codec_id)
2871
-                    return 1;
2872
-            }
2873
-            if (avctag->id == st->codec->codec_id)
2874
-                tag = avctag->tag;
2875
-            avctag++;
2876
-        }
2877
-    }
2878
-    if (id != AV_CODEC_ID_NONE)
2879
-        return 0;
2880
-    if (tag && (st->codec->strict_std_compliance >= FF_COMPLIANCE_NORMAL))
2881
-        return 0;
2882
-    return 1;
2883
-}
2884
-
2885
-int avformat_write_header(AVFormatContext *s, AVDictionary **options)
2886
-{
2887
-    int ret = 0, i;
2888
-    AVStream *st;
2889
-    AVDictionary *tmp = NULL;
2890
-
2891
-    if (options)
2892
-        av_dict_copy(&tmp, *options, 0);
2893
-    if ((ret = av_opt_set_dict(s, &tmp)) < 0)
2894
-        goto fail;
2895
-
2896
-    // some sanity checks
2897
-    if (s->nb_streams == 0 && !(s->oformat->flags & AVFMT_NOSTREAMS)) {
2898
-        av_log(s, AV_LOG_ERROR, "no streams\n");
2899
-        ret = AVERROR(EINVAL);
2900
-        goto fail;
2901
-    }
2902
-
2903
-    for(i=0;i<s->nb_streams;i++) {
2904
-        st = s->streams[i];
2905
-
2906
-        switch (st->codec->codec_type) {
2907
-        case AVMEDIA_TYPE_AUDIO:
2908
-            if(st->codec->sample_rate<=0){
2909
-                av_log(s, AV_LOG_ERROR, "sample rate not set\n");
2910
-                ret = AVERROR(EINVAL);
2911
-                goto fail;
2912
-            }
2913
-            if(!st->codec->block_align)
2914
-                st->codec->block_align = st->codec->channels *
2915
-                    av_get_bits_per_sample(st->codec->codec_id) >> 3;
2916
-            break;
2917
-        case AVMEDIA_TYPE_VIDEO:
2918
-            if(st->codec->time_base.num<=0 || st->codec->time_base.den<=0){ //FIXME audio too?
2919
-                av_log(s, AV_LOG_ERROR, "time base not set\n");
2920
-                ret = AVERROR(EINVAL);
2921
-                goto fail;
2922
-            }
2923
-            if((st->codec->width<=0 || st->codec->height<=0) && !(s->oformat->flags & AVFMT_NODIMENSIONS)){
2924
-                av_log(s, AV_LOG_ERROR, "dimensions not set\n");
2925
-                ret = AVERROR(EINVAL);
2926
-                goto fail;
2927
-            }
2928
-            if(av_cmp_q(st->sample_aspect_ratio, st->codec->sample_aspect_ratio)){
2929
-                av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between muxer "
2930
-                       "(%d/%d) and encoder layer (%d/%d)\n",
2931
-                       st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
2932
-                       st->codec->sample_aspect_ratio.num,
2933
-                       st->codec->sample_aspect_ratio.den);
2934
-                ret = AVERROR(EINVAL);
2935
-                goto fail;
2936
-            }
2937
-            break;
2938
-        }
2939
-
2940
-        if(s->oformat->codec_tag){
2941
-            if(st->codec->codec_tag && st->codec->codec_id == AV_CODEC_ID_RAWVIDEO && av_codec_get_tag(s->oformat->codec_tag, st->codec->codec_id) == 0 && !validate_codec_tag(s, st)){
2942
-                //the current rawvideo encoding system ends up setting the wrong codec_tag for avi, we override it here
2943
-                st->codec->codec_tag= 0;
2944
-            }
2945
-            if(st->codec->codec_tag){
2946
-                if (!validate_codec_tag(s, st)) {
2947
-                    char tagbuf[32];
2948
-                    av_get_codec_tag_string(tagbuf, sizeof(tagbuf), st->codec->codec_tag);
2949
-                    av_log(s, AV_LOG_ERROR,
2950
-                           "Tag %s/0x%08x incompatible with output codec id '%d'\n",
2951
-                           tagbuf, st->codec->codec_tag, st->codec->codec_id);
2952
-                    ret = AVERROR_INVALIDDATA;
2953
-                    goto fail;
2954
-                }
2955
-            }else
2956
-                st->codec->codec_tag= av_codec_get_tag(s->oformat->codec_tag, st->codec->codec_id);
2957
-        }
2958
-
2959
-        if(s->oformat->flags & AVFMT_GLOBALHEADER &&
2960
-            !(st->codec->flags & CODEC_FLAG_GLOBAL_HEADER))
2961
-          av_log(s, AV_LOG_WARNING, "Codec for stream %d does not use global headers but container format requires global headers\n", i);
2962
-    }
2963
-
2964
-    if (!s->priv_data && s->oformat->priv_data_size > 0) {
2965
-        s->priv_data = av_mallocz(s->oformat->priv_data_size);
2966
-        if (!s->priv_data) {
2967
-            ret = AVERROR(ENOMEM);
2968
-            goto fail;
2969
-        }
2970
-        if (s->oformat->priv_class) {
2971
-            *(const AVClass**)s->priv_data= s->oformat->priv_class;
2972
-            av_opt_set_defaults(s->priv_data);
2973
-            if ((ret = av_opt_set_dict(s->priv_data, &tmp)) < 0)
2974
-                goto fail;
2975
-        }
2976
-    }
2977
-
2978
-    /* set muxer identification string */
2979
-    if (s->nb_streams && !(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) {
2980
-        av_dict_set(&s->metadata, "encoder", LIBAVFORMAT_IDENT, 0);
2981
-    }
2982
-
2983
-    if(s->oformat->write_header){
2984
-        ret = s->oformat->write_header(s);
2985
-        if (ret < 0)
2986
-            goto fail;
2987
-    }
2988
-
2989
-    /* init PTS generation */
2990
-    for(i=0;i<s->nb_streams;i++) {
2991
-        int64_t den = AV_NOPTS_VALUE;
2992
-        st = s->streams[i];
2993
-
2994
-        switch (st->codec->codec_type) {
2995
-        case AVMEDIA_TYPE_AUDIO:
2996
-            den = (int64_t)st->time_base.num * st->codec->sample_rate;
2997
-            break;
2998
-        case AVMEDIA_TYPE_VIDEO:
2999
-            den = (int64_t)st->time_base.num * st->codec->time_base.den;
3000
-            break;
3001
-        default:
3002
-            break;
3003
-        }
3004
-        if (den != AV_NOPTS_VALUE) {
3005
-            if (den <= 0) {
3006
-                ret = AVERROR_INVALIDDATA;
3007
-                goto fail;
3008
-            }
3009
-            frac_init(&st->pts, 0, 0, den);
3010
-        }
3011
-    }
3012
-
3013
-    if (options) {
3014
-        av_dict_free(options);
3015
-        *options = tmp;
3016
-    }
3017
-    return 0;
3018
-fail:
3019
-    av_dict_free(&tmp);
3020
-    return ret;
3021
-}
3022
-
3023
-//FIXME merge with compute_pkt_fields
3024
-static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt){
3025
-    int delay = FFMAX(st->codec->has_b_frames, !!st->codec->max_b_frames);
3026
-    int num, den, frame_size, i;
3027
-
3028
-    av_dlog(s, "compute_pkt_fields2: pts:%"PRId64" dts:%"PRId64" cur_dts:%"PRId64" b:%d size:%d st:%d\n",
3029
-            pkt->pts, pkt->dts, st->cur_dts, delay, pkt->size, pkt->stream_index);
3030
-
3031
-/*    if(pkt->pts == AV_NOPTS_VALUE && pkt->dts == AV_NOPTS_VALUE)
3032
-        return AVERROR(EINVAL);*/
3033
-
3034
-    /* duration field */
3035
-    if (pkt->duration == 0) {
3036
-        compute_frame_duration(&num, &den, st, NULL, pkt);
3037
-        if (den && num) {
3038
-            pkt->duration = av_rescale(1, num * (int64_t)st->time_base.den * st->codec->ticks_per_frame, den * (int64_t)st->time_base.num);
3039
-        }
3040
-    }
3041
-
3042
-    if(pkt->pts == AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && delay==0)
3043
-        pkt->pts= pkt->dts;
3044
-
3045
-    //XXX/FIXME this is a temporary hack until all encoders output pts
3046
-    if((pkt->pts == 0 || pkt->pts == AV_NOPTS_VALUE) && pkt->dts == AV_NOPTS_VALUE && !delay){
3047
-        pkt->dts=
3048
-//        pkt->pts= st->cur_dts;
3049
-        pkt->pts= st->pts.val;
3050
-    }
3051
-
3052
-    //calculate dts from pts
3053
-    if(pkt->pts != AV_NOPTS_VALUE && pkt->dts == AV_NOPTS_VALUE && delay <= MAX_REORDER_DELAY){
3054
-        st->pts_buffer[0]= pkt->pts;
3055
-        for(i=1; i<delay+1 && st->pts_buffer[i] == AV_NOPTS_VALUE; i++)
3056
-            st->pts_buffer[i]= pkt->pts + (i-delay-1) * pkt->duration;
3057
-        for(i=0; i<delay && st->pts_buffer[i] > st->pts_buffer[i+1]; i++)
3058
-            FFSWAP(int64_t, st->pts_buffer[i], st->pts_buffer[i+1]);
3059
-
3060
-        pkt->dts= st->pts_buffer[0];
3061
-    }
3062
-
3063
-    if (st->cur_dts && st->cur_dts != AV_NOPTS_VALUE &&
3064
-        ((!(s->oformat->flags & AVFMT_TS_NONSTRICT) &&
3065
-          st->cur_dts >= pkt->dts) || st->cur_dts > pkt->dts)) {
3066
-        av_log(s, AV_LOG_ERROR,
3067
-               "Application provided invalid, non monotonically increasing dts to muxer in stream %d: %"PRId64" >= %"PRId64"\n",
3068
-               st->index, st->cur_dts, pkt->dts);
3069
-        return AVERROR(EINVAL);
3070
-    }
3071
-    if(pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts < pkt->dts){
3072
-        av_log(s, AV_LOG_ERROR, "pts < dts in stream %d\n", st->index);
3073
-        return AVERROR(EINVAL);
3074
-    }
3075
-
3076
-    av_dlog(s, "av_write_frame: pts2:%"PRId64" dts2:%"PRId64"\n",
3077
-            pkt->pts, pkt->dts);
3078
-    st->cur_dts= pkt->dts;
3079
-    st->pts.val= pkt->dts;
3080
-
3081
-    /* update pts */
3082
-    switch (st->codec->codec_type) {
3083
-    case AVMEDIA_TYPE_AUDIO:
3084
-        frame_size = get_audio_frame_size(st->codec, pkt->size, 1);
3085
-
3086
-        /* HACK/FIXME, we skip the initial 0 size packets as they are most
3087
-           likely equal to the encoder delay, but it would be better if we
3088
-           had the real timestamps from the encoder */
3089
-        if (frame_size >= 0 && (pkt->size || st->pts.num!=st->pts.den>>1 || st->pts.val)) {
3090
-            frac_add(&st->pts, (int64_t)st->time_base.den * frame_size);
3091
-        }
3092
-        break;
3093
-    case AVMEDIA_TYPE_VIDEO:
3094
-        frac_add(&st->pts, (int64_t)st->time_base.den * st->codec->time_base.num);
3095
-        break;
3096
-    default:
3097
-        break;
3098
-    }
3099
-    return 0;
3100
-}
3101
-
3102
-int av_write_frame(AVFormatContext *s, AVPacket *pkt)
3103
-{
3104
-    int ret;
3105
-
3106
-    if (!pkt) {
3107
-        if (s->oformat->flags & AVFMT_ALLOW_FLUSH)
3108
-            return s->oformat->write_packet(s, pkt);
3109
-        return 1;
3110
-    }
3111
-
3112
-    ret = compute_pkt_fields2(s, s->streams[pkt->stream_index], pkt);
3113
-
3114
-    if(ret<0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
3115
-        return ret;
3116
-
3117
-    ret= s->oformat->write_packet(s, pkt);
3118
-
3119
-    if (ret >= 0)
3120
-        s->streams[pkt->stream_index]->nb_frames++;
3121
-    return ret;
3122
-}
3123
-
3124
-void ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt,
3125
-                              int (*compare)(AVFormatContext *, AVPacket *, AVPacket *))
3126
-{
3127
-    AVPacketList **next_point, *this_pktl;
3128
-
3129
-    this_pktl = av_mallocz(sizeof(AVPacketList));
3130
-    this_pktl->pkt= *pkt;
3131
-    pkt->destruct= NULL;             // do not free original but only the copy
3132
-    av_dup_packet(&this_pktl->pkt);  // duplicate the packet if it uses non-alloced memory
3133
-
3134
-    if(s->streams[pkt->stream_index]->last_in_packet_buffer){
3135
-        next_point = &(s->streams[pkt->stream_index]->last_in_packet_buffer->next);
3136
-    }else
3137
-        next_point = &s->packet_buffer;
3138
-
3139
-    if(*next_point){
3140
-        if(compare(s, &s->packet_buffer_end->pkt, pkt)){
3141
-            while(!compare(s, &(*next_point)->pkt, pkt)){
3142
-                next_point= &(*next_point)->next;
3143
-            }
3144
-            goto next_non_null;
3145
-        }else{
3146
-            next_point = &(s->packet_buffer_end->next);
3147
-        }
3148
-    }
3149
-    assert(!*next_point);
3150
-
3151
-    s->packet_buffer_end= this_pktl;
3152
-next_non_null:
3153
-
3154
-    this_pktl->next= *next_point;
3155
-
3156
-    s->streams[pkt->stream_index]->last_in_packet_buffer=
3157
-    *next_point= this_pktl;
3158
-}
3159
-
3160
-static int ff_interleave_compare_dts(AVFormatContext *s, AVPacket *next, AVPacket *pkt)
3161
-{
3162
-    AVStream *st = s->streams[ pkt ->stream_index];
3163
-    AVStream *st2= s->streams[ next->stream_index];
3164
-    int comp = av_compare_ts(next->dts, st2->time_base, pkt->dts,
3165
-                             st->time_base);
3166
-
3167
-    if (comp == 0)
3168
-        return pkt->stream_index < next->stream_index;
3169
-    return comp > 0;
3170
-}
3171
-
3172
-int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
3173
-                                 AVPacket *pkt, int flush)
3174
-{
3175
-    AVPacketList *pktl;
3176
-    int stream_count=0;
3177
-    int i;
3178
-
3179
-    if(pkt){
3180
-        ff_interleave_add_packet(s, pkt, ff_interleave_compare_dts);
3181
-    }
3182
-
3183
-    for(i=0; i < s->nb_streams; i++)
3184
-        stream_count+= !!s->streams[i]->last_in_packet_buffer;
3185
-
3186
-    if(stream_count && (s->nb_streams == stream_count || flush)){
3187
-        pktl= s->packet_buffer;
3188
-        *out= pktl->pkt;
3189
-
3190
-        s->packet_buffer= pktl->next;
3191
-        if(!s->packet_buffer)
3192
-            s->packet_buffer_end= NULL;
3193
-
3194
-        if(s->streams[out->stream_index]->last_in_packet_buffer == pktl)
3195
-            s->streams[out->stream_index]->last_in_packet_buffer= NULL;
3196
-        av_freep(&pktl);
3197
-        return 1;
3198
-    }else{
3199
-        av_init_packet(out);
3200
-        return 0;
3201
-    }
3202
-}
3203
-
3204
-#if FF_API_INTERLEAVE_PACKET
3205
-int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
3206
-                                 AVPacket *pkt, int flush)
3207
-{
3208
-    return ff_interleave_packet_per_dts(s, out, pkt, flush);
3209
-}
3210
-#endif
3211
-
3212
-/**
3213
- * Interleave an AVPacket correctly so it can be muxed.
3214
- * @param out the interleaved packet will be output here
3215
- * @param in the input packet
3216
- * @param flush 1 if no further packets are available as input and all
3217
- *              remaining packets should be output
3218
- * @return 1 if a packet was output, 0 if no packet could be output,
3219
- *         < 0 if an error occurred
3220
- */
3221
-static int interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *in, int flush){
3222
-    if (s->oformat->interleave_packet) {
3223
-        int ret = s->oformat->interleave_packet(s, out, in, flush);
3224
-        if (in)
3225
-            av_free_packet(in);
3226
-        return ret;
3227
-    } else
3228
-        return ff_interleave_packet_per_dts(s, out, in, flush);
3229
-}
3230
-
3231
-int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt){
3232
-    int ret, flush = 0;
3233
-
3234
-    if (pkt) {
3235
-        AVStream *st= s->streams[ pkt->stream_index];
3236
-
3237
-        //FIXME/XXX/HACK drop zero sized packets
3238
-        if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO && pkt->size==0)
3239
-            return 0;
3240
-
3241
-        av_dlog(s, "av_interleaved_write_frame size:%d dts:%"PRId64" pts:%"PRId64"\n",
3242
-                pkt->size, pkt->dts, pkt->pts);
3243
-        if((ret = compute_pkt_fields2(s, st, pkt)) < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
3244
-            return ret;
3245
-
3246
-        if(pkt->dts == AV_NOPTS_VALUE && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
3247
-            return AVERROR(EINVAL);
3248
-    } else {
3249
-        av_dlog(s, "av_interleaved_write_frame FLUSH\n");
3250
-        flush = 1;
3251
-    }
3252
-
3253
-    for(;;){
3254
-        AVPacket opkt;
3255
-        int ret= interleave_packet(s, &opkt, pkt, flush);
3256
-        if(ret<=0) //FIXME cleanup needed for ret<0 ?
3257
-            return ret;
3258
-
3259
-        ret= s->oformat->write_packet(s, &opkt);
3260
-        if (ret >= 0)
3261
-            s->streams[opkt.stream_index]->nb_frames++;
3262
-
3263
-        av_free_packet(&opkt);
3264
-        pkt= NULL;
3265
-
3266
-        if(ret<0)
3267
-            return ret;
3268
-    }
3269
-}
3270
-
3271
-int av_write_trailer(AVFormatContext *s)
3272
-{
3273
-    int ret, i;
3274
-
3275
-    for (;;) {
3276
-        AVPacket pkt;
3277
-        ret = interleave_packet(s, &pkt, NULL, 1);
3278
-        if (ret < 0) //FIXME cleanup needed for ret<0 ?
3279
-            goto fail;
3280
-        if (!ret)
3281
-            break;
3282
-
3283
-        ret = s->oformat->write_packet(s, &pkt);
3284
-        if (ret >= 0)
3285
-            s->streams[pkt.stream_index]->nb_frames++;
3286
-
3287
-        av_free_packet(&pkt);
3288
-
3289
-        if (ret < 0)
3290
-            goto fail;
3291
-    }
3292
-
3293
-    if (s->oformat->write_trailer)
3294
-        ret = s->oformat->write_trailer(s);
3295
-
3296
-    if (!(s->oformat->flags & AVFMT_NOFILE))
3297
-        avio_flush(s->pb);
3298
-
3299
-fail:
3300
-    for (i = 0; i < s->nb_streams; i++) {
3301
-        av_freep(&s->streams[i]->priv_data);
3302
-        av_freep(&s->streams[i]->index_entries);
3303
-    }
3304
-    if (s->oformat->priv_class)
3305
-        av_opt_free(s->priv_data);
3306
-    av_freep(&s->priv_data);
3307
-    return ret;
3308
-}
3309
-
3310 2849
 void ff_program_add_stream_index(AVFormatContext *ac, int progid, unsigned int idx)
3311 2850
 {
3312 2851
     int i, j;