Commit 1c37848f authored by Vignesh Venkatasubramanian's avatar Vignesh Venkatasubramanian Committed by Michael Niedermayer

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: 's avatarVignesh Venkatasubramanian <vigneshv@google.com>
Signed-off-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parent 8254011b
...@@ -179,7 +179,7 @@ static int write_representation(AVFormatContext *s, AVStream *stream, char *id, ...@@ -179,7 +179,7 @@ static int write_representation(AVFormatContext *s, AVStream *stream, char *id,
AVDictionaryEntry *bandwidth = av_dict_get(stream->metadata, BANDWIDTH, NULL, 0); AVDictionaryEntry *bandwidth = av_dict_get(stream->metadata, BANDWIDTH, NULL, 0);
if ((w->is_live && (!filename)) || if ((w->is_live && (!filename)) ||
(!w->is_live && (!irange || !cues_start || !cues_end || !filename || !bandwidth))) { (!w->is_live && (!irange || !cues_start || !cues_end || !filename || !bandwidth))) {
return -1; return AVERROR_INVALIDDATA;
} }
avio_printf(s->pb, "<Representation id=\"%s\"", id); avio_printf(s->pb, "<Representation id=\"%s\"", id);
// FIXME: For live, This should be obtained from the input file or as an AVOption. // 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) { ...@@ -252,6 +252,16 @@ static int check_matching_sample_rate(AVFormatContext *s, AdaptationSet *as) {
return 1; 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, * Parses a live header filename and computes the representation id,
* initialization pattern and the media pattern. Pass NULL if you don't want to * 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, ...@@ -274,9 +284,9 @@ static int parse_filename(char *filename, char **representation_id,
underscore_pos = temp_pos + 1; underscore_pos = temp_pos + 1;
temp_pos = av_stristr(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, "."); period_pos = av_stristr(underscore_pos, ".");
if (!period_pos) return -1; if (!period_pos) return AVERROR_INVALIDDATA;
*(underscore_pos - 1) = 0; *(underscore_pos - 1) = 0;
if (representation_id) { if (representation_id) {
*representation_id = av_malloc(period_pos - underscore_pos + 1); *representation_id = av_malloc(period_pos - underscore_pos + 1);
...@@ -373,19 +383,22 @@ static int write_adaptation_set(AVFormatContext *s, int as_index) ...@@ -373,19 +383,22 @@ static int write_adaptation_set(AVFormatContext *s, int as_index)
for (i = 0; i < as->nb_streams; i++) { for (i = 0; i < as->nb_streams; i++) {
char *representation_id = NULL; char *representation_id = NULL;
int ret;
if (w->is_live) { if (w->is_live) {
AVDictionaryEntry *filename = AVDictionaryEntry *filename =
av_dict_get(s->streams[as->streams[i]]->metadata, FILENAME, NULL, 0); av_dict_get(s->streams[as->streams[i]]->metadata, FILENAME, NULL, 0);
if (!filename || if (!filename ||
parse_filename(filename->value, &representation_id, NULL, NULL)) { (ret = parse_filename(filename->value, &representation_id, NULL, NULL))) {
return -1; return ret;
} }
} else { } else {
representation_id = av_asprintf("%d", w->representation_id++); 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, ret = write_representation(s, s->streams[as->streams[i]],
!width_in_as, !height_in_as, !sample_rate_in_as); representation_id, !width_in_as,
!height_in_as, !sample_rate_in_as);
if (ret) return ret;
av_free(representation_id); av_free(representation_id);
} }
avio_printf(s->pb, "</AdaptationSet>\n"); avio_printf(s->pb, "</AdaptationSet>\n");
...@@ -416,9 +429,11 @@ static int parse_adaptation_sets(AVFormatContext *s) ...@@ -416,9 +429,11 @@ static int parse_adaptation_sets(AVFormatContext *s)
if (*p == ' ') if (*p == ' ')
continue; continue;
else if (state == new_set && !strncmp(p, "id=", 3)) { else if (state == new_set && !strncmp(p, "id=", 3)) {
w->as = av_realloc(w->as, sizeof(*w->as) * ++w->nb_as); void *mem = av_realloc(w->as, sizeof(*w->as) * (w->nb_as + 1));
if (w->as == NULL) if (mem == NULL)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
w->as = mem;
++w->nb_as;
w->as[w->nb_as - 1].nb_streams = 0; w->as[w->nb_as - 1].nb_streams = 0;
w->as[w->nb_as - 1].streams = NULL; w->as[w->nb_as - 1].streams = NULL;
p += 3; // consume "id=" p += 3; // consume "id="
...@@ -453,8 +468,13 @@ static int webm_dash_manifest_write_header(AVFormatContext *s) ...@@ -453,8 +468,13 @@ static int webm_dash_manifest_write_header(AVFormatContext *s)
{ {
int i; int i;
double start = 0.0; double start = 0.0;
int ret;
WebMDashMuxContext *w = s->priv_data; 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); write_header(s);
avio_printf(s->pb, "<Period id=\"0\""); avio_printf(s->pb, "<Period id=\"0\"");
avio_printf(s->pb, " start=\"PT%gS\"", start); avio_printf(s->pb, " start=\"PT%gS\"", start);
...@@ -464,7 +484,11 @@ static int webm_dash_manifest_write_header(AVFormatContext *s) ...@@ -464,7 +484,11 @@ static int webm_dash_manifest_write_header(AVFormatContext *s)
avio_printf(s->pb, " >\n"); avio_printf(s->pb, " >\n");
for (i = 0; i < w->nb_as; i++) { 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"); avio_printf(s->pb, "</Period>\n");
...@@ -479,12 +503,7 @@ static int webm_dash_manifest_write_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -479,12 +503,7 @@ static int webm_dash_manifest_write_packet(AVFormatContext *s, AVPacket *pkt)
static int webm_dash_manifest_write_trailer(AVFormatContext *s) static int webm_dash_manifest_write_trailer(AVFormatContext *s)
{ {
WebMDashMuxContext *w = s->priv_data; free_adaptation_sets(s);
int i;
for (i = 0; i < w->nb_as; i++) {
av_freep(&w->as[i].streams);
}
av_freep(&w->as);
return 0; return 0;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment