From 50d1b89fa0d393bb019d984e989bff1b6fb81f39 Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 27 Sep 2024 14:57:07 -0300 Subject: [PATCH] avformat/avformat: add side data to AVStreamGroupTileGrid Will be used to export certain information present in HEIF samples, like rotation metadata, ICC profiles, and potentially others. Signed-off-by: James Almer --- doc/APIchanges | 3 +++ libavformat/avformat.c | 2 ++ libavformat/avformat.h | 13 +++++++++++++ libavformat/dump.c | 30 ++++++++++++++++++------------ libavformat/version.h | 2 +- 5 files changed, 37 insertions(+), 13 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index f9a4d0e442..1939b8758f 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -2,6 +2,9 @@ The last version increases of all libraries were on 2024-03-07 API changes, most recent first: +2024-09-30 - xxxxxxxxxx - lavf 61.9.100 - avformat.h + Add {nb_}coded_side_data to AVStreamGroupTileGrid. + 2024-09-xx - xxxxxxxxxx - lavu 59 Deprecate av_int_list_length_for_size(), av_int_list_length(), and av_opt_set_int_list() without replacement. All AVOptions using these diff --git a/libavformat/avformat.c b/libavformat/avformat.c index 06dcde0565..89ee669bf9 100644 --- a/libavformat/avformat.c +++ b/libavformat/avformat.c @@ -102,6 +102,8 @@ void ff_free_stream_group(AVStreamGroup **pstg) case AV_STREAM_GROUP_PARAMS_TILE_GRID: av_opt_free(stg->params.tile_grid); av_freep(&stg->params.tile_grid->offsets); + av_packet_side_data_free(&stg->params.tile_grid->coded_side_data, + &stg->params.tile_grid->nb_coded_side_data); av_freep(&stg->params.tile_grid); break; case AV_STREAM_GROUP_PARAMS_LCEVC: diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 56c1c80289..2e5f2dc795 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1082,6 +1082,19 @@ typedef struct AVStreamGroupTileGrid { * final image before presentation. */ int height; + + /** + * Additional data associated with the grid. + * + * Should be allocated with av_packet_side_data_new() or + * av_packet_side_data_add(), and will be freed by avformat_free_context(). + */ + AVPacketSideData *coded_side_data; + + /** + * Amount of entries in @ref coded_side_data. + */ + int nb_coded_side_data; } AVStreamGroupTileGrid; /** diff --git a/libavformat/dump.c b/libavformat/dump.c index a8e968fd86..7dc7f0ad5a 100644 --- a/libavformat/dump.c +++ b/libavformat/dump.c @@ -377,7 +377,7 @@ static void dump_ambient_viewing_environment_metadata(void *ctx, const AVPacketS av_q2d(ambient->ambient_light_y)); } -static void dump_spherical(void *ctx, const AVCodecParameters *par, +static void dump_spherical(void *ctx, int w, int h, const AVPacketSideData *sd, int log_level) { const AVSphericalMapping *spherical = (const AVSphericalMapping *)sd->data; @@ -399,7 +399,7 @@ static void dump_spherical(void *ctx, const AVCodecParameters *par, if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR_TILE) { size_t l, t, r, b; - av_spherical_tile_bounds(spherical, par->width, par->height, + av_spherical_tile_bounds(spherical, w, h, &l, &t, &r, &b); av_log(ctx, log_level, "[%"SIZE_SPECIFIER", %"SIZE_SPECIFIER", %"SIZE_SPECIFIER", %"SIZE_SPECIFIER"] ", @@ -427,7 +427,7 @@ static void dump_dovi_conf(void *ctx, const AVPacketSideData *sd, dovi->dv_md_compression); } -static void dump_s12m_timecode(void *ctx, const AVStream *st, const AVPacketSideData *sd, +static void dump_s12m_timecode(void *ctx, AVRational avg_frame_rate, const AVPacketSideData *sd, int log_level) { const uint32_t *tc = (const uint32_t *)sd->data; @@ -439,7 +439,7 @@ static void dump_s12m_timecode(void *ctx, const AVStream *st, const AVPacketSide for (int j = 1; j <= tc[0]; j++) { char tcbuf[AV_TIMECODE_STR_SIZE]; - av_timecode_make_smpte_tc_string2(tcbuf, st->avg_frame_rate, tc[j], 0, 0); + av_timecode_make_smpte_tc_string2(tcbuf, avg_frame_rate, tc[j], 0, 0); av_log(ctx, log_level, "timecode - %s%s", tcbuf, j != tc[0] ? ", " : ""); } } @@ -461,16 +461,17 @@ static void dump_cropping(void *ctx, const AVPacketSideData *sd) av_log(ctx, AV_LOG_INFO, "%d/%d/%d/%d", left, right, top, bottom); } -static void dump_sidedata(void *ctx, const AVStream *st, const char *indent, - int log_level) +static void dump_sidedata(void *ctx, const AVPacketSideData *side_data, int nb_side_data, + int w, int h, AVRational avg_frame_rate, + const char *indent, int log_level) { int i; - if (st->codecpar->nb_coded_side_data) + if (nb_side_data) av_log(ctx, log_level, "%sSide data:\n", indent); - for (i = 0; i < st->codecpar->nb_coded_side_data; i++) { - const AVPacketSideData *sd = &st->codecpar->coded_side_data[i]; + for (i = 0; i < nb_side_data; i++) { + const AVPacketSideData *sd = &side_data[i]; av_log(ctx, log_level, "%s ", indent); switch (sd->type) { @@ -516,7 +517,7 @@ static void dump_sidedata(void *ctx, const AVStream *st, const char *indent, break; case AV_PKT_DATA_SPHERICAL: av_log(ctx, log_level, "spherical: "); - dump_spherical(ctx, st->codecpar, sd, log_level); + dump_spherical(ctx, w, h, sd, log_level); break; case AV_PKT_DATA_CONTENT_LIGHT_LEVEL: dump_content_light_metadata(ctx, sd, log_level); @@ -530,7 +531,7 @@ static void dump_sidedata(void *ctx, const AVStream *st, const char *indent, break; case AV_PKT_DATA_S12M_TIMECODE: av_log(ctx, log_level, "SMPTE ST 12-1:2014: "); - dump_s12m_timecode(ctx, st, sd, log_level); + dump_s12m_timecode(ctx, avg_frame_rate, sd, log_level); break; case AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT: dump_ambient_viewing_environment_metadata(ctx, sd); @@ -678,7 +679,9 @@ static void dump_stream_format(const AVFormatContext *ic, int i, dump_metadata(NULL, st->metadata, extra_indent, log_level); - dump_sidedata(NULL, st, extra_indent, log_level); + dump_sidedata(NULL, st->codecpar->coded_side_data, st->codecpar->nb_coded_side_data, + st->codecpar->width, st->codecpar->height, st->avg_frame_rate, + extra_indent, log_level); } static void dump_stream_group(const AVFormatContext *ic, uint8_t *printed, @@ -782,6 +785,9 @@ static void dump_stream_group(const AVFormatContext *ic, uint8_t *printed, dump_disposition(stg->disposition, AV_LOG_INFO); av_log(NULL, AV_LOG_INFO, "\n"); dump_metadata(NULL, stg->metadata, " ", AV_LOG_INFO); + dump_sidedata(NULL, tile_grid->coded_side_data, tile_grid->nb_coded_side_data, + tile_grid->width, tile_grid->height, (AVRational) {0,1}, + " ", AV_LOG_INFO); for (int i = 0; i < tile_grid->nb_tiles; i++) { const AVStream *st = stg->streams[tile_grid->offsets[i].idx]; dump_stream_format(ic, st->index, i, index, is_output, AV_LOG_VERBOSE); diff --git a/libavformat/version.h b/libavformat/version.h index 35d796d318..1b079ebce8 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -31,7 +31,7 @@ #include "version_major.h" -#define LIBAVFORMAT_VERSION_MINOR 8 +#define LIBAVFORMAT_VERSION_MINOR 9 #define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \