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