mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-30 14:28:30 +00:00
segment: Fix the failure paths
A failure in segment_end() or segment_start() would lead to freeing a dangling pointer and in general further calls to seg_write_packet() or to seg_write_trailer() would have the same faulty behaviour. CC: libav-stable@libav.org Reported-By: luodalongde@gmail.com
This commit is contained in:
parent
8a3d9ca603
commit
b3f0465736
@ -184,6 +184,13 @@ static void close_null_ctx(AVIOContext *pb)
|
|||||||
av_free(pb);
|
av_free(pb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void seg_free_context(SegmentContext *seg)
|
||||||
|
{
|
||||||
|
avio_closep(&seg->pb);
|
||||||
|
avformat_free_context(seg->avf);
|
||||||
|
seg->avf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int seg_write_header(AVFormatContext *s)
|
static int seg_write_header(AVFormatContext *s)
|
||||||
{
|
{
|
||||||
SegmentContext *seg = s->priv_data;
|
SegmentContext *seg = s->priv_data;
|
||||||
@ -265,12 +272,9 @@ static int seg_write_header(AVFormatContext *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (ret) {
|
if (ret < 0)
|
||||||
if (seg->list)
|
seg_free_context(seg);
|
||||||
avio_close(seg->pb);
|
|
||||||
if (seg->avf)
|
|
||||||
avformat_free_context(seg->avf);
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,6 +286,9 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
int64_t end_pts = seg->recording_time * seg->number;
|
int64_t end_pts = seg->recording_time * seg->number;
|
||||||
int ret, can_split = 1;
|
int ret, can_split = 1;
|
||||||
|
|
||||||
|
if (!oc)
|
||||||
|
return AVERROR(EINVAL);
|
||||||
|
|
||||||
if (seg->has_video) {
|
if (seg->has_video) {
|
||||||
can_split = st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
|
can_split = st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
|
||||||
pkt->flags & AV_PKT_FLAG_KEY;
|
pkt->flags & AV_PKT_FLAG_KEY;
|
||||||
@ -322,11 +329,8 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
ret = ff_write_chained(oc, pkt->stream_index, pkt, s);
|
ret = ff_write_chained(oc, pkt->stream_index, pkt, s);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
if (seg->list)
|
seg_free_context(seg);
|
||||||
avio_close(seg->pb);
|
|
||||||
avformat_free_context(oc);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -335,7 +339,11 @@ static int seg_write_trailer(struct AVFormatContext *s)
|
|||||||
{
|
{
|
||||||
SegmentContext *seg = s->priv_data;
|
SegmentContext *seg = s->priv_data;
|
||||||
AVFormatContext *oc = seg->avf;
|
AVFormatContext *oc = seg->avf;
|
||||||
int ret;
|
int ret = 0;
|
||||||
|
|
||||||
|
if (!oc)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
if (!seg->write_header_trailer) {
|
if (!seg->write_header_trailer) {
|
||||||
if ((ret = segment_end(oc, 0)) < 0)
|
if ((ret = segment_end(oc, 0)) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
Loading…
Reference in New Issue
Block a user