1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-11-26 19:01:44 +02:00

avformat: add an LCEVC stream group

Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
James Almer 2024-08-20 13:56:48 -03:00
parent 5896318229
commit ba0ef0860f
6 changed files with 94 additions and 3 deletions

View File

@ -2,6 +2,11 @@ The last version increases of all libraries were on 2024-03-07
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
Add AV_CODEC_ID_LCEVC.

View File

@ -104,6 +104,10 @@ void ff_free_stream_group(AVStreamGroup **pstg)
av_freep(&stg->params.tile_grid->offsets);
av_freep(&stg->params.tile_grid);
break;
case AV_STREAM_GROUP_PARAMS_LCEVC:
av_opt_free(stg->params.lcevc);
av_freep(&stg->params.lcevc);
break;
default:
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_MIX_PRESENTATION: return "IAMF Mix Presentation";
case AV_STREAM_GROUP_PARAMS_TILE_GRID: return "Tile Grid";
case AV_STREAM_GROUP_PARAMS_LCEVC: return "LCEVC (Split video and enhancement)";
}
return NULL;
}

View File

@ -1084,11 +1084,37 @@ typedef struct AVStreamGroupTileGrid {
int height;
} 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 {
AV_STREAM_GROUP_PARAMS_NONE,
AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT,
AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION,
AV_STREAM_GROUP_PARAMS_TILE_GRID,
AV_STREAM_GROUP_PARAMS_LCEVC,
};
struct AVIAMFAudioElement;
@ -1130,6 +1156,7 @@ typedef struct AVStreamGroup {
struct AVIAMFAudioElement *iamf_audio_element;
struct AVIAMFMixPresentation *iamf_mix_presentation;
struct AVStreamGroupTileGrid *tile_grid;
struct AVStreamGroupLCEVC *lcevc;
} params;
/**

View File

@ -789,6 +789,33 @@ static void dump_stream_group(const AVFormatContext *ic, uint8_t *printed,
}
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:
break;
}

View File

@ -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 },
{ NULL },
};
#undef FLAGS
#undef OFFSET
static const AVClass tile_grid_class = {
@ -357,6 +356,20 @@ static const AVClass tile_grid_class = {
.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)
{
AVStreamGroup *stg = obj;
@ -368,6 +381,8 @@ static void *stream_group_child_next(void *obj, void *prev)
return stg->params.iamf_mix_presentation;
case AV_STREAM_GROUP_PARAMS_TILE_GRID:
return stg->params.tile_grid;
case AV_STREAM_GROUP_PARAMS_LCEVC:
return stg->params.lcevc;
default:
break;
}
@ -375,6 +390,8 @@ static void *stream_group_child_next(void *obj, void *prev)
return NULL;
}
#undef FLAGS
static const AVClass *stream_group_child_iterate(void **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:
ret = &tile_grid_class;
break;
case AV_STREAM_GROUP_PARAMS_LCEVC:
ret = &lcevc_class;
break;
default:
break;
}
@ -462,6 +482,13 @@ AVStreamGroup *avformat_stream_group_create(AVFormatContext *s,
stg->params.tile_grid->av_class = &tile_grid_class;
av_opt_set_defaults(stg->params.tile_grid);
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:
goto fail;
}

View File

@ -31,8 +31,8 @@
#include "version_major.h"
#define LIBAVFORMAT_VERSION_MINOR 5
#define LIBAVFORMAT_VERSION_MICRO 101
#define LIBAVFORMAT_VERSION_MINOR 6
#define LIBAVFORMAT_VERSION_MICRO 100
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
LIBAVFORMAT_VERSION_MINOR, \