aboutsummaryrefslogtreecommitdiffstats
path: root/libavformat/webmdashenc.c
diff options
context:
space:
mode:
authorVignesh Venkatasubramanian <vigneshv@google.com>2015-04-16 17:32:21 -0700
committerMichael Niedermayer <michaelni@gmx.at>2015-04-17 04:48:29 +0200
commit1c37848f9029985d1271da9a0d161c2ebf0aca81 (patch)
tree06630a5d9b8241da4e85689e558ec9d0a7c73725 /libavformat/webmdashenc.c
parent8254011b217356915fb49d4c78592fd141e1ca46 (diff)
downloadffmpeg-1c37848f9029985d1271da9a0d161c2ebf0aca81.tar.gz
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>
Diffstat (limited to 'libavformat/webmdashenc.c')
-rw-r--r--libavformat/webmdashenc.c55
1 files changed, 37 insertions, 18 deletions
diff --git a/libavformat/webmdashenc.c b/libavformat/webmdashenc.c
index c5d715851f..a8eb8acb52 100644
--- a/libavformat/webmdashenc.c
+++ b/libavformat/webmdashenc.c
@@ -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;
}