xref: /third_party/ffmpeg/libavformat/mux.c (revision cabdff1a)
1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * muxing functions for use within FFmpeg
3cabdff1aSopenharmony_ci * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
4cabdff1aSopenharmony_ci *
5cabdff1aSopenharmony_ci * This file is part of FFmpeg.
6cabdff1aSopenharmony_ci *
7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
11cabdff1aSopenharmony_ci *
12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15cabdff1aSopenharmony_ci * Lesser General Public License for more details.
16cabdff1aSopenharmony_ci *
17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20cabdff1aSopenharmony_ci */
21cabdff1aSopenharmony_ci
22cabdff1aSopenharmony_ci#include "avformat.h"
23cabdff1aSopenharmony_ci#include "internal.h"
24cabdff1aSopenharmony_ci#include "mux.h"
25cabdff1aSopenharmony_ci#include "version.h"
26cabdff1aSopenharmony_ci#include "libavcodec/bsf.h"
27cabdff1aSopenharmony_ci#include "libavcodec/internal.h"
28cabdff1aSopenharmony_ci#include "libavcodec/packet_internal.h"
29cabdff1aSopenharmony_ci#include "libavutil/opt.h"
30cabdff1aSopenharmony_ci#include "libavutil/dict.h"
31cabdff1aSopenharmony_ci#include "libavutil/timestamp.h"
32cabdff1aSopenharmony_ci#include "libavutil/avassert.h"
33cabdff1aSopenharmony_ci#include "libavutil/internal.h"
34cabdff1aSopenharmony_ci#include "libavutil/mathematics.h"
35cabdff1aSopenharmony_ci
36cabdff1aSopenharmony_ci/**
37cabdff1aSopenharmony_ci * @file
38cabdff1aSopenharmony_ci * muxing functions for use within libavformat
39cabdff1aSopenharmony_ci */
40cabdff1aSopenharmony_ci
41cabdff1aSopenharmony_ci/* fraction handling */
42cabdff1aSopenharmony_ci
43cabdff1aSopenharmony_ci/**
44cabdff1aSopenharmony_ci * f = val + (num / den) + 0.5.
45cabdff1aSopenharmony_ci *
46cabdff1aSopenharmony_ci * 'num' is normalized so that it is such as 0 <= num < den.
47cabdff1aSopenharmony_ci *
48cabdff1aSopenharmony_ci * @param f fractional number
49cabdff1aSopenharmony_ci * @param val integer value
50cabdff1aSopenharmony_ci * @param num must be >= 0
51cabdff1aSopenharmony_ci * @param den must be >= 1
52cabdff1aSopenharmony_ci */
53cabdff1aSopenharmony_cistatic void frac_init(FFFrac *f, int64_t val, int64_t num, int64_t den)
54cabdff1aSopenharmony_ci{
55cabdff1aSopenharmony_ci    num += (den >> 1);
56cabdff1aSopenharmony_ci    if (num >= den) {
57cabdff1aSopenharmony_ci        val += num / den;
58cabdff1aSopenharmony_ci        num  = num % den;
59cabdff1aSopenharmony_ci    }
60cabdff1aSopenharmony_ci    f->val = val;
61cabdff1aSopenharmony_ci    f->num = num;
62cabdff1aSopenharmony_ci    f->den = den;
63cabdff1aSopenharmony_ci}
64cabdff1aSopenharmony_ci
65cabdff1aSopenharmony_ci/**
66cabdff1aSopenharmony_ci * Fractional addition to f: f = f + (incr / f->den).
67cabdff1aSopenharmony_ci *
68cabdff1aSopenharmony_ci * @param f fractional number
69cabdff1aSopenharmony_ci * @param incr increment, can be positive or negative
70cabdff1aSopenharmony_ci */
71cabdff1aSopenharmony_cistatic void frac_add(FFFrac *f, int64_t incr)
72cabdff1aSopenharmony_ci{
73cabdff1aSopenharmony_ci    int64_t num, den;
74cabdff1aSopenharmony_ci
75cabdff1aSopenharmony_ci    num = f->num + incr;
76cabdff1aSopenharmony_ci    den = f->den;
77cabdff1aSopenharmony_ci    if (num < 0) {
78cabdff1aSopenharmony_ci        f->val += num / den;
79cabdff1aSopenharmony_ci        num     = num % den;
80cabdff1aSopenharmony_ci        if (num < 0) {
81cabdff1aSopenharmony_ci            num += den;
82cabdff1aSopenharmony_ci            f->val--;
83cabdff1aSopenharmony_ci        }
84cabdff1aSopenharmony_ci    } else if (num >= den) {
85cabdff1aSopenharmony_ci        f->val += num / den;
86cabdff1aSopenharmony_ci        num     = num % den;
87cabdff1aSopenharmony_ci    }
88cabdff1aSopenharmony_ci    f->num = num;
89cabdff1aSopenharmony_ci}
90cabdff1aSopenharmony_ci
91cabdff1aSopenharmony_ciint avformat_alloc_output_context2(AVFormatContext **avctx, const AVOutputFormat *oformat,
92cabdff1aSopenharmony_ci                                   const char *format, const char *filename)
93cabdff1aSopenharmony_ci{
94cabdff1aSopenharmony_ci    AVFormatContext *s = avformat_alloc_context();
95cabdff1aSopenharmony_ci    int ret = 0;
96cabdff1aSopenharmony_ci
97cabdff1aSopenharmony_ci    *avctx = NULL;
98cabdff1aSopenharmony_ci    if (!s)
99cabdff1aSopenharmony_ci        goto nomem;
100cabdff1aSopenharmony_ci
101cabdff1aSopenharmony_ci    if (!oformat) {
102cabdff1aSopenharmony_ci        if (format) {
103cabdff1aSopenharmony_ci            oformat = av_guess_format(format, NULL, NULL);
104cabdff1aSopenharmony_ci            if (!oformat) {
105cabdff1aSopenharmony_ci                av_log(s, AV_LOG_ERROR, "Requested output format '%s' is not a suitable output format\n", format);
106cabdff1aSopenharmony_ci                ret = AVERROR(EINVAL);
107cabdff1aSopenharmony_ci                goto error;
108cabdff1aSopenharmony_ci            }
109cabdff1aSopenharmony_ci        } else {
110cabdff1aSopenharmony_ci            oformat = av_guess_format(NULL, filename, NULL);
111cabdff1aSopenharmony_ci            if (!oformat) {
112cabdff1aSopenharmony_ci                ret = AVERROR(EINVAL);
113cabdff1aSopenharmony_ci                av_log(s, AV_LOG_ERROR, "Unable to find a suitable output format for '%s'\n",
114cabdff1aSopenharmony_ci                       filename);
115cabdff1aSopenharmony_ci                goto error;
116cabdff1aSopenharmony_ci            }
117cabdff1aSopenharmony_ci        }
118cabdff1aSopenharmony_ci    }
119cabdff1aSopenharmony_ci
120cabdff1aSopenharmony_ci    s->oformat = oformat;
121cabdff1aSopenharmony_ci    if (s->oformat->priv_data_size > 0) {
122cabdff1aSopenharmony_ci        s->priv_data = av_mallocz(s->oformat->priv_data_size);
123cabdff1aSopenharmony_ci        if (!s->priv_data)
124cabdff1aSopenharmony_ci            goto nomem;
125cabdff1aSopenharmony_ci        if (s->oformat->priv_class) {
126cabdff1aSopenharmony_ci            *(const AVClass**)s->priv_data= s->oformat->priv_class;
127cabdff1aSopenharmony_ci            av_opt_set_defaults(s->priv_data);
128cabdff1aSopenharmony_ci        }
129cabdff1aSopenharmony_ci    } else
130cabdff1aSopenharmony_ci        s->priv_data = NULL;
131cabdff1aSopenharmony_ci
132cabdff1aSopenharmony_ci    if (filename) {
133cabdff1aSopenharmony_ci        if (!(s->url = av_strdup(filename)))
134cabdff1aSopenharmony_ci            goto nomem;
135cabdff1aSopenharmony_ci
136cabdff1aSopenharmony_ci    }
137cabdff1aSopenharmony_ci    *avctx = s;
138cabdff1aSopenharmony_ci    return 0;
139cabdff1aSopenharmony_cinomem:
140cabdff1aSopenharmony_ci    av_log(s, AV_LOG_ERROR, "Out of memory\n");
141cabdff1aSopenharmony_ci    ret = AVERROR(ENOMEM);
142cabdff1aSopenharmony_cierror:
143cabdff1aSopenharmony_ci    avformat_free_context(s);
144cabdff1aSopenharmony_ci    return ret;
145cabdff1aSopenharmony_ci}
146cabdff1aSopenharmony_ci
147cabdff1aSopenharmony_cistatic int validate_codec_tag(AVFormatContext *s, AVStream *st)
148cabdff1aSopenharmony_ci{
149cabdff1aSopenharmony_ci    const AVCodecTag *avctag;
150cabdff1aSopenharmony_ci    enum AVCodecID id = AV_CODEC_ID_NONE;
151cabdff1aSopenharmony_ci    int64_t tag  = -1;
152cabdff1aSopenharmony_ci
153cabdff1aSopenharmony_ci    /**
154cabdff1aSopenharmony_ci     * Check that tag + id is in the table
155cabdff1aSopenharmony_ci     * If neither is in the table -> OK
156cabdff1aSopenharmony_ci     * If tag is in the table with another id -> FAIL
157cabdff1aSopenharmony_ci     * If id is in the table with another tag -> FAIL unless strict < normal
158cabdff1aSopenharmony_ci     */
159cabdff1aSopenharmony_ci    for (int n = 0; s->oformat->codec_tag[n]; n++) {
160cabdff1aSopenharmony_ci        avctag = s->oformat->codec_tag[n];
161cabdff1aSopenharmony_ci        while (avctag->id != AV_CODEC_ID_NONE) {
162cabdff1aSopenharmony_ci            if (ff_toupper4(avctag->tag) == ff_toupper4(st->codecpar->codec_tag)) {
163cabdff1aSopenharmony_ci                id = avctag->id;
164cabdff1aSopenharmony_ci                if (id == st->codecpar->codec_id)
165cabdff1aSopenharmony_ci                    return 1;
166cabdff1aSopenharmony_ci            }
167cabdff1aSopenharmony_ci            if (avctag->id == st->codecpar->codec_id)
168cabdff1aSopenharmony_ci                tag = avctag->tag;
169cabdff1aSopenharmony_ci            avctag++;
170cabdff1aSopenharmony_ci        }
171cabdff1aSopenharmony_ci    }
172cabdff1aSopenharmony_ci    if (id != AV_CODEC_ID_NONE)
173cabdff1aSopenharmony_ci        return 0;
174cabdff1aSopenharmony_ci    if (tag >= 0 && (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL))
175cabdff1aSopenharmony_ci        return 0;
176cabdff1aSopenharmony_ci    return 1;
177cabdff1aSopenharmony_ci}
178cabdff1aSopenharmony_ci
179cabdff1aSopenharmony_ci
180cabdff1aSopenharmony_cistatic int init_muxer(AVFormatContext *s, AVDictionary **options)
181cabdff1aSopenharmony_ci{
182cabdff1aSopenharmony_ci    FFFormatContext *const si = ffformatcontext(s);
183cabdff1aSopenharmony_ci    AVDictionary *tmp = NULL;
184cabdff1aSopenharmony_ci    const AVOutputFormat *of = s->oformat;
185cabdff1aSopenharmony_ci    AVDictionaryEntry *e;
186cabdff1aSopenharmony_ci    int ret = 0;
187cabdff1aSopenharmony_ci
188cabdff1aSopenharmony_ci    if (options)
189cabdff1aSopenharmony_ci        av_dict_copy(&tmp, *options, 0);
190cabdff1aSopenharmony_ci
191cabdff1aSopenharmony_ci    if ((ret = av_opt_set_dict(s, &tmp)) < 0)
192cabdff1aSopenharmony_ci        goto fail;
193cabdff1aSopenharmony_ci    if (s->priv_data && s->oformat->priv_class && *(const AVClass**)s->priv_data==s->oformat->priv_class &&
194cabdff1aSopenharmony_ci        (ret = av_opt_set_dict2(s->priv_data, &tmp, AV_OPT_SEARCH_CHILDREN)) < 0)
195cabdff1aSopenharmony_ci        goto fail;
196cabdff1aSopenharmony_ci
197cabdff1aSopenharmony_ci    if (!s->url && !(s->url = av_strdup(""))) {
198cabdff1aSopenharmony_ci        ret = AVERROR(ENOMEM);
199cabdff1aSopenharmony_ci        goto fail;
200cabdff1aSopenharmony_ci    }
201cabdff1aSopenharmony_ci
202cabdff1aSopenharmony_ci    // some sanity checks
203cabdff1aSopenharmony_ci    if (s->nb_streams == 0 && !(of->flags & AVFMT_NOSTREAMS)) {
204cabdff1aSopenharmony_ci        av_log(s, AV_LOG_ERROR, "No streams to mux were specified\n");
205cabdff1aSopenharmony_ci        ret = AVERROR(EINVAL);
206cabdff1aSopenharmony_ci        goto fail;
207cabdff1aSopenharmony_ci    }
208cabdff1aSopenharmony_ci
209cabdff1aSopenharmony_ci    for (unsigned i = 0; i < s->nb_streams; i++) {
210cabdff1aSopenharmony_ci        AVStream          *const  st = s->streams[i];
211cabdff1aSopenharmony_ci        FFStream          *const sti = ffstream(st);
212cabdff1aSopenharmony_ci        AVCodecParameters *const par = st->codecpar;
213cabdff1aSopenharmony_ci        const AVCodecDescriptor *desc;
214cabdff1aSopenharmony_ci
215cabdff1aSopenharmony_ci        if (!st->time_base.num) {
216cabdff1aSopenharmony_ci            /* fall back on the default timebase values */
217cabdff1aSopenharmony_ci            if (par->codec_type == AVMEDIA_TYPE_AUDIO && par->sample_rate)
218cabdff1aSopenharmony_ci                avpriv_set_pts_info(st, 64, 1, par->sample_rate);
219cabdff1aSopenharmony_ci            else
220cabdff1aSopenharmony_ci                avpriv_set_pts_info(st, 33, 1, 90000);
221cabdff1aSopenharmony_ci        }
222cabdff1aSopenharmony_ci
223cabdff1aSopenharmony_ci        switch (par->codec_type) {
224cabdff1aSopenharmony_ci        case AVMEDIA_TYPE_AUDIO:
225cabdff1aSopenharmony_ci            if (par->sample_rate <= 0) {
226cabdff1aSopenharmony_ci                av_log(s, AV_LOG_ERROR, "sample rate not set\n");
227cabdff1aSopenharmony_ci                ret = AVERROR(EINVAL);
228cabdff1aSopenharmony_ci                goto fail;
229cabdff1aSopenharmony_ci            }
230cabdff1aSopenharmony_ci
231cabdff1aSopenharmony_ci#if FF_API_OLD_CHANNEL_LAYOUT
232cabdff1aSopenharmony_ciFF_DISABLE_DEPRECATION_WARNINGS
233cabdff1aSopenharmony_ci            /* if the caller is using the deprecated channel layout API,
234cabdff1aSopenharmony_ci             * convert it to the new style */
235cabdff1aSopenharmony_ci            if (!par->ch_layout.nb_channels &&
236cabdff1aSopenharmony_ci                par->channels) {
237cabdff1aSopenharmony_ci                if (par->channel_layout) {
238cabdff1aSopenharmony_ci                    av_channel_layout_from_mask(&par->ch_layout, par->channel_layout);
239cabdff1aSopenharmony_ci                } else {
240cabdff1aSopenharmony_ci                    par->ch_layout.order       = AV_CHANNEL_ORDER_UNSPEC;
241cabdff1aSopenharmony_ci                    par->ch_layout.nb_channels = par->channels;
242cabdff1aSopenharmony_ci                }
243cabdff1aSopenharmony_ci            }
244cabdff1aSopenharmony_ciFF_ENABLE_DEPRECATION_WARNINGS
245cabdff1aSopenharmony_ci#endif
246cabdff1aSopenharmony_ci
247cabdff1aSopenharmony_ci            if (!par->block_align)
248cabdff1aSopenharmony_ci                par->block_align = par->ch_layout.nb_channels *
249cabdff1aSopenharmony_ci                                   av_get_bits_per_sample(par->codec_id) >> 3;
250cabdff1aSopenharmony_ci            break;
251cabdff1aSopenharmony_ci        case AVMEDIA_TYPE_VIDEO:
252cabdff1aSopenharmony_ci            if ((par->width <= 0 || par->height <= 0) &&
253cabdff1aSopenharmony_ci                !(of->flags & AVFMT_NODIMENSIONS)) {
254cabdff1aSopenharmony_ci                av_log(s, AV_LOG_ERROR, "dimensions not set\n");
255cabdff1aSopenharmony_ci                ret = AVERROR(EINVAL);
256cabdff1aSopenharmony_ci                goto fail;
257cabdff1aSopenharmony_ci            }
258cabdff1aSopenharmony_ci            if (av_cmp_q(st->sample_aspect_ratio, par->sample_aspect_ratio)
259cabdff1aSopenharmony_ci                && fabs(av_q2d(st->sample_aspect_ratio) - av_q2d(par->sample_aspect_ratio)) > 0.004*av_q2d(st->sample_aspect_ratio)
260cabdff1aSopenharmony_ci            ) {
261cabdff1aSopenharmony_ci                if (st->sample_aspect_ratio.num != 0 &&
262cabdff1aSopenharmony_ci                    st->sample_aspect_ratio.den != 0 &&
263cabdff1aSopenharmony_ci                    par->sample_aspect_ratio.num != 0 &&
264cabdff1aSopenharmony_ci                    par->sample_aspect_ratio.den != 0) {
265cabdff1aSopenharmony_ci                    av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between muxer "
266cabdff1aSopenharmony_ci                           "(%d/%d) and encoder layer (%d/%d)\n",
267cabdff1aSopenharmony_ci                           st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
268cabdff1aSopenharmony_ci                           par->sample_aspect_ratio.num,
269cabdff1aSopenharmony_ci                           par->sample_aspect_ratio.den);
270cabdff1aSopenharmony_ci                    ret = AVERROR(EINVAL);
271cabdff1aSopenharmony_ci                    goto fail;
272cabdff1aSopenharmony_ci                }
273cabdff1aSopenharmony_ci            }
274cabdff1aSopenharmony_ci            break;
275cabdff1aSopenharmony_ci        }
276cabdff1aSopenharmony_ci
277cabdff1aSopenharmony_ci        desc = avcodec_descriptor_get(par->codec_id);
278cabdff1aSopenharmony_ci        if (desc && desc->props & AV_CODEC_PROP_REORDER)
279cabdff1aSopenharmony_ci            sti->reorder = 1;
280cabdff1aSopenharmony_ci
281cabdff1aSopenharmony_ci        sti->is_intra_only = ff_is_intra_only(par->codec_id);
282cabdff1aSopenharmony_ci
283cabdff1aSopenharmony_ci        if (of->codec_tag) {
284cabdff1aSopenharmony_ci            if (   par->codec_tag
285cabdff1aSopenharmony_ci                && par->codec_id == AV_CODEC_ID_RAWVIDEO
286cabdff1aSopenharmony_ci                && (   av_codec_get_tag(of->codec_tag, par->codec_id) == 0
287cabdff1aSopenharmony_ci                    || av_codec_get_tag(of->codec_tag, par->codec_id) == MKTAG('r', 'a', 'w', ' '))
288cabdff1aSopenharmony_ci                && !validate_codec_tag(s, st)) {
289cabdff1aSopenharmony_ci                // the current rawvideo encoding system ends up setting
290cabdff1aSopenharmony_ci                // the wrong codec_tag for avi/mov, we override it here
291cabdff1aSopenharmony_ci                par->codec_tag = 0;
292cabdff1aSopenharmony_ci            }
293cabdff1aSopenharmony_ci            if (par->codec_tag) {
294cabdff1aSopenharmony_ci                if (!validate_codec_tag(s, st)) {
295cabdff1aSopenharmony_ci                    const uint32_t otag = av_codec_get_tag(s->oformat->codec_tag, par->codec_id);
296cabdff1aSopenharmony_ci                    av_log(s, AV_LOG_ERROR,
297cabdff1aSopenharmony_ci                           "Tag %s incompatible with output codec id '%d' (%s)\n",
298cabdff1aSopenharmony_ci                           av_fourcc2str(par->codec_tag), par->codec_id, av_fourcc2str(otag));
299cabdff1aSopenharmony_ci                    ret = AVERROR_INVALIDDATA;
300cabdff1aSopenharmony_ci                    goto fail;
301cabdff1aSopenharmony_ci                }
302cabdff1aSopenharmony_ci            } else
303cabdff1aSopenharmony_ci                par->codec_tag = av_codec_get_tag(of->codec_tag, par->codec_id);
304cabdff1aSopenharmony_ci        }
305cabdff1aSopenharmony_ci
306cabdff1aSopenharmony_ci        if (par->codec_type != AVMEDIA_TYPE_ATTACHMENT)
307cabdff1aSopenharmony_ci            si->nb_interleaved_streams++;
308cabdff1aSopenharmony_ci    }
309cabdff1aSopenharmony_ci    si->interleave_packet = of->interleave_packet;
310cabdff1aSopenharmony_ci    if (!si->interleave_packet)
311cabdff1aSopenharmony_ci        si->interleave_packet = si->nb_interleaved_streams > 1 ?
312cabdff1aSopenharmony_ci                                    ff_interleave_packet_per_dts :
313cabdff1aSopenharmony_ci                                    ff_interleave_packet_passthrough;
314cabdff1aSopenharmony_ci
315cabdff1aSopenharmony_ci    if (!s->priv_data && of->priv_data_size > 0) {
316cabdff1aSopenharmony_ci        s->priv_data = av_mallocz(of->priv_data_size);
317cabdff1aSopenharmony_ci        if (!s->priv_data) {
318cabdff1aSopenharmony_ci            ret = AVERROR(ENOMEM);
319cabdff1aSopenharmony_ci            goto fail;
320cabdff1aSopenharmony_ci        }
321cabdff1aSopenharmony_ci        if (of->priv_class) {
322cabdff1aSopenharmony_ci            *(const AVClass **)s->priv_data = of->priv_class;
323cabdff1aSopenharmony_ci            av_opt_set_defaults(s->priv_data);
324cabdff1aSopenharmony_ci            if ((ret = av_opt_set_dict2(s->priv_data, &tmp, AV_OPT_SEARCH_CHILDREN)) < 0)
325cabdff1aSopenharmony_ci                goto fail;
326cabdff1aSopenharmony_ci        }
327cabdff1aSopenharmony_ci    }
328cabdff1aSopenharmony_ci
329cabdff1aSopenharmony_ci    /* set muxer identification string */
330cabdff1aSopenharmony_ci    if (!(s->flags & AVFMT_FLAG_BITEXACT)) {
331cabdff1aSopenharmony_ci        av_dict_set(&s->metadata, "encoder", LIBAVFORMAT_IDENT, 0);
332cabdff1aSopenharmony_ci    } else {
333cabdff1aSopenharmony_ci        av_dict_set(&s->metadata, "encoder", NULL, 0);
334cabdff1aSopenharmony_ci    }
335cabdff1aSopenharmony_ci
336cabdff1aSopenharmony_ci    for (e = NULL; e = av_dict_get(s->metadata, "encoder-", e, AV_DICT_IGNORE_SUFFIX); ) {
337cabdff1aSopenharmony_ci        av_dict_set(&s->metadata, e->key, NULL, 0);
338cabdff1aSopenharmony_ci    }
339cabdff1aSopenharmony_ci
340cabdff1aSopenharmony_ci    if (options) {
341cabdff1aSopenharmony_ci         av_dict_free(options);
342cabdff1aSopenharmony_ci         *options = tmp;
343cabdff1aSopenharmony_ci    }
344cabdff1aSopenharmony_ci
345cabdff1aSopenharmony_ci    if (s->oformat->init) {
346cabdff1aSopenharmony_ci        if ((ret = s->oformat->init(s)) < 0) {
347cabdff1aSopenharmony_ci            if (s->oformat->deinit)
348cabdff1aSopenharmony_ci                s->oformat->deinit(s);
349cabdff1aSopenharmony_ci            return ret;
350cabdff1aSopenharmony_ci        }
351cabdff1aSopenharmony_ci        return ret == 0;
352cabdff1aSopenharmony_ci    }
353cabdff1aSopenharmony_ci
354cabdff1aSopenharmony_ci    return 0;
355cabdff1aSopenharmony_ci
356cabdff1aSopenharmony_cifail:
357cabdff1aSopenharmony_ci    av_dict_free(&tmp);
358cabdff1aSopenharmony_ci    return ret;
359cabdff1aSopenharmony_ci}
360cabdff1aSopenharmony_ci
361cabdff1aSopenharmony_cistatic int init_pts(AVFormatContext *s)
362cabdff1aSopenharmony_ci{
363cabdff1aSopenharmony_ci    FFFormatContext *const si = ffformatcontext(s);
364cabdff1aSopenharmony_ci
365cabdff1aSopenharmony_ci    /* init PTS generation */
366cabdff1aSopenharmony_ci    for (unsigned i = 0; i < s->nb_streams; i++) {
367cabdff1aSopenharmony_ci        AVStream *const st = s->streams[i];
368cabdff1aSopenharmony_ci        FFStream *const sti = ffstream(st);
369cabdff1aSopenharmony_ci        int64_t den = AV_NOPTS_VALUE;
370cabdff1aSopenharmony_ci
371cabdff1aSopenharmony_ci        switch (st->codecpar->codec_type) {
372cabdff1aSopenharmony_ci        case AVMEDIA_TYPE_AUDIO:
373cabdff1aSopenharmony_ci            den = (int64_t)st->time_base.num * st->codecpar->sample_rate;
374cabdff1aSopenharmony_ci            break;
375cabdff1aSopenharmony_ci        case AVMEDIA_TYPE_VIDEO:
376cabdff1aSopenharmony_ci            den = (int64_t)st->time_base.num * st->time_base.den;
377cabdff1aSopenharmony_ci            break;
378cabdff1aSopenharmony_ci#ifdef OHOS_TIMED_META_TRACK
379cabdff1aSopenharmony_ci        case AVMEDIA_TYPE_TIMEDMETA:
380cabdff1aSopenharmony_ci            den = (int64_t)st->time_base.num * st->time_base.den;
381cabdff1aSopenharmony_ci            break;
382cabdff1aSopenharmony_ci#endif
383cabdff1aSopenharmony_ci        default:
384cabdff1aSopenharmony_ci            break;
385cabdff1aSopenharmony_ci        }
386cabdff1aSopenharmony_ci
387cabdff1aSopenharmony_ci        if (!sti->priv_pts)
388cabdff1aSopenharmony_ci            sti->priv_pts = av_mallocz(sizeof(*sti->priv_pts));
389cabdff1aSopenharmony_ci        if (!sti->priv_pts)
390cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
391cabdff1aSopenharmony_ci
392cabdff1aSopenharmony_ci        if (den != AV_NOPTS_VALUE) {
393cabdff1aSopenharmony_ci            if (den <= 0)
394cabdff1aSopenharmony_ci                return AVERROR_INVALIDDATA;
395cabdff1aSopenharmony_ci
396cabdff1aSopenharmony_ci            frac_init(sti->priv_pts, 0, 0, den);
397cabdff1aSopenharmony_ci        }
398cabdff1aSopenharmony_ci    }
399cabdff1aSopenharmony_ci
400cabdff1aSopenharmony_ci    si->avoid_negative_ts_status = AVOID_NEGATIVE_TS_UNKNOWN;
401cabdff1aSopenharmony_ci    if (s->avoid_negative_ts < 0) {
402cabdff1aSopenharmony_ci        av_assert2(s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO);
403cabdff1aSopenharmony_ci        if (s->oformat->flags & (AVFMT_TS_NEGATIVE | AVFMT_NOTIMESTAMPS)) {
404cabdff1aSopenharmony_ci            s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_DISABLED;
405cabdff1aSopenharmony_ci            si->avoid_negative_ts_status = AVOID_NEGATIVE_TS_DISABLED;
406cabdff1aSopenharmony_ci        } else
407cabdff1aSopenharmony_ci            s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE;
408cabdff1aSopenharmony_ci    } else if (s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_DISABLED)
409cabdff1aSopenharmony_ci        si->avoid_negative_ts_status = AVOID_NEGATIVE_TS_DISABLED;
410cabdff1aSopenharmony_ci
411cabdff1aSopenharmony_ci    return 0;
412cabdff1aSopenharmony_ci}
413cabdff1aSopenharmony_ci
414cabdff1aSopenharmony_cistatic void flush_if_needed(AVFormatContext *s)
415cabdff1aSopenharmony_ci{
416cabdff1aSopenharmony_ci    if (s->pb && s->pb->error >= 0) {
417cabdff1aSopenharmony_ci        if (s->flush_packets == 1 || s->flags & AVFMT_FLAG_FLUSH_PACKETS)
418cabdff1aSopenharmony_ci            avio_flush(s->pb);
419cabdff1aSopenharmony_ci        else if (s->flush_packets && !(s->oformat->flags & AVFMT_NOFILE))
420cabdff1aSopenharmony_ci            avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_FLUSH_POINT);
421cabdff1aSopenharmony_ci    }
422cabdff1aSopenharmony_ci}
423cabdff1aSopenharmony_ci
424cabdff1aSopenharmony_cistatic void deinit_muxer(AVFormatContext *s)
425cabdff1aSopenharmony_ci{
426cabdff1aSopenharmony_ci    FFFormatContext *const si = ffformatcontext(s);
427cabdff1aSopenharmony_ci    if (s->oformat && s->oformat->deinit && si->initialized)
428cabdff1aSopenharmony_ci        s->oformat->deinit(s);
429cabdff1aSopenharmony_ci    si->initialized =
430cabdff1aSopenharmony_ci    si->streams_initialized = 0;
431cabdff1aSopenharmony_ci}
432cabdff1aSopenharmony_ci
433cabdff1aSopenharmony_ciint avformat_init_output(AVFormatContext *s, AVDictionary **options)
434cabdff1aSopenharmony_ci{
435cabdff1aSopenharmony_ci    FFFormatContext *const si = ffformatcontext(s);
436cabdff1aSopenharmony_ci    int ret = 0;
437cabdff1aSopenharmony_ci
438cabdff1aSopenharmony_ci    if ((ret = init_muxer(s, options)) < 0)
439cabdff1aSopenharmony_ci        return ret;
440cabdff1aSopenharmony_ci
441cabdff1aSopenharmony_ci    si->initialized = 1;
442cabdff1aSopenharmony_ci    si->streams_initialized = ret;
443cabdff1aSopenharmony_ci
444cabdff1aSopenharmony_ci    if (s->oformat->init && ret) {
445cabdff1aSopenharmony_ci        if ((ret = init_pts(s)) < 0)
446cabdff1aSopenharmony_ci            return ret;
447cabdff1aSopenharmony_ci
448cabdff1aSopenharmony_ci        return AVSTREAM_INIT_IN_INIT_OUTPUT;
449cabdff1aSopenharmony_ci    }
450cabdff1aSopenharmony_ci
451cabdff1aSopenharmony_ci    return AVSTREAM_INIT_IN_WRITE_HEADER;
452cabdff1aSopenharmony_ci}
453cabdff1aSopenharmony_ci
454cabdff1aSopenharmony_ciint avformat_write_header(AVFormatContext *s, AVDictionary **options)
455cabdff1aSopenharmony_ci{
456cabdff1aSopenharmony_ci    FFFormatContext *const si = ffformatcontext(s);
457cabdff1aSopenharmony_ci    int already_initialized = si->initialized;
458cabdff1aSopenharmony_ci    int streams_already_initialized = si->streams_initialized;
459cabdff1aSopenharmony_ci    int ret = 0;
460cabdff1aSopenharmony_ci
461cabdff1aSopenharmony_ci    if (!already_initialized)
462cabdff1aSopenharmony_ci        if ((ret = avformat_init_output(s, options)) < 0)
463cabdff1aSopenharmony_ci            return ret;
464cabdff1aSopenharmony_ci
465cabdff1aSopenharmony_ci    if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
466cabdff1aSopenharmony_ci        avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_HEADER);
467cabdff1aSopenharmony_ci    if (s->oformat->write_header) {
468cabdff1aSopenharmony_ci        ret = s->oformat->write_header(s);
469cabdff1aSopenharmony_ci        if (ret >= 0 && s->pb && s->pb->error < 0)
470cabdff1aSopenharmony_ci            ret = s->pb->error;
471cabdff1aSopenharmony_ci        if (ret < 0)
472cabdff1aSopenharmony_ci            goto fail;
473cabdff1aSopenharmony_ci        flush_if_needed(s);
474cabdff1aSopenharmony_ci    }
475cabdff1aSopenharmony_ci    if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
476cabdff1aSopenharmony_ci        avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_UNKNOWN);
477cabdff1aSopenharmony_ci
478cabdff1aSopenharmony_ci    if (!si->streams_initialized) {
479cabdff1aSopenharmony_ci        if ((ret = init_pts(s)) < 0)
480cabdff1aSopenharmony_ci            goto fail;
481cabdff1aSopenharmony_ci    }
482cabdff1aSopenharmony_ci
483cabdff1aSopenharmony_ci    return streams_already_initialized;
484cabdff1aSopenharmony_ci
485cabdff1aSopenharmony_cifail:
486cabdff1aSopenharmony_ci    deinit_muxer(s);
487cabdff1aSopenharmony_ci    return ret;
488cabdff1aSopenharmony_ci}
489cabdff1aSopenharmony_ci
490cabdff1aSopenharmony_ci#define AV_PKT_FLAG_UNCODED_FRAME 0x2000
491cabdff1aSopenharmony_ci
492cabdff1aSopenharmony_ci
493cabdff1aSopenharmony_ci#if FF_API_COMPUTE_PKT_FIELDS2
494cabdff1aSopenharmony_ciFF_DISABLE_DEPRECATION_WARNINGS
495cabdff1aSopenharmony_ci//FIXME merge with compute_pkt_fields
496cabdff1aSopenharmony_cistatic int compute_muxer_pkt_fields(AVFormatContext *s, AVStream *st, AVPacket *pkt)
497cabdff1aSopenharmony_ci{
498cabdff1aSopenharmony_ci    FFFormatContext *const si = ffformatcontext(s);
499cabdff1aSopenharmony_ci    FFStream *const sti = ffstream(st);
500cabdff1aSopenharmony_ci    int delay = st->codecpar->video_delay;
501cabdff1aSopenharmony_ci    int frame_size;
502cabdff1aSopenharmony_ci
503cabdff1aSopenharmony_ci    if (!si->missing_ts_warning &&
504cabdff1aSopenharmony_ci        !(s->oformat->flags & AVFMT_NOTIMESTAMPS) &&
505cabdff1aSopenharmony_ci        (!(st->disposition & AV_DISPOSITION_ATTACHED_PIC) || (st->disposition & AV_DISPOSITION_TIMED_THUMBNAILS)) &&
506cabdff1aSopenharmony_ci        (pkt->pts == AV_NOPTS_VALUE || pkt->dts == AV_NOPTS_VALUE)) {
507cabdff1aSopenharmony_ci        av_log(s, AV_LOG_WARNING,
508cabdff1aSopenharmony_ci               "Timestamps are unset in a packet for stream %d. "
509cabdff1aSopenharmony_ci               "This is deprecated and will stop working in the future. "
510cabdff1aSopenharmony_ci               "Fix your code to set the timestamps properly\n", st->index);
511cabdff1aSopenharmony_ci        si->missing_ts_warning = 1;
512cabdff1aSopenharmony_ci    }
513cabdff1aSopenharmony_ci
514cabdff1aSopenharmony_ci    if (s->debug & FF_FDEBUG_TS)
515cabdff1aSopenharmony_ci        av_log(s, AV_LOG_DEBUG, "compute_muxer_pkt_fields: pts:%s dts:%s cur_dts:%s b:%d size:%d st:%d\n",
516cabdff1aSopenharmony_ci            av_ts2str(pkt->pts), av_ts2str(pkt->dts), av_ts2str(sti->cur_dts), delay, pkt->size, pkt->stream_index);
517cabdff1aSopenharmony_ci
518cabdff1aSopenharmony_ci    if (pkt->pts == AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && delay == 0)
519cabdff1aSopenharmony_ci        pkt->pts = pkt->dts;
520cabdff1aSopenharmony_ci
521cabdff1aSopenharmony_ci    //XXX/FIXME this is a temporary hack until all encoders output pts
522cabdff1aSopenharmony_ci    if ((pkt->pts == 0 || pkt->pts == AV_NOPTS_VALUE) && pkt->dts == AV_NOPTS_VALUE && !delay) {
523cabdff1aSopenharmony_ci        static int warned;
524cabdff1aSopenharmony_ci        if (!warned) {
525cabdff1aSopenharmony_ci            av_log(s, AV_LOG_WARNING, "Encoder did not produce proper pts, making some up.\n");
526cabdff1aSopenharmony_ci            warned = 1;
527cabdff1aSopenharmony_ci        }
528cabdff1aSopenharmony_ci        pkt->dts =
529cabdff1aSopenharmony_ci//        pkt->pts= st->cur_dts;
530cabdff1aSopenharmony_ci            pkt->pts = sti->priv_pts->val;
531cabdff1aSopenharmony_ci    }
532cabdff1aSopenharmony_ci
533cabdff1aSopenharmony_ci    //calculate dts from pts
534cabdff1aSopenharmony_ci    if (pkt->pts != AV_NOPTS_VALUE && pkt->dts == AV_NOPTS_VALUE && delay <= MAX_REORDER_DELAY) {
535cabdff1aSopenharmony_ci        sti->pts_buffer[0] = pkt->pts;
536cabdff1aSopenharmony_ci        for (int i = 1; i < delay + 1 && sti->pts_buffer[i] == AV_NOPTS_VALUE; i++)
537cabdff1aSopenharmony_ci            sti->pts_buffer[i] = pkt->pts + (i - delay - 1) * pkt->duration;
538cabdff1aSopenharmony_ci        for (int i = 0; i<delay && sti->pts_buffer[i] > sti->pts_buffer[i + 1]; i++)
539cabdff1aSopenharmony_ci            FFSWAP(int64_t, sti->pts_buffer[i], sti->pts_buffer[i + 1]);
540cabdff1aSopenharmony_ci
541cabdff1aSopenharmony_ci        pkt->dts = sti->pts_buffer[0];
542cabdff1aSopenharmony_ci    }
543cabdff1aSopenharmony_ci
544cabdff1aSopenharmony_ci    if (sti->cur_dts && sti->cur_dts != AV_NOPTS_VALUE &&
545cabdff1aSopenharmony_ci        ((!(s->oformat->flags & AVFMT_TS_NONSTRICT) &&
546cabdff1aSopenharmony_ci          st->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE &&
547cabdff1aSopenharmony_ci          st->codecpar->codec_type != AVMEDIA_TYPE_DATA &&
548cabdff1aSopenharmony_ci          sti->cur_dts >= pkt->dts) || sti->cur_dts > pkt->dts)) {
549cabdff1aSopenharmony_ci        av_log(s, AV_LOG_ERROR,
550cabdff1aSopenharmony_ci               "Application provided invalid, non monotonically increasing dts to muxer in stream %d: %s >= %s\n",
551cabdff1aSopenharmony_ci               st->index, av_ts2str(sti->cur_dts), av_ts2str(pkt->dts));
552cabdff1aSopenharmony_ci        return AVERROR(EINVAL);
553cabdff1aSopenharmony_ci    }
554cabdff1aSopenharmony_ci    if (pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts < pkt->dts) {
555cabdff1aSopenharmony_ci        av_log(s, AV_LOG_ERROR,
556cabdff1aSopenharmony_ci               "pts (%s) < dts (%s) in stream %d\n",
557cabdff1aSopenharmony_ci               av_ts2str(pkt->pts), av_ts2str(pkt->dts),
558cabdff1aSopenharmony_ci               st->index);
559cabdff1aSopenharmony_ci        return AVERROR(EINVAL);
560cabdff1aSopenharmony_ci    }
561cabdff1aSopenharmony_ci
562cabdff1aSopenharmony_ci    if (s->debug & FF_FDEBUG_TS)
563cabdff1aSopenharmony_ci        av_log(s, AV_LOG_DEBUG, "av_write_frame: pts2:%s dts2:%s\n",
564cabdff1aSopenharmony_ci            av_ts2str(pkt->pts), av_ts2str(pkt->dts));
565cabdff1aSopenharmony_ci
566cabdff1aSopenharmony_ci    sti->cur_dts      = pkt->dts;
567cabdff1aSopenharmony_ci    sti->priv_pts->val = pkt->dts;
568cabdff1aSopenharmony_ci
569cabdff1aSopenharmony_ci    /* update pts */
570cabdff1aSopenharmony_ci    switch (st->codecpar->codec_type) {
571cabdff1aSopenharmony_ci    case AVMEDIA_TYPE_AUDIO:
572cabdff1aSopenharmony_ci        frame_size = (pkt->flags & AV_PKT_FLAG_UNCODED_FRAME) ?
573cabdff1aSopenharmony_ci                     (*(AVFrame **)pkt->data)->nb_samples :
574cabdff1aSopenharmony_ci                     av_get_audio_frame_duration2(st->codecpar, pkt->size);
575cabdff1aSopenharmony_ci
576cabdff1aSopenharmony_ci        /* HACK/FIXME, we skip the initial 0 size packets as they are most
577cabdff1aSopenharmony_ci         * likely equal to the encoder delay, but it would be better if we
578cabdff1aSopenharmony_ci         * had the real timestamps from the encoder */
579cabdff1aSopenharmony_ci        if (frame_size >= 0 && (pkt->size || sti->priv_pts->num != sti->priv_pts->den >> 1 || sti->priv_pts->val)) {
580cabdff1aSopenharmony_ci            frac_add(sti->priv_pts, (int64_t)st->time_base.den * frame_size);
581cabdff1aSopenharmony_ci        }
582cabdff1aSopenharmony_ci        break;
583cabdff1aSopenharmony_ci    case AVMEDIA_TYPE_VIDEO:
584cabdff1aSopenharmony_ci        frac_add(sti->priv_pts, (int64_t)st->time_base.den * st->time_base.num);
585cabdff1aSopenharmony_ci        break;
586cabdff1aSopenharmony_ci    }
587cabdff1aSopenharmony_ci    return 0;
588cabdff1aSopenharmony_ci}
589cabdff1aSopenharmony_ciFF_ENABLE_DEPRECATION_WARNINGS
590cabdff1aSopenharmony_ci#endif
591cabdff1aSopenharmony_ci
592cabdff1aSopenharmony_cistatic void guess_pkt_duration(AVFormatContext *s, AVStream *st, AVPacket *pkt)
593cabdff1aSopenharmony_ci{
594cabdff1aSopenharmony_ci    if (pkt->duration < 0 && st->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) {
595cabdff1aSopenharmony_ci        av_log(s, AV_LOG_WARNING, "Packet with invalid duration %"PRId64" in stream %d\n",
596cabdff1aSopenharmony_ci               pkt->duration, pkt->stream_index);
597cabdff1aSopenharmony_ci        pkt->duration = 0;
598cabdff1aSopenharmony_ci    }
599cabdff1aSopenharmony_ci
600cabdff1aSopenharmony_ci    if (pkt->duration)
601cabdff1aSopenharmony_ci        return;
602cabdff1aSopenharmony_ci
603cabdff1aSopenharmony_ci    switch (st->codecpar->codec_type) {
604cabdff1aSopenharmony_ci    case AVMEDIA_TYPE_VIDEO:
605cabdff1aSopenharmony_ci        if (st->avg_frame_rate.num > 0 && st->avg_frame_rate.den > 0) {
606cabdff1aSopenharmony_ci            pkt->duration = av_rescale_q(1, av_inv_q(st->avg_frame_rate),
607cabdff1aSopenharmony_ci                                         st->time_base);
608cabdff1aSopenharmony_ci        } else if (st->time_base.num * 1000LL > st->time_base.den)
609cabdff1aSopenharmony_ci            pkt->duration = 1;
610cabdff1aSopenharmony_ci        break;
611cabdff1aSopenharmony_ci    case AVMEDIA_TYPE_AUDIO: {
612cabdff1aSopenharmony_ci        int frame_size = av_get_audio_frame_duration2(st->codecpar, pkt->size);
613cabdff1aSopenharmony_ci        if (frame_size && st->codecpar->sample_rate) {
614cabdff1aSopenharmony_ci            pkt->duration = av_rescale_q(frame_size,
615cabdff1aSopenharmony_ci                                         (AVRational){1, st->codecpar->sample_rate},
616cabdff1aSopenharmony_ci                                         st->time_base);
617cabdff1aSopenharmony_ci        }
618cabdff1aSopenharmony_ci        break;
619cabdff1aSopenharmony_ci        }
620cabdff1aSopenharmony_ci    }
621cabdff1aSopenharmony_ci}
622cabdff1aSopenharmony_ci
623cabdff1aSopenharmony_cistatic void handle_avoid_negative_ts(FFFormatContext *si, FFStream *sti,
624cabdff1aSopenharmony_ci                                     AVPacket *pkt)
625cabdff1aSopenharmony_ci{
626cabdff1aSopenharmony_ci    AVFormatContext *const s = &si->pub;
627cabdff1aSopenharmony_ci    int64_t offset;
628cabdff1aSopenharmony_ci
629cabdff1aSopenharmony_ci    if (!AVOID_NEGATIVE_TS_ENABLED(si->avoid_negative_ts_status))
630cabdff1aSopenharmony_ci        return;
631cabdff1aSopenharmony_ci
632cabdff1aSopenharmony_ci    if (si->avoid_negative_ts_status == AVOID_NEGATIVE_TS_UNKNOWN) {
633cabdff1aSopenharmony_ci        int use_pts = si->avoid_negative_ts_use_pts;
634cabdff1aSopenharmony_ci        int64_t ts = use_pts ? pkt->pts : pkt->dts;
635cabdff1aSopenharmony_ci        AVRational tb = sti->pub.time_base;
636cabdff1aSopenharmony_ci
637cabdff1aSopenharmony_ci        if (ts == AV_NOPTS_VALUE)
638cabdff1aSopenharmony_ci            return;
639cabdff1aSopenharmony_ci
640cabdff1aSopenharmony_ci        /* Peek into the muxing queue to improve our estimate
641cabdff1aSopenharmony_ci         * of the lowest timestamp if av_interleaved_write_frame() is used. */
642cabdff1aSopenharmony_ci        for (const PacketListEntry *pktl = si->packet_buffer.head;
643cabdff1aSopenharmony_ci             pktl; pktl = pktl->next) {
644cabdff1aSopenharmony_ci            AVRational cmp_tb = s->streams[pktl->pkt.stream_index]->time_base;
645cabdff1aSopenharmony_ci            int64_t cmp_ts = use_pts ? pktl->pkt.pts : pktl->pkt.dts;
646cabdff1aSopenharmony_ci            if (cmp_ts == AV_NOPTS_VALUE)
647cabdff1aSopenharmony_ci                continue;
648cabdff1aSopenharmony_ci            if (s->output_ts_offset)
649cabdff1aSopenharmony_ci                cmp_ts += av_rescale_q(s->output_ts_offset, AV_TIME_BASE_Q, cmp_tb);
650cabdff1aSopenharmony_ci            if (av_compare_ts(cmp_ts, cmp_tb, ts, tb) < 0) {
651cabdff1aSopenharmony_ci                ts = cmp_ts;
652cabdff1aSopenharmony_ci                tb = cmp_tb;
653cabdff1aSopenharmony_ci            }
654cabdff1aSopenharmony_ci        }
655cabdff1aSopenharmony_ci
656cabdff1aSopenharmony_ci        if (ts < 0 ||
657cabdff1aSopenharmony_ci            ts > 0 && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO) {
658cabdff1aSopenharmony_ci            for (unsigned i = 0; i < s->nb_streams; i++) {
659cabdff1aSopenharmony_ci                AVStream *const st2  = s->streams[i];
660cabdff1aSopenharmony_ci                FFStream *const sti2 = ffstream(st2);
661cabdff1aSopenharmony_ci                sti2->mux_ts_offset = av_rescale_q_rnd(-ts, tb,
662cabdff1aSopenharmony_ci                                                       st2->time_base,
663cabdff1aSopenharmony_ci                                                       AV_ROUND_UP);
664cabdff1aSopenharmony_ci            }
665cabdff1aSopenharmony_ci        }
666cabdff1aSopenharmony_ci        si->avoid_negative_ts_status = AVOID_NEGATIVE_TS_KNOWN;
667cabdff1aSopenharmony_ci    }
668cabdff1aSopenharmony_ci
669cabdff1aSopenharmony_ci    offset = sti->mux_ts_offset;
670cabdff1aSopenharmony_ci
671cabdff1aSopenharmony_ci    if (pkt->dts != AV_NOPTS_VALUE)
672cabdff1aSopenharmony_ci        pkt->dts += offset;
673cabdff1aSopenharmony_ci    if (pkt->pts != AV_NOPTS_VALUE)
674cabdff1aSopenharmony_ci        pkt->pts += offset;
675cabdff1aSopenharmony_ci
676cabdff1aSopenharmony_ci    if (si->avoid_negative_ts_use_pts) {
677cabdff1aSopenharmony_ci        if (pkt->pts != AV_NOPTS_VALUE && pkt->pts < 0) {
678cabdff1aSopenharmony_ci            av_log(s, AV_LOG_WARNING, "failed to avoid negative "
679cabdff1aSopenharmony_ci                   "pts %s in stream %d.\n"
680cabdff1aSopenharmony_ci                   "Try -avoid_negative_ts 1 as a possible workaround.\n",
681cabdff1aSopenharmony_ci                   av_ts2str(pkt->pts),
682cabdff1aSopenharmony_ci                   pkt->stream_index
683cabdff1aSopenharmony_ci            );
684cabdff1aSopenharmony_ci        }
685cabdff1aSopenharmony_ci    } else {
686cabdff1aSopenharmony_ci        if (pkt->dts != AV_NOPTS_VALUE && pkt->dts < 0) {
687cabdff1aSopenharmony_ci            av_log(s, AV_LOG_WARNING,
688cabdff1aSopenharmony_ci                   "Packets poorly interleaved, failed to avoid negative "
689cabdff1aSopenharmony_ci                   "timestamp %s in stream %d.\n"
690cabdff1aSopenharmony_ci                   "Try -max_interleave_delta 0 as a possible workaround.\n",
691cabdff1aSopenharmony_ci                   av_ts2str(pkt->dts),
692cabdff1aSopenharmony_ci                   pkt->stream_index
693cabdff1aSopenharmony_ci            );
694cabdff1aSopenharmony_ci        }
695cabdff1aSopenharmony_ci    }
696cabdff1aSopenharmony_ci}
697cabdff1aSopenharmony_ci
698cabdff1aSopenharmony_ci/**
699cabdff1aSopenharmony_ci * Shift timestamps and call muxer; the original pts/dts are not kept.
700cabdff1aSopenharmony_ci *
701cabdff1aSopenharmony_ci * FIXME: this function should NEVER get undefined pts/dts beside when the
702cabdff1aSopenharmony_ci * AVFMT_NOTIMESTAMPS is set.
703cabdff1aSopenharmony_ci * Those additional safety checks should be dropped once the correct checks
704cabdff1aSopenharmony_ci * are set in the callers.
705cabdff1aSopenharmony_ci */
706cabdff1aSopenharmony_cistatic int write_packet(AVFormatContext *s, AVPacket *pkt)
707cabdff1aSopenharmony_ci{
708cabdff1aSopenharmony_ci    FFFormatContext *const si = ffformatcontext(s);
709cabdff1aSopenharmony_ci    AVStream *const st = s->streams[pkt->stream_index];
710cabdff1aSopenharmony_ci    FFStream *const sti = ffstream(st);
711cabdff1aSopenharmony_ci    int ret;
712cabdff1aSopenharmony_ci
713cabdff1aSopenharmony_ci    // If the timestamp offsetting below is adjusted, adjust
714cabdff1aSopenharmony_ci    // ff_interleaved_peek similarly.
715cabdff1aSopenharmony_ci    if (s->output_ts_offset) {
716cabdff1aSopenharmony_ci        int64_t offset = av_rescale_q(s->output_ts_offset, AV_TIME_BASE_Q, st->time_base);
717cabdff1aSopenharmony_ci
718cabdff1aSopenharmony_ci        if (pkt->dts != AV_NOPTS_VALUE)
719cabdff1aSopenharmony_ci            pkt->dts += offset;
720cabdff1aSopenharmony_ci        if (pkt->pts != AV_NOPTS_VALUE)
721cabdff1aSopenharmony_ci            pkt->pts += offset;
722cabdff1aSopenharmony_ci    }
723cabdff1aSopenharmony_ci    handle_avoid_negative_ts(si, sti, pkt);
724cabdff1aSopenharmony_ci
725cabdff1aSopenharmony_ci    if ((pkt->flags & AV_PKT_FLAG_UNCODED_FRAME)) {
726cabdff1aSopenharmony_ci        AVFrame **frame = (AVFrame **)pkt->data;
727cabdff1aSopenharmony_ci        av_assert0(pkt->size == sizeof(*frame));
728cabdff1aSopenharmony_ci        ret = s->oformat->write_uncoded_frame(s, pkt->stream_index, frame, 0);
729cabdff1aSopenharmony_ci    } else {
730cabdff1aSopenharmony_ci        ret = s->oformat->write_packet(s, pkt);
731cabdff1aSopenharmony_ci    }
732cabdff1aSopenharmony_ci
733cabdff1aSopenharmony_ci    if (s->pb && ret >= 0) {
734cabdff1aSopenharmony_ci        flush_if_needed(s);
735cabdff1aSopenharmony_ci        if (s->pb->error < 0)
736cabdff1aSopenharmony_ci            ret = s->pb->error;
737cabdff1aSopenharmony_ci    }
738cabdff1aSopenharmony_ci
739cabdff1aSopenharmony_ci    if (ret >= 0)
740cabdff1aSopenharmony_ci        st->nb_frames++;
741cabdff1aSopenharmony_ci
742cabdff1aSopenharmony_ci    return ret;
743cabdff1aSopenharmony_ci}
744cabdff1aSopenharmony_ci
745cabdff1aSopenharmony_cistatic int check_packet(AVFormatContext *s, AVPacket *pkt)
746cabdff1aSopenharmony_ci{
747cabdff1aSopenharmony_ci    if (pkt->stream_index < 0 || pkt->stream_index >= s->nb_streams) {
748cabdff1aSopenharmony_ci        av_log(s, AV_LOG_ERROR, "Invalid packet stream index: %d\n",
749cabdff1aSopenharmony_ci               pkt->stream_index);
750cabdff1aSopenharmony_ci        return AVERROR(EINVAL);
751cabdff1aSopenharmony_ci    }
752cabdff1aSopenharmony_ci
753cabdff1aSopenharmony_ci    if (s->streams[pkt->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_ATTACHMENT) {
754cabdff1aSopenharmony_ci        av_log(s, AV_LOG_ERROR, "Received a packet for an attachment stream.\n");
755cabdff1aSopenharmony_ci        return AVERROR(EINVAL);
756cabdff1aSopenharmony_ci    }
757cabdff1aSopenharmony_ci
758cabdff1aSopenharmony_ci    return 0;
759cabdff1aSopenharmony_ci}
760cabdff1aSopenharmony_ci
761cabdff1aSopenharmony_cistatic int prepare_input_packet(AVFormatContext *s, AVStream *st, AVPacket *pkt)
762cabdff1aSopenharmony_ci{
763cabdff1aSopenharmony_ci    FFStream *const sti = ffstream(st);
764cabdff1aSopenharmony_ci#if !FF_API_COMPUTE_PKT_FIELDS2
765cabdff1aSopenharmony_ci    /* sanitize the timestamps */
766cabdff1aSopenharmony_ci    if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS)) {
767cabdff1aSopenharmony_ci
768cabdff1aSopenharmony_ci        /* when there is no reordering (so dts is equal to pts), but
769cabdff1aSopenharmony_ci         * only one of them is set, set the other as well */
770cabdff1aSopenharmony_ci        if (!sti->reorder) {
771cabdff1aSopenharmony_ci            if (pkt->pts == AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE)
772cabdff1aSopenharmony_ci                pkt->pts = pkt->dts;
773cabdff1aSopenharmony_ci            if (pkt->dts == AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE)
774cabdff1aSopenharmony_ci                pkt->dts = pkt->pts;
775cabdff1aSopenharmony_ci        }
776cabdff1aSopenharmony_ci
777cabdff1aSopenharmony_ci        /* check that the timestamps are set */
778cabdff1aSopenharmony_ci        if (pkt->pts == AV_NOPTS_VALUE || pkt->dts == AV_NOPTS_VALUE) {
779cabdff1aSopenharmony_ci            av_log(s, AV_LOG_ERROR,
780cabdff1aSopenharmony_ci                   "Timestamps are unset in a packet for stream %d\n", st->index);
781cabdff1aSopenharmony_ci            return AVERROR(EINVAL);
782cabdff1aSopenharmony_ci        }
783cabdff1aSopenharmony_ci
784cabdff1aSopenharmony_ci        /* check that the dts are increasing (or at least non-decreasing,
785cabdff1aSopenharmony_ci         * if the format allows it */
786cabdff1aSopenharmony_ci        if (sti->cur_dts != AV_NOPTS_VALUE &&
787cabdff1aSopenharmony_ci            ((!(s->oformat->flags & AVFMT_TS_NONSTRICT) && sti->cur_dts >= pkt->dts) ||
788cabdff1aSopenharmony_ci             sti->cur_dts > pkt->dts)) {
789cabdff1aSopenharmony_ci            av_log(s, AV_LOG_ERROR,
790cabdff1aSopenharmony_ci                   "Application provided invalid, non monotonically increasing "
791cabdff1aSopenharmony_ci                   "dts to muxer in stream %d: %" PRId64 " >= %" PRId64 "\n",
792cabdff1aSopenharmony_ci                   st->index, sti->cur_dts, pkt->dts);
793cabdff1aSopenharmony_ci            return AVERROR(EINVAL);
794cabdff1aSopenharmony_ci        }
795cabdff1aSopenharmony_ci
796cabdff1aSopenharmony_ci        if (pkt->pts < pkt->dts) {
797cabdff1aSopenharmony_ci            av_log(s, AV_LOG_ERROR, "pts %" PRId64 " < dts %" PRId64 " in stream %d\n",
798cabdff1aSopenharmony_ci                   pkt->pts, pkt->dts, st->index);
799cabdff1aSopenharmony_ci            return AVERROR(EINVAL);
800cabdff1aSopenharmony_ci        }
801cabdff1aSopenharmony_ci    }
802cabdff1aSopenharmony_ci#endif
803cabdff1aSopenharmony_ci    /* update flags */
804cabdff1aSopenharmony_ci    if (sti->is_intra_only)
805cabdff1aSopenharmony_ci        pkt->flags |= AV_PKT_FLAG_KEY;
806cabdff1aSopenharmony_ci
807cabdff1aSopenharmony_ci    if (!pkt->data && !pkt->side_data_elems) {
808cabdff1aSopenharmony_ci        /* Such empty packets signal EOS for the BSF API; so sanitize
809cabdff1aSopenharmony_ci         * the packet by allocating data of size 0 (+ padding). */
810cabdff1aSopenharmony_ci        av_buffer_unref(&pkt->buf);
811cabdff1aSopenharmony_ci        return av_packet_make_refcounted(pkt);
812cabdff1aSopenharmony_ci    }
813cabdff1aSopenharmony_ci
814cabdff1aSopenharmony_ci    return 0;
815cabdff1aSopenharmony_ci}
816cabdff1aSopenharmony_ci
817cabdff1aSopenharmony_ci#define CHUNK_START 0x1000
818cabdff1aSopenharmony_ci
819cabdff1aSopenharmony_ciint ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt,
820cabdff1aSopenharmony_ci                             int (*compare)(AVFormatContext *, const AVPacket *, const AVPacket *))
821cabdff1aSopenharmony_ci{
822cabdff1aSopenharmony_ci    int ret;
823cabdff1aSopenharmony_ci    FFFormatContext *const si = ffformatcontext(s);
824cabdff1aSopenharmony_ci    PacketListEntry **next_point, *this_pktl;
825cabdff1aSopenharmony_ci    AVStream *st = s->streams[pkt->stream_index];
826cabdff1aSopenharmony_ci    FFStream *const sti = ffstream(st);
827cabdff1aSopenharmony_ci    int chunked  = s->max_chunk_size || s->max_chunk_duration;
828cabdff1aSopenharmony_ci
829cabdff1aSopenharmony_ci    this_pktl    = av_malloc(sizeof(*this_pktl));
830cabdff1aSopenharmony_ci    if (!this_pktl) {
831cabdff1aSopenharmony_ci        av_packet_unref(pkt);
832cabdff1aSopenharmony_ci        return AVERROR(ENOMEM);
833cabdff1aSopenharmony_ci    }
834cabdff1aSopenharmony_ci    if ((ret = av_packet_make_refcounted(pkt)) < 0) {
835cabdff1aSopenharmony_ci        av_free(this_pktl);
836cabdff1aSopenharmony_ci        av_packet_unref(pkt);
837cabdff1aSopenharmony_ci        return ret;
838cabdff1aSopenharmony_ci    }
839cabdff1aSopenharmony_ci
840cabdff1aSopenharmony_ci    av_packet_move_ref(&this_pktl->pkt, pkt);
841cabdff1aSopenharmony_ci    pkt = &this_pktl->pkt;
842cabdff1aSopenharmony_ci
843cabdff1aSopenharmony_ci    if (sti->last_in_packet_buffer) {
844cabdff1aSopenharmony_ci        next_point = &(sti->last_in_packet_buffer->next);
845cabdff1aSopenharmony_ci    } else {
846cabdff1aSopenharmony_ci        next_point = &si->packet_buffer.head;
847cabdff1aSopenharmony_ci    }
848cabdff1aSopenharmony_ci
849cabdff1aSopenharmony_ci    if (chunked) {
850cabdff1aSopenharmony_ci        uint64_t max= av_rescale_q_rnd(s->max_chunk_duration, AV_TIME_BASE_Q, st->time_base, AV_ROUND_UP);
851cabdff1aSopenharmony_ci        sti->interleaver_chunk_size     += pkt->size;
852cabdff1aSopenharmony_ci        sti->interleaver_chunk_duration += pkt->duration;
853cabdff1aSopenharmony_ci        if (   (s->max_chunk_size && sti->interleaver_chunk_size > s->max_chunk_size)
854cabdff1aSopenharmony_ci            || (max && sti->interleaver_chunk_duration           > max)) {
855cabdff1aSopenharmony_ci            sti->interleaver_chunk_size = 0;
856cabdff1aSopenharmony_ci            pkt->flags |= CHUNK_START;
857cabdff1aSopenharmony_ci            if (max && sti->interleaver_chunk_duration > max) {
858cabdff1aSopenharmony_ci                int64_t syncoffset = (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)*max/2;
859cabdff1aSopenharmony_ci                int64_t syncto = av_rescale(pkt->dts + syncoffset, 1, max)*max - syncoffset;
860cabdff1aSopenharmony_ci
861cabdff1aSopenharmony_ci                sti->interleaver_chunk_duration += (pkt->dts - syncto)/8 - max;
862cabdff1aSopenharmony_ci            } else
863cabdff1aSopenharmony_ci                sti->interleaver_chunk_duration  = 0;
864cabdff1aSopenharmony_ci        }
865cabdff1aSopenharmony_ci    }
866cabdff1aSopenharmony_ci    if (*next_point) {
867cabdff1aSopenharmony_ci        if (chunked && !(pkt->flags & CHUNK_START))
868cabdff1aSopenharmony_ci            goto next_non_null;
869cabdff1aSopenharmony_ci
870cabdff1aSopenharmony_ci        if (compare(s, &si->packet_buffer.tail->pkt, pkt)) {
871cabdff1aSopenharmony_ci            while (   *next_point
872cabdff1aSopenharmony_ci                   && ((chunked && !((*next_point)->pkt.flags&CHUNK_START))
873cabdff1aSopenharmony_ci                       || !compare(s, &(*next_point)->pkt, pkt)))
874cabdff1aSopenharmony_ci                next_point = &(*next_point)->next;
875cabdff1aSopenharmony_ci            if (*next_point)
876cabdff1aSopenharmony_ci                goto next_non_null;
877cabdff1aSopenharmony_ci        } else {
878cabdff1aSopenharmony_ci            next_point = &(si->packet_buffer.tail->next);
879cabdff1aSopenharmony_ci        }
880cabdff1aSopenharmony_ci    }
881cabdff1aSopenharmony_ci    av_assert1(!*next_point);
882cabdff1aSopenharmony_ci
883cabdff1aSopenharmony_ci    si->packet_buffer.tail = this_pktl;
884cabdff1aSopenharmony_cinext_non_null:
885cabdff1aSopenharmony_ci
886cabdff1aSopenharmony_ci    this_pktl->next = *next_point;
887cabdff1aSopenharmony_ci
888cabdff1aSopenharmony_ci    sti->last_in_packet_buffer = *next_point = this_pktl;
889cabdff1aSopenharmony_ci
890cabdff1aSopenharmony_ci    return 0;
891cabdff1aSopenharmony_ci}
892cabdff1aSopenharmony_ci
893cabdff1aSopenharmony_cistatic int interleave_compare_dts(AVFormatContext *s, const AVPacket *next,
894cabdff1aSopenharmony_ci                                                      const AVPacket *pkt)
895cabdff1aSopenharmony_ci{
896cabdff1aSopenharmony_ci    AVStream *st  = s->streams[pkt->stream_index];
897cabdff1aSopenharmony_ci    AVStream *st2 = s->streams[next->stream_index];
898cabdff1aSopenharmony_ci    int comp      = av_compare_ts(next->dts, st2->time_base, pkt->dts,
899cabdff1aSopenharmony_ci                                  st->time_base);
900cabdff1aSopenharmony_ci    if (s->audio_preload) {
901cabdff1aSopenharmony_ci        int preload  = st ->codecpar->codec_type == AVMEDIA_TYPE_AUDIO;
902cabdff1aSopenharmony_ci        int preload2 = st2->codecpar->codec_type == AVMEDIA_TYPE_AUDIO;
903cabdff1aSopenharmony_ci        if (preload != preload2) {
904cabdff1aSopenharmony_ci            int64_t ts, ts2;
905cabdff1aSopenharmony_ci            preload  *= s->audio_preload;
906cabdff1aSopenharmony_ci            preload2 *= s->audio_preload;
907cabdff1aSopenharmony_ci            ts = av_rescale_q(pkt ->dts, st ->time_base, AV_TIME_BASE_Q) - preload;
908cabdff1aSopenharmony_ci            ts2= av_rescale_q(next->dts, st2->time_base, AV_TIME_BASE_Q) - preload2;
909cabdff1aSopenharmony_ci            if (ts == ts2) {
910cabdff1aSopenharmony_ci                ts  = ((uint64_t)pkt ->dts*st ->time_base.num*AV_TIME_BASE - (uint64_t)preload *st ->time_base.den)*st2->time_base.den
911cabdff1aSopenharmony_ci                    - ((uint64_t)next->dts*st2->time_base.num*AV_TIME_BASE - (uint64_t)preload2*st2->time_base.den)*st ->time_base.den;
912cabdff1aSopenharmony_ci                ts2 = 0;
913cabdff1aSopenharmony_ci            }
914cabdff1aSopenharmony_ci            comp = (ts2 > ts) - (ts2 < ts);
915cabdff1aSopenharmony_ci        }
916cabdff1aSopenharmony_ci    }
917cabdff1aSopenharmony_ci
918cabdff1aSopenharmony_ci    if (comp == 0)
919cabdff1aSopenharmony_ci        return pkt->stream_index < next->stream_index;
920cabdff1aSopenharmony_ci    return comp > 0;
921cabdff1aSopenharmony_ci}
922cabdff1aSopenharmony_ci
923cabdff1aSopenharmony_ciint ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *pkt,
924cabdff1aSopenharmony_ci                                 int flush, int has_packet)
925cabdff1aSopenharmony_ci{
926cabdff1aSopenharmony_ci    FFFormatContext *const si = ffformatcontext(s);
927cabdff1aSopenharmony_ci    int stream_count = 0;
928cabdff1aSopenharmony_ci    int noninterleaved_count = 0;
929cabdff1aSopenharmony_ci    int ret;
930cabdff1aSopenharmony_ci    int eof = flush;
931cabdff1aSopenharmony_ci
932cabdff1aSopenharmony_ci    if (has_packet) {
933cabdff1aSopenharmony_ci        if ((ret = ff_interleave_add_packet(s, pkt, interleave_compare_dts)) < 0)
934cabdff1aSopenharmony_ci            return ret;
935cabdff1aSopenharmony_ci    }
936cabdff1aSopenharmony_ci
937cabdff1aSopenharmony_ci    for (unsigned i = 0; i < s->nb_streams; i++) {
938cabdff1aSopenharmony_ci        const AVStream *const st  = s->streams[i];
939cabdff1aSopenharmony_ci        const FFStream *const sti = cffstream(st);
940cabdff1aSopenharmony_ci        const AVCodecParameters *const par = st->codecpar;
941cabdff1aSopenharmony_ci        if (sti->last_in_packet_buffer) {
942cabdff1aSopenharmony_ci            ++stream_count;
943cabdff1aSopenharmony_ci        } else if (par->codec_type != AVMEDIA_TYPE_ATTACHMENT &&
944cabdff1aSopenharmony_ci                   par->codec_id != AV_CODEC_ID_VP8 &&
945cabdff1aSopenharmony_ci                   par->codec_id != AV_CODEC_ID_VP9) {
946cabdff1aSopenharmony_ci            ++noninterleaved_count;
947cabdff1aSopenharmony_ci        }
948cabdff1aSopenharmony_ci    }
949cabdff1aSopenharmony_ci
950cabdff1aSopenharmony_ci    if (si->nb_interleaved_streams == stream_count)
951cabdff1aSopenharmony_ci        flush = 1;
952cabdff1aSopenharmony_ci
953cabdff1aSopenharmony_ci    if (s->max_interleave_delta > 0 &&
954cabdff1aSopenharmony_ci        si->packet_buffer.head &&
955cabdff1aSopenharmony_ci        !flush &&
956cabdff1aSopenharmony_ci        si->nb_interleaved_streams == stream_count+noninterleaved_count
957cabdff1aSopenharmony_ci    ) {
958cabdff1aSopenharmony_ci        AVPacket *const top_pkt = &si->packet_buffer.head->pkt;
959cabdff1aSopenharmony_ci        int64_t delta_dts = INT64_MIN;
960cabdff1aSopenharmony_ci        int64_t top_dts = av_rescale_q(top_pkt->dts,
961cabdff1aSopenharmony_ci                                       s->streams[top_pkt->stream_index]->time_base,
962cabdff1aSopenharmony_ci                                       AV_TIME_BASE_Q);
963cabdff1aSopenharmony_ci
964cabdff1aSopenharmony_ci        for (unsigned i = 0; i < s->nb_streams; i++) {
965cabdff1aSopenharmony_ci            const AVStream *const st  = s->streams[i];
966cabdff1aSopenharmony_ci            const FFStream *const sti = cffstream(st);
967cabdff1aSopenharmony_ci            const PacketListEntry *const last = sti->last_in_packet_buffer;
968cabdff1aSopenharmony_ci            int64_t last_dts;
969cabdff1aSopenharmony_ci
970cabdff1aSopenharmony_ci            if (!last)
971cabdff1aSopenharmony_ci                continue;
972cabdff1aSopenharmony_ci
973cabdff1aSopenharmony_ci            last_dts = av_rescale_q(last->pkt.dts,
974cabdff1aSopenharmony_ci                                    st->time_base,
975cabdff1aSopenharmony_ci                                    AV_TIME_BASE_Q);
976cabdff1aSopenharmony_ci            delta_dts = FFMAX(delta_dts, last_dts - top_dts);
977cabdff1aSopenharmony_ci        }
978cabdff1aSopenharmony_ci
979cabdff1aSopenharmony_ci        if (delta_dts > s->max_interleave_delta) {
980cabdff1aSopenharmony_ci            av_log(s, AV_LOG_DEBUG,
981cabdff1aSopenharmony_ci                   "Delay between the first packet and last packet in the "
982cabdff1aSopenharmony_ci                   "muxing queue is %"PRId64" > %"PRId64": forcing output\n",
983cabdff1aSopenharmony_ci                   delta_dts, s->max_interleave_delta);
984cabdff1aSopenharmony_ci            flush = 1;
985cabdff1aSopenharmony_ci        }
986cabdff1aSopenharmony_ci    }
987cabdff1aSopenharmony_ci
988cabdff1aSopenharmony_ci    if (si->packet_buffer.head &&
989cabdff1aSopenharmony_ci        eof &&
990cabdff1aSopenharmony_ci        (s->flags & AVFMT_FLAG_SHORTEST) &&
991cabdff1aSopenharmony_ci        si->shortest_end == AV_NOPTS_VALUE) {
992cabdff1aSopenharmony_ci        AVPacket *const top_pkt = &si->packet_buffer.head->pkt;
993cabdff1aSopenharmony_ci
994cabdff1aSopenharmony_ci        si->shortest_end = av_rescale_q(top_pkt->dts,
995cabdff1aSopenharmony_ci                                       s->streams[top_pkt->stream_index]->time_base,
996cabdff1aSopenharmony_ci                                       AV_TIME_BASE_Q);
997cabdff1aSopenharmony_ci    }
998cabdff1aSopenharmony_ci
999cabdff1aSopenharmony_ci    if (si->shortest_end != AV_NOPTS_VALUE) {
1000cabdff1aSopenharmony_ci        while (si->packet_buffer.head) {
1001cabdff1aSopenharmony_ci            PacketListEntry *pktl = si->packet_buffer.head;
1002cabdff1aSopenharmony_ci            AVPacket *const top_pkt = &pktl->pkt;
1003cabdff1aSopenharmony_ci            AVStream *const st = s->streams[top_pkt->stream_index];
1004cabdff1aSopenharmony_ci            FFStream *const sti = ffstream(st);
1005cabdff1aSopenharmony_ci            int64_t top_dts = av_rescale_q(top_pkt->dts, st->time_base,
1006cabdff1aSopenharmony_ci                                        AV_TIME_BASE_Q);
1007cabdff1aSopenharmony_ci
1008cabdff1aSopenharmony_ci            if (si->shortest_end + 1 >= top_dts)
1009cabdff1aSopenharmony_ci                break;
1010cabdff1aSopenharmony_ci
1011cabdff1aSopenharmony_ci            si->packet_buffer.head = pktl->next;
1012cabdff1aSopenharmony_ci            if (!si->packet_buffer.head)
1013cabdff1aSopenharmony_ci                si->packet_buffer.tail = NULL;
1014cabdff1aSopenharmony_ci
1015cabdff1aSopenharmony_ci            if (sti->last_in_packet_buffer == pktl)
1016cabdff1aSopenharmony_ci                sti->last_in_packet_buffer = NULL;
1017cabdff1aSopenharmony_ci
1018cabdff1aSopenharmony_ci            av_packet_unref(&pktl->pkt);
1019cabdff1aSopenharmony_ci            av_freep(&pktl);
1020cabdff1aSopenharmony_ci            flush = 0;
1021cabdff1aSopenharmony_ci        }
1022cabdff1aSopenharmony_ci    }
1023cabdff1aSopenharmony_ci
1024cabdff1aSopenharmony_ci    if (stream_count && flush) {
1025cabdff1aSopenharmony_ci        PacketListEntry *pktl = si->packet_buffer.head;
1026cabdff1aSopenharmony_ci        AVStream *const st = s->streams[pktl->pkt.stream_index];
1027cabdff1aSopenharmony_ci        FFStream *const sti = ffstream(st);
1028cabdff1aSopenharmony_ci
1029cabdff1aSopenharmony_ci        if (sti->last_in_packet_buffer == pktl)
1030cabdff1aSopenharmony_ci            sti->last_in_packet_buffer = NULL;
1031cabdff1aSopenharmony_ci        avpriv_packet_list_get(&si->packet_buffer, pkt);
1032cabdff1aSopenharmony_ci
1033cabdff1aSopenharmony_ci        return 1;
1034cabdff1aSopenharmony_ci    } else {
1035cabdff1aSopenharmony_ci        return 0;
1036cabdff1aSopenharmony_ci    }
1037cabdff1aSopenharmony_ci}
1038cabdff1aSopenharmony_ci
1039cabdff1aSopenharmony_ciint ff_interleave_packet_passthrough(AVFormatContext *s, AVPacket *pkt,
1040cabdff1aSopenharmony_ci                                     int flush, int has_packet)
1041cabdff1aSopenharmony_ci{
1042cabdff1aSopenharmony_ci    return has_packet;
1043cabdff1aSopenharmony_ci}
1044cabdff1aSopenharmony_ci
1045cabdff1aSopenharmony_ciint ff_get_muxer_ts_offset(AVFormatContext *s, int stream_index, int64_t *offset)
1046cabdff1aSopenharmony_ci{
1047cabdff1aSopenharmony_ci    AVStream *st;
1048cabdff1aSopenharmony_ci
1049cabdff1aSopenharmony_ci    if (stream_index < 0 || stream_index >= s->nb_streams)
1050cabdff1aSopenharmony_ci        return AVERROR(EINVAL);
1051cabdff1aSopenharmony_ci
1052cabdff1aSopenharmony_ci    st = s->streams[stream_index];
1053cabdff1aSopenharmony_ci    *offset = ffstream(st)->mux_ts_offset;
1054cabdff1aSopenharmony_ci
1055cabdff1aSopenharmony_ci    if (s->output_ts_offset)
1056cabdff1aSopenharmony_ci        *offset += av_rescale_q(s->output_ts_offset, AV_TIME_BASE_Q, st->time_base);
1057cabdff1aSopenharmony_ci
1058cabdff1aSopenharmony_ci    return 0;
1059cabdff1aSopenharmony_ci}
1060cabdff1aSopenharmony_ci
1061cabdff1aSopenharmony_ciconst AVPacket *ff_interleaved_peek(AVFormatContext *s, int stream)
1062cabdff1aSopenharmony_ci{
1063cabdff1aSopenharmony_ci    FFFormatContext *const si = ffformatcontext(s);
1064cabdff1aSopenharmony_ci    PacketListEntry *pktl = si->packet_buffer.head;
1065cabdff1aSopenharmony_ci    while (pktl) {
1066cabdff1aSopenharmony_ci        if (pktl->pkt.stream_index == stream) {
1067cabdff1aSopenharmony_ci            return &pktl->pkt;
1068cabdff1aSopenharmony_ci        }
1069cabdff1aSopenharmony_ci        pktl = pktl->next;
1070cabdff1aSopenharmony_ci    }
1071cabdff1aSopenharmony_ci    return NULL;
1072cabdff1aSopenharmony_ci}
1073cabdff1aSopenharmony_ci
1074cabdff1aSopenharmony_cistatic int check_bitstream(AVFormatContext *s, FFStream *sti, AVPacket *pkt)
1075cabdff1aSopenharmony_ci{
1076cabdff1aSopenharmony_ci    int ret;
1077cabdff1aSopenharmony_ci
1078cabdff1aSopenharmony_ci    if (!(s->flags & AVFMT_FLAG_AUTO_BSF))
1079cabdff1aSopenharmony_ci        return 1;
1080cabdff1aSopenharmony_ci
1081cabdff1aSopenharmony_ci    if (s->oformat->check_bitstream) {
1082cabdff1aSopenharmony_ci        if (!sti->bitstream_checked) {
1083cabdff1aSopenharmony_ci            if ((ret = s->oformat->check_bitstream(s, &sti->pub, pkt)) < 0)
1084cabdff1aSopenharmony_ci                return ret;
1085cabdff1aSopenharmony_ci            else if (ret == 1)
1086cabdff1aSopenharmony_ci                sti->bitstream_checked = 1;
1087cabdff1aSopenharmony_ci        }
1088cabdff1aSopenharmony_ci    }
1089cabdff1aSopenharmony_ci
1090cabdff1aSopenharmony_ci    return 1;
1091cabdff1aSopenharmony_ci}
1092cabdff1aSopenharmony_ci
1093cabdff1aSopenharmony_cistatic int interleaved_write_packet(AVFormatContext *s, AVPacket *pkt,
1094cabdff1aSopenharmony_ci                                    int flush, int has_packet)
1095cabdff1aSopenharmony_ci{
1096cabdff1aSopenharmony_ci    FFFormatContext *const si = ffformatcontext(s);
1097cabdff1aSopenharmony_ci    for (;; ) {
1098cabdff1aSopenharmony_ci        int ret = si->interleave_packet(s, pkt, flush, has_packet);
1099cabdff1aSopenharmony_ci        if (ret <= 0)
1100cabdff1aSopenharmony_ci            return ret;
1101cabdff1aSopenharmony_ci
1102cabdff1aSopenharmony_ci        has_packet = 0;
1103cabdff1aSopenharmony_ci
1104cabdff1aSopenharmony_ci        ret = write_packet(s, pkt);
1105cabdff1aSopenharmony_ci        av_packet_unref(pkt);
1106cabdff1aSopenharmony_ci        if (ret < 0)
1107cabdff1aSopenharmony_ci            return ret;
1108cabdff1aSopenharmony_ci    }
1109cabdff1aSopenharmony_ci}
1110cabdff1aSopenharmony_ci
1111cabdff1aSopenharmony_cistatic int write_packet_common(AVFormatContext *s, AVStream *st, AVPacket *pkt, int interleaved)
1112cabdff1aSopenharmony_ci{
1113cabdff1aSopenharmony_ci    int ret;
1114cabdff1aSopenharmony_ci
1115cabdff1aSopenharmony_ci    if (s->debug & FF_FDEBUG_TS)
1116cabdff1aSopenharmony_ci        av_log(s, AV_LOG_DEBUG, "%s size:%d dts:%s pts:%s\n", __FUNCTION__,
1117cabdff1aSopenharmony_ci               pkt->size, av_ts2str(pkt->dts), av_ts2str(pkt->pts));
1118cabdff1aSopenharmony_ci
1119cabdff1aSopenharmony_ci    guess_pkt_duration(s, st, pkt);
1120cabdff1aSopenharmony_ci
1121cabdff1aSopenharmony_ci#if FF_API_COMPUTE_PKT_FIELDS2
1122cabdff1aSopenharmony_ci    if ((ret = compute_muxer_pkt_fields(s, st, pkt)) < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
1123cabdff1aSopenharmony_ci        return ret;
1124cabdff1aSopenharmony_ci#endif
1125cabdff1aSopenharmony_ci
1126cabdff1aSopenharmony_ci    if (interleaved) {
1127cabdff1aSopenharmony_ci        if (pkt->dts == AV_NOPTS_VALUE && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
1128cabdff1aSopenharmony_ci            return AVERROR(EINVAL);
1129cabdff1aSopenharmony_ci        return interleaved_write_packet(s, pkt, 0, 1);
1130cabdff1aSopenharmony_ci    } else {
1131cabdff1aSopenharmony_ci        return write_packet(s, pkt);
1132cabdff1aSopenharmony_ci    }
1133cabdff1aSopenharmony_ci}
1134cabdff1aSopenharmony_ci
1135cabdff1aSopenharmony_cistatic int write_packets_from_bsfs(AVFormatContext *s, AVStream *st, AVPacket *pkt, int interleaved)
1136cabdff1aSopenharmony_ci{
1137cabdff1aSopenharmony_ci    FFStream *const sti = ffstream(st);
1138cabdff1aSopenharmony_ci    AVBSFContext *const bsfc = sti->bsfc;
1139cabdff1aSopenharmony_ci    int ret;
1140cabdff1aSopenharmony_ci
1141cabdff1aSopenharmony_ci    if ((ret = av_bsf_send_packet(bsfc, pkt)) < 0) {
1142cabdff1aSopenharmony_ci        av_log(s, AV_LOG_ERROR,
1143cabdff1aSopenharmony_ci                "Failed to send packet to filter %s for stream %d\n",
1144cabdff1aSopenharmony_ci                bsfc->filter->name, st->index);
1145cabdff1aSopenharmony_ci        return ret;
1146cabdff1aSopenharmony_ci    }
1147cabdff1aSopenharmony_ci
1148cabdff1aSopenharmony_ci    do {
1149cabdff1aSopenharmony_ci        ret = av_bsf_receive_packet(bsfc, pkt);
1150cabdff1aSopenharmony_ci        if (ret < 0) {
1151cabdff1aSopenharmony_ci            if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
1152cabdff1aSopenharmony_ci                return 0;
1153cabdff1aSopenharmony_ci            av_log(s, AV_LOG_ERROR, "Error applying bitstream filters to an output "
1154cabdff1aSopenharmony_ci                   "packet for stream #%d: %s\n", st->index, av_err2str(ret));
1155cabdff1aSopenharmony_ci            if (!(s->error_recognition & AV_EF_EXPLODE) && ret != AVERROR(ENOMEM))
1156cabdff1aSopenharmony_ci                continue;
1157cabdff1aSopenharmony_ci            return ret;
1158cabdff1aSopenharmony_ci        }
1159cabdff1aSopenharmony_ci        av_packet_rescale_ts(pkt, bsfc->time_base_out, st->time_base);
1160cabdff1aSopenharmony_ci        ret = write_packet_common(s, st, pkt, interleaved);
1161cabdff1aSopenharmony_ci        if (ret >= 0 && !interleaved) // a successful write_packet_common already unrefed pkt for interleaved
1162cabdff1aSopenharmony_ci            av_packet_unref(pkt);
1163cabdff1aSopenharmony_ci    } while (ret >= 0);
1164cabdff1aSopenharmony_ci
1165cabdff1aSopenharmony_ci    return ret;
1166cabdff1aSopenharmony_ci}
1167cabdff1aSopenharmony_ci
1168cabdff1aSopenharmony_cistatic int write_packets_common(AVFormatContext *s, AVPacket *pkt, int interleaved)
1169cabdff1aSopenharmony_ci{
1170cabdff1aSopenharmony_ci    AVStream *st;
1171cabdff1aSopenharmony_ci    FFStream *sti;
1172cabdff1aSopenharmony_ci    int ret = check_packet(s, pkt);
1173cabdff1aSopenharmony_ci    if (ret < 0)
1174cabdff1aSopenharmony_ci        return ret;
1175cabdff1aSopenharmony_ci    st = s->streams[pkt->stream_index];
1176cabdff1aSopenharmony_ci    sti = ffstream(st);
1177cabdff1aSopenharmony_ci
1178cabdff1aSopenharmony_ci    ret = prepare_input_packet(s, st, pkt);
1179cabdff1aSopenharmony_ci    if (ret < 0)
1180cabdff1aSopenharmony_ci        return ret;
1181cabdff1aSopenharmony_ci
1182cabdff1aSopenharmony_ci    ret = check_bitstream(s, sti, pkt);
1183cabdff1aSopenharmony_ci    if (ret < 0)
1184cabdff1aSopenharmony_ci        return ret;
1185cabdff1aSopenharmony_ci
1186cabdff1aSopenharmony_ci    if (sti->bsfc) {
1187cabdff1aSopenharmony_ci        return write_packets_from_bsfs(s, st, pkt, interleaved);
1188cabdff1aSopenharmony_ci    } else {
1189cabdff1aSopenharmony_ci        return write_packet_common(s, st, pkt, interleaved);
1190cabdff1aSopenharmony_ci    }
1191cabdff1aSopenharmony_ci}
1192cabdff1aSopenharmony_ci
1193cabdff1aSopenharmony_ciint av_write_frame(AVFormatContext *s, AVPacket *in)
1194cabdff1aSopenharmony_ci{
1195cabdff1aSopenharmony_ci    FFFormatContext *const si = ffformatcontext(s);
1196cabdff1aSopenharmony_ci    AVPacket *pkt = si->parse_pkt;
1197cabdff1aSopenharmony_ci    int ret;
1198cabdff1aSopenharmony_ci
1199cabdff1aSopenharmony_ci    if (!in) {
1200cabdff1aSopenharmony_ci        if (s->oformat->flags & AVFMT_ALLOW_FLUSH) {
1201cabdff1aSopenharmony_ci            ret = s->oformat->write_packet(s, NULL);
1202cabdff1aSopenharmony_ci            flush_if_needed(s);
1203cabdff1aSopenharmony_ci            if (ret >= 0 && s->pb && s->pb->error < 0)
1204cabdff1aSopenharmony_ci                ret = s->pb->error;
1205cabdff1aSopenharmony_ci            return ret;
1206cabdff1aSopenharmony_ci        }
1207cabdff1aSopenharmony_ci        return 1;
1208cabdff1aSopenharmony_ci    }
1209cabdff1aSopenharmony_ci
1210cabdff1aSopenharmony_ci    if (in->flags & AV_PKT_FLAG_UNCODED_FRAME) {
1211cabdff1aSopenharmony_ci        pkt = in;
1212cabdff1aSopenharmony_ci    } else {
1213cabdff1aSopenharmony_ci        /* We don't own in, so we have to make sure not to modify it.
1214cabdff1aSopenharmony_ci         * (ff_write_chained() relies on this fact.)
1215cabdff1aSopenharmony_ci         * The following avoids copying in's data unnecessarily.
1216cabdff1aSopenharmony_ci         * Copying side data is unavoidable as a bitstream filter
1217cabdff1aSopenharmony_ci         * may change it, e.g. free it on errors. */
1218cabdff1aSopenharmony_ci        pkt->data = in->data;
1219cabdff1aSopenharmony_ci        pkt->size = in->size;
1220cabdff1aSopenharmony_ci        ret = av_packet_copy_props(pkt, in);
1221cabdff1aSopenharmony_ci        if (ret < 0)
1222cabdff1aSopenharmony_ci            return ret;
1223cabdff1aSopenharmony_ci        if (in->buf) {
1224cabdff1aSopenharmony_ci            pkt->buf = av_buffer_ref(in->buf);
1225cabdff1aSopenharmony_ci            if (!pkt->buf) {
1226cabdff1aSopenharmony_ci                ret = AVERROR(ENOMEM);
1227cabdff1aSopenharmony_ci                goto fail;
1228cabdff1aSopenharmony_ci            }
1229cabdff1aSopenharmony_ci        }
1230cabdff1aSopenharmony_ci    }
1231cabdff1aSopenharmony_ci
1232cabdff1aSopenharmony_ci    ret = write_packets_common(s, pkt, 0/*non-interleaved*/);
1233cabdff1aSopenharmony_ci
1234cabdff1aSopenharmony_cifail:
1235cabdff1aSopenharmony_ci    // Uncoded frames using the noninterleaved codepath are also freed here
1236cabdff1aSopenharmony_ci    av_packet_unref(pkt);
1237cabdff1aSopenharmony_ci    return ret;
1238cabdff1aSopenharmony_ci}
1239cabdff1aSopenharmony_ci
1240cabdff1aSopenharmony_ciint av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt)
1241cabdff1aSopenharmony_ci{
1242cabdff1aSopenharmony_ci    int ret;
1243cabdff1aSopenharmony_ci
1244cabdff1aSopenharmony_ci    if (pkt) {
1245cabdff1aSopenharmony_ci        ret = write_packets_common(s, pkt, 1/*interleaved*/);
1246cabdff1aSopenharmony_ci        if (ret < 0)
1247cabdff1aSopenharmony_ci            av_packet_unref(pkt);
1248cabdff1aSopenharmony_ci        return ret;
1249cabdff1aSopenharmony_ci    } else {
1250cabdff1aSopenharmony_ci        av_log(s, AV_LOG_TRACE, "av_interleaved_write_frame FLUSH\n");
1251cabdff1aSopenharmony_ci        return interleaved_write_packet(s, ffformatcontext(s)->parse_pkt, 1/*flush*/, 0);
1252cabdff1aSopenharmony_ci    }
1253cabdff1aSopenharmony_ci}
1254cabdff1aSopenharmony_ci
1255cabdff1aSopenharmony_ciint av_write_trailer(AVFormatContext *s)
1256cabdff1aSopenharmony_ci{
1257cabdff1aSopenharmony_ci    FFFormatContext *const si = ffformatcontext(s);
1258cabdff1aSopenharmony_ci    AVPacket *const pkt = si->parse_pkt;
1259cabdff1aSopenharmony_ci    int ret1, ret = 0;
1260cabdff1aSopenharmony_ci
1261cabdff1aSopenharmony_ci    for (unsigned i = 0; i < s->nb_streams; i++) {
1262cabdff1aSopenharmony_ci        AVStream *const st  = s->streams[i];
1263cabdff1aSopenharmony_ci        FFStream *const sti = ffstream(st);
1264cabdff1aSopenharmony_ci        if (sti->bsfc) {
1265cabdff1aSopenharmony_ci            ret1 = write_packets_from_bsfs(s, st, pkt, 1/*interleaved*/);
1266cabdff1aSopenharmony_ci            if (ret1 < 0)
1267cabdff1aSopenharmony_ci                av_packet_unref(pkt);
1268cabdff1aSopenharmony_ci            if (ret >= 0)
1269cabdff1aSopenharmony_ci                ret = ret1;
1270cabdff1aSopenharmony_ci        }
1271cabdff1aSopenharmony_ci    }
1272cabdff1aSopenharmony_ci    ret1 = interleaved_write_packet(s, pkt, 1, 0);
1273cabdff1aSopenharmony_ci    if (ret >= 0)
1274cabdff1aSopenharmony_ci        ret = ret1;
1275cabdff1aSopenharmony_ci
1276cabdff1aSopenharmony_ci    if (s->oformat->write_trailer) {
1277cabdff1aSopenharmony_ci        if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
1278cabdff1aSopenharmony_ci            avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_TRAILER);
1279cabdff1aSopenharmony_ci        if (ret >= 0) {
1280cabdff1aSopenharmony_ci        ret = s->oformat->write_trailer(s);
1281cabdff1aSopenharmony_ci        } else {
1282cabdff1aSopenharmony_ci            s->oformat->write_trailer(s);
1283cabdff1aSopenharmony_ci        }
1284cabdff1aSopenharmony_ci    }
1285cabdff1aSopenharmony_ci
1286cabdff1aSopenharmony_ci    deinit_muxer(s);
1287cabdff1aSopenharmony_ci
1288cabdff1aSopenharmony_ci    if (s->pb)
1289cabdff1aSopenharmony_ci       avio_flush(s->pb);
1290cabdff1aSopenharmony_ci    if (ret == 0)
1291cabdff1aSopenharmony_ci       ret = s->pb ? s->pb->error : 0;
1292cabdff1aSopenharmony_ci    for (unsigned i = 0; i < s->nb_streams; i++) {
1293cabdff1aSopenharmony_ci        av_freep(&s->streams[i]->priv_data);
1294cabdff1aSopenharmony_ci        av_freep(&ffstream(s->streams[i])->index_entries);
1295cabdff1aSopenharmony_ci    }
1296cabdff1aSopenharmony_ci    if (s->oformat->priv_class)
1297cabdff1aSopenharmony_ci        av_opt_free(s->priv_data);
1298cabdff1aSopenharmony_ci    av_freep(&s->priv_data);
1299cabdff1aSopenharmony_ci    av_packet_unref(si->pkt);
1300cabdff1aSopenharmony_ci    return ret;
1301cabdff1aSopenharmony_ci}
1302cabdff1aSopenharmony_ci
1303cabdff1aSopenharmony_ciint av_get_output_timestamp(struct AVFormatContext *s, int stream,
1304cabdff1aSopenharmony_ci                            int64_t *dts, int64_t *wall)
1305cabdff1aSopenharmony_ci{
1306cabdff1aSopenharmony_ci    if (!s->oformat || !s->oformat->get_output_timestamp)
1307cabdff1aSopenharmony_ci        return AVERROR(ENOSYS);
1308cabdff1aSopenharmony_ci    s->oformat->get_output_timestamp(s, stream, dts, wall);
1309cabdff1aSopenharmony_ci    return 0;
1310cabdff1aSopenharmony_ci}
1311cabdff1aSopenharmony_ci
1312cabdff1aSopenharmony_ciint ff_stream_add_bitstream_filter(AVStream *st, const char *name, const char *args)
1313cabdff1aSopenharmony_ci{
1314cabdff1aSopenharmony_ci    int ret;
1315cabdff1aSopenharmony_ci    const AVBitStreamFilter *bsf;
1316cabdff1aSopenharmony_ci    FFStream *const sti = ffstream(st);
1317cabdff1aSopenharmony_ci    AVBSFContext *bsfc;
1318cabdff1aSopenharmony_ci
1319cabdff1aSopenharmony_ci    av_assert0(!sti->bsfc);
1320cabdff1aSopenharmony_ci
1321cabdff1aSopenharmony_ci    if (!(bsf = av_bsf_get_by_name(name))) {
1322cabdff1aSopenharmony_ci        av_log(NULL, AV_LOG_ERROR, "Unknown bitstream filter '%s'\n", name);
1323cabdff1aSopenharmony_ci        return AVERROR_BSF_NOT_FOUND;
1324cabdff1aSopenharmony_ci    }
1325cabdff1aSopenharmony_ci
1326cabdff1aSopenharmony_ci    if ((ret = av_bsf_alloc(bsf, &bsfc)) < 0)
1327cabdff1aSopenharmony_ci        return ret;
1328cabdff1aSopenharmony_ci
1329cabdff1aSopenharmony_ci    bsfc->time_base_in = st->time_base;
1330cabdff1aSopenharmony_ci    if ((ret = avcodec_parameters_copy(bsfc->par_in, st->codecpar)) < 0) {
1331cabdff1aSopenharmony_ci        av_bsf_free(&bsfc);
1332cabdff1aSopenharmony_ci        return ret;
1333cabdff1aSopenharmony_ci    }
1334cabdff1aSopenharmony_ci
1335cabdff1aSopenharmony_ci    if (args && bsfc->filter->priv_class) {
1336cabdff1aSopenharmony_ci        if ((ret = av_set_options_string(bsfc->priv_data, args, "=", ":")) < 0) {
1337cabdff1aSopenharmony_ci            av_bsf_free(&bsfc);
1338cabdff1aSopenharmony_ci            return ret;
1339cabdff1aSopenharmony_ci        }
1340cabdff1aSopenharmony_ci    }
1341cabdff1aSopenharmony_ci
1342cabdff1aSopenharmony_ci    if ((ret = av_bsf_init(bsfc)) < 0) {
1343cabdff1aSopenharmony_ci        av_bsf_free(&bsfc);
1344cabdff1aSopenharmony_ci        return ret;
1345cabdff1aSopenharmony_ci    }
1346cabdff1aSopenharmony_ci
1347cabdff1aSopenharmony_ci    sti->bsfc = bsfc;
1348cabdff1aSopenharmony_ci
1349cabdff1aSopenharmony_ci    av_log(NULL, AV_LOG_VERBOSE,
1350cabdff1aSopenharmony_ci           "Automatically inserted bitstream filter '%s'; args='%s'\n",
1351cabdff1aSopenharmony_ci           name, args ? args : "");
1352cabdff1aSopenharmony_ci    return 1;
1353cabdff1aSopenharmony_ci}
1354cabdff1aSopenharmony_ci
1355cabdff1aSopenharmony_ciint ff_write_chained(AVFormatContext *dst, int dst_stream, AVPacket *pkt,
1356cabdff1aSopenharmony_ci                     AVFormatContext *src, int interleave)
1357cabdff1aSopenharmony_ci{
1358cabdff1aSopenharmony_ci    int64_t pts = pkt->pts, dts = pkt->dts, duration = pkt->duration;
1359cabdff1aSopenharmony_ci    int stream_index = pkt->stream_index;
1360cabdff1aSopenharmony_ci    AVRational time_base = pkt->time_base;
1361cabdff1aSopenharmony_ci    int ret;
1362cabdff1aSopenharmony_ci
1363cabdff1aSopenharmony_ci    pkt->stream_index = dst_stream;
1364cabdff1aSopenharmony_ci
1365cabdff1aSopenharmony_ci    av_packet_rescale_ts(pkt,
1366cabdff1aSopenharmony_ci                         src->streams[stream_index]->time_base,
1367cabdff1aSopenharmony_ci                         dst->streams[dst_stream]->time_base);
1368cabdff1aSopenharmony_ci
1369cabdff1aSopenharmony_ci    if (!interleave) {
1370cabdff1aSopenharmony_ci        ret = av_write_frame(dst, pkt);
1371cabdff1aSopenharmony_ci        /* We only have to backup and restore the fields that
1372cabdff1aSopenharmony_ci         * we changed ourselves, because av_write_frame() does not
1373cabdff1aSopenharmony_ci         * modify the packet given to it. */
1374cabdff1aSopenharmony_ci        pkt->pts          = pts;
1375cabdff1aSopenharmony_ci        pkt->dts          = dts;
1376cabdff1aSopenharmony_ci        pkt->duration     = duration;
1377cabdff1aSopenharmony_ci        pkt->stream_index = stream_index;
1378cabdff1aSopenharmony_ci        pkt->time_base    = time_base;
1379cabdff1aSopenharmony_ci    } else
1380cabdff1aSopenharmony_ci        ret = av_interleaved_write_frame(dst, pkt);
1381cabdff1aSopenharmony_ci
1382cabdff1aSopenharmony_ci    return ret;
1383cabdff1aSopenharmony_ci}
1384cabdff1aSopenharmony_ci
1385cabdff1aSopenharmony_cistatic void uncoded_frame_free(void *unused, uint8_t *data)
1386cabdff1aSopenharmony_ci{
1387cabdff1aSopenharmony_ci    av_frame_free((AVFrame **)data);
1388cabdff1aSopenharmony_ci    av_free(data);
1389cabdff1aSopenharmony_ci}
1390cabdff1aSopenharmony_ci
1391cabdff1aSopenharmony_cistatic int write_uncoded_frame_internal(AVFormatContext *s, int stream_index,
1392cabdff1aSopenharmony_ci                                        AVFrame *frame, int interleaved)
1393cabdff1aSopenharmony_ci{
1394cabdff1aSopenharmony_ci    FFFormatContext *const si = ffformatcontext(s);
1395cabdff1aSopenharmony_ci    AVPacket *pkt = si->parse_pkt;
1396cabdff1aSopenharmony_ci
1397cabdff1aSopenharmony_ci    av_assert0(s->oformat);
1398cabdff1aSopenharmony_ci    if (!s->oformat->write_uncoded_frame) {
1399cabdff1aSopenharmony_ci        av_frame_free(&frame);
1400cabdff1aSopenharmony_ci        return AVERROR(ENOSYS);
1401cabdff1aSopenharmony_ci    }
1402cabdff1aSopenharmony_ci
1403cabdff1aSopenharmony_ci    if (!frame) {
1404cabdff1aSopenharmony_ci        pkt = NULL;
1405cabdff1aSopenharmony_ci    } else {
1406cabdff1aSopenharmony_ci        size_t   bufsize = sizeof(frame) + AV_INPUT_BUFFER_PADDING_SIZE;
1407cabdff1aSopenharmony_ci        AVFrame **framep = av_mallocz(bufsize);
1408cabdff1aSopenharmony_ci
1409cabdff1aSopenharmony_ci        if (!framep)
1410cabdff1aSopenharmony_ci            goto fail;
1411cabdff1aSopenharmony_ci        pkt->buf = av_buffer_create((void *)framep, bufsize,
1412cabdff1aSopenharmony_ci                                   uncoded_frame_free, NULL, 0);
1413cabdff1aSopenharmony_ci        if (!pkt->buf) {
1414cabdff1aSopenharmony_ci            av_free(framep);
1415cabdff1aSopenharmony_ci    fail:
1416cabdff1aSopenharmony_ci            av_frame_free(&frame);
1417cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
1418cabdff1aSopenharmony_ci        }
1419cabdff1aSopenharmony_ci        *framep = frame;
1420cabdff1aSopenharmony_ci
1421cabdff1aSopenharmony_ci        pkt->data         = (void *)framep;
1422cabdff1aSopenharmony_ci        pkt->size         = sizeof(frame);
1423cabdff1aSopenharmony_ci        pkt->pts          =
1424cabdff1aSopenharmony_ci        pkt->dts          = frame->pts;
1425cabdff1aSopenharmony_ci        pkt->duration     = frame->pkt_duration;
1426cabdff1aSopenharmony_ci        pkt->stream_index = stream_index;
1427cabdff1aSopenharmony_ci        pkt->flags |= AV_PKT_FLAG_UNCODED_FRAME;
1428cabdff1aSopenharmony_ci    }
1429cabdff1aSopenharmony_ci
1430cabdff1aSopenharmony_ci    return interleaved ? av_interleaved_write_frame(s, pkt) :
1431cabdff1aSopenharmony_ci                         av_write_frame(s, pkt);
1432cabdff1aSopenharmony_ci}
1433cabdff1aSopenharmony_ci
1434cabdff1aSopenharmony_ciint av_write_uncoded_frame(AVFormatContext *s, int stream_index,
1435cabdff1aSopenharmony_ci                           AVFrame *frame)
1436cabdff1aSopenharmony_ci{
1437cabdff1aSopenharmony_ci    return write_uncoded_frame_internal(s, stream_index, frame, 0);
1438cabdff1aSopenharmony_ci}
1439cabdff1aSopenharmony_ci
1440cabdff1aSopenharmony_ciint av_interleaved_write_uncoded_frame(AVFormatContext *s, int stream_index,
1441cabdff1aSopenharmony_ci                                       AVFrame *frame)
1442cabdff1aSopenharmony_ci{
1443cabdff1aSopenharmony_ci    return write_uncoded_frame_internal(s, stream_index, frame, 1);
1444cabdff1aSopenharmony_ci}
1445cabdff1aSopenharmony_ci
1446cabdff1aSopenharmony_ciint av_write_uncoded_frame_query(AVFormatContext *s, int stream_index)
1447cabdff1aSopenharmony_ci{
1448cabdff1aSopenharmony_ci    av_assert0(s->oformat);
1449cabdff1aSopenharmony_ci    if (!s->oformat->write_uncoded_frame)
1450cabdff1aSopenharmony_ci        return AVERROR(ENOSYS);
1451cabdff1aSopenharmony_ci    return s->oformat->write_uncoded_frame(s, stream_index, NULL,
1452cabdff1aSopenharmony_ci                                           AV_WRITE_UNCODED_FRAME_QUERY);
1453cabdff1aSopenharmony_ci}
1454