| Index: patches/ugly/11_ogg_seek_first_frame.patch
|
| ===================================================================
|
| --- patches/ugly/11_ogg_seek_first_frame.patch (revision 53990)
|
| +++ patches/ugly/11_ogg_seek_first_frame.patch (working copy)
|
| @@ -1,486 +1,486 @@
|
| -diff -rpu ffmpeg-mt/libavformat/Makefile patched-ffmpeg-mt/libavformat/Makefile
|
| ---- ffmpeg-mt/libavformat/Makefile 2010-04-02 14:43:51 -0700
|
| -+++ patched-ffmpeg-mt/libavformat/Makefile 2010-04-02 14:23:11 -0700
|
| -@@ -148,7 +148,6 @@ OBJS-$(CONFIG_DIRAC_DEMUXER)
|
| - OBJS-$(CONFIG_LIBSPEEX) += oggparsespeex.o
|
| - OBJS-$(CONFIG_OGG_DEMUXER) += oggdec.o \
|
| - oggparseogm.o \
|
| -- oggparseskeleton.o \
|
| - oggparsetheora.o \
|
| - oggparsevorbis.o \
|
| - riff.o \
|
| -diff -rpu ffmpeg-mt/libavformat/oggdec.c patched-ffmpeg-mt/libavformat/oggdec.c
|
| ---- ffmpeg-mt/libavformat/oggdec.c 2010-04-02 14:43:51 -0700
|
| -+++ patched-ffmpeg-mt/libavformat/oggdec.c 2010-04-02 14:16:43 -0700
|
| -@@ -6,7 +6,7 @@
|
| - */
|
| -
|
| - /**
|
| -- Copyright (C) 2005 Michael Ahlberg, Måns Rullgård
|
| -+ Copyright (C) 2005 Michael Ahlberg, Måns Rullgård
|
| -
|
| - Permission is hereby granted, free of charge, to any person
|
| - obtaining a copy of this software and associated documentation
|
| -@@ -33,13 +33,11 @@
|
| - #include <stdio.h>
|
| - #include "oggdec.h"
|
| - #include "avformat.h"
|
| --#include "vorbiscomment.h"
|
| -
|
| - #define MAX_PAGE_SIZE 65307
|
| - #define DECODER_BUFFER_SIZE MAX_PAGE_SIZE
|
| -
|
| - static const struct ogg_codec * const ogg_codecs[] = {
|
| -- &ff_skeleton_codec,
|
| - #if CONFIG_DIRAC_DEMUXER
|
| - &ff_dirac_codec,
|
| - #endif
|
| -@@ -132,8 +130,6 @@ ogg_reset (struct ogg * ogg)
|
| - os->granule = -1;
|
| - os->lastpts = AV_NOPTS_VALUE;
|
| - os->lastdts = AV_NOPTS_VALUE;
|
| -- os->sync_pos = -1;
|
| -- os->page_pos = 0;
|
| - os->nsegs = 0;
|
| - os->segp = 0;
|
| - os->incomplete = 0;
|
| -@@ -158,6 +154,18 @@ ogg_find_codec (uint8_t * buf, int size)
|
| - }
|
| -
|
| - static int
|
| -+ogg_find_stream (struct ogg * ogg, int serial)
|
| -+{
|
| -+ int i;
|
| -+
|
| -+ for (i = 0; i < ogg->nstreams; i++)
|
| -+ if (ogg->streams[i].serial == serial)
|
| -+ return i;
|
| -+
|
| -+ return -1;
|
| -+}
|
| -+
|
| -+static int
|
| - ogg_new_stream (AVFormatContext * s, uint32_t serial)
|
| - {
|
| -
|
| -@@ -202,7 +210,7 @@ ogg_new_buf(struct ogg *ogg, int idx)
|
| - }
|
| -
|
| - static int
|
| --ogg_read_page (AVFormatContext * s, int *str)
|
| -+ogg_read_page (AVFormatContext * s, int *str, int64_t *offset)
|
| - {
|
| - ByteIOContext *bc = s->pb;
|
| - struct ogg *ogg = s->priv_data;
|
| -@@ -216,6 +224,7 @@ ogg_read_page (AVFormatContext * s, int
|
| - int size, idx;
|
| - uint8_t sync[4];
|
| - int sp = 0;
|
| -+ int64_t poffset = url_ftell(bc);
|
| -
|
| - if (get_buffer (bc, sync, 4) < 4)
|
| - return -1;
|
| -@@ -257,7 +266,6 @@ ogg_read_page (AVFormatContext * s, int
|
| - }
|
| -
|
| - os = ogg->streams + idx;
|
| -- os->page_pos = url_ftell(bc) - 27;
|
| -
|
| - if(os->psize > 0)
|
| - ogg_new_buf(ogg, idx);
|
| -@@ -280,11 +288,9 @@ ogg_read_page (AVFormatContext * s, int
|
| - if (seg < 255)
|
| - break;
|
| - }
|
| -- os->sync_pos = os->page_pos;
|
| - }
|
| - }else{
|
| - os->psize = 0;
|
| -- os->sync_pos = os->page_pos;
|
| - }
|
| -
|
| - if (os->bufsize - os->bufpos < size){
|
| -@@ -303,18 +309,22 @@ ogg_read_page (AVFormatContext * s, int
|
| -
|
| - if (str)
|
| - *str = idx;
|
| -+ if (offset)
|
| -+ *offset = poffset;
|
| -
|
| - return 0;
|
| - }
|
| -
|
| - static int
|
| --ogg_packet (AVFormatContext * s, int *str, int *dstart, int *dsize, int64_t *fpos)
|
| -+ogg_packet (AVFormatContext * s, int *str, int *dstart, int *dsize, int64_t* offset)
|
| - {
|
| - struct ogg *ogg = s->priv_data;
|
| - int idx, i;
|
| - struct ogg_stream *os;
|
| - int complete = 0;
|
| - int segp = 0, psize = 0;
|
| -+ int64_t poffset;
|
| -+ int pnum = 0;
|
| -
|
| - #if 0
|
| - av_log (s, AV_LOG_DEBUG, "ogg_packet: curidx=%i\n", ogg->curidx);
|
| -@@ -324,10 +334,13 @@ ogg_packet (AVFormatContext * s, int *st
|
| - idx = ogg->curidx;
|
| -
|
| - while (idx < 0){
|
| -- if (ogg_read_page (s, &idx) < 0)
|
| -+ if (ogg_read_page (s, &idx, &poffset) < 0)
|
| - return -1;
|
| - }
|
| -
|
| -+ if (pnum++ == 0 && offset)
|
| -+ *offset = poffset;
|
| -+
|
| - os = ogg->streams + idx;
|
| -
|
| - #if 0
|
| -@@ -375,19 +388,20 @@ ogg_packet (AVFormatContext * s, int *st
|
| - ogg->curidx = idx;
|
| - os->incomplete = 0;
|
| -
|
| -- if (os->header) {
|
| -- os->header = os->codec->header (s, idx);
|
| -- if (!os->header){
|
| -+ if (!ogg->headers){
|
| -+ int hdr = os->codec->header (s, idx);
|
| -+ os->header = os->seq;
|
| -+ if (!hdr){
|
| - os->segp = segp;
|
| - os->psize = psize;
|
| -- if (!ogg->headers)
|
| -- s->data_offset = os->sync_pos;
|
| - ogg->headers = 1;
|
| - }else{
|
| - os->pstart += os->psize;
|
| - os->psize = 0;
|
| - }
|
| -- } else {
|
| -+ }
|
| -+
|
| -+ if (os->header > -1 && os->seq > os->header){
|
| - os->pflags = 0;
|
| - os->pduration = 0;
|
| - if (os->codec && os->codec->packet)
|
| -@@ -398,11 +412,8 @@ ogg_packet (AVFormatContext * s, int *st
|
| - *dstart = os->pstart;
|
| - if (dsize)
|
| - *dsize = os->psize;
|
| -- if (fpos)
|
| -- *fpos = os->sync_pos;
|
| - os->pstart += os->psize;
|
| - os->psize = 0;
|
| -- os->sync_pos = os->page_pos;
|
| - }
|
| -
|
| - // determine whether there are more complete packets in this page
|
| -@@ -414,6 +425,7 @@ ogg_packet (AVFormatContext * s, int *st
|
| - break;
|
| - }
|
| -
|
| -+ os->seq++;
|
| - if (os->segp == os->nsegs)
|
| - ogg->curidx = -1;
|
| -
|
| -@@ -424,12 +436,15 @@ static int
|
| - ogg_get_headers (AVFormatContext * s)
|
| - {
|
| - struct ogg *ogg = s->priv_data;
|
| -+ int64_t pos = 0;
|
| -
|
| - do{
|
| -- if (ogg_packet (s, NULL, NULL, NULL, NULL) < 0)
|
| -+ if (ogg_packet (s, NULL, NULL, NULL, &pos) < 0)
|
| - return -1;
|
| - }while (!ogg->headers);
|
| -
|
| -+ s->data_offset = pos;
|
| -+
|
| - #if 0
|
| - av_log (s, AV_LOG_DEBUG, "found headers\n");
|
| - #endif
|
| -@@ -437,6 +452,25 @@ ogg_get_headers (AVFormatContext * s)
|
| - return 0;
|
| - }
|
| -
|
| -+static uint64_t
|
| -+ogg_gptopts (AVFormatContext * s, int i, uint64_t gp, int64_t *dts)
|
| -+{
|
| -+ struct ogg *ogg = s->priv_data;
|
| -+ struct ogg_stream *os = ogg->streams + i;
|
| -+ uint64_t pts = AV_NOPTS_VALUE;
|
| -+
|
| -+ if(os->codec->gptopts){
|
| -+ pts = os->codec->gptopts(s, i, gp, dts);
|
| -+ } else {
|
| -+ pts = gp;
|
| -+ if (dts)
|
| -+ *dts = pts;
|
| -+ }
|
| -+
|
| -+ return pts;
|
| -+}
|
| -+
|
| -+
|
| - static int
|
| - ogg_get_length (AVFormatContext * s)
|
| - {
|
| -@@ -459,7 +493,7 @@ ogg_get_length (AVFormatContext * s)
|
| - ogg_save (s);
|
| - url_fseek (s->pb, end, SEEK_SET);
|
| -
|
| -- while (!ogg_read_page (s, &i)){
|
| -+ while (!ogg_read_page (s, &i, NULL)){
|
| - if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
|
| - ogg->streams[i].codec)
|
| - idx = i;
|
| -@@ -468,8 +502,6 @@ ogg_get_length (AVFormatContext * s)
|
| - if (idx != -1){
|
| - s->streams[idx]->duration =
|
| - ogg_gptopts (s, idx, ogg->streams[idx].granule, NULL);
|
| -- if (s->streams[idx]->start_time != AV_NOPTS_VALUE)
|
| -- s->streams[idx]->duration -= s->streams[idx]->start_time;
|
| - }
|
| -
|
| - ogg->size = size;
|
| -@@ -501,36 +533,6 @@ ogg_read_header (AVFormatContext * s, AV
|
| - return 0;
|
| - }
|
| -
|
| --static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
|
| --{
|
| -- struct ogg *ogg = s->priv_data;
|
| -- struct ogg_stream *os = ogg->streams + idx;
|
| -- int64_t pts = AV_NOPTS_VALUE;
|
| --
|
| -- if (dts)
|
| -- *dts = AV_NOPTS_VALUE;
|
| --
|
| -- if (os->lastpts != AV_NOPTS_VALUE) {
|
| -- pts = os->lastpts;
|
| -- os->lastpts = AV_NOPTS_VALUE;
|
| -- }
|
| -- if (os->lastdts != AV_NOPTS_VALUE) {
|
| -- if (dts)
|
| -- *dts = os->lastdts;
|
| -- os->lastdts = AV_NOPTS_VALUE;
|
| -- }
|
| -- if (os->page_end) {
|
| -- if (os->granule != -1LL) {
|
| -- if (os->codec && os->codec->granule_is_start)
|
| -- pts = ogg_gptopts(s, idx, os->granule, dts);
|
| -- else
|
| -- os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
|
| -- os->granule = -1LL;
|
| -- } else
|
| -- av_log(s, AV_LOG_WARNING, "Packet is missing granule\n");
|
| -- }
|
| -- return pts;
|
| --}
|
| -
|
| - static int
|
| - ogg_read_packet (AVFormatContext * s, AVPacket * pkt)
|
| -@@ -539,36 +541,43 @@ ogg_read_packet (AVFormatContext * s, AV
|
| - struct ogg_stream *os;
|
| - int idx = -1;
|
| - int pstart, psize;
|
| -- int64_t fpos, pts, dts;
|
| -
|
| - //Get an ogg packet
|
| --retry:
|
| - do{
|
| -- if (ogg_packet (s, &idx, &pstart, &psize, &fpos) < 0)
|
| -+ if (ogg_packet (s, &idx, &pstart, &psize, NULL) < 0)
|
| - return AVERROR(EIO);
|
| - }while (idx < 0 || !s->streams[idx]);
|
| -
|
| - ogg = s->priv_data;
|
| - os = ogg->streams + idx;
|
| -
|
| -- // pflags might not be set until after this
|
| -- pts = ogg_calc_pts(s, idx, &dts);
|
| --
|
| -- if (os->keyframe_seek && !(os->pflags & PKT_FLAG_KEY))
|
| -- goto retry;
|
| -- os->keyframe_seek = 0;
|
| --
|
| - //Alloc a pkt
|
| - if (av_new_packet (pkt, psize) < 0)
|
| - return AVERROR(EIO);
|
| - pkt->stream_index = idx;
|
| - memcpy (pkt->data, os->buf + pstart, psize);
|
| -
|
| -- pkt->pts = pts;
|
| -- pkt->dts = dts;
|
| -+ if (os->lastpts != AV_NOPTS_VALUE) {
|
| -+ pkt->pts = os->lastpts;
|
| -+ os->lastpts = AV_NOPTS_VALUE;
|
| -+ }
|
| -+ if (os->lastdts != AV_NOPTS_VALUE) {
|
| -+ pkt->dts = os->lastdts;
|
| -+ os->lastdts = AV_NOPTS_VALUE;
|
| -+ }
|
| -+ if (os->page_end) {
|
| -+ if (os->granule != -1LL) {
|
| -+ if (os->codec && os->codec->granule_is_start)
|
| -+ pkt->pts = ogg_gptopts(s, idx, os->granule, &pkt->dts);
|
| -+ else
|
| -+ os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
|
| -+ os->granule = -1LL;
|
| -+ } else
|
| -+ av_log(s, AV_LOG_WARNING, "Packet is missing granule\n");
|
| -+ }
|
| -+
|
| - pkt->flags = os->pflags;
|
| - pkt->duration = os->pduration;
|
| -- pkt->pos = fpos;
|
| -
|
| - return psize;
|
| - }
|
| -@@ -594,44 +603,27 @@ ogg_read_timestamp (AVFormatContext * s,
|
| - int64_t pos_limit)
|
| - {
|
| - struct ogg *ogg = s->priv_data;
|
| -- struct ogg_stream *os = ogg->streams + stream_index;
|
| - ByteIOContext *bc = s->pb;
|
| - int64_t pts = AV_NOPTS_VALUE;
|
| - int i;
|
| -+ int64_t fpoffset = AV_NOPTS_VALUE;
|
| -+ int64_t poffset;
|
| - url_fseek(bc, *pos_arg, SEEK_SET);
|
| -- ogg_reset(ogg);
|
| --
|
| -- while (url_ftell(bc) < pos_limit && !ogg_packet(s, &i, NULL, NULL, pos_arg)) {
|
| -- if (i == stream_index) {
|
| -- pts = ogg_calc_pts(s, i, NULL);
|
| -- if (os->keyframe_seek && !(os->pflags & PKT_FLAG_KEY))
|
| -- pts = AV_NOPTS_VALUE;
|
| -- }
|
| -- if (pts != AV_NOPTS_VALUE)
|
| -+ while (url_ftell(bc) < pos_limit && !ogg_read_page (s, &i, &poffset)) {
|
| -+ if (fpoffset == AV_NOPTS_VALUE && i == stream_index)
|
| -+ fpoffset = poffset;
|
| -+ if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
|
| -+ ogg->streams[i].codec && i == stream_index) {
|
| -+ pts = ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
|
| -+ *pos_arg = fpoffset;
|
| -+ url_fseek(bc, fpoffset, SEEK_SET);
|
| - break;
|
| -+ }
|
| - }
|
| - ogg_reset(ogg);
|
| - return pts;
|
| - }
|
| -
|
| --static int ogg_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
|
| --{
|
| -- struct ogg *ogg = s->priv_data;
|
| -- struct ogg_stream *os = ogg->streams + stream_index;
|
| -- int ret;
|
| --
|
| -- // Try seeking to a keyframe first. If this fails (very possible),
|
| -- // av_seek_frame will fall back to ignoring keyframes
|
| -- if (s->streams[stream_index]->codec->codec_type == CODEC_TYPE_VIDEO
|
| -- && !(flags & AVSEEK_FLAG_ANY))
|
| -- os->keyframe_seek = 1;
|
| --
|
| -- ret = av_seek_frame_binary(s, stream_index, timestamp, flags);
|
| -- if (ret < 0)
|
| -- os->keyframe_seek = 0;
|
| -- return ret;
|
| --}
|
| --
|
| - static int ogg_probe(AVProbeData *p)
|
| - {
|
| - if (p->buf[0] == 'O' && p->buf[1] == 'g' &&
|
| -@@ -650,8 +642,9 @@ AVInputFormat ogg_demuxer = {
|
| - ogg_read_header,
|
| - ogg_read_packet,
|
| - ogg_read_close,
|
| -- ogg_read_seek,
|
| -+ NULL,
|
| - ogg_read_timestamp,
|
| - .extensions = "ogg",
|
| - .metadata_conv = ff_vorbiscomment_metadata_conv,
|
| - };
|
| -+
|
| -diff -rpu ffmpeg-mt/libavformat/oggdec.h patched-ffmpeg-mt/libavformat/oggdec.h
|
| ---- ffmpeg-mt/libavformat/oggdec.h 2010-03-31 19:59:57 -0700
|
| -+++ patched-ffmpeg-mt/libavformat/oggdec.h 2010-04-02 14:21:41 -0700
|
| -@@ -1,5 +1,5 @@
|
| - /**
|
| -- Copyright (C) 2005 Michael Ahlberg, Måns Rullgård
|
| -+ Copyright (C) 2005 Michael Ahlberg, Måns Rullgård
|
| -
|
| - Permission is hereby granted, free of charge, to any person
|
| - obtaining a copy of this software and associated documentation
|
| -@@ -62,11 +62,10 @@ struct ogg_stream {
|
| - unsigned int pflags;
|
| - unsigned int pduration;
|
| - uint32_t serial;
|
| -+ uint32_t seq;
|
| - uint64_t granule;
|
| - int64_t lastpts;
|
| - int64_t lastdts;
|
| -- int64_t sync_pos; ///< file offset of the first page needed to reconstruct the current packet
|
| -- int64_t page_pos; ///< file offset of the current page
|
| - int flags;
|
| - const struct ogg_codec *codec;
|
| - int header;
|
| -@@ -74,7 +73,6 @@ struct ogg_stream {
|
| - uint8_t segments[255];
|
| - int incomplete; ///< whether we're expecting a continuation in the next page
|
| - int page_end; ///< current packet is the last one completed in the page
|
| -- int keyframe_seek;
|
| - void *private;
|
| - };
|
| -
|
| -@@ -107,41 +105,12 @@ extern const struct ogg_codec ff_ogm_tex
|
| - extern const struct ogg_codec ff_ogm_video_codec;
|
| - extern const struct ogg_codec ff_old_dirac_codec;
|
| - extern const struct ogg_codec ff_old_flac_codec;
|
| --extern const struct ogg_codec ff_skeleton_codec;
|
| - extern const struct ogg_codec ff_speex_codec;
|
| - extern const struct ogg_codec ff_theora_codec;
|
| - extern const struct ogg_codec ff_vorbis_codec;
|
| -
|
| --int ff_vorbis_comment(AVFormatContext *ms, AVMetadata **m, const uint8_t *buf, int size);
|
| -+extern const AVMetadataConv ff_vorbiscomment_metadata_conv[];
|
| -
|
| --static inline int
|
| --ogg_find_stream (struct ogg * ogg, int serial)
|
| --{
|
| -- int i;
|
| --
|
| -- for (i = 0; i < ogg->nstreams; i++)
|
| -- if (ogg->streams[i].serial == serial)
|
| -- return i;
|
| --
|
| -- return -1;
|
| --}
|
| --
|
| --static inline uint64_t
|
| --ogg_gptopts (AVFormatContext * s, int i, uint64_t gp, int64_t *dts)
|
| --{
|
| -- struct ogg *ogg = s->priv_data;
|
| -- struct ogg_stream *os = ogg->streams + i;
|
| -- uint64_t pts = AV_NOPTS_VALUE;
|
| --
|
| -- if(os->codec && os->codec->gptopts){
|
| -- pts = os->codec->gptopts(s, i, gp, dts);
|
| -- } else {
|
| -- pts = gp;
|
| -- if (dts)
|
| -- *dts = pts;
|
| -- }
|
| --
|
| -- return pts;
|
| --}
|
| -+int vorbis_comment(AVFormatContext *ms, uint8_t *buf, int size);
|
| -
|
| - #endif /* AVFORMAT_OGGDEC_H */
|
| -
|
| +diff -rpu ffmpeg-mt/libavformat/Makefile patched-ffmpeg-mt/libavformat/Makefile
|
| +--- ffmpeg-mt/libavformat/Makefile 2010-04-02 14:43:51 -0700
|
| ++++ patched-ffmpeg-mt/libavformat/Makefile 2010-04-02 14:23:11 -0700
|
| +@@ -148,7 +148,6 @@ OBJS-$(CONFIG_DIRAC_DEMUXER)
|
| + OBJS-$(CONFIG_LIBSPEEX) += oggparsespeex.o
|
| + OBJS-$(CONFIG_OGG_DEMUXER) += oggdec.o \
|
| + oggparseogm.o \
|
| +- oggparseskeleton.o \
|
| + oggparsetheora.o \
|
| + oggparsevorbis.o \
|
| + riff.o \
|
| +diff -rpu ffmpeg-mt/libavformat/oggdec.c patched-ffmpeg-mt/libavformat/oggdec.c
|
| +--- ffmpeg-mt/libavformat/oggdec.c 2010-04-02 14:43:51 -0700
|
| ++++ patched-ffmpeg-mt/libavformat/oggdec.c 2010-04-02 14:16:43 -0700
|
| +@@ -6,7 +6,7 @@
|
| + */
|
| +
|
| + /**
|
| +- Copyright (C) 2005 Michael Ahlberg, Måns Rullgård
|
| ++ Copyright (C) 2005 Michael Ahlberg, Måns Rullgård
|
| +
|
| + Permission is hereby granted, free of charge, to any person
|
| + obtaining a copy of this software and associated documentation
|
| +@@ -33,13 +33,11 @@
|
| + #include <stdio.h>
|
| + #include "oggdec.h"
|
| + #include "avformat.h"
|
| +-#include "vorbiscomment.h"
|
| +
|
| + #define MAX_PAGE_SIZE 65307
|
| + #define DECODER_BUFFER_SIZE MAX_PAGE_SIZE
|
| +
|
| + static const struct ogg_codec * const ogg_codecs[] = {
|
| +- &ff_skeleton_codec,
|
| + #if CONFIG_DIRAC_DEMUXER
|
| + &ff_dirac_codec,
|
| + #endif
|
| +@@ -132,8 +130,6 @@ ogg_reset (struct ogg * ogg)
|
| + os->granule = -1;
|
| + os->lastpts = AV_NOPTS_VALUE;
|
| + os->lastdts = AV_NOPTS_VALUE;
|
| +- os->sync_pos = -1;
|
| +- os->page_pos = 0;
|
| + os->nsegs = 0;
|
| + os->segp = 0;
|
| + os->incomplete = 0;
|
| +@@ -158,6 +154,18 @@ ogg_find_codec (uint8_t * buf, int size)
|
| + }
|
| +
|
| + static int
|
| ++ogg_find_stream (struct ogg * ogg, int serial)
|
| ++{
|
| ++ int i;
|
| ++
|
| ++ for (i = 0; i < ogg->nstreams; i++)
|
| ++ if (ogg->streams[i].serial == serial)
|
| ++ return i;
|
| ++
|
| ++ return -1;
|
| ++}
|
| ++
|
| ++static int
|
| + ogg_new_stream (AVFormatContext * s, uint32_t serial)
|
| + {
|
| +
|
| +@@ -202,7 +210,7 @@ ogg_new_buf(struct ogg *ogg, int idx)
|
| + }
|
| +
|
| + static int
|
| +-ogg_read_page (AVFormatContext * s, int *str)
|
| ++ogg_read_page (AVFormatContext * s, int *str, int64_t *offset)
|
| + {
|
| + ByteIOContext *bc = s->pb;
|
| + struct ogg *ogg = s->priv_data;
|
| +@@ -216,6 +224,7 @@ ogg_read_page (AVFormatContext * s, int
|
| + int size, idx;
|
| + uint8_t sync[4];
|
| + int sp = 0;
|
| ++ int64_t poffset = url_ftell(bc);
|
| +
|
| + if (get_buffer (bc, sync, 4) < 4)
|
| + return -1;
|
| +@@ -257,7 +266,6 @@ ogg_read_page (AVFormatContext * s, int
|
| + }
|
| +
|
| + os = ogg->streams + idx;
|
| +- os->page_pos = url_ftell(bc) - 27;
|
| +
|
| + if(os->psize > 0)
|
| + ogg_new_buf(ogg, idx);
|
| +@@ -280,11 +288,9 @@ ogg_read_page (AVFormatContext * s, int
|
| + if (seg < 255)
|
| + break;
|
| + }
|
| +- os->sync_pos = os->page_pos;
|
| + }
|
| + }else{
|
| + os->psize = 0;
|
| +- os->sync_pos = os->page_pos;
|
| + }
|
| +
|
| + if (os->bufsize - os->bufpos < size){
|
| +@@ -303,18 +309,22 @@ ogg_read_page (AVFormatContext * s, int
|
| +
|
| + if (str)
|
| + *str = idx;
|
| ++ if (offset)
|
| ++ *offset = poffset;
|
| +
|
| + return 0;
|
| + }
|
| +
|
| + static int
|
| +-ogg_packet (AVFormatContext * s, int *str, int *dstart, int *dsize, int64_t *fpos)
|
| ++ogg_packet (AVFormatContext * s, int *str, int *dstart, int *dsize, int64_t* offset)
|
| + {
|
| + struct ogg *ogg = s->priv_data;
|
| + int idx, i;
|
| + struct ogg_stream *os;
|
| + int complete = 0;
|
| + int segp = 0, psize = 0;
|
| ++ int64_t poffset;
|
| ++ int pnum = 0;
|
| +
|
| + #if 0
|
| + av_log (s, AV_LOG_DEBUG, "ogg_packet: curidx=%i\n", ogg->curidx);
|
| +@@ -324,10 +334,13 @@ ogg_packet (AVFormatContext * s, int *st
|
| + idx = ogg->curidx;
|
| +
|
| + while (idx < 0){
|
| +- if (ogg_read_page (s, &idx) < 0)
|
| ++ if (ogg_read_page (s, &idx, &poffset) < 0)
|
| + return -1;
|
| + }
|
| +
|
| ++ if (pnum++ == 0 && offset)
|
| ++ *offset = poffset;
|
| ++
|
| + os = ogg->streams + idx;
|
| +
|
| + #if 0
|
| +@@ -375,19 +388,20 @@ ogg_packet (AVFormatContext * s, int *st
|
| + ogg->curidx = idx;
|
| + os->incomplete = 0;
|
| +
|
| +- if (os->header) {
|
| +- os->header = os->codec->header (s, idx);
|
| +- if (!os->header){
|
| ++ if (!ogg->headers){
|
| ++ int hdr = os->codec->header (s, idx);
|
| ++ os->header = os->seq;
|
| ++ if (!hdr){
|
| + os->segp = segp;
|
| + os->psize = psize;
|
| +- if (!ogg->headers)
|
| +- s->data_offset = os->sync_pos;
|
| + ogg->headers = 1;
|
| + }else{
|
| + os->pstart += os->psize;
|
| + os->psize = 0;
|
| + }
|
| +- } else {
|
| ++ }
|
| ++
|
| ++ if (os->header > -1 && os->seq > os->header){
|
| + os->pflags = 0;
|
| + os->pduration = 0;
|
| + if (os->codec && os->codec->packet)
|
| +@@ -398,11 +412,8 @@ ogg_packet (AVFormatContext * s, int *st
|
| + *dstart = os->pstart;
|
| + if (dsize)
|
| + *dsize = os->psize;
|
| +- if (fpos)
|
| +- *fpos = os->sync_pos;
|
| + os->pstart += os->psize;
|
| + os->psize = 0;
|
| +- os->sync_pos = os->page_pos;
|
| + }
|
| +
|
| + // determine whether there are more complete packets in this page
|
| +@@ -414,6 +425,7 @@ ogg_packet (AVFormatContext * s, int *st
|
| + break;
|
| + }
|
| +
|
| ++ os->seq++;
|
| + if (os->segp == os->nsegs)
|
| + ogg->curidx = -1;
|
| +
|
| +@@ -424,12 +436,15 @@ static int
|
| + ogg_get_headers (AVFormatContext * s)
|
| + {
|
| + struct ogg *ogg = s->priv_data;
|
| ++ int64_t pos = 0;
|
| +
|
| + do{
|
| +- if (ogg_packet (s, NULL, NULL, NULL, NULL) < 0)
|
| ++ if (ogg_packet (s, NULL, NULL, NULL, &pos) < 0)
|
| + return -1;
|
| + }while (!ogg->headers);
|
| +
|
| ++ s->data_offset = pos;
|
| ++
|
| + #if 0
|
| + av_log (s, AV_LOG_DEBUG, "found headers\n");
|
| + #endif
|
| +@@ -437,6 +452,25 @@ ogg_get_headers (AVFormatContext * s)
|
| + return 0;
|
| + }
|
| +
|
| ++static uint64_t
|
| ++ogg_gptopts (AVFormatContext * s, int i, uint64_t gp, int64_t *dts)
|
| ++{
|
| ++ struct ogg *ogg = s->priv_data;
|
| ++ struct ogg_stream *os = ogg->streams + i;
|
| ++ uint64_t pts = AV_NOPTS_VALUE;
|
| ++
|
| ++ if(os->codec->gptopts){
|
| ++ pts = os->codec->gptopts(s, i, gp, dts);
|
| ++ } else {
|
| ++ pts = gp;
|
| ++ if (dts)
|
| ++ *dts = pts;
|
| ++ }
|
| ++
|
| ++ return pts;
|
| ++}
|
| ++
|
| ++
|
| + static int
|
| + ogg_get_length (AVFormatContext * s)
|
| + {
|
| +@@ -459,7 +493,7 @@ ogg_get_length (AVFormatContext * s)
|
| + ogg_save (s);
|
| + url_fseek (s->pb, end, SEEK_SET);
|
| +
|
| +- while (!ogg_read_page (s, &i)){
|
| ++ while (!ogg_read_page (s, &i, NULL)){
|
| + if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
|
| + ogg->streams[i].codec)
|
| + idx = i;
|
| +@@ -468,8 +502,6 @@ ogg_get_length (AVFormatContext * s)
|
| + if (idx != -1){
|
| + s->streams[idx]->duration =
|
| + ogg_gptopts (s, idx, ogg->streams[idx].granule, NULL);
|
| +- if (s->streams[idx]->start_time != AV_NOPTS_VALUE)
|
| +- s->streams[idx]->duration -= s->streams[idx]->start_time;
|
| + }
|
| +
|
| + ogg->size = size;
|
| +@@ -501,36 +533,6 @@ ogg_read_header (AVFormatContext * s, AV
|
| + return 0;
|
| + }
|
| +
|
| +-static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
|
| +-{
|
| +- struct ogg *ogg = s->priv_data;
|
| +- struct ogg_stream *os = ogg->streams + idx;
|
| +- int64_t pts = AV_NOPTS_VALUE;
|
| +-
|
| +- if (dts)
|
| +- *dts = AV_NOPTS_VALUE;
|
| +-
|
| +- if (os->lastpts != AV_NOPTS_VALUE) {
|
| +- pts = os->lastpts;
|
| +- os->lastpts = AV_NOPTS_VALUE;
|
| +- }
|
| +- if (os->lastdts != AV_NOPTS_VALUE) {
|
| +- if (dts)
|
| +- *dts = os->lastdts;
|
| +- os->lastdts = AV_NOPTS_VALUE;
|
| +- }
|
| +- if (os->page_end) {
|
| +- if (os->granule != -1LL) {
|
| +- if (os->codec && os->codec->granule_is_start)
|
| +- pts = ogg_gptopts(s, idx, os->granule, dts);
|
| +- else
|
| +- os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
|
| +- os->granule = -1LL;
|
| +- } else
|
| +- av_log(s, AV_LOG_WARNING, "Packet is missing granule\n");
|
| +- }
|
| +- return pts;
|
| +-}
|
| +
|
| + static int
|
| + ogg_read_packet (AVFormatContext * s, AVPacket * pkt)
|
| +@@ -539,36 +541,43 @@ ogg_read_packet (AVFormatContext * s, AV
|
| + struct ogg_stream *os;
|
| + int idx = -1;
|
| + int pstart, psize;
|
| +- int64_t fpos, pts, dts;
|
| +
|
| + //Get an ogg packet
|
| +-retry:
|
| + do{
|
| +- if (ogg_packet (s, &idx, &pstart, &psize, &fpos) < 0)
|
| ++ if (ogg_packet (s, &idx, &pstart, &psize, NULL) < 0)
|
| + return AVERROR(EIO);
|
| + }while (idx < 0 || !s->streams[idx]);
|
| +
|
| + ogg = s->priv_data;
|
| + os = ogg->streams + idx;
|
| +
|
| +- // pflags might not be set until after this
|
| +- pts = ogg_calc_pts(s, idx, &dts);
|
| +-
|
| +- if (os->keyframe_seek && !(os->pflags & PKT_FLAG_KEY))
|
| +- goto retry;
|
| +- os->keyframe_seek = 0;
|
| +-
|
| + //Alloc a pkt
|
| + if (av_new_packet (pkt, psize) < 0)
|
| + return AVERROR(EIO);
|
| + pkt->stream_index = idx;
|
| + memcpy (pkt->data, os->buf + pstart, psize);
|
| +
|
| +- pkt->pts = pts;
|
| +- pkt->dts = dts;
|
| ++ if (os->lastpts != AV_NOPTS_VALUE) {
|
| ++ pkt->pts = os->lastpts;
|
| ++ os->lastpts = AV_NOPTS_VALUE;
|
| ++ }
|
| ++ if (os->lastdts != AV_NOPTS_VALUE) {
|
| ++ pkt->dts = os->lastdts;
|
| ++ os->lastdts = AV_NOPTS_VALUE;
|
| ++ }
|
| ++ if (os->page_end) {
|
| ++ if (os->granule != -1LL) {
|
| ++ if (os->codec && os->codec->granule_is_start)
|
| ++ pkt->pts = ogg_gptopts(s, idx, os->granule, &pkt->dts);
|
| ++ else
|
| ++ os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
|
| ++ os->granule = -1LL;
|
| ++ } else
|
| ++ av_log(s, AV_LOG_WARNING, "Packet is missing granule\n");
|
| ++ }
|
| ++
|
| + pkt->flags = os->pflags;
|
| + pkt->duration = os->pduration;
|
| +- pkt->pos = fpos;
|
| +
|
| + return psize;
|
| + }
|
| +@@ -594,44 +603,27 @@ ogg_read_timestamp (AVFormatContext * s,
|
| + int64_t pos_limit)
|
| + {
|
| + struct ogg *ogg = s->priv_data;
|
| +- struct ogg_stream *os = ogg->streams + stream_index;
|
| + ByteIOContext *bc = s->pb;
|
| + int64_t pts = AV_NOPTS_VALUE;
|
| + int i;
|
| ++ int64_t fpoffset = AV_NOPTS_VALUE;
|
| ++ int64_t poffset;
|
| + url_fseek(bc, *pos_arg, SEEK_SET);
|
| +- ogg_reset(ogg);
|
| +-
|
| +- while (url_ftell(bc) < pos_limit && !ogg_packet(s, &i, NULL, NULL, pos_arg)) {
|
| +- if (i == stream_index) {
|
| +- pts = ogg_calc_pts(s, i, NULL);
|
| +- if (os->keyframe_seek && !(os->pflags & PKT_FLAG_KEY))
|
| +- pts = AV_NOPTS_VALUE;
|
| +- }
|
| +- if (pts != AV_NOPTS_VALUE)
|
| ++ while (url_ftell(bc) < pos_limit && !ogg_read_page (s, &i, &poffset)) {
|
| ++ if (fpoffset == AV_NOPTS_VALUE && i == stream_index)
|
| ++ fpoffset = poffset;
|
| ++ if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
|
| ++ ogg->streams[i].codec && i == stream_index) {
|
| ++ pts = ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
|
| ++ *pos_arg = fpoffset;
|
| ++ url_fseek(bc, fpoffset, SEEK_SET);
|
| + break;
|
| ++ }
|
| + }
|
| + ogg_reset(ogg);
|
| + return pts;
|
| + }
|
| +
|
| +-static int ogg_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
|
| +-{
|
| +- struct ogg *ogg = s->priv_data;
|
| +- struct ogg_stream *os = ogg->streams + stream_index;
|
| +- int ret;
|
| +-
|
| +- // Try seeking to a keyframe first. If this fails (very possible),
|
| +- // av_seek_frame will fall back to ignoring keyframes
|
| +- if (s->streams[stream_index]->codec->codec_type == CODEC_TYPE_VIDEO
|
| +- && !(flags & AVSEEK_FLAG_ANY))
|
| +- os->keyframe_seek = 1;
|
| +-
|
| +- ret = av_seek_frame_binary(s, stream_index, timestamp, flags);
|
| +- if (ret < 0)
|
| +- os->keyframe_seek = 0;
|
| +- return ret;
|
| +-}
|
| +-
|
| + static int ogg_probe(AVProbeData *p)
|
| + {
|
| + if (p->buf[0] == 'O' && p->buf[1] == 'g' &&
|
| +@@ -650,8 +642,9 @@ AVInputFormat ogg_demuxer = {
|
| + ogg_read_header,
|
| + ogg_read_packet,
|
| + ogg_read_close,
|
| +- ogg_read_seek,
|
| ++ NULL,
|
| + ogg_read_timestamp,
|
| + .extensions = "ogg",
|
| + .metadata_conv = ff_vorbiscomment_metadata_conv,
|
| + };
|
| ++
|
| +diff -rpu ffmpeg-mt/libavformat/oggdec.h patched-ffmpeg-mt/libavformat/oggdec.h
|
| +--- ffmpeg-mt/libavformat/oggdec.h 2010-03-31 19:59:57 -0700
|
| ++++ patched-ffmpeg-mt/libavformat/oggdec.h 2010-04-02 14:21:41 -0700
|
| +@@ -1,5 +1,5 @@
|
| + /**
|
| +- Copyright (C) 2005 Michael Ahlberg, Måns Rullgård
|
| ++ Copyright (C) 2005 Michael Ahlberg, Måns Rullgård
|
| +
|
| + Permission is hereby granted, free of charge, to any person
|
| + obtaining a copy of this software and associated documentation
|
| +@@ -62,11 +62,10 @@ struct ogg_stream {
|
| + unsigned int pflags;
|
| + unsigned int pduration;
|
| + uint32_t serial;
|
| ++ uint32_t seq;
|
| + uint64_t granule;
|
| + int64_t lastpts;
|
| + int64_t lastdts;
|
| +- int64_t sync_pos; ///< file offset of the first page needed to reconstruct the current packet
|
| +- int64_t page_pos; ///< file offset of the current page
|
| + int flags;
|
| + const struct ogg_codec *codec;
|
| + int header;
|
| +@@ -74,7 +73,6 @@ struct ogg_stream {
|
| + uint8_t segments[255];
|
| + int incomplete; ///< whether we're expecting a continuation in the next page
|
| + int page_end; ///< current packet is the last one completed in the page
|
| +- int keyframe_seek;
|
| + void *private;
|
| + };
|
| +
|
| +@@ -107,41 +105,12 @@ extern const struct ogg_codec ff_ogm_tex
|
| + extern const struct ogg_codec ff_ogm_video_codec;
|
| + extern const struct ogg_codec ff_old_dirac_codec;
|
| + extern const struct ogg_codec ff_old_flac_codec;
|
| +-extern const struct ogg_codec ff_skeleton_codec;
|
| + extern const struct ogg_codec ff_speex_codec;
|
| + extern const struct ogg_codec ff_theora_codec;
|
| + extern const struct ogg_codec ff_vorbis_codec;
|
| +
|
| +-int ff_vorbis_comment(AVFormatContext *ms, AVMetadata **m, const uint8_t *buf, int size);
|
| ++extern const AVMetadataConv ff_vorbiscomment_metadata_conv[];
|
| +
|
| +-static inline int
|
| +-ogg_find_stream (struct ogg * ogg, int serial)
|
| +-{
|
| +- int i;
|
| +-
|
| +- for (i = 0; i < ogg->nstreams; i++)
|
| +- if (ogg->streams[i].serial == serial)
|
| +- return i;
|
| +-
|
| +- return -1;
|
| +-}
|
| +-
|
| +-static inline uint64_t
|
| +-ogg_gptopts (AVFormatContext * s, int i, uint64_t gp, int64_t *dts)
|
| +-{
|
| +- struct ogg *ogg = s->priv_data;
|
| +- struct ogg_stream *os = ogg->streams + i;
|
| +- uint64_t pts = AV_NOPTS_VALUE;
|
| +-
|
| +- if(os->codec && os->codec->gptopts){
|
| +- pts = os->codec->gptopts(s, i, gp, dts);
|
| +- } else {
|
| +- pts = gp;
|
| +- if (dts)
|
| +- *dts = pts;
|
| +- }
|
| +-
|
| +- return pts;
|
| +-}
|
| ++int vorbis_comment(AVFormatContext *ms, uint8_t *buf, int size);
|
| +
|
| + #endif /* AVFORMAT_OGGDEC_H */
|
| +
|
|
|
| Property changes on: patches\ugly\11_ogg_seek_first_frame.patch
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|