avformat: add an LCEVC stream group

Signed-off-by: James Almer <jamrial@gmail.com>
release/7.1
James Almer 4 months ago
parent 5896318229
commit ba0ef0860f
  1. 5
      doc/APIchanges
  2. 5
      libavformat/avformat.c
  3. 27
      libavformat/avformat.h
  4. 27
      libavformat/dump.c
  5. 29
      libavformat/options.c
  6. 4
      libavformat/version.h

@ -2,6 +2,11 @@ The last version increases of all libraries were on 2024-03-07
API changes, most recent first: API changes, most recent first:
2024-09-18 - xxxxxxxxxx - lavf 61.5.100 - avformat.h
Add AVStreamGroupLCEVC
Add AV_STREAM_GROUP_PARAMS_LCEVC
Add AVStreamGroup.params.lcevc
2024-09-18 - xxxxxxxxxx - lavc 61.16.100 - avcodec.h 2024-09-18 - xxxxxxxxxx - lavc 61.16.100 - avcodec.h
Add AV_CODEC_ID_LCEVC. Add AV_CODEC_ID_LCEVC.

@ -104,6 +104,10 @@ void ff_free_stream_group(AVStreamGroup **pstg)
av_freep(&stg->params.tile_grid->offsets); av_freep(&stg->params.tile_grid->offsets);
av_freep(&stg->params.tile_grid); av_freep(&stg->params.tile_grid);
break; break;
case AV_STREAM_GROUP_PARAMS_LCEVC:
av_opt_free(stg->params.lcevc);
av_freep(&stg->params.lcevc);
break;
default: default:
break; break;
} }
@ -327,6 +331,7 @@ const char *avformat_stream_group_name(enum AVStreamGroupParamsType type)
case AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT: return "IAMF Audio Element"; case AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT: return "IAMF Audio Element";
case AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION: return "IAMF Mix Presentation"; case AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION: return "IAMF Mix Presentation";
case AV_STREAM_GROUP_PARAMS_TILE_GRID: return "Tile Grid"; case AV_STREAM_GROUP_PARAMS_TILE_GRID: return "Tile Grid";
case AV_STREAM_GROUP_PARAMS_LCEVC: return "LCEVC (Split video and enhancement)";
} }
return NULL; return NULL;
} }

@ -1084,11 +1084,37 @@ typedef struct AVStreamGroupTileGrid {
int height; int height;
} AVStreamGroupTileGrid; } AVStreamGroupTileGrid;
/**
* AVStreamGroupLCEVC is meant to define the relation between video streams
* and a data stream containing LCEVC enhancement layer NALUs.
*
* No more than one stream of @ref AVCodecParameters.codec_type "codec_type"
* AVMEDIA_TYPE_DATA shall be present, and it must be of
* @ref AVCodecParameters.codec_id "codec_id" AV_CODEC_ID_LCEVC.
*/
typedef struct AVStreamGroupLCEVC {
const AVClass *av_class;
/**
* Index of the LCEVC data stream in AVStreamGroup.
*/
unsigned int lcevc_index;
/**
* Width of the final stream for presentation.
*/
int width;
/**
* Height of the final image for presentation.
*/
int height;
} AVStreamGroupLCEVC;
enum AVStreamGroupParamsType { enum AVStreamGroupParamsType {
AV_STREAM_GROUP_PARAMS_NONE, AV_STREAM_GROUP_PARAMS_NONE,
AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT, AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT,
AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION, AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION,
AV_STREAM_GROUP_PARAMS_TILE_GRID, AV_STREAM_GROUP_PARAMS_TILE_GRID,
AV_STREAM_GROUP_PARAMS_LCEVC,
}; };
struct AVIAMFAudioElement; struct AVIAMFAudioElement;
@ -1130,6 +1156,7 @@ typedef struct AVStreamGroup {
struct AVIAMFAudioElement *iamf_audio_element; struct AVIAMFAudioElement *iamf_audio_element;
struct AVIAMFMixPresentation *iamf_mix_presentation; struct AVIAMFMixPresentation *iamf_mix_presentation;
struct AVStreamGroupTileGrid *tile_grid; struct AVStreamGroupTileGrid *tile_grid;
struct AVStreamGroupLCEVC *lcevc;
} params; } params;
/** /**

@ -789,6 +789,33 @@ static void dump_stream_group(const AVFormatContext *ic, uint8_t *printed,
} }
break; break;
} }
case AV_STREAM_GROUP_PARAMS_LCEVC: {
const AVStreamGroupLCEVC *lcevc = stg->params.lcevc;
AVCodecContext *avctx = avcodec_alloc_context3(NULL);
const char *ptr = NULL;
av_log(NULL, AV_LOG_INFO, " LCEVC:");
if (avctx && stg->nb_streams && !avcodec_parameters_to_context(avctx, stg->streams[0]->codecpar)) {
avctx->width = lcevc->width;
avctx->height = lcevc->height;
avctx->coded_width = lcevc->width;
avctx->coded_height = lcevc->height;
if (ic->dump_separator)
av_opt_set(avctx, "dump_separator", ic->dump_separator, 0);
buf[0] = 0;
avcodec_string(buf, sizeof(buf), avctx, is_output);
ptr = av_stristr(buf, " ");
}
avcodec_free_context(&avctx);
if (ptr)
av_log(NULL, AV_LOG_INFO, "%s", ptr);
av_log(NULL, AV_LOG_INFO, "\n");
for (int i = 0; i < stg->nb_streams; i++) {
const AVStream *st = stg->streams[i];
dump_stream_format(ic, st->index, i, index, is_output, AV_LOG_VERBOSE);
printed[st->index] = 1;
}
break;
}
default: default:
break; break;
} }

@ -348,7 +348,6 @@ static const AVOption tile_grid_options[] = {
{ "vertical_offset", NULL, OFFSET(vertical_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS }, { "vertical_offset", NULL, OFFSET(vertical_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },
{ NULL }, { NULL },
}; };
#undef FLAGS
#undef OFFSET #undef OFFSET
static const AVClass tile_grid_class = { static const AVClass tile_grid_class = {
@ -357,6 +356,20 @@ static const AVClass tile_grid_class = {
.option = tile_grid_options, .option = tile_grid_options,
}; };
#define OFFSET(x) offsetof(AVStreamGroupLCEVC, x)
static const AVOption lcevc_options[] = {
{ "video_size", "size of video after LCEVC enhancement has been applied", OFFSET(width),
AV_OPT_TYPE_IMAGE_SIZE, { .str = NULL }, 0, INT_MAX, FLAGS },
{ NULL },
};
#undef OFFSET
static const AVClass lcevc_class = {
.class_name = "AVStreamGroupLCEVC",
.version = LIBAVUTIL_VERSION_INT,
.option = lcevc_options,
};
static void *stream_group_child_next(void *obj, void *prev) static void *stream_group_child_next(void *obj, void *prev)
{ {
AVStreamGroup *stg = obj; AVStreamGroup *stg = obj;
@ -368,6 +381,8 @@ static void *stream_group_child_next(void *obj, void *prev)
return stg->params.iamf_mix_presentation; return stg->params.iamf_mix_presentation;
case AV_STREAM_GROUP_PARAMS_TILE_GRID: case AV_STREAM_GROUP_PARAMS_TILE_GRID:
return stg->params.tile_grid; return stg->params.tile_grid;
case AV_STREAM_GROUP_PARAMS_LCEVC:
return stg->params.lcevc;
default: default:
break; break;
} }
@ -375,6 +390,8 @@ static void *stream_group_child_next(void *obj, void *prev)
return NULL; return NULL;
} }
#undef FLAGS
static const AVClass *stream_group_child_iterate(void **opaque) static const AVClass *stream_group_child_iterate(void **opaque)
{ {
uintptr_t i = (uintptr_t)*opaque; uintptr_t i = (uintptr_t)*opaque;
@ -393,6 +410,9 @@ static const AVClass *stream_group_child_iterate(void **opaque)
case AV_STREAM_GROUP_PARAMS_TILE_GRID: case AV_STREAM_GROUP_PARAMS_TILE_GRID:
ret = &tile_grid_class; ret = &tile_grid_class;
break; break;
case AV_STREAM_GROUP_PARAMS_LCEVC:
ret = &lcevc_class;
break;
default: default:
break; break;
} }
@ -462,6 +482,13 @@ AVStreamGroup *avformat_stream_group_create(AVFormatContext *s,
stg->params.tile_grid->av_class = &tile_grid_class; stg->params.tile_grid->av_class = &tile_grid_class;
av_opt_set_defaults(stg->params.tile_grid); av_opt_set_defaults(stg->params.tile_grid);
break; break;
case AV_STREAM_GROUP_PARAMS_LCEVC:
stg->params.lcevc = av_mallocz(sizeof(*stg->params.lcevc));
if (!stg->params.lcevc)
goto fail;
stg->params.lcevc->av_class = &lcevc_class;
av_opt_set_defaults(stg->params.lcevc);
break;
default: default:
goto fail; goto fail;
} }

@ -31,8 +31,8 @@
#include "version_major.h" #include "version_major.h"
#define LIBAVFORMAT_VERSION_MINOR 5 #define LIBAVFORMAT_VERSION_MINOR 6
#define LIBAVFORMAT_VERSION_MICRO 101 #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, \
LIBAVFORMAT_VERSION_MINOR, \ LIBAVFORMAT_VERSION_MINOR, \

Loading…
Cancel
Save