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