summaryrefslogtreecommitdiff
path: root/ffmpeg/libavformat/oggdec.c
diff options
context:
space:
mode:
Diffstat (limited to 'ffmpeg/libavformat/oggdec.c')
-rw-r--r--ffmpeg/libavformat/oggdec.c53
1 files changed, 37 insertions, 16 deletions
diff --git a/ffmpeg/libavformat/oggdec.c b/ffmpeg/libavformat/oggdec.c
index fdb5e96..8639eae 100644
--- a/ffmpeg/libavformat/oggdec.c
+++ b/ffmpeg/libavformat/oggdec.c
@@ -30,6 +30,7 @@
#include <stdio.h>
#include "libavutil/avassert.h"
+#include "libavutil/intreadwrite.h"
#include "oggdec.h"
#include "avformat.h"
#include "internal.h"
@@ -88,7 +89,7 @@ static int ogg_restore(AVFormatContext *s, int discard)
struct ogg *ogg = s->priv_data;
AVIOContext *bc = s->pb;
struct ogg_state *ost = ogg->state;
- int i;
+ int i, err;
if (!ost)
return 0;
@@ -96,25 +97,21 @@ static int ogg_restore(AVFormatContext *s, int discard)
ogg->state = ost->next;
if (!discard) {
- struct ogg_stream *old_streams = ogg->streams;
for (i = 0; i < ogg->nstreams; i++)
- av_free(ogg->streams[i].buf);
+ av_freep(&ogg->streams[i].buf);
avio_seek(bc, ost->pos, SEEK_SET);
ogg->page_pos = -1;
ogg->curidx = ost->curidx;
ogg->nstreams = ost->nstreams;
- ogg->streams = av_realloc(ogg->streams,
- ogg->nstreams * sizeof(*ogg->streams));
-
- if (ogg->streams) {
+ if ((err = av_reallocp_array(&ogg->streams, ogg->nstreams,
+ sizeof(*ogg->streams))) < 0) {
+ ogg->nstreams = 0;
+ return err;
+ } else
memcpy(ogg->streams, ost->streams,
ost->nstreams * sizeof(*ogg->streams));
- } else {
- av_free(old_streams);
- ogg->nstreams = 0;
- }
}
av_free(ost);
@@ -145,6 +142,7 @@ static int ogg_reset(AVFormatContext *s)
if (start_pos <= s->data_offset) {
os->lastpts = 0;
}
+ os->end_trimming = 0;
}
ogg->page_pos = -1;
@@ -636,14 +634,14 @@ static int ogg_read_close(AVFormatContext *s)
int i;
for (i = 0; i < ogg->nstreams; i++) {
- av_free(ogg->streams[i].buf);
+ av_freep(&ogg->streams[i].buf);
if (ogg->streams[i].codec &&
ogg->streams[i].codec->cleanup) {
ogg->streams[i].codec->cleanup(s, i);
}
- av_free(ogg->streams[i].private);
+ av_freep(&ogg->streams[i].private);
}
- av_free(ogg->streams);
+ av_freep(&ogg->streams);
return 0;
}
@@ -671,7 +669,12 @@ static int ogg_read_header(AVFormatContext *s)
av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
ogg->streams[i].codec = NULL;
} else if (os->codec && os->nb_header < os->codec->nb_header) {
- av_log(s, AV_LOG_WARNING, "Number of headers (%d) mismatch for stream %d\n", os->nb_header, i);
+ av_log(s, AV_LOG_WARNING,
+ "Headers mismatch for stream %d: "
+ "expected %d received %d.\n",
+ i, os->codec->nb_header, os->nb_header);
+ if (s->error_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
}
if (os->start_granule != OGG_NOGRANULE_VALUE)
os->lastpts = s->streams[i]->start_time =
@@ -735,6 +738,11 @@ static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
int pstart, psize;
int64_t fpos, pts, dts;
+ if (s->io_repositioned) {
+ ogg_reset(s);
+ s->io_repositioned = 0;
+ }
+
//Get an ogg packet
retry:
do {
@@ -767,6 +775,19 @@ retry:
pkt->duration = os->pduration;
pkt->pos = fpos;
+ if (os->end_trimming) {
+ uint8_t *side_data = av_packet_new_side_data(pkt,
+ AV_PKT_DATA_SKIP_SAMPLES,
+ 10);
+ if(side_data == NULL) {
+ av_free_packet(pkt);
+ av_free(pkt);
+ return AVERROR(ENOMEM);
+ }
+ AV_WL32(side_data + 4, os->end_trimming);
+ os->end_trimming = 0;
+ }
+
return psize;
}
@@ -849,5 +870,5 @@ AVInputFormat ff_ogg_demuxer = {
.read_seek = ogg_read_seek,
.read_timestamp = ogg_read_timestamp,
.extensions = "ogg",
- .flags = AVFMT_GENERIC_INDEX | AVFMT_TS_DISCONT,
+ .flags = AVFMT_GENERIC_INDEX | AVFMT_TS_DISCONT | AVFMT_NOBINSEARCH,
};