summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-09-16 18:11:00 +0200
committerwm4 <wm4@nowhere>2014-09-16 18:11:00 +0200
commitcaaeb15318dbdd38344f15a8919540f188de5c46 (patch)
treee0416e67067fcbb4485d96deaacd7dd55f55a51e
parent26e0cce9699e672b3d56c3b184a662955c4815bc (diff)
downloadmpv-caaeb15318dbdd38344f15a8919540f188de5c46.tar.bz2
mpv-caaeb15318dbdd38344f15a8919540f188de5c46.tar.xz
demux: gracefully handle packet allocation failures
Now the packet allocation functions can fail.
-rw-r--r--demux/demux_lavf.c12
-rw-r--r--demux/demux_mf.c10
-rw-r--r--demux/demux_mkv.c10
-rw-r--r--demux/demux_raw.c5
-rw-r--r--demux/demux_tv.c24
-rw-r--r--demux/packet.c18
-rw-r--r--sub/dec_sub.c6
7 files changed, 58 insertions, 27 deletions
diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c
index ce945a2c4b..750f0f09f3 100644
--- a/demux/demux_lavf.c
+++ b/demux/demux_lavf.c
@@ -479,9 +479,11 @@ static void handle_stream(demuxer_t *demuxer, int i)
if (st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
sh->attached_picture = new_demux_packet_from(st->attached_pic.data,
st->attached_pic.size);
- sh->attached_picture->pts = 0;
- talloc_steal(sh, sh->attached_picture);
- sh->attached_picture->keyframe = true;
+ if (sh->attached_picture) {
+ sh->attached_picture->pts = 0;
+ talloc_steal(sh, sh->attached_picture);
+ sh->attached_picture->keyframe = true;
+ }
}
sh->format = codec->codec_tag;
@@ -820,6 +822,10 @@ static int demux_lavf_fill_buffer(demuxer_t *demux)
}
struct demux_packet *dp = new_demux_packet_from_avpacket(pkt);
+ if (!dp) {
+ av_free_packet(pkt);
+ return 1;
+ }
if (pkt->pts != AV_NOPTS_VALUE)
dp->pts = pkt->pts * av_q2d(st->time_base);
diff --git a/demux/demux_mf.c b/demux/demux_mf.c
index c0e4cd7757..fa42f52782 100644
--- a/demux/demux_mf.c
+++ b/demux/demux_mf.c
@@ -77,10 +77,12 @@ static int demux_mf_fill_buffer(demuxer_t *demuxer)
bstr data = stream_read_complete(stream, NULL, MF_MAX_FILE_SIZE);
if (data.len) {
demux_packet_t *dp = new_demux_packet(data.len);
- memcpy(dp->buffer, data.start, data.len);
- dp->pts = mf->curr_frame / mf->sh->fps;
- dp->keyframe = true;
- demux_add_packet(demuxer->streams[0], dp);
+ if (dp) {
+ memcpy(dp->buffer, data.start, data.len);
+ dp->pts = mf->curr_frame / mf->sh->fps;
+ dp->keyframe = true;
+ demux_add_packet(demuxer->streams[0], dp);
+ }
}
talloc_free(data.start);
}
diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c
index 978e367ec5..c20a1aa999 100644
--- a/demux/demux_mkv.c
+++ b/demux/demux_mkv.c
@@ -1978,6 +1978,8 @@ static void handle_realvideo(demuxer_t *demuxer, mkv_track_t *track,
int64_t timestamp = mkv_d->last_pts * 1000;
dp = new_demux_packet_from(data.start, data.len);
+ if (!dp)
+ return;
if (mkv_d->v_skip_to_keyframe) {
dp->pts = mkv_d->last_pts;
@@ -2096,6 +2098,8 @@ static void handle_realaudio(demuxer_t *demuxer, mkv_track_t *track,
for (int x = 0; x < sph * w / apk_usize; x++) {
dp = new_demux_packet_from(track->audio_buf + x * apk_usize,
apk_usize);
+ if (!dp)
+ goto error;
/* Put timestamp only on packets that correspond to original
* audio packets in file */
dp->pts = (x * apk_usize % w) ? MP_NOPTS_VALUE :
@@ -2107,6 +2111,8 @@ static void handle_realaudio(demuxer_t *demuxer, mkv_track_t *track,
}
} else { // Not a codec that requires reordering
dp = new_demux_packet_from(buffer, size);
+ if (!dp)
+ goto error;
if (track->ra_pts == mkv_d->last_pts && !mkv_d->a_skip_to_keyframe)
dp->pts = MP_NOPTS_VALUE;
else
@@ -2119,7 +2125,7 @@ static void handle_realaudio(demuxer_t *demuxer, mkv_track_t *track,
}
return;
error:
- MP_ERR(demuxer, "RealAudio decrypting error.\n");
+ MP_ERR(demuxer, "RealAudio packet extraction or decryption error.\n");
}
static void mkv_seek_reset(demuxer_t *demuxer)
@@ -2424,6 +2430,8 @@ static int handle_block(demuxer_t *demuxer, struct block_info *block_info)
while (raw.start && mkv_parse_packet(track, &raw, &buffer)) {
demux_packet_t *dp =
new_demux_packet_from(buffer.start, buffer.len);
+ if (!dp)
+ break;
dp->keyframe = keyframe;
/* If default_duration is 0, assume no pts value is known
* for packets after the first one (rather than all pts
diff --git a/demux/demux_raw.c b/demux/demux_raw.c
index 4388900ce6..288a1c931c 100644
--- a/demux/demux_raw.c
+++ b/demux/demux_raw.c
@@ -227,6 +227,11 @@ static int raw_fill_buffer(demuxer_t *demuxer)
return 0;
struct demux_packet *dp = new_demux_packet(p->frame_size * p->read_frames);
+ if (!dp) {
+ MP_ERR(demuxer, "Can't read packet.\n");
+ return 1;
+ }
+
dp->pos = stream_tell(demuxer->stream);
dp->pts = (dp->pos / p->frame_size) / p->frame_rate;
diff --git a/demux/demux_tv.c b/demux/demux_tv.c
index f0ee9793e3..fe7584a387 100644
--- a/demux/demux_tv.c
+++ b/demux/demux_tv.c
@@ -204,26 +204,30 @@ static int demux_tv_fill_buffer(demuxer_t *demux)
if (want_audio && tvh->tv_param->audio &&
tvh->functions->control(tvh->priv,
TVI_CONTROL_IS_AUDIO, 0) == TVI_CONTROL_TRUE)
- {
+ {
len = tvh->functions->get_audio_framesize(tvh->priv);
dp=new_demux_packet(len);
- dp->keyframe = true;
- dp->pts=tvh->functions->grab_audio_frame(tvh->priv, dp->buffer,len);
- demux_add_packet(want_audio, dp);
+ if (dp) {
+ dp->keyframe = true;
+ dp->pts=tvh->functions->grab_audio_frame(tvh->priv, dp->buffer,len);
+ demux_add_packet(want_audio, dp);
}
+ }
/* ================== ADD VIDEO PACKET =================== */
if (want_video && tvh->functions->control(tvh->priv,
TVI_CONTROL_IS_VIDEO, 0) == TVI_CONTROL_TRUE)
- {
- len = tvh->functions->get_video_framesize(tvh->priv);
+ {
+ len = tvh->functions->get_video_framesize(tvh->priv);
dp=new_demux_packet(len);
- dp->keyframe = true;
- dp->pts=tvh->functions->grab_video_frame(tvh->priv, dp->buffer, len);
- demux_add_packet(want_video, dp);
- }
+ if (dp) {
+ dp->keyframe = true;
+ dp->pts=tvh->functions->grab_video_frame(tvh->priv, dp->buffer, len);
+ demux_add_packet(want_video, dp);
+ }
+ }
if (tvh->tv_param->scan) tv_scan(tvh);
return 1;
diff --git a/demux/packet.c b/demux/packet.c
index 2008113600..959c707732 100644
--- a/demux/packet.c
+++ b/demux/packet.c
@@ -37,10 +37,8 @@ static void packet_destroy(void *ptr)
// does not allow it, but we do it to simplify new_demux_packet().
struct demux_packet *new_demux_packet_from_avpacket(struct AVPacket *avpkt)
{
- if (avpkt->size > 1000000000) {
- fprintf(stderr, "Attempt to allocate demux packet over 1 GB!\n");
- abort();
- }
+ if (avpkt->size > 1000000000)
+ return NULL;
struct demux_packet *dp = talloc(NULL, struct demux_packet);
talloc_set_destructor(dp, packet_destroy);
*dp = (struct demux_packet) {
@@ -61,8 +59,9 @@ struct demux_packet *new_demux_packet_from_avpacket(struct AVPacket *avpkt)
r = av_new_packet(dp->avpacket, avpkt->size);
}
if (r < 0) {
- fprintf(stderr, "Out of memory when referencing packet.\n");
- abort();
+ *dp->avpacket = (AVPacket){0};
+ talloc_free(dp);
+ return NULL;
}
dp->buffer = dp->avpacket->data;
dp->len = dp->avpacket->size;
@@ -72,13 +71,16 @@ struct demux_packet *new_demux_packet_from_avpacket(struct AVPacket *avpkt)
// Input data doesn't need to be padded.
struct demux_packet *new_demux_packet_from(void *data, size_t len)
{
+ if (len > INT_MAX)
+ return NULL;
AVPacket pkt = { .data = data, .size = len };
return new_demux_packet_from_avpacket(&pkt);
}
struct demux_packet *new_demux_packet(size_t len)
{
- assert(len <= INT_MAX);
+ if (len > INT_MAX)
+ return NULL;
AVPacket pkt = { .data = NULL, .size = len };
return new_demux_packet_from_avpacket(&pkt);
}
@@ -104,6 +106,8 @@ struct demux_packet *demux_copy_packet(struct demux_packet *dp)
// Some packets might be not created by new_demux_packet*().
new = new_demux_packet_from(dp->buffer, dp->len);
}
+ if (!new)
+ return NULL;
new->pts = dp->pts;
new->dts = dp->dts;
new->duration = dp->duration;
diff --git a/sub/dec_sub.c b/sub/dec_sub.c
index cc608c3ca5..7a0f5eb408 100644
--- a/sub/dec_sub.c
+++ b/sub/dec_sub.c
@@ -400,8 +400,10 @@ static void add_sub_list(struct dec_sub *sub, int at, struct packet_list *subs)
static void add_packet(struct packet_list *subs, struct demux_packet *pkt)
{
pkt = demux_copy_packet(pkt);
- talloc_steal(subs, pkt);
- MP_TARRAY_APPEND(subs, subs->packets, subs->num_packets, pkt);
+ if (pkt) {
+ talloc_steal(subs, pkt);
+ MP_TARRAY_APPEND(subs, subs->packets, subs->num_packets, pkt);
+ }
}
// Read all packets from the demuxer and decode/add them. Returns false if