1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Various functions used by both muxers and demuxers 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 <math.h> 23cabdff1aSopenharmony_ci#include "libavutil/avassert.h" 24cabdff1aSopenharmony_ci#include "libavutil/avstring.h" 25cabdff1aSopenharmony_ci#include "libavutil/channel_layout.h" 26cabdff1aSopenharmony_ci#include "libavutil/intreadwrite.h" 27cabdff1aSopenharmony_ci#include "libavutil/mem.h" 28cabdff1aSopenharmony_ci#include "libavutil/opt.h" 29cabdff1aSopenharmony_ci#include "libavutil/pixfmt.h" 30cabdff1aSopenharmony_ci#include "libavutil/samplefmt.h" 31cabdff1aSopenharmony_ci#include "libavcodec/avcodec.h" 32cabdff1aSopenharmony_ci#include "libavcodec/bsf.h" 33cabdff1aSopenharmony_ci#include "libavcodec/codec_desc.h" 34cabdff1aSopenharmony_ci#include "libavcodec/packet_internal.h" 35cabdff1aSopenharmony_ci#include "avformat.h" 36cabdff1aSopenharmony_ci#include "avio.h" 37cabdff1aSopenharmony_ci#include "demux.h" 38cabdff1aSopenharmony_ci#include "internal.h" 39cabdff1aSopenharmony_ci 40cabdff1aSopenharmony_civoid ff_free_stream(AVStream **pst) 41cabdff1aSopenharmony_ci{ 42cabdff1aSopenharmony_ci AVStream *st = *pst; 43cabdff1aSopenharmony_ci FFStream *const sti = ffstream(st); 44cabdff1aSopenharmony_ci 45cabdff1aSopenharmony_ci if (!st) 46cabdff1aSopenharmony_ci return; 47cabdff1aSopenharmony_ci 48cabdff1aSopenharmony_ci for (int i = 0; i < st->nb_side_data; i++) 49cabdff1aSopenharmony_ci av_freep(&st->side_data[i].data); 50cabdff1aSopenharmony_ci av_freep(&st->side_data); 51cabdff1aSopenharmony_ci 52cabdff1aSopenharmony_ci if (st->attached_pic.data) 53cabdff1aSopenharmony_ci av_packet_unref(&st->attached_pic); 54cabdff1aSopenharmony_ci 55cabdff1aSopenharmony_ci av_parser_close(sti->parser); 56cabdff1aSopenharmony_ci avcodec_free_context(&sti->avctx); 57cabdff1aSopenharmony_ci av_bsf_free(&sti->bsfc); 58cabdff1aSopenharmony_ci av_freep(&sti->priv_pts); 59cabdff1aSopenharmony_ci av_freep(&sti->index_entries); 60cabdff1aSopenharmony_ci av_freep(&sti->probe_data.buf); 61cabdff1aSopenharmony_ci 62cabdff1aSopenharmony_ci av_bsf_free(&sti->extract_extradata.bsf); 63cabdff1aSopenharmony_ci 64cabdff1aSopenharmony_ci if (sti->info) { 65cabdff1aSopenharmony_ci av_freep(&sti->info->duration_error); 66cabdff1aSopenharmony_ci av_freep(&sti->info); 67cabdff1aSopenharmony_ci } 68cabdff1aSopenharmony_ci 69cabdff1aSopenharmony_ci av_dict_free(&st->metadata); 70cabdff1aSopenharmony_ci avcodec_parameters_free(&st->codecpar); 71cabdff1aSopenharmony_ci av_freep(&st->priv_data); 72cabdff1aSopenharmony_ci 73cabdff1aSopenharmony_ci av_freep(pst); 74cabdff1aSopenharmony_ci} 75cabdff1aSopenharmony_ci 76cabdff1aSopenharmony_civoid ff_remove_stream(AVFormatContext *s, AVStream *st) 77cabdff1aSopenharmony_ci{ 78cabdff1aSopenharmony_ci av_assert0(s->nb_streams>0); 79cabdff1aSopenharmony_ci av_assert0(s->streams[ s->nb_streams - 1 ] == st); 80cabdff1aSopenharmony_ci 81cabdff1aSopenharmony_ci ff_free_stream(&s->streams[ --s->nb_streams ]); 82cabdff1aSopenharmony_ci} 83cabdff1aSopenharmony_ci 84cabdff1aSopenharmony_ci/* XXX: suppress the packet queue */ 85cabdff1aSopenharmony_civoid ff_flush_packet_queue(AVFormatContext *s) 86cabdff1aSopenharmony_ci{ 87cabdff1aSopenharmony_ci FFFormatContext *const si = ffformatcontext(s); 88cabdff1aSopenharmony_ci avpriv_packet_list_free(&si->parse_queue); 89cabdff1aSopenharmony_ci avpriv_packet_list_free(&si->packet_buffer); 90cabdff1aSopenharmony_ci avpriv_packet_list_free(&si->raw_packet_buffer); 91cabdff1aSopenharmony_ci 92cabdff1aSopenharmony_ci si->raw_packet_buffer_size = 0; 93cabdff1aSopenharmony_ci} 94cabdff1aSopenharmony_ci 95cabdff1aSopenharmony_civoid avformat_free_context(AVFormatContext *s) 96cabdff1aSopenharmony_ci{ 97cabdff1aSopenharmony_ci FFFormatContext *si; 98cabdff1aSopenharmony_ci 99cabdff1aSopenharmony_ci if (!s) 100cabdff1aSopenharmony_ci return; 101cabdff1aSopenharmony_ci si = ffformatcontext(s); 102cabdff1aSopenharmony_ci 103cabdff1aSopenharmony_ci if (s->oformat && s->oformat->deinit && si->initialized) 104cabdff1aSopenharmony_ci s->oformat->deinit(s); 105cabdff1aSopenharmony_ci 106cabdff1aSopenharmony_ci av_opt_free(s); 107cabdff1aSopenharmony_ci if (s->iformat && s->iformat->priv_class && s->priv_data) 108cabdff1aSopenharmony_ci av_opt_free(s->priv_data); 109cabdff1aSopenharmony_ci if (s->oformat && s->oformat->priv_class && s->priv_data) 110cabdff1aSopenharmony_ci av_opt_free(s->priv_data); 111cabdff1aSopenharmony_ci 112cabdff1aSopenharmony_ci for (unsigned i = 0; i < s->nb_streams; i++) 113cabdff1aSopenharmony_ci ff_free_stream(&s->streams[i]); 114cabdff1aSopenharmony_ci s->nb_streams = 0; 115cabdff1aSopenharmony_ci 116cabdff1aSopenharmony_ci for (unsigned i = 0; i < s->nb_programs; i++) { 117cabdff1aSopenharmony_ci av_dict_free(&s->programs[i]->metadata); 118cabdff1aSopenharmony_ci av_freep(&s->programs[i]->stream_index); 119cabdff1aSopenharmony_ci av_freep(&s->programs[i]); 120cabdff1aSopenharmony_ci } 121cabdff1aSopenharmony_ci s->nb_programs = 0; 122cabdff1aSopenharmony_ci 123cabdff1aSopenharmony_ci av_freep(&s->programs); 124cabdff1aSopenharmony_ci av_freep(&s->priv_data); 125cabdff1aSopenharmony_ci while (s->nb_chapters--) { 126cabdff1aSopenharmony_ci av_dict_free(&s->chapters[s->nb_chapters]->metadata); 127cabdff1aSopenharmony_ci av_freep(&s->chapters[s->nb_chapters]); 128cabdff1aSopenharmony_ci } 129cabdff1aSopenharmony_ci av_freep(&s->chapters); 130cabdff1aSopenharmony_ci av_dict_free(&s->metadata); 131cabdff1aSopenharmony_ci av_dict_free(&si->id3v2_meta); 132cabdff1aSopenharmony_ci av_packet_free(&si->pkt); 133cabdff1aSopenharmony_ci av_packet_free(&si->parse_pkt); 134cabdff1aSopenharmony_ci av_freep(&s->streams); 135cabdff1aSopenharmony_ci ff_flush_packet_queue(s); 136cabdff1aSopenharmony_ci av_freep(&s->url); 137cabdff1aSopenharmony_ci av_free(s); 138cabdff1aSopenharmony_ci} 139cabdff1aSopenharmony_ci 140cabdff1aSopenharmony_ciuint8_t *av_stream_get_side_data(const AVStream *st, 141cabdff1aSopenharmony_ci enum AVPacketSideDataType type, size_t *size) 142cabdff1aSopenharmony_ci{ 143cabdff1aSopenharmony_ci for (int i = 0; i < st->nb_side_data; i++) { 144cabdff1aSopenharmony_ci if (st->side_data[i].type == type) { 145cabdff1aSopenharmony_ci if (size) 146cabdff1aSopenharmony_ci *size = st->side_data[i].size; 147cabdff1aSopenharmony_ci return st->side_data[i].data; 148cabdff1aSopenharmony_ci } 149cabdff1aSopenharmony_ci } 150cabdff1aSopenharmony_ci if (size) 151cabdff1aSopenharmony_ci *size = 0; 152cabdff1aSopenharmony_ci return NULL; 153cabdff1aSopenharmony_ci} 154cabdff1aSopenharmony_ci 155cabdff1aSopenharmony_ciint av_stream_add_side_data(AVStream *st, enum AVPacketSideDataType type, 156cabdff1aSopenharmony_ci uint8_t *data, size_t size) 157cabdff1aSopenharmony_ci{ 158cabdff1aSopenharmony_ci AVPacketSideData *sd, *tmp; 159cabdff1aSopenharmony_ci 160cabdff1aSopenharmony_ci for (int i = 0; i < st->nb_side_data; i++) { 161cabdff1aSopenharmony_ci sd = &st->side_data[i]; 162cabdff1aSopenharmony_ci 163cabdff1aSopenharmony_ci if (sd->type == type) { 164cabdff1aSopenharmony_ci av_freep(&sd->data); 165cabdff1aSopenharmony_ci sd->data = data; 166cabdff1aSopenharmony_ci sd->size = size; 167cabdff1aSopenharmony_ci return 0; 168cabdff1aSopenharmony_ci } 169cabdff1aSopenharmony_ci } 170cabdff1aSopenharmony_ci 171cabdff1aSopenharmony_ci if (st->nb_side_data + 1U > FFMIN(INT_MAX, SIZE_MAX / sizeof(*tmp))) 172cabdff1aSopenharmony_ci return AVERROR(ERANGE); 173cabdff1aSopenharmony_ci 174cabdff1aSopenharmony_ci tmp = av_realloc_array(st->side_data, st->nb_side_data + 1, sizeof(*tmp)); 175cabdff1aSopenharmony_ci if (!tmp) { 176cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 177cabdff1aSopenharmony_ci } 178cabdff1aSopenharmony_ci 179cabdff1aSopenharmony_ci st->side_data = tmp; 180cabdff1aSopenharmony_ci st->nb_side_data++; 181cabdff1aSopenharmony_ci 182cabdff1aSopenharmony_ci sd = &st->side_data[st->nb_side_data - 1]; 183cabdff1aSopenharmony_ci sd->type = type; 184cabdff1aSopenharmony_ci sd->data = data; 185cabdff1aSopenharmony_ci sd->size = size; 186cabdff1aSopenharmony_ci 187cabdff1aSopenharmony_ci return 0; 188cabdff1aSopenharmony_ci} 189cabdff1aSopenharmony_ci 190cabdff1aSopenharmony_ciuint8_t *av_stream_new_side_data(AVStream *st, enum AVPacketSideDataType type, 191cabdff1aSopenharmony_ci size_t size) 192cabdff1aSopenharmony_ci{ 193cabdff1aSopenharmony_ci int ret; 194cabdff1aSopenharmony_ci uint8_t *data = av_malloc(size); 195cabdff1aSopenharmony_ci 196cabdff1aSopenharmony_ci if (!data) 197cabdff1aSopenharmony_ci return NULL; 198cabdff1aSopenharmony_ci 199cabdff1aSopenharmony_ci ret = av_stream_add_side_data(st, type, data, size); 200cabdff1aSopenharmony_ci if (ret < 0) { 201cabdff1aSopenharmony_ci av_freep(&data); 202cabdff1aSopenharmony_ci return NULL; 203cabdff1aSopenharmony_ci } 204cabdff1aSopenharmony_ci 205cabdff1aSopenharmony_ci return data; 206cabdff1aSopenharmony_ci} 207cabdff1aSopenharmony_ci 208cabdff1aSopenharmony_ciint ff_stream_side_data_copy(AVStream *dst, const AVStream *src) 209cabdff1aSopenharmony_ci{ 210cabdff1aSopenharmony_ci /* Free existing side data*/ 211cabdff1aSopenharmony_ci for (int i = 0; i < dst->nb_side_data; i++) 212cabdff1aSopenharmony_ci av_free(dst->side_data[i].data); 213cabdff1aSopenharmony_ci av_freep(&dst->side_data); 214cabdff1aSopenharmony_ci dst->nb_side_data = 0; 215cabdff1aSopenharmony_ci 216cabdff1aSopenharmony_ci /* Copy side data if present */ 217cabdff1aSopenharmony_ci if (src->nb_side_data) { 218cabdff1aSopenharmony_ci dst->side_data = av_calloc(src->nb_side_data, 219cabdff1aSopenharmony_ci sizeof(*dst->side_data)); 220cabdff1aSopenharmony_ci if (!dst->side_data) 221cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 222cabdff1aSopenharmony_ci dst->nb_side_data = src->nb_side_data; 223cabdff1aSopenharmony_ci 224cabdff1aSopenharmony_ci for (int i = 0; i < src->nb_side_data; i++) { 225cabdff1aSopenharmony_ci uint8_t *data = av_memdup(src->side_data[i].data, 226cabdff1aSopenharmony_ci src->side_data[i].size); 227cabdff1aSopenharmony_ci if (!data) 228cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 229cabdff1aSopenharmony_ci dst->side_data[i].type = src->side_data[i].type; 230cabdff1aSopenharmony_ci dst->side_data[i].size = src->side_data[i].size; 231cabdff1aSopenharmony_ci dst->side_data[i].data = data; 232cabdff1aSopenharmony_ci } 233cabdff1aSopenharmony_ci } 234cabdff1aSopenharmony_ci 235cabdff1aSopenharmony_ci return 0; 236cabdff1aSopenharmony_ci} 237cabdff1aSopenharmony_ci 238cabdff1aSopenharmony_ciAVProgram *av_new_program(AVFormatContext *ac, int id) 239cabdff1aSopenharmony_ci{ 240cabdff1aSopenharmony_ci AVProgram *program = NULL; 241cabdff1aSopenharmony_ci int ret; 242cabdff1aSopenharmony_ci 243cabdff1aSopenharmony_ci av_log(ac, AV_LOG_TRACE, "new_program: id=0x%04x\n", id); 244cabdff1aSopenharmony_ci 245cabdff1aSopenharmony_ci for (unsigned i = 0; i < ac->nb_programs; i++) 246cabdff1aSopenharmony_ci if (ac->programs[i]->id == id) 247cabdff1aSopenharmony_ci program = ac->programs[i]; 248cabdff1aSopenharmony_ci 249cabdff1aSopenharmony_ci if (!program) { 250cabdff1aSopenharmony_ci program = av_mallocz(sizeof(*program)); 251cabdff1aSopenharmony_ci if (!program) 252cabdff1aSopenharmony_ci return NULL; 253cabdff1aSopenharmony_ci ret = av_dynarray_add_nofree(&ac->programs, &ac->nb_programs, program); 254cabdff1aSopenharmony_ci if (ret < 0) { 255cabdff1aSopenharmony_ci av_free(program); 256cabdff1aSopenharmony_ci return NULL; 257cabdff1aSopenharmony_ci } 258cabdff1aSopenharmony_ci program->discard = AVDISCARD_NONE; 259cabdff1aSopenharmony_ci program->pmt_version = -1; 260cabdff1aSopenharmony_ci program->id = id; 261cabdff1aSopenharmony_ci program->pts_wrap_reference = AV_NOPTS_VALUE; 262cabdff1aSopenharmony_ci program->pts_wrap_behavior = AV_PTS_WRAP_IGNORE; 263cabdff1aSopenharmony_ci program->start_time = 264cabdff1aSopenharmony_ci program->end_time = AV_NOPTS_VALUE; 265cabdff1aSopenharmony_ci } 266cabdff1aSopenharmony_ci return program; 267cabdff1aSopenharmony_ci} 268cabdff1aSopenharmony_ci 269cabdff1aSopenharmony_civoid av_program_add_stream_index(AVFormatContext *ac, int progid, unsigned idx) 270cabdff1aSopenharmony_ci{ 271cabdff1aSopenharmony_ci AVProgram *program = NULL; 272cabdff1aSopenharmony_ci void *tmp; 273cabdff1aSopenharmony_ci 274cabdff1aSopenharmony_ci if (idx >= ac->nb_streams) { 275cabdff1aSopenharmony_ci av_log(ac, AV_LOG_ERROR, "stream index %d is not valid\n", idx); 276cabdff1aSopenharmony_ci return; 277cabdff1aSopenharmony_ci } 278cabdff1aSopenharmony_ci 279cabdff1aSopenharmony_ci for (unsigned i = 0; i < ac->nb_programs; i++) { 280cabdff1aSopenharmony_ci if (ac->programs[i]->id != progid) 281cabdff1aSopenharmony_ci continue; 282cabdff1aSopenharmony_ci program = ac->programs[i]; 283cabdff1aSopenharmony_ci for (unsigned j = 0; j < program->nb_stream_indexes; j++) 284cabdff1aSopenharmony_ci if (program->stream_index[j] == idx) 285cabdff1aSopenharmony_ci return; 286cabdff1aSopenharmony_ci 287cabdff1aSopenharmony_ci tmp = av_realloc_array(program->stream_index, program->nb_stream_indexes+1, sizeof(unsigned int)); 288cabdff1aSopenharmony_ci if (!tmp) 289cabdff1aSopenharmony_ci return; 290cabdff1aSopenharmony_ci program->stream_index = tmp; 291cabdff1aSopenharmony_ci program->stream_index[program->nb_stream_indexes++] = idx; 292cabdff1aSopenharmony_ci return; 293cabdff1aSopenharmony_ci } 294cabdff1aSopenharmony_ci} 295cabdff1aSopenharmony_ci 296cabdff1aSopenharmony_ciAVProgram *av_find_program_from_stream(AVFormatContext *ic, AVProgram *last, int s) 297cabdff1aSopenharmony_ci{ 298cabdff1aSopenharmony_ci for (unsigned i = 0; i < ic->nb_programs; i++) { 299cabdff1aSopenharmony_ci if (ic->programs[i] == last) { 300cabdff1aSopenharmony_ci last = NULL; 301cabdff1aSopenharmony_ci } else { 302cabdff1aSopenharmony_ci if (!last) 303cabdff1aSopenharmony_ci for (unsigned j = 0; j < ic->programs[i]->nb_stream_indexes; j++) 304cabdff1aSopenharmony_ci if (ic->programs[i]->stream_index[j] == s) 305cabdff1aSopenharmony_ci return ic->programs[i]; 306cabdff1aSopenharmony_ci } 307cabdff1aSopenharmony_ci } 308cabdff1aSopenharmony_ci return NULL; 309cabdff1aSopenharmony_ci} 310cabdff1aSopenharmony_ci 311cabdff1aSopenharmony_ciint av_find_default_stream_index(AVFormatContext *s) 312cabdff1aSopenharmony_ci{ 313cabdff1aSopenharmony_ci int best_stream = 0; 314cabdff1aSopenharmony_ci int best_score = INT_MIN; 315cabdff1aSopenharmony_ci 316cabdff1aSopenharmony_ci if (s->nb_streams <= 0) 317cabdff1aSopenharmony_ci return -1; 318cabdff1aSopenharmony_ci for (unsigned i = 0; i < s->nb_streams; i++) { 319cabdff1aSopenharmony_ci const AVStream *const st = s->streams[i]; 320cabdff1aSopenharmony_ci const FFStream *const sti = cffstream(st); 321cabdff1aSopenharmony_ci int score = 0; 322cabdff1aSopenharmony_ci if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { 323cabdff1aSopenharmony_ci if (st->disposition & AV_DISPOSITION_ATTACHED_PIC) 324cabdff1aSopenharmony_ci score -= 400; 325cabdff1aSopenharmony_ci if (st->codecpar->width && st->codecpar->height) 326cabdff1aSopenharmony_ci score += 50; 327cabdff1aSopenharmony_ci score+= 25; 328cabdff1aSopenharmony_ci } 329cabdff1aSopenharmony_ci if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { 330cabdff1aSopenharmony_ci if (st->codecpar->sample_rate) 331cabdff1aSopenharmony_ci score += 50; 332cabdff1aSopenharmony_ci } 333cabdff1aSopenharmony_ci if (sti->codec_info_nb_frames) 334cabdff1aSopenharmony_ci score += 12; 335cabdff1aSopenharmony_ci 336cabdff1aSopenharmony_ci if (st->discard != AVDISCARD_ALL) 337cabdff1aSopenharmony_ci score += 200; 338cabdff1aSopenharmony_ci 339cabdff1aSopenharmony_ci if (score > best_score) { 340cabdff1aSopenharmony_ci best_score = score; 341cabdff1aSopenharmony_ci best_stream = i; 342cabdff1aSopenharmony_ci } 343cabdff1aSopenharmony_ci } 344cabdff1aSopenharmony_ci return best_stream; 345cabdff1aSopenharmony_ci} 346cabdff1aSopenharmony_ci 347cabdff1aSopenharmony_ciint av_find_best_stream(AVFormatContext *ic, enum AVMediaType type, 348cabdff1aSopenharmony_ci int wanted_stream_nb, int related_stream, 349cabdff1aSopenharmony_ci const AVCodec **decoder_ret, int flags) 350cabdff1aSopenharmony_ci{ 351cabdff1aSopenharmony_ci int nb_streams = ic->nb_streams; 352cabdff1aSopenharmony_ci int ret = AVERROR_STREAM_NOT_FOUND; 353cabdff1aSopenharmony_ci int best_count = -1, best_multiframe = -1, best_disposition = -1; 354cabdff1aSopenharmony_ci int count, multiframe, disposition; 355cabdff1aSopenharmony_ci int64_t best_bitrate = -1; 356cabdff1aSopenharmony_ci int64_t bitrate; 357cabdff1aSopenharmony_ci unsigned *program = NULL; 358cabdff1aSopenharmony_ci const AVCodec *decoder = NULL, *best_decoder = NULL; 359cabdff1aSopenharmony_ci 360cabdff1aSopenharmony_ci if (related_stream >= 0 && wanted_stream_nb < 0) { 361cabdff1aSopenharmony_ci AVProgram *p = av_find_program_from_stream(ic, NULL, related_stream); 362cabdff1aSopenharmony_ci if (p) { 363cabdff1aSopenharmony_ci program = p->stream_index; 364cabdff1aSopenharmony_ci nb_streams = p->nb_stream_indexes; 365cabdff1aSopenharmony_ci } 366cabdff1aSopenharmony_ci } 367cabdff1aSopenharmony_ci for (unsigned i = 0; i < nb_streams; i++) { 368cabdff1aSopenharmony_ci int real_stream_index = program ? program[i] : i; 369cabdff1aSopenharmony_ci AVStream *st = ic->streams[real_stream_index]; 370cabdff1aSopenharmony_ci AVCodecParameters *par = st->codecpar; 371cabdff1aSopenharmony_ci if (par->codec_type != type) 372cabdff1aSopenharmony_ci continue; 373cabdff1aSopenharmony_ci if (wanted_stream_nb >= 0 && real_stream_index != wanted_stream_nb) 374cabdff1aSopenharmony_ci continue; 375cabdff1aSopenharmony_ci if (type == AVMEDIA_TYPE_AUDIO && !(par->ch_layout.nb_channels && par->sample_rate)) 376cabdff1aSopenharmony_ci continue; 377cabdff1aSopenharmony_ci if (decoder_ret) { 378cabdff1aSopenharmony_ci decoder = ff_find_decoder(ic, st, par->codec_id); 379cabdff1aSopenharmony_ci if (!decoder) { 380cabdff1aSopenharmony_ci if (ret < 0) 381cabdff1aSopenharmony_ci ret = AVERROR_DECODER_NOT_FOUND; 382cabdff1aSopenharmony_ci continue; 383cabdff1aSopenharmony_ci } 384cabdff1aSopenharmony_ci } 385cabdff1aSopenharmony_ci disposition = !(st->disposition & (AV_DISPOSITION_HEARING_IMPAIRED | AV_DISPOSITION_VISUAL_IMPAIRED)) 386cabdff1aSopenharmony_ci + !! (st->disposition & AV_DISPOSITION_DEFAULT); 387cabdff1aSopenharmony_ci count = ffstream(st)->codec_info_nb_frames; 388cabdff1aSopenharmony_ci bitrate = par->bit_rate; 389cabdff1aSopenharmony_ci multiframe = FFMIN(5, count); 390cabdff1aSopenharmony_ci if ((best_disposition > disposition) || 391cabdff1aSopenharmony_ci (best_disposition == disposition && best_multiframe > multiframe) || 392cabdff1aSopenharmony_ci (best_disposition == disposition && best_multiframe == multiframe && best_bitrate > bitrate) || 393cabdff1aSopenharmony_ci (best_disposition == disposition && best_multiframe == multiframe && best_bitrate == bitrate && best_count >= count)) 394cabdff1aSopenharmony_ci continue; 395cabdff1aSopenharmony_ci best_disposition = disposition; 396cabdff1aSopenharmony_ci best_count = count; 397cabdff1aSopenharmony_ci best_bitrate = bitrate; 398cabdff1aSopenharmony_ci best_multiframe = multiframe; 399cabdff1aSopenharmony_ci ret = real_stream_index; 400cabdff1aSopenharmony_ci best_decoder = decoder; 401cabdff1aSopenharmony_ci if (program && i == nb_streams - 1 && ret < 0) { 402cabdff1aSopenharmony_ci program = NULL; 403cabdff1aSopenharmony_ci nb_streams = ic->nb_streams; 404cabdff1aSopenharmony_ci /* no related stream found, try again with everything */ 405cabdff1aSopenharmony_ci i = 0; 406cabdff1aSopenharmony_ci } 407cabdff1aSopenharmony_ci } 408cabdff1aSopenharmony_ci if (decoder_ret) 409cabdff1aSopenharmony_ci *decoder_ret = best_decoder; 410cabdff1aSopenharmony_ci return ret; 411cabdff1aSopenharmony_ci} 412cabdff1aSopenharmony_ci 413cabdff1aSopenharmony_ci/** 414cabdff1aSopenharmony_ci * Matches a stream specifier (but ignores requested index). 415cabdff1aSopenharmony_ci * 416cabdff1aSopenharmony_ci * @param indexptr set to point to the requested stream index if there is one 417cabdff1aSopenharmony_ci * 418cabdff1aSopenharmony_ci * @return <0 on error 419cabdff1aSopenharmony_ci * 0 if st is NOT a matching stream 420cabdff1aSopenharmony_ci * >0 if st is a matching stream 421cabdff1aSopenharmony_ci */ 422cabdff1aSopenharmony_cistatic int match_stream_specifier(const AVFormatContext *s, const AVStream *st, 423cabdff1aSopenharmony_ci const char *spec, const char **indexptr, 424cabdff1aSopenharmony_ci const AVProgram **p) 425cabdff1aSopenharmony_ci{ 426cabdff1aSopenharmony_ci int match = 1; /* Stores if the specifier matches so far. */ 427cabdff1aSopenharmony_ci while (*spec) { 428cabdff1aSopenharmony_ci if (*spec <= '9' && *spec >= '0') { /* opt:index */ 429cabdff1aSopenharmony_ci if (indexptr) 430cabdff1aSopenharmony_ci *indexptr = spec; 431cabdff1aSopenharmony_ci return match; 432cabdff1aSopenharmony_ci } else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd' || 433cabdff1aSopenharmony_ci *spec == 't' || *spec == 'V') { /* opt:[vasdtV] */ 434cabdff1aSopenharmony_ci enum AVMediaType type; 435cabdff1aSopenharmony_ci int nopic = 0; 436cabdff1aSopenharmony_ci 437cabdff1aSopenharmony_ci switch (*spec++) { 438cabdff1aSopenharmony_ci case 'v': type = AVMEDIA_TYPE_VIDEO; break; 439cabdff1aSopenharmony_ci case 'a': type = AVMEDIA_TYPE_AUDIO; break; 440cabdff1aSopenharmony_ci case 's': type = AVMEDIA_TYPE_SUBTITLE; break; 441cabdff1aSopenharmony_ci case 'd': type = AVMEDIA_TYPE_DATA; break; 442cabdff1aSopenharmony_ci case 't': type = AVMEDIA_TYPE_ATTACHMENT; break; 443cabdff1aSopenharmony_ci case 'V': type = AVMEDIA_TYPE_VIDEO; nopic = 1; break; 444cabdff1aSopenharmony_ci default: av_assert0(0); 445cabdff1aSopenharmony_ci } 446cabdff1aSopenharmony_ci if (*spec && *spec++ != ':') /* If we are not at the end, then another specifier must follow. */ 447cabdff1aSopenharmony_ci return AVERROR(EINVAL); 448cabdff1aSopenharmony_ci 449cabdff1aSopenharmony_ci if (type != st->codecpar->codec_type) 450cabdff1aSopenharmony_ci match = 0; 451cabdff1aSopenharmony_ci if (nopic && (st->disposition & AV_DISPOSITION_ATTACHED_PIC)) 452cabdff1aSopenharmony_ci match = 0; 453cabdff1aSopenharmony_ci } else if (*spec == 'p' && *(spec + 1) == ':') { 454cabdff1aSopenharmony_ci int prog_id; 455cabdff1aSopenharmony_ci int found = 0; 456cabdff1aSopenharmony_ci char *endptr; 457cabdff1aSopenharmony_ci spec += 2; 458cabdff1aSopenharmony_ci prog_id = strtol(spec, &endptr, 0); 459cabdff1aSopenharmony_ci /* Disallow empty id and make sure that if we are not at the end, then another specifier must follow. */ 460cabdff1aSopenharmony_ci if (spec == endptr || (*endptr && *endptr++ != ':')) 461cabdff1aSopenharmony_ci return AVERROR(EINVAL); 462cabdff1aSopenharmony_ci spec = endptr; 463cabdff1aSopenharmony_ci if (match) { 464cabdff1aSopenharmony_ci for (unsigned i = 0; i < s->nb_programs; i++) { 465cabdff1aSopenharmony_ci if (s->programs[i]->id != prog_id) 466cabdff1aSopenharmony_ci continue; 467cabdff1aSopenharmony_ci 468cabdff1aSopenharmony_ci for (unsigned j = 0; j < s->programs[i]->nb_stream_indexes; j++) { 469cabdff1aSopenharmony_ci if (st->index == s->programs[i]->stream_index[j]) { 470cabdff1aSopenharmony_ci found = 1; 471cabdff1aSopenharmony_ci if (p) 472cabdff1aSopenharmony_ci *p = s->programs[i]; 473cabdff1aSopenharmony_ci i = s->nb_programs; 474cabdff1aSopenharmony_ci break; 475cabdff1aSopenharmony_ci } 476cabdff1aSopenharmony_ci } 477cabdff1aSopenharmony_ci } 478cabdff1aSopenharmony_ci } 479cabdff1aSopenharmony_ci if (!found) 480cabdff1aSopenharmony_ci match = 0; 481cabdff1aSopenharmony_ci } else if (*spec == '#' || 482cabdff1aSopenharmony_ci (*spec == 'i' && *(spec + 1) == ':')) { 483cabdff1aSopenharmony_ci int stream_id; 484cabdff1aSopenharmony_ci char *endptr; 485cabdff1aSopenharmony_ci spec += 1 + (*spec == 'i'); 486cabdff1aSopenharmony_ci stream_id = strtol(spec, &endptr, 0); 487cabdff1aSopenharmony_ci if (spec == endptr || *endptr) /* Disallow empty id and make sure we are at the end. */ 488cabdff1aSopenharmony_ci return AVERROR(EINVAL); 489cabdff1aSopenharmony_ci return match && (stream_id == st->id); 490cabdff1aSopenharmony_ci } else if (*spec == 'm' && *(spec + 1) == ':') { 491cabdff1aSopenharmony_ci const AVDictionaryEntry *tag; 492cabdff1aSopenharmony_ci char *key, *val; 493cabdff1aSopenharmony_ci int ret; 494cabdff1aSopenharmony_ci 495cabdff1aSopenharmony_ci if (match) { 496cabdff1aSopenharmony_ci spec += 2; 497cabdff1aSopenharmony_ci val = strchr(spec, ':'); 498cabdff1aSopenharmony_ci 499cabdff1aSopenharmony_ci key = val ? av_strndup(spec, val - spec) : av_strdup(spec); 500cabdff1aSopenharmony_ci if (!key) 501cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 502cabdff1aSopenharmony_ci 503cabdff1aSopenharmony_ci tag = av_dict_get(st->metadata, key, NULL, 0); 504cabdff1aSopenharmony_ci if (tag) { 505cabdff1aSopenharmony_ci if (!val || !strcmp(tag->value, val + 1)) 506cabdff1aSopenharmony_ci ret = 1; 507cabdff1aSopenharmony_ci else 508cabdff1aSopenharmony_ci ret = 0; 509cabdff1aSopenharmony_ci } else 510cabdff1aSopenharmony_ci ret = 0; 511cabdff1aSopenharmony_ci 512cabdff1aSopenharmony_ci av_freep(&key); 513cabdff1aSopenharmony_ci } 514cabdff1aSopenharmony_ci return match && ret; 515cabdff1aSopenharmony_ci } else if (*spec == 'u' && *(spec + 1) == '\0') { 516cabdff1aSopenharmony_ci const AVCodecParameters *par = st->codecpar; 517cabdff1aSopenharmony_ci int val; 518cabdff1aSopenharmony_ci switch (par->codec_type) { 519cabdff1aSopenharmony_ci case AVMEDIA_TYPE_AUDIO: 520cabdff1aSopenharmony_ci val = par->sample_rate && par->ch_layout.nb_channels; 521cabdff1aSopenharmony_ci if (par->format == AV_SAMPLE_FMT_NONE) 522cabdff1aSopenharmony_ci return 0; 523cabdff1aSopenharmony_ci break; 524cabdff1aSopenharmony_ci case AVMEDIA_TYPE_VIDEO: 525cabdff1aSopenharmony_ci val = par->width && par->height; 526cabdff1aSopenharmony_ci if (par->format == AV_PIX_FMT_NONE) 527cabdff1aSopenharmony_ci return 0; 528cabdff1aSopenharmony_ci break; 529cabdff1aSopenharmony_ci case AVMEDIA_TYPE_UNKNOWN: 530cabdff1aSopenharmony_ci val = 0; 531cabdff1aSopenharmony_ci break; 532cabdff1aSopenharmony_ci default: 533cabdff1aSopenharmony_ci val = 1; 534cabdff1aSopenharmony_ci break; 535cabdff1aSopenharmony_ci } 536cabdff1aSopenharmony_ci return match && (par->codec_id != AV_CODEC_ID_NONE && val != 0); 537cabdff1aSopenharmony_ci } else { 538cabdff1aSopenharmony_ci return AVERROR(EINVAL); 539cabdff1aSopenharmony_ci } 540cabdff1aSopenharmony_ci } 541cabdff1aSopenharmony_ci 542cabdff1aSopenharmony_ci return match; 543cabdff1aSopenharmony_ci} 544cabdff1aSopenharmony_ci 545cabdff1aSopenharmony_ciint avformat_match_stream_specifier(AVFormatContext *s, AVStream *st, 546cabdff1aSopenharmony_ci const char *spec) 547cabdff1aSopenharmony_ci{ 548cabdff1aSopenharmony_ci int ret, index; 549cabdff1aSopenharmony_ci char *endptr; 550cabdff1aSopenharmony_ci const char *indexptr = NULL; 551cabdff1aSopenharmony_ci const AVProgram *p = NULL; 552cabdff1aSopenharmony_ci int nb_streams; 553cabdff1aSopenharmony_ci 554cabdff1aSopenharmony_ci ret = match_stream_specifier(s, st, spec, &indexptr, &p); 555cabdff1aSopenharmony_ci if (ret < 0) 556cabdff1aSopenharmony_ci goto error; 557cabdff1aSopenharmony_ci 558cabdff1aSopenharmony_ci if (!indexptr) 559cabdff1aSopenharmony_ci return ret; 560cabdff1aSopenharmony_ci 561cabdff1aSopenharmony_ci index = strtol(indexptr, &endptr, 0); 562cabdff1aSopenharmony_ci if (*endptr) { /* We can't have anything after the requested index. */ 563cabdff1aSopenharmony_ci ret = AVERROR(EINVAL); 564cabdff1aSopenharmony_ci goto error; 565cabdff1aSopenharmony_ci } 566cabdff1aSopenharmony_ci 567cabdff1aSopenharmony_ci /* This is not really needed but saves us a loop for simple stream index specifiers. */ 568cabdff1aSopenharmony_ci if (spec == indexptr) 569cabdff1aSopenharmony_ci return (index == st->index); 570cabdff1aSopenharmony_ci 571cabdff1aSopenharmony_ci /* If we requested a matching stream index, we have to ensure st is that. */ 572cabdff1aSopenharmony_ci nb_streams = p ? p->nb_stream_indexes : s->nb_streams; 573cabdff1aSopenharmony_ci for (int i = 0; i < nb_streams && index >= 0; i++) { 574cabdff1aSopenharmony_ci const AVStream *candidate = s->streams[p ? p->stream_index[i] : i]; 575cabdff1aSopenharmony_ci ret = match_stream_specifier(s, candidate, spec, NULL, NULL); 576cabdff1aSopenharmony_ci if (ret < 0) 577cabdff1aSopenharmony_ci goto error; 578cabdff1aSopenharmony_ci if (ret > 0 && index-- == 0 && st == candidate) 579cabdff1aSopenharmony_ci return 1; 580cabdff1aSopenharmony_ci } 581cabdff1aSopenharmony_ci return 0; 582cabdff1aSopenharmony_ci 583cabdff1aSopenharmony_cierror: 584cabdff1aSopenharmony_ci if (ret == AVERROR(EINVAL)) 585cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec); 586cabdff1aSopenharmony_ci return ret; 587cabdff1aSopenharmony_ci} 588cabdff1aSopenharmony_ci 589cabdff1aSopenharmony_ciAVRational av_guess_sample_aspect_ratio(AVFormatContext *format, AVStream *stream, AVFrame *frame) 590cabdff1aSopenharmony_ci{ 591cabdff1aSopenharmony_ci AVRational undef = {0, 1}; 592cabdff1aSopenharmony_ci AVRational stream_sample_aspect_ratio = stream ? stream->sample_aspect_ratio : undef; 593cabdff1aSopenharmony_ci AVRational codec_sample_aspect_ratio = stream && stream->codecpar ? stream->codecpar->sample_aspect_ratio : undef; 594cabdff1aSopenharmony_ci AVRational frame_sample_aspect_ratio = frame ? frame->sample_aspect_ratio : codec_sample_aspect_ratio; 595cabdff1aSopenharmony_ci 596cabdff1aSopenharmony_ci av_reduce(&stream_sample_aspect_ratio.num, &stream_sample_aspect_ratio.den, 597cabdff1aSopenharmony_ci stream_sample_aspect_ratio.num, stream_sample_aspect_ratio.den, INT_MAX); 598cabdff1aSopenharmony_ci if (stream_sample_aspect_ratio.num <= 0 || stream_sample_aspect_ratio.den <= 0) 599cabdff1aSopenharmony_ci stream_sample_aspect_ratio = undef; 600cabdff1aSopenharmony_ci 601cabdff1aSopenharmony_ci av_reduce(&frame_sample_aspect_ratio.num, &frame_sample_aspect_ratio.den, 602cabdff1aSopenharmony_ci frame_sample_aspect_ratio.num, frame_sample_aspect_ratio.den, INT_MAX); 603cabdff1aSopenharmony_ci if (frame_sample_aspect_ratio.num <= 0 || frame_sample_aspect_ratio.den <= 0) 604cabdff1aSopenharmony_ci frame_sample_aspect_ratio = undef; 605cabdff1aSopenharmony_ci 606cabdff1aSopenharmony_ci if (stream_sample_aspect_ratio.num) 607cabdff1aSopenharmony_ci return stream_sample_aspect_ratio; 608cabdff1aSopenharmony_ci else 609cabdff1aSopenharmony_ci return frame_sample_aspect_ratio; 610cabdff1aSopenharmony_ci} 611cabdff1aSopenharmony_ci 612cabdff1aSopenharmony_ciAVRational av_guess_frame_rate(AVFormatContext *format, AVStream *st, AVFrame *frame) 613cabdff1aSopenharmony_ci{ 614cabdff1aSopenharmony_ci AVRational fr = st->r_frame_rate; 615cabdff1aSopenharmony_ci AVCodecContext *const avctx = ffstream(st)->avctx; 616cabdff1aSopenharmony_ci AVRational codec_fr = avctx->framerate; 617cabdff1aSopenharmony_ci AVRational avg_fr = st->avg_frame_rate; 618cabdff1aSopenharmony_ci 619cabdff1aSopenharmony_ci if (avg_fr.num > 0 && avg_fr.den > 0 && fr.num > 0 && fr.den > 0 && 620cabdff1aSopenharmony_ci av_q2d(avg_fr) < 70 && av_q2d(fr) > 210) { 621cabdff1aSopenharmony_ci fr = avg_fr; 622cabdff1aSopenharmony_ci } 623cabdff1aSopenharmony_ci 624cabdff1aSopenharmony_ci if (avctx->ticks_per_frame > 1) { 625cabdff1aSopenharmony_ci if ( codec_fr.num > 0 && codec_fr.den > 0 && 626cabdff1aSopenharmony_ci (fr.num == 0 || av_q2d(codec_fr) < av_q2d(fr)*0.7 && fabs(1.0 - av_q2d(av_div_q(avg_fr, fr))) > 0.1)) 627cabdff1aSopenharmony_ci fr = codec_fr; 628cabdff1aSopenharmony_ci } 629cabdff1aSopenharmony_ci 630cabdff1aSopenharmony_ci return fr; 631cabdff1aSopenharmony_ci} 632cabdff1aSopenharmony_ci 633cabdff1aSopenharmony_ciint avformat_transfer_internal_stream_timing_info(const AVOutputFormat *ofmt, 634cabdff1aSopenharmony_ci AVStream *ost, const AVStream *ist, 635cabdff1aSopenharmony_ci enum AVTimebaseSource copy_tb) 636cabdff1aSopenharmony_ci{ 637cabdff1aSopenharmony_ci const AVCodecContext *const dec_ctx = cffstream(ist)->avctx; 638cabdff1aSopenharmony_ci AVCodecContext *const enc_ctx = ffstream(ost)->avctx; 639cabdff1aSopenharmony_ci 640cabdff1aSopenharmony_ci enc_ctx->time_base = ist->time_base; 641cabdff1aSopenharmony_ci /* 642cabdff1aSopenharmony_ci * Avi is a special case here because it supports variable fps but 643cabdff1aSopenharmony_ci * having the fps and timebase differe significantly adds quite some 644cabdff1aSopenharmony_ci * overhead 645cabdff1aSopenharmony_ci */ 646cabdff1aSopenharmony_ci if (!strcmp(ofmt->name, "avi")) { 647cabdff1aSopenharmony_ci#if FF_API_R_FRAME_RATE 648cabdff1aSopenharmony_ci if (copy_tb == AVFMT_TBCF_AUTO && ist->r_frame_rate.num 649cabdff1aSopenharmony_ci && av_q2d(ist->r_frame_rate) >= av_q2d(ist->avg_frame_rate) 650cabdff1aSopenharmony_ci && 0.5/av_q2d(ist->r_frame_rate) > av_q2d(ist->time_base) 651cabdff1aSopenharmony_ci && 0.5/av_q2d(ist->r_frame_rate) > av_q2d(dec_ctx->time_base) 652cabdff1aSopenharmony_ci && av_q2d(ist->time_base) < 1.0/500 && av_q2d(dec_ctx->time_base) < 1.0/500 653cabdff1aSopenharmony_ci || copy_tb == AVFMT_TBCF_R_FRAMERATE) { 654cabdff1aSopenharmony_ci enc_ctx->time_base.num = ist->r_frame_rate.den; 655cabdff1aSopenharmony_ci enc_ctx->time_base.den = 2*ist->r_frame_rate.num; 656cabdff1aSopenharmony_ci enc_ctx->ticks_per_frame = 2; 657cabdff1aSopenharmony_ci } else 658cabdff1aSopenharmony_ci#endif 659cabdff1aSopenharmony_ci if (copy_tb == AVFMT_TBCF_AUTO && av_q2d(dec_ctx->time_base)*dec_ctx->ticks_per_frame > 2*av_q2d(ist->time_base) 660cabdff1aSopenharmony_ci && av_q2d(ist->time_base) < 1.0/500 661cabdff1aSopenharmony_ci || copy_tb == AVFMT_TBCF_DECODER) { 662cabdff1aSopenharmony_ci enc_ctx->time_base = dec_ctx->time_base; 663cabdff1aSopenharmony_ci enc_ctx->time_base.num *= dec_ctx->ticks_per_frame; 664cabdff1aSopenharmony_ci enc_ctx->time_base.den *= 2; 665cabdff1aSopenharmony_ci enc_ctx->ticks_per_frame = 2; 666cabdff1aSopenharmony_ci } 667cabdff1aSopenharmony_ci } else if (!(ofmt->flags & AVFMT_VARIABLE_FPS) 668cabdff1aSopenharmony_ci && !av_match_name(ofmt->name, "mov,mp4,3gp,3g2,psp,ipod,ismv,f4v")) { 669cabdff1aSopenharmony_ci if (copy_tb == AVFMT_TBCF_AUTO && dec_ctx->time_base.den 670cabdff1aSopenharmony_ci && av_q2d(dec_ctx->time_base)*dec_ctx->ticks_per_frame > av_q2d(ist->time_base) 671cabdff1aSopenharmony_ci && av_q2d(ist->time_base) < 1.0/500 672cabdff1aSopenharmony_ci || copy_tb == AVFMT_TBCF_DECODER) { 673cabdff1aSopenharmony_ci enc_ctx->time_base = dec_ctx->time_base; 674cabdff1aSopenharmony_ci enc_ctx->time_base.num *= dec_ctx->ticks_per_frame; 675cabdff1aSopenharmony_ci } 676cabdff1aSopenharmony_ci } 677cabdff1aSopenharmony_ci 678cabdff1aSopenharmony_ci if ((enc_ctx->codec_tag == AV_RL32("tmcd") || ost->codecpar->codec_tag == AV_RL32("tmcd")) 679cabdff1aSopenharmony_ci && dec_ctx->time_base.num < dec_ctx->time_base.den 680cabdff1aSopenharmony_ci && dec_ctx->time_base.num > 0 681cabdff1aSopenharmony_ci && 121LL*dec_ctx->time_base.num > dec_ctx->time_base.den) { 682cabdff1aSopenharmony_ci enc_ctx->time_base = dec_ctx->time_base; 683cabdff1aSopenharmony_ci } 684cabdff1aSopenharmony_ci 685cabdff1aSopenharmony_ci av_reduce(&enc_ctx->time_base.num, &enc_ctx->time_base.den, 686cabdff1aSopenharmony_ci enc_ctx->time_base.num, enc_ctx->time_base.den, INT_MAX); 687cabdff1aSopenharmony_ci 688cabdff1aSopenharmony_ci return 0; 689cabdff1aSopenharmony_ci} 690cabdff1aSopenharmony_ci 691cabdff1aSopenharmony_ciAVRational av_stream_get_codec_timebase(const AVStream *st) 692cabdff1aSopenharmony_ci{ 693cabdff1aSopenharmony_ci // See avformat_transfer_internal_stream_timing_info() TODO. 694cabdff1aSopenharmony_ci return cffstream(st)->avctx->time_base; 695cabdff1aSopenharmony_ci} 696cabdff1aSopenharmony_ci 697cabdff1aSopenharmony_civoid avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, 698cabdff1aSopenharmony_ci unsigned int pts_num, unsigned int pts_den) 699cabdff1aSopenharmony_ci{ 700cabdff1aSopenharmony_ci FFStream *const sti = ffstream(st); 701cabdff1aSopenharmony_ci AVRational new_tb; 702cabdff1aSopenharmony_ci if (av_reduce(&new_tb.num, &new_tb.den, pts_num, pts_den, INT_MAX)) { 703cabdff1aSopenharmony_ci if (new_tb.num != pts_num) 704cabdff1aSopenharmony_ci av_log(NULL, AV_LOG_DEBUG, 705cabdff1aSopenharmony_ci "st:%d removing common factor %d from timebase\n", 706cabdff1aSopenharmony_ci st->index, pts_num / new_tb.num); 707cabdff1aSopenharmony_ci } else 708cabdff1aSopenharmony_ci av_log(NULL, AV_LOG_WARNING, 709cabdff1aSopenharmony_ci "st:%d has too large timebase, reducing\n", st->index); 710cabdff1aSopenharmony_ci 711cabdff1aSopenharmony_ci if (new_tb.num <= 0 || new_tb.den <= 0) { 712cabdff1aSopenharmony_ci av_log(NULL, AV_LOG_ERROR, 713cabdff1aSopenharmony_ci "Ignoring attempt to set invalid timebase %d/%d for st:%d\n", 714cabdff1aSopenharmony_ci new_tb.num, new_tb.den, 715cabdff1aSopenharmony_ci st->index); 716cabdff1aSopenharmony_ci return; 717cabdff1aSopenharmony_ci } 718cabdff1aSopenharmony_ci st->time_base = new_tb; 719cabdff1aSopenharmony_ci sti->avctx->pkt_timebase = new_tb; 720cabdff1aSopenharmony_ci st->pts_wrap_bits = pts_wrap_bits; 721cabdff1aSopenharmony_ci} 722cabdff1aSopenharmony_ci 723cabdff1aSopenharmony_ciconst AVCodec *ff_find_decoder(AVFormatContext *s, const AVStream *st, 724cabdff1aSopenharmony_ci enum AVCodecID codec_id) 725cabdff1aSopenharmony_ci{ 726cabdff1aSopenharmony_ci switch (st->codecpar->codec_type) { 727cabdff1aSopenharmony_ci case AVMEDIA_TYPE_VIDEO: 728cabdff1aSopenharmony_ci if (s->video_codec) return s->video_codec; 729cabdff1aSopenharmony_ci break; 730cabdff1aSopenharmony_ci case AVMEDIA_TYPE_AUDIO: 731cabdff1aSopenharmony_ci if (s->audio_codec) return s->audio_codec; 732cabdff1aSopenharmony_ci break; 733cabdff1aSopenharmony_ci case AVMEDIA_TYPE_SUBTITLE: 734cabdff1aSopenharmony_ci if (s->subtitle_codec) return s->subtitle_codec; 735cabdff1aSopenharmony_ci break; 736cabdff1aSopenharmony_ci } 737cabdff1aSopenharmony_ci 738cabdff1aSopenharmony_ci return avcodec_find_decoder(codec_id); 739cabdff1aSopenharmony_ci} 740cabdff1aSopenharmony_ci 741cabdff1aSopenharmony_ciint ff_copy_whiteblacklists(AVFormatContext *dst, const AVFormatContext *src) 742cabdff1aSopenharmony_ci{ 743cabdff1aSopenharmony_ci av_assert0(!dst->codec_whitelist && 744cabdff1aSopenharmony_ci !dst->format_whitelist && 745cabdff1aSopenharmony_ci !dst->protocol_whitelist && 746cabdff1aSopenharmony_ci !dst->protocol_blacklist); 747cabdff1aSopenharmony_ci dst-> codec_whitelist = av_strdup(src->codec_whitelist); 748cabdff1aSopenharmony_ci dst->format_whitelist = av_strdup(src->format_whitelist); 749cabdff1aSopenharmony_ci dst->protocol_whitelist = av_strdup(src->protocol_whitelist); 750cabdff1aSopenharmony_ci dst->protocol_blacklist = av_strdup(src->protocol_blacklist); 751cabdff1aSopenharmony_ci if ( (src-> codec_whitelist && !dst-> codec_whitelist) 752cabdff1aSopenharmony_ci || (src-> format_whitelist && !dst-> format_whitelist) 753cabdff1aSopenharmony_ci || (src->protocol_whitelist && !dst->protocol_whitelist) 754cabdff1aSopenharmony_ci || (src->protocol_blacklist && !dst->protocol_blacklist)) { 755cabdff1aSopenharmony_ci av_log(dst, AV_LOG_ERROR, "Failed to duplicate black/whitelist\n"); 756cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 757cabdff1aSopenharmony_ci } 758cabdff1aSopenharmony_ci return 0; 759cabdff1aSopenharmony_ci} 760cabdff1aSopenharmony_ci 761cabdff1aSopenharmony_ciint ff_is_intra_only(enum AVCodecID id) 762cabdff1aSopenharmony_ci{ 763cabdff1aSopenharmony_ci const AVCodecDescriptor *d = avcodec_descriptor_get(id); 764cabdff1aSopenharmony_ci if (!d) 765cabdff1aSopenharmony_ci return 0; 766cabdff1aSopenharmony_ci if ((d->type == AVMEDIA_TYPE_VIDEO || d->type == AVMEDIA_TYPE_AUDIO) && 767cabdff1aSopenharmony_ci !(d->props & AV_CODEC_PROP_INTRA_ONLY)) 768cabdff1aSopenharmony_ci return 0; 769cabdff1aSopenharmony_ci return 1; 770cabdff1aSopenharmony_ci} 771cabdff1aSopenharmony_ci 772cabdff1aSopenharmony_civoid ff_format_set_url(AVFormatContext *s, char *url) 773cabdff1aSopenharmony_ci{ 774cabdff1aSopenharmony_ci av_assert0(url); 775cabdff1aSopenharmony_ci av_freep(&s->url); 776cabdff1aSopenharmony_ci s->url = url; 777cabdff1aSopenharmony_ci} 778cabdff1aSopenharmony_ci 779cabdff1aSopenharmony_ciint ff_format_io_close(AVFormatContext *s, AVIOContext **pb) 780cabdff1aSopenharmony_ci{ 781cabdff1aSopenharmony_ci int ret = 0; 782cabdff1aSopenharmony_ci if (*pb) { 783cabdff1aSopenharmony_ci if (s->io_close == ff_format_io_close_default || s->io_close == NULL) 784cabdff1aSopenharmony_ci ret = s->io_close2(s, *pb); 785cabdff1aSopenharmony_ci else 786cabdff1aSopenharmony_ci s->io_close(s, *pb); 787cabdff1aSopenharmony_ci } 788cabdff1aSopenharmony_ci *pb = NULL; 789cabdff1aSopenharmony_ci return ret; 790cabdff1aSopenharmony_ci} 791cabdff1aSopenharmony_ci 792cabdff1aSopenharmony_ci/** 793cabdff1aSopenharmony_ci * Get the frame position for every key frame. 794cabdff1aSopenharmony_ci * 795cabdff1aSopenharmony_ci * @param st input stream to extract the position for every key frame 796cabdff1aSopenharmony_ci * @param key_frame_pos_list output list which carry the frame position for every key frame 797cabdff1aSopenharmony_ci */ 798cabdff1aSopenharmony_ci 799cabdff1aSopenharmony_ciint av_get_key_frame_pos_from_stream(const AVStream *st, struct KeyFrameNode **key_frame_pos_list) 800cabdff1aSopenharmony_ci{ 801cabdff1aSopenharmony_ci if ((st == NULL) || (key_frame_pos_list == NULL)) { 802cabdff1aSopenharmony_ci av_log(NULL, AV_LOG_ERROR, "st or key_frame_pos_list is NULL\n"); 803cabdff1aSopenharmony_ci return 1; 804cabdff1aSopenharmony_ci } 805cabdff1aSopenharmony_ci struct KeyFrameNode *head = NULL; // head pointer 806cabdff1aSopenharmony_ci struct KeyFrameNode *cur = NULL; // current pointer 807cabdff1aSopenharmony_ci struct KeyFrameNode *tail = NULL; // tail pointer 808cabdff1aSopenharmony_ci FFStream *sti = ffstream(st); 809cabdff1aSopenharmony_ci if (sti == NULL) { 810cabdff1aSopenharmony_ci av_log(NULL, AV_LOG_ERROR, "ffstream(st) return NULL\n"); 811cabdff1aSopenharmony_ci return 1; 812cabdff1aSopenharmony_ci } 813cabdff1aSopenharmony_ci for (int i = 0; i < sti->nb_index_entries; i++) { 814cabdff1aSopenharmony_ci if (sti->index_entries[i].flags & AVINDEX_KEYFRAME) { 815cabdff1aSopenharmony_ci cur = (struct KeyFrameNode *)malloc(sizeof(struct KeyFrameNode)); 816cabdff1aSopenharmony_ci if (cur == NULL) { 817cabdff1aSopenharmony_ci av_destory_key_frame_pos_list(head); 818cabdff1aSopenharmony_ci return 1; 819cabdff1aSopenharmony_ci } 820cabdff1aSopenharmony_ci cur->pos = i; 821cabdff1aSopenharmony_ci cur->next = NULL; 822cabdff1aSopenharmony_ci if (head != NULL) { 823cabdff1aSopenharmony_ci tail->next = cur; 824cabdff1aSopenharmony_ci } else { 825cabdff1aSopenharmony_ci head = cur; 826cabdff1aSopenharmony_ci } 827cabdff1aSopenharmony_ci tail = cur; 828cabdff1aSopenharmony_ci } 829cabdff1aSopenharmony_ci } 830cabdff1aSopenharmony_ci *key_frame_pos_list = head; 831cabdff1aSopenharmony_ci return 0; 832cabdff1aSopenharmony_ci} 833cabdff1aSopenharmony_ci 834cabdff1aSopenharmony_ci/** 835cabdff1aSopenharmony_ci * Destroy the list which is created by av_get_key_frame_pos_from_stream function. 836cabdff1aSopenharmony_ci * 837cabdff1aSopenharmony_ci * This function is useful after doing av_get_key_frame_pos_from_stream to release resource. 838cabdff1aSopenharmony_ci * 839cabdff1aSopenharmony_ci * @param key_frame_pos_list input list which carry the frame position for every key frame 840cabdff1aSopenharmony_ci */ 841cabdff1aSopenharmony_civoid av_destory_key_frame_pos_list(struct KeyFrameNode *key_frame_pos_list) 842cabdff1aSopenharmony_ci{ 843cabdff1aSopenharmony_ci struct KeyFrameNode *cur = key_frame_pos_list; 844cabdff1aSopenharmony_ci struct KeyFrameNode *next; 845cabdff1aSopenharmony_ci while (cur != NULL) { 846cabdff1aSopenharmony_ci next = cur->next; 847cabdff1aSopenharmony_ci free(cur); 848cabdff1aSopenharmony_ci cur = next; 849cabdff1aSopenharmony_ci } 850cabdff1aSopenharmony_ci}