avformat: add a disposition field to AVStreamGroup
The existing (and upcoming) available group types are meant to combine several streams for presentation, with the result being treated as if it was a stream itself. For example, a file could export two stream groups of the same type with one of them as the "default". Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
@@ -2,6 +2,9 @@ The last version increases of all libraries were on 2023-02-09
|
|||||||
|
|
||||||
API changes, most recent first:
|
API changes, most recent first:
|
||||||
|
|
||||||
|
2024-02-13 - xxxxxxxxxx - lavf 60.21.100 - avformat.h
|
||||||
|
Add AVStreamGroup.disposition.
|
||||||
|
|
||||||
2024-02-xx - xxxxxxxxxx - lavu 58.38.100 - channel_layout.h
|
2024-02-xx - xxxxxxxxxx - lavu 58.38.100 - channel_layout.h
|
||||||
Add av_channel_layout_retype().
|
Add av_channel_layout_retype().
|
||||||
|
|
||||||
|
@@ -1093,6 +1093,16 @@ typedef struct AVStreamGroup {
|
|||||||
* Freed by libavformat in avformat_free_context().
|
* Freed by libavformat in avformat_free_context().
|
||||||
*/
|
*/
|
||||||
AVStream **streams;
|
AVStream **streams;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stream group disposition - a combination of AV_DISPOSITION_* flags.
|
||||||
|
* This field currently applies to all defined AVStreamGroupParamsType.
|
||||||
|
*
|
||||||
|
* - demuxing: set by libavformat when creating the group or in
|
||||||
|
* avformat_find_stream_info().
|
||||||
|
* - muxing: may be set by the caller before avformat_write_header().
|
||||||
|
*/
|
||||||
|
int disposition;
|
||||||
} AVStreamGroup;
|
} AVStreamGroup;
|
||||||
|
|
||||||
struct AVCodecParserContext *av_stream_get_parser(const AVStream *s);
|
struct AVCodecParserContext *av_stream_get_parser(const AVStream *s);
|
||||||
|
@@ -538,6 +538,46 @@ static void dump_sidedata(void *ctx, const AVStream *st, const char *indent,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dump_disposition(int disposition, int log_level)
|
||||||
|
{
|
||||||
|
if (disposition & AV_DISPOSITION_DEFAULT)
|
||||||
|
av_log(NULL, log_level, " (default)");
|
||||||
|
if (disposition & AV_DISPOSITION_DUB)
|
||||||
|
av_log(NULL, log_level, " (dub)");
|
||||||
|
if (disposition & AV_DISPOSITION_ORIGINAL)
|
||||||
|
av_log(NULL, log_level, " (original)");
|
||||||
|
if (disposition & AV_DISPOSITION_COMMENT)
|
||||||
|
av_log(NULL, log_level, " (comment)");
|
||||||
|
if (disposition & AV_DISPOSITION_LYRICS)
|
||||||
|
av_log(NULL, log_level, " (lyrics)");
|
||||||
|
if (disposition & AV_DISPOSITION_KARAOKE)
|
||||||
|
av_log(NULL, log_level, " (karaoke)");
|
||||||
|
if (disposition & AV_DISPOSITION_FORCED)
|
||||||
|
av_log(NULL, log_level, " (forced)");
|
||||||
|
if (disposition & AV_DISPOSITION_HEARING_IMPAIRED)
|
||||||
|
av_log(NULL, log_level, " (hearing impaired)");
|
||||||
|
if (disposition & AV_DISPOSITION_VISUAL_IMPAIRED)
|
||||||
|
av_log(NULL, log_level, " (visual impaired)");
|
||||||
|
if (disposition & AV_DISPOSITION_CLEAN_EFFECTS)
|
||||||
|
av_log(NULL, log_level, " (clean effects)");
|
||||||
|
if (disposition & AV_DISPOSITION_ATTACHED_PIC)
|
||||||
|
av_log(NULL, log_level, " (attached pic)");
|
||||||
|
if (disposition & AV_DISPOSITION_TIMED_THUMBNAILS)
|
||||||
|
av_log(NULL, log_level, " (timed thumbnails)");
|
||||||
|
if (disposition & AV_DISPOSITION_CAPTIONS)
|
||||||
|
av_log(NULL, log_level, " (captions)");
|
||||||
|
if (disposition & AV_DISPOSITION_DESCRIPTIONS)
|
||||||
|
av_log(NULL, log_level, " (descriptions)");
|
||||||
|
if (disposition & AV_DISPOSITION_METADATA)
|
||||||
|
av_log(NULL, log_level, " (metadata)");
|
||||||
|
if (disposition & AV_DISPOSITION_DEPENDENT)
|
||||||
|
av_log(NULL, log_level, " (dependent)");
|
||||||
|
if (disposition & AV_DISPOSITION_STILL_IMAGE)
|
||||||
|
av_log(NULL, log_level, " (still image)");
|
||||||
|
if (disposition & AV_DISPOSITION_NON_DIEGETIC)
|
||||||
|
av_log(NULL, log_level, " (non-diegetic)");
|
||||||
|
}
|
||||||
|
|
||||||
/* "user interface" functions */
|
/* "user interface" functions */
|
||||||
static void dump_stream_format(const AVFormatContext *ic, int i,
|
static void dump_stream_format(const AVFormatContext *ic, int i,
|
||||||
int group_index, int index, int is_output,
|
int group_index, int index, int is_output,
|
||||||
@@ -620,42 +660,7 @@ static void dump_stream_format(const AVFormatContext *ic, int i,
|
|||||||
print_fps(1 / av_q2d(st->time_base), "tbn", log_level);
|
print_fps(1 / av_q2d(st->time_base), "tbn", log_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st->disposition & AV_DISPOSITION_DEFAULT)
|
dump_disposition(st->disposition, log_level);
|
||||||
av_log(NULL, log_level, " (default)");
|
|
||||||
if (st->disposition & AV_DISPOSITION_DUB)
|
|
||||||
av_log(NULL, log_level, " (dub)");
|
|
||||||
if (st->disposition & AV_DISPOSITION_ORIGINAL)
|
|
||||||
av_log(NULL, log_level, " (original)");
|
|
||||||
if (st->disposition & AV_DISPOSITION_COMMENT)
|
|
||||||
av_log(NULL, log_level, " (comment)");
|
|
||||||
if (st->disposition & AV_DISPOSITION_LYRICS)
|
|
||||||
av_log(NULL, log_level, " (lyrics)");
|
|
||||||
if (st->disposition & AV_DISPOSITION_KARAOKE)
|
|
||||||
av_log(NULL, log_level, " (karaoke)");
|
|
||||||
if (st->disposition & AV_DISPOSITION_FORCED)
|
|
||||||
av_log(NULL, log_level, " (forced)");
|
|
||||||
if (st->disposition & AV_DISPOSITION_HEARING_IMPAIRED)
|
|
||||||
av_log(NULL, log_level, " (hearing impaired)");
|
|
||||||
if (st->disposition & AV_DISPOSITION_VISUAL_IMPAIRED)
|
|
||||||
av_log(NULL, log_level, " (visual impaired)");
|
|
||||||
if (st->disposition & AV_DISPOSITION_CLEAN_EFFECTS)
|
|
||||||
av_log(NULL, log_level, " (clean effects)");
|
|
||||||
if (st->disposition & AV_DISPOSITION_ATTACHED_PIC)
|
|
||||||
av_log(NULL, log_level, " (attached pic)");
|
|
||||||
if (st->disposition & AV_DISPOSITION_TIMED_THUMBNAILS)
|
|
||||||
av_log(NULL, log_level, " (timed thumbnails)");
|
|
||||||
if (st->disposition & AV_DISPOSITION_CAPTIONS)
|
|
||||||
av_log(NULL, log_level, " (captions)");
|
|
||||||
if (st->disposition & AV_DISPOSITION_DESCRIPTIONS)
|
|
||||||
av_log(NULL, log_level, " (descriptions)");
|
|
||||||
if (st->disposition & AV_DISPOSITION_METADATA)
|
|
||||||
av_log(NULL, log_level, " (metadata)");
|
|
||||||
if (st->disposition & AV_DISPOSITION_DEPENDENT)
|
|
||||||
av_log(NULL, log_level, " (dependent)");
|
|
||||||
if (st->disposition & AV_DISPOSITION_STILL_IMAGE)
|
|
||||||
av_log(NULL, log_level, " (still image)");
|
|
||||||
if (st->disposition & AV_DISPOSITION_NON_DIEGETIC)
|
|
||||||
av_log(NULL, log_level, " (non-diegetic)");
|
|
||||||
av_log(NULL, log_level, "\n");
|
av_log(NULL, log_level, "\n");
|
||||||
|
|
||||||
dump_metadata(NULL, st->metadata, extra_indent, log_level);
|
dump_metadata(NULL, st->metadata, extra_indent, log_level);
|
||||||
@@ -679,7 +684,9 @@ static void dump_stream_group(const AVFormatContext *ic, uint8_t *printed,
|
|||||||
switch (stg->type) {
|
switch (stg->type) {
|
||||||
case AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT: {
|
case AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT: {
|
||||||
const AVIAMFAudioElement *audio_element = stg->params.iamf_audio_element;
|
const AVIAMFAudioElement *audio_element = stg->params.iamf_audio_element;
|
||||||
av_log(NULL, AV_LOG_INFO, " IAMF Audio Element\n");
|
av_log(NULL, AV_LOG_INFO, " IAMF Audio Element:");
|
||||||
|
dump_disposition(st->disposition, log_level);
|
||||||
|
av_log(NULL, AV_LOG_INFO, "\n");
|
||||||
dump_metadata(NULL, stg->metadata, " ", AV_LOG_INFO);
|
dump_metadata(NULL, stg->metadata, " ", AV_LOG_INFO);
|
||||||
for (int j = 0; j < audio_element->nb_layers; j++) {
|
for (int j = 0; j < audio_element->nb_layers; j++) {
|
||||||
const AVIAMFLayer *layer = audio_element->layers[j];
|
const AVIAMFLayer *layer = audio_element->layers[j];
|
||||||
@@ -700,7 +707,9 @@ static void dump_stream_group(const AVFormatContext *ic, uint8_t *printed,
|
|||||||
}
|
}
|
||||||
case AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION: {
|
case AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION: {
|
||||||
const AVIAMFMixPresentation *mix_presentation = stg->params.iamf_mix_presentation;
|
const AVIAMFMixPresentation *mix_presentation = stg->params.iamf_mix_presentation;
|
||||||
av_log(NULL, AV_LOG_INFO, " IAMF Mix Presentation\n");
|
av_log(NULL, AV_LOG_INFO, " IAMF Mix Presentation:");
|
||||||
|
dump_disposition(st->disposition, log_level);
|
||||||
|
av_log(NULL, AV_LOG_INFO, "\n");
|
||||||
dump_metadata(NULL, stg->metadata, " ", AV_LOG_INFO);
|
dump_metadata(NULL, stg->metadata, " ", AV_LOG_INFO);
|
||||||
dump_dictionary(NULL, mix_presentation->annotations, "Annotations", " ", AV_LOG_INFO);
|
dump_dictionary(NULL, mix_presentation->annotations, "Annotations", " ", AV_LOG_INFO);
|
||||||
for (int j = 0; j < mix_presentation->nb_submixes; j++) {
|
for (int j = 0; j < mix_presentation->nb_submixes; j++) {
|
||||||
|
@@ -208,28 +208,30 @@ const AVClass *avformat_get_class(void)
|
|||||||
return &av_format_context_class;
|
return &av_format_context_class;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const AVOption stream_options[] = {
|
#define DISPOSITION_OPT(ctx) \
|
||||||
{ "disposition", NULL, offsetof(AVStream, disposition), AV_OPT_TYPE_FLAGS, { .i64 = 0 },
|
{ "disposition", NULL, offsetof(ctx, disposition), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, \
|
||||||
.flags = AV_OPT_FLAG_ENCODING_PARAM, .unit = "disposition" },
|
.flags = AV_OPT_FLAG_ENCODING_PARAM, .unit = "disposition" }, \
|
||||||
{ "default", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DEFAULT }, .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" },
|
{ "dub", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DUB }, .unit = "disposition" }, \
|
||||||
{ "original", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_ORIGINAL }, .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" },
|
{ "comment", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_COMMENT }, .unit = "disposition" }, \
|
||||||
{ "lyrics", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_LYRICS }, .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" },
|
{ "karaoke", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_KARAOKE }, .unit = "disposition" }, \
|
||||||
{ "forced", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_FORCED }, .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" },
|
{ "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" },
|
{ "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" },
|
{ "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" },
|
{ "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" },
|
{ "timed_thumbnails", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_TIMED_THUMBNAILS }, .unit = "disposition" }, \
|
||||||
{ "non_diegetic", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_NON_DIEGETIC }, .unit = "disposition" },
|
{ "non_diegetic", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_NON_DIEGETIC }, .unit = "disposition" }, \
|
||||||
{ "captions", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_CAPTIONS }, .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" },
|
{ "descriptions", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DESCRIPTIONS }, .unit = "disposition" }, \
|
||||||
{ "metadata", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_METADATA }, .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" },
|
{ "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" },
|
{ "still_image", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_STILL_IMAGE }, .unit = "disposition" }
|
||||||
|
|
||||||
|
static const AVOption stream_options[] = {
|
||||||
|
DISPOSITION_OPT(AVStream),
|
||||||
{ "discard", NULL, offsetof(AVStream, discard), AV_OPT_TYPE_INT, { .i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX,
|
{ "discard", NULL, offsetof(AVStream, discard), AV_OPT_TYPE_INT, { .i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX,
|
||||||
.flags = AV_OPT_FLAG_DECODING_PARAM, .unit = "avdiscard" },
|
.flags = AV_OPT_FLAG_DECODING_PARAM, .unit = "avdiscard" },
|
||||||
{ "none", .type = AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONE }, .unit = "avdiscard" },
|
{ "none", .type = AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONE }, .unit = "avdiscard" },
|
||||||
@@ -380,6 +382,7 @@ static const AVClass *stream_group_child_iterate(void **opaque)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const AVOption stream_group_options[] = {
|
static const AVOption stream_group_options[] = {
|
||||||
|
DISPOSITION_OPT(AVStreamGroup),
|
||||||
{"id", "Set group id", offsetof(AVStreamGroup, id), AV_OPT_TYPE_INT64, {.i64 = 0}, 0, INT64_MAX, AV_OPT_FLAG_ENCODING_PARAM },
|
{"id", "Set group id", offsetof(AVStreamGroup, id), AV_OPT_TYPE_INT64, {.i64 = 0}, 0, INT64_MAX, AV_OPT_FLAG_ENCODING_PARAM },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
@@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
#include "version_major.h"
|
#include "version_major.h"
|
||||||
|
|
||||||
#define LIBAVFORMAT_VERSION_MINOR 20
|
#define LIBAVFORMAT_VERSION_MINOR 21
|
||||||
#define LIBAVFORMAT_VERSION_MICRO 100
|
#define LIBAVFORMAT_VERSION_MICRO 100
|
||||||
|
|
||||||
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
|
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
|
||||||
|
Reference in New Issue
Block a user