diff options
Diffstat (limited to 'ffmpeg/libavformat/oggdec.c')
| -rw-r--r-- | ffmpeg/libavformat/oggdec.c | 53 |
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, }; |
