avformat/dashdec: export LCEVC Stream Groups when the manifest reports the relevant dependency

Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
James Almer
2026-03-23 14:07:42 -03:00
parent 0510aff11b
commit e7696357de
2 changed files with 62 additions and 2 deletions

View File

@@ -87,6 +87,8 @@ struct representation {
char *id;
char *lang;
int bandwidth;
char *dependencyid;
char *codecs;
AVRational framerate;
AVStream *assoc_stream; /* demuxer stream associated with this representation */
@@ -365,6 +367,8 @@ static void free_representation(struct representation *pls)
av_freep(&pls->url_template);
av_freep(&pls->lang);
av_freep(&pls->dependencyid);
av_freep(&pls->codecs);
av_freep(&pls->id);
av_freep(&pls);
}
@@ -908,6 +912,8 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
xmlNodePtr baseurl_nodes[4];
xmlNodePtr representation_node = node;
char *rep_bandwidth_val;
char *rep_codecs_val;
char *rep_dependencyid_val;
enum AVMediaType type = AVMEDIA_TYPE_UNKNOWN;
// try get information from representation
@@ -942,6 +948,10 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
representation_baseurl_node = find_child_node_by_name(representation_node, "BaseURL");
representation_segmentlist_node = find_child_node_by_name(representation_node, "SegmentList");
rep_bandwidth_val = xmlGetProp(representation_node, "bandwidth");
rep_dependencyid_val = xmlGetProp(representation_node, "dependencyId");
rep_codecs_val = xmlGetProp(representation_node, "codecs");
if (!rep_codecs_val)
rep_codecs_val = xmlGetProp(adaptionset_node, "codecs");
val = xmlGetProp(representation_node, "id");
if (val) {
rep->id = av_strdup(val);
@@ -1094,6 +1104,20 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
if (rep->fragment_duration > 0 && !rep->fragment_timescale)
rep->fragment_timescale = 1;
rep->bandwidth = rep_bandwidth_val ? atoi(rep_bandwidth_val) : 0;
if (rep_dependencyid_val) {
rep->dependencyid = av_strdup(rep_dependencyid_val);
if (!rep->dependencyid) {
xmlFree(rep_dependencyid_val);
goto enomem;
}
}
if (rep_codecs_val) {
rep->codecs = av_strdup(rep_codecs_val);
if (!rep->codecs) {
xmlFree(rep_codecs_val);
goto enomem;
}
}
rep->framerate = av_make_q(0, 0);
if (type == AVMEDIA_TYPE_VIDEO) {
char *rep_framerate_val = xmlGetProp(representation_node, "frameRate");
@@ -1122,6 +1146,10 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
end:
if (rep_bandwidth_val)
xmlFree(rep_bandwidth_val);
if (rep_dependencyid_val)
xmlFree(rep_dependencyid_val);
if (rep_codecs_val)
xmlFree(rep_codecs_val);
return ret;
enomem:
@@ -2051,7 +2079,7 @@ static int dash_read_header(AVFormatContext *s)
AVProgram *program;
int ret = 0;
int stream_index = 0;
int i;
int i, j;
c->interrupt_callback = &s->interrupt_callback;
@@ -2157,6 +2185,38 @@ static int dash_read_header(AVFormatContext *s)
move_metadata(rep->assoc_stream, "language", &rep->lang);
}
/* Create stream groups if needed */
for (i = 0; i < c->n_videos; i++) {
struct representation *ref;
rep = c->videos[i];
if (!rep->dependencyid)
continue;
for (j = 0; j < c->n_videos; j++) {
if (j == i)
continue;
ref = c->videos[j];
const AVDictionaryEntry *id = av_dict_get(ref->assoc_stream->metadata, "id", NULL, AV_DICT_MATCH_CASE);
if (!strcmp(rep->dependencyid, id->value))
break;
}
if (j >= c->n_videos || !av_strstart(rep->codecs, "lvc1", NULL) ||
rep->assoc_stream->codecpar->codec_id != AV_CODEC_ID_LCEVC)
continue;
AVStreamGroup *stg = avformat_stream_group_create(s, AV_STREAM_GROUP_PARAMS_LCEVC, NULL);
if (!stg)
return AVERROR(ENOMEM);
stg->params.lcevc->width = rep->assoc_stream->codecpar->width;
stg->params.lcevc->height = rep->assoc_stream->codecpar->height;
ret = avformat_stream_group_add_stream(stg, ref->assoc_stream);
if (ret < 0)
return ret;
ret = avformat_stream_group_add_stream(stg, rep->assoc_stream);
if (ret < 0)
return ret;
stg->id = stg->index;
stg->params.lcevc->lcevc_index = stg->nb_streams - 1;
}
return 0;
}

View File

@@ -32,7 +32,7 @@
#include "version_major.h"
#define LIBAVFORMAT_VERSION_MINOR 13
#define LIBAVFORMAT_VERSION_MICRO 101
#define LIBAVFORMAT_VERSION_MICRO 102
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
LIBAVFORMAT_VERSION_MINOR, \