summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Rheinhardt <andreas.rheinhardt@outlook.com>2022-05-06 15:23:34 +0200
committerAndreas Rheinhardt <andreas.rheinhardt@outlook.com>2022-05-10 07:28:54 +0200
commitb9f6d416ecbed36fbe1b819d1099f71ba2936ddd (patch)
treee59b719db78da0b35b89bf9d61f9b95a0b38c1f3
parent7547f135485623e00844d2ad40debb5b048e6b5d (diff)
avformat/utils: Move stream_options, avformat_new_stream to options.c
This is the appropriate place given that AVStream is about to become an AVOpt-enabled struct. Also move av_disposition_(to|from)_string, as these are tied to the disposition stream option. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
-rw-r--r--libavformat/avidec.c2
-rw-r--r--libavformat/internal.h12
-rw-r--r--libavformat/options.c151
-rw-r--r--libavformat/rmdec.c2
-rw-r--r--libavformat/utils.c159
5 files changed, 169 insertions, 157 deletions
diff --git a/libavformat/avidec.c b/libavformat/avidec.c
index 3c749aec14..21fc2b87ff 100644
--- a/libavformat/avidec.c
+++ b/libavformat/avidec.c
@@ -621,7 +621,7 @@ static int avi_read_header(AVFormatContext *s)
ast = s->streams[0]->priv_data;
st->priv_data = NULL;
- ff_free_stream(s, st);
+ ff_remove_stream(s, st);
avi->dv_demux = avpriv_dv_init_demux(s);
if (!avi->dv_demux) {
diff --git a/libavformat/internal.h b/libavformat/internal.h
index a40a29c5c0..a3fdab03af 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -742,7 +742,17 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt);
int ff_add_attached_pic(AVFormatContext *s, AVStream *st, AVIOContext *pb,
AVBufferRef **buf, int size);
-void ff_free_stream(AVFormatContext *s, AVStream *st);
+/**
+ * Frees a stream without modifying the corresponding AVFormatContext.
+ * Must only be called if the latter doesn't matter or if the stream
+ * is not yet attached to an AVFormatContext.
+ */
+void ff_free_stream(AVStream **st);
+/**
+ * Remove a stream from its AVFormatContext and free it.
+ * The stream must be the last stream of the AVFormatContext.
+ */
+void ff_remove_stream(AVFormatContext *s, AVStream *st);
unsigned int ff_codec_get_tag(const AVCodecTag *tags, enum AVCodecID id);
diff --git a/libavformat/options.c b/libavformat/options.c
index 2d55d3ad6e..14ae55e3fd 100644
--- a/libavformat/options.c
+++ b/libavformat/options.c
@@ -21,8 +21,12 @@
#include "avio_internal.h"
#include "internal.h"
+#include "libavcodec/avcodec.h"
+#include "libavcodec/codec_par.h"
+
#include "libavutil/avassert.h"
#include "libavutil/internal.h"
+#include "libavutil/intmath.h"
#include "libavutil/opt.h"
/**
@@ -188,3 +192,150 @@ const AVClass *avformat_get_class(void)
{
return &av_format_context_class;
}
+
+static const AVOption stream_options[] = {
+ { "disposition", NULL, offsetof(AVStream, disposition), AV_OPT_TYPE_FLAGS, { .i64 = 0 },
+ .flags = AV_OPT_FLAG_ENCODING_PARAM, .unit = "disposition" },
+ { "default", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DEFAULT }, .unit = "disposition" },
+ { "dub", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DUB }, .unit = "disposition" },
+ { "original", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_ORIGINAL }, .unit = "disposition" },
+ { "comment", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_COMMENT }, .unit = "disposition" },
+ { "lyrics", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_LYRICS }, .unit = "disposition" },
+ { "karaoke", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_KARAOKE }, .unit = "disposition" },
+ { "forced", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_FORCED }, .unit = "disposition" },
+ { "hearing_impaired", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_HEARING_IMPAIRED }, .unit = "disposition" },
+ { "visual_impaired", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_VISUAL_IMPAIRED }, .unit = "disposition" },
+ { "clean_effects", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_CLEAN_EFFECTS }, .unit = "disposition" },
+ { "attached_pic", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_ATTACHED_PIC }, .unit = "disposition" },
+ { "timed_thumbnails", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_TIMED_THUMBNAILS }, .unit = "disposition" },
+ { "captions", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_CAPTIONS }, .unit = "disposition" },
+ { "descriptions", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DESCRIPTIONS }, .unit = "disposition" },
+ { "metadata", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_METADATA }, .unit = "disposition" },
+ { "dependent", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DEPENDENT }, .unit = "disposition" },
+ { "still_image", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_STILL_IMAGE }, .unit = "disposition" },
+ { NULL }
+};
+
+static const AVClass stream_class = {
+ .class_name = "AVStream",
+ .item_name = av_default_item_name,
+ .version = LIBAVUTIL_VERSION_INT,
+ .option = stream_options,
+};
+
+const AVClass *av_stream_get_class(void)
+{
+ return &stream_class;
+}
+
+AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c)
+{
+ FFFormatContext *const si = ffformatcontext(s);
+ FFStream *sti;
+ AVStream *st;
+ AVStream **streams;
+
+ if (s->nb_streams >= s->max_streams) {
+ av_log(s, AV_LOG_ERROR, "Number of streams exceeds max_streams parameter"
+ " (%d), see the documentation if you wish to increase it\n",
+ s->max_streams);
+ return NULL;
+ }
+ streams = av_realloc_array(s->streams, s->nb_streams + 1, sizeof(*streams));
+ if (!streams)
+ return NULL;
+ s->streams = streams;
+
+ sti = av_mallocz(sizeof(*sti));
+ if (!sti)
+ return NULL;
+ st = &sti->pub;
+
+#if FF_API_AVSTREAM_CLASS
+ st->av_class = &stream_class;
+#endif
+
+ st->codecpar = avcodec_parameters_alloc();
+ if (!st->codecpar)
+ goto fail;
+
+ sti->avctx = avcodec_alloc_context3(NULL);
+ if (!sti->avctx)
+ goto fail;
+
+ if (s->iformat) {
+ sti->info = av_mallocz(sizeof(*sti->info));
+ if (!sti->info)
+ goto fail;
+
+#if FF_API_R_FRAME_RATE
+ sti->info->last_dts = AV_NOPTS_VALUE;
+#endif
+ sti->info->fps_first_dts = AV_NOPTS_VALUE;
+ sti->info->fps_last_dts = AV_NOPTS_VALUE;
+
+ /* default pts setting is MPEG-like */
+ avpriv_set_pts_info(st, 33, 1, 90000);
+ /* we set the current DTS to 0 so that formats without any timestamps
+ * but durations get some timestamps, formats with some unknown
+ * timestamps have their first few packets buffered and the
+ * timestamps corrected before they are returned to the user */
+ sti->cur_dts = RELATIVE_TS_BASE;
+ } else {
+ sti->cur_dts = AV_NOPTS_VALUE;
+ }
+
+ st->index = s->nb_streams;
+ st->start_time = AV_NOPTS_VALUE;
+ st->duration = AV_NOPTS_VALUE;
+ sti->first_dts = AV_NOPTS_VALUE;
+ sti->probe_packets = s->max_probe_packets;
+ sti->pts_wrap_reference = AV_NOPTS_VALUE;
+ sti->pts_wrap_behavior = AV_PTS_WRAP_IGNORE;
+
+ sti->last_IP_pts = AV_NOPTS_VALUE;
+ sti->last_dts_for_order_check = AV_NOPTS_VALUE;
+ for (int i = 0; i < MAX_REORDER_DELAY + 1; i++)
+ sti->pts_buffer[i] = AV_NOPTS_VALUE;
+
+ st->sample_aspect_ratio = (AVRational) { 0, 1 };
+
+ sti->inject_global_side_data = si->inject_global_side_data;
+
+ sti->need_context_update = 1;
+
+ s->streams[s->nb_streams++] = st;
+ return st;
+fail:
+ ff_free_stream(&st);
+ return NULL;
+}
+
+static int option_is_disposition(const AVOption *opt)
+{
+ return opt->type == AV_OPT_TYPE_CONST &&
+ opt->unit && !strcmp(opt->unit, "disposition");
+}
+
+int av_disposition_from_string(const char *disp)
+{
+ for (const AVOption *opt = stream_options; opt->name; opt++)
+ if (option_is_disposition(opt) && !strcmp(disp, opt->name))
+ return opt->default_val.i64;
+ return AVERROR(EINVAL);
+}
+
+const char *av_disposition_to_string(int disposition)
+{
+ int val;
+
+ if (disposition <= 0)
+ return NULL;
+
+ val = 1 << ff_ctz(disposition);
+ for (const AVOption *opt = stream_options; opt->name; opt++)
+ if (option_is_disposition(opt) && opt->default_val.i64 == val)
+ return opt->name;
+
+ return NULL;
+}
diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c
index b6b72e6ead..cb0ca31f40 100644
--- a/libavformat/rmdec.c
+++ b/libavformat/rmdec.c
@@ -349,7 +349,7 @@ int ff_rm_read_mdpr_codecdata(AVFormatContext *s, AVIOContext *pb,
st->codecpar->codec_tag);
} else if(mime && !strcmp(mime, "logical-fileinfo")){
int stream_count, rule_count, property_count, i;
- ff_free_stream(s, st);
+ ff_remove_stream(s, st);
if (avio_rb16(pb) != 0) {
av_log(s, AV_LOG_WARNING, "Unsupported version\n");
goto skip;
diff --git a/libavformat/utils.c b/libavformat/utils.c
index fcee417c4e..f31dda9b44 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -28,7 +28,6 @@
#include "libavutil/bprint.h"
#include "libavutil/dict.h"
#include "libavutil/internal.h"
-#include "libavutil/intmath.h"
#include "libavutil/opt.h"
#include "libavutil/parseutils.h"
#include "libavutil/pixfmt.h"
@@ -258,7 +257,7 @@ int ff_add_attached_pic(AVFormatContext *s, AVStream *st0, AVIOContext *pb,
return 0;
fail:
if (!st0)
- ff_free_stream(s, st);
+ ff_remove_stream(s, st);
return ret;
}
@@ -621,7 +620,7 @@ int ff_stream_side_data_copy(AVStream *dst, const AVStream *src)
return 0;
}
-static void free_stream(AVStream **pst)
+void ff_free_stream(AVStream **pst)
{
AVStream *st = *pst;
FFStream *const sti = ffstream(st);
@@ -657,12 +656,12 @@ static void free_stream(AVStream **pst)
av_freep(pst);
}
-void ff_free_stream(AVFormatContext *s, AVStream *st)
+void ff_remove_stream(AVFormatContext *s, AVStream *st)
{
av_assert0(s->nb_streams>0);
av_assert0(s->streams[ s->nb_streams - 1 ] == st);
- free_stream(&s->streams[ --s->nb_streams ]);
+ ff_free_stream(&s->streams[ --s->nb_streams ]);
}
void avformat_free_context(AVFormatContext *s)
@@ -683,7 +682,7 @@ void avformat_free_context(AVFormatContext *s)
av_opt_free(s->priv_data);
for (unsigned i = 0; i < s->nb_streams; i++)
- free_stream(&s->streams[i]);
+ ff_free_stream(&s->streams[i]);
s->nb_streams = 0;
for (unsigned i = 0; i < s->nb_programs; i++) {
@@ -710,125 +709,6 @@ void avformat_free_context(AVFormatContext *s)
av_free(s);
}
-static const AVOption stream_options[] = {
- { "disposition", NULL, offsetof(AVStream, disposition), AV_OPT_TYPE_FLAGS, { .i64 = 0 },
- .flags = AV_OPT_FLAG_ENCODING_PARAM, .unit = "disposition" },
- { "default", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DEFAULT }, .unit = "disposition" },
- { "dub", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DUB }, .unit = "disposition" },
- { "original", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_ORIGINAL }, .unit = "disposition" },
- { "comment", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_COMMENT }, .unit = "disposition" },
- { "lyrics", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_LYRICS }, .unit = "disposition" },
- { "karaoke", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_KARAOKE }, .unit = "disposition" },
- { "forced", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_FORCED }, .unit = "disposition" },
- { "hearing_impaired", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_HEARING_IMPAIRED }, .unit = "disposition" },
- { "visual_impaired", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_VISUAL_IMPAIRED }, .unit = "disposition" },
- { "clean_effects", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_CLEAN_EFFECTS }, .unit = "disposition" },
- { "attached_pic", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_ATTACHED_PIC }, .unit = "disposition" },
- { "timed_thumbnails", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_TIMED_THUMBNAILS }, .unit = "disposition" },
- { "captions", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_CAPTIONS }, .unit = "disposition" },
- { "descriptions", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DESCRIPTIONS }, .unit = "disposition" },
- { "metadata", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_METADATA }, .unit = "disposition" },
- { "dependent", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DEPENDENT }, .unit = "disposition" },
- { "still_image", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_STILL_IMAGE }, .unit = "disposition" },
- { NULL }
-};
-
-static const AVClass stream_class = {
- .class_name = "AVStream",
- .item_name = av_default_item_name,
- .version = LIBAVUTIL_VERSION_INT,
- .option = stream_options,
-};
-
-const AVClass *av_stream_get_class(void)
-{
- return &stream_class;
-}
-
-AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c)
-{
- FFFormatContext *const si = ffformatcontext(s);
- FFStream *sti;
- AVStream *st;
- AVStream **streams;
-
- if (s->nb_streams >= s->max_streams) {
- av_log(s, AV_LOG_ERROR, "Number of streams exceeds max_streams parameter"
- " (%d), see the documentation if you wish to increase it\n",
- s->max_streams);
- return NULL;
- }
- streams = av_realloc_array(s->streams, s->nb_streams + 1, sizeof(*streams));
- if (!streams)
- return NULL;
- s->streams = streams;
-
-
- sti = av_mallocz(sizeof(*sti));
- if (!sti)
- return NULL;
- st = &sti->pub;
-
-#if FF_API_AVSTREAM_CLASS
- st->av_class = &stream_class;
-#endif
-
- st->codecpar = avcodec_parameters_alloc();
- if (!st->codecpar)
- goto fail;
-
- sti->avctx = avcodec_alloc_context3(NULL);
- if (!sti->avctx)
- goto fail;
-
- if (s->iformat) {
- sti->info = av_mallocz(sizeof(*sti->info));
- if (!sti->info)
- goto fail;
-
-#if FF_API_R_FRAME_RATE
- sti->info->last_dts = AV_NOPTS_VALUE;
-#endif
- sti->info->fps_first_dts = AV_NOPTS_VALUE;
- sti->info->fps_last_dts = AV_NOPTS_VALUE;
-
- /* default pts setting is MPEG-like */
- avpriv_set_pts_info(st, 33, 1, 90000);
- /* we set the current DTS to 0 so that formats without any timestamps
- * but durations get some timestamps, formats with some unknown
- * timestamps have their first few packets buffered and the
- * timestamps corrected before they are returned to the user */
- sti->cur_dts = RELATIVE_TS_BASE;
- } else {
- sti->cur_dts = AV_NOPTS_VALUE;
- }
-
- st->index = s->nb_streams;
- st->start_time = AV_NOPTS_VALUE;
- st->duration = AV_NOPTS_VALUE;
- sti->first_dts = AV_NOPTS_VALUE;
- sti->probe_packets = s->max_probe_packets;
- sti->pts_wrap_reference = AV_NOPTS_VALUE;
- sti->pts_wrap_behavior = AV_PTS_WRAP_IGNORE;
-
- sti->last_IP_pts = AV_NOPTS_VALUE;
- sti->last_dts_for_order_check = AV_NOPTS_VALUE;
- for (int i = 0; i < MAX_REORDER_DELAY + 1; i++)
- sti->pts_buffer[i] = AV_NOPTS_VALUE;
-
- st->sample_aspect_ratio = (AVRational) { 0, 1 };
-
- sti->inject_global_side_data = si->inject_global_side_data;
-
- sti->need_context_update = 1;
-
- s->streams[s->nb_streams++] = st;
- return st;
-fail:
- free_stream(&st);
- return NULL;
-}
-
AVProgram *av_new_program(AVFormatContext *ac, int id)
{
AVProgram *program = NULL;
@@ -1953,35 +1833,6 @@ void ff_format_set_url(AVFormatContext *s, char *url)
s->url = url;
}
-static int option_is_disposition(const AVOption *opt)
-{
- return opt->type == AV_OPT_TYPE_CONST &&
- opt->unit && !strcmp(opt->unit, "disposition");
-}
-
-int av_disposition_from_string(const char *disp)
-{
- for (const AVOption *opt = stream_options; opt->name; opt++)
- if (option_is_disposition(opt) && !strcmp(disp, opt->name))
- return opt->default_val.i64;
- return AVERROR(EINVAL);
-}
-
-const char *av_disposition_to_string(int disposition)
-{
- int val;
-
- if (disposition <= 0)
- return NULL;
-
- val = 1 << ff_ctz(disposition);
- for (const AVOption *opt = stream_options; opt->name; opt++)
- if (option_is_disposition(opt) && opt->default_val.i64 == val)
- return opt->name;
-
- return NULL;
-}
-
int ff_format_shift_data(AVFormatContext *s, int64_t read_start, int shift_size)
{
int ret;