mirror of https://git.ffmpeg.org/ffmpeg.git
webmdashenc: Add better error handling
Return appropriate error codes and propagate the error codes from helper functions to the outer calls. Also fix a potential leak in call to av_realloc. Signed-off-by: Vignesh Venkatasubramanian <vigneshv@google.com> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
8254011b21
commit
1c37848f90
|
@ -179,7 +179,7 @@ static int write_representation(AVFormatContext *s, AVStream *stream, char *id,
|
|||
AVDictionaryEntry *bandwidth = av_dict_get(stream->metadata, BANDWIDTH, NULL, 0);
|
||||
if ((w->is_live && (!filename)) ||
|
||||
(!w->is_live && (!irange || !cues_start || !cues_end || !filename || !bandwidth))) {
|
||||
return -1;
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
avio_printf(s->pb, "<Representation id=\"%s\"", id);
|
||||
// FIXME: For live, This should be obtained from the input file or as an AVOption.
|
||||
|
@ -252,6 +252,16 @@ static int check_matching_sample_rate(AVFormatContext *s, AdaptationSet *as) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void free_adaptation_sets(AVFormatContext *s) {
|
||||
WebMDashMuxContext *w = s->priv_data;
|
||||
int i;
|
||||
for (i = 0; i < w->nb_as; i++) {
|
||||
av_freep(&w->as[i].streams);
|
||||
}
|
||||
av_freep(&w->as);
|
||||
w->nb_as = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses a live header filename and computes the representation id,
|
||||
* initialization pattern and the media pattern. Pass NULL if you don't want to
|
||||
|
@ -274,9 +284,9 @@ static int parse_filename(char *filename, char **representation_id,
|
|||
underscore_pos = temp_pos + 1;
|
||||
temp_pos = av_stristr(temp_pos + 1, "_");
|
||||
}
|
||||
if (!underscore_pos) return -1;
|
||||
if (!underscore_pos) return AVERROR_INVALIDDATA;
|
||||
period_pos = av_stristr(underscore_pos, ".");
|
||||
if (!period_pos) return -1;
|
||||
if (!period_pos) return AVERROR_INVALIDDATA;
|
||||
*(underscore_pos - 1) = 0;
|
||||
if (representation_id) {
|
||||
*representation_id = av_malloc(period_pos - underscore_pos + 1);
|
||||
|
@ -373,19 +383,22 @@ static int write_adaptation_set(AVFormatContext *s, int as_index)
|
|||
|
||||
for (i = 0; i < as->nb_streams; i++) {
|
||||
char *representation_id = NULL;
|
||||
int ret;
|
||||
if (w->is_live) {
|
||||
AVDictionaryEntry *filename =
|
||||
av_dict_get(s->streams[as->streams[i]]->metadata, FILENAME, NULL, 0);
|
||||
if (!filename ||
|
||||
parse_filename(filename->value, &representation_id, NULL, NULL)) {
|
||||
return -1;
|
||||
(ret = parse_filename(filename->value, &representation_id, NULL, NULL))) {
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
representation_id = av_asprintf("%d", w->representation_id++);
|
||||
if (!representation_id) return -1;
|
||||
if (!representation_id) return AVERROR(ENOMEM);
|
||||
}
|
||||
write_representation(s, s->streams[as->streams[i]], representation_id,
|
||||
!width_in_as, !height_in_as, !sample_rate_in_as);
|
||||
ret = write_representation(s, s->streams[as->streams[i]],
|
||||
representation_id, !width_in_as,
|
||||
!height_in_as, !sample_rate_in_as);
|
||||
if (ret) return ret;
|
||||
av_free(representation_id);
|
||||
}
|
||||
avio_printf(s->pb, "</AdaptationSet>\n");
|
||||
|
@ -416,9 +429,11 @@ static int parse_adaptation_sets(AVFormatContext *s)
|
|||
if (*p == ' ')
|
||||
continue;
|
||||
else if (state == new_set && !strncmp(p, "id=", 3)) {
|
||||
w->as = av_realloc(w->as, sizeof(*w->as) * ++w->nb_as);
|
||||
if (w->as == NULL)
|
||||
void *mem = av_realloc(w->as, sizeof(*w->as) * (w->nb_as + 1));
|
||||
if (mem == NULL)
|
||||
return AVERROR(ENOMEM);
|
||||
w->as = mem;
|
||||
++w->nb_as;
|
||||
w->as[w->nb_as - 1].nb_streams = 0;
|
||||
w->as[w->nb_as - 1].streams = NULL;
|
||||
p += 3; // consume "id="
|
||||
|
@ -453,8 +468,13 @@ static int webm_dash_manifest_write_header(AVFormatContext *s)
|
|||
{
|
||||
int i;
|
||||
double start = 0.0;
|
||||
int ret;
|
||||
WebMDashMuxContext *w = s->priv_data;
|
||||
parse_adaptation_sets(s);
|
||||
ret = parse_adaptation_sets(s);
|
||||
if (ret < 0) {
|
||||
free_adaptation_sets(s);
|
||||
return ret;
|
||||
}
|
||||
write_header(s);
|
||||
avio_printf(s->pb, "<Period id=\"0\"");
|
||||
avio_printf(s->pb, " start=\"PT%gS\"", start);
|
||||
|
@ -464,7 +484,11 @@ static int webm_dash_manifest_write_header(AVFormatContext *s)
|
|||
avio_printf(s->pb, " >\n");
|
||||
|
||||
for (i = 0; i < w->nb_as; i++) {
|
||||
if (write_adaptation_set(s, i) < 0) return -1;
|
||||
ret = write_adaptation_set(s, i);
|
||||
if (ret < 0) {
|
||||
free_adaptation_sets(s);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
avio_printf(s->pb, "</Period>\n");
|
||||
|
@ -479,12 +503,7 @@ static int webm_dash_manifest_write_packet(AVFormatContext *s, AVPacket *pkt)
|
|||
|
||||
static int webm_dash_manifest_write_trailer(AVFormatContext *s)
|
||||
{
|
||||
WebMDashMuxContext *w = s->priv_data;
|
||||
int i;
|
||||
for (i = 0; i < w->nb_as; i++) {
|
||||
av_freep(&w->as[i].streams);
|
||||
}
|
||||
av_freep(&w->as);
|
||||
free_adaptation_sets(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue