[FFmpeg-cvslog] r20815 - in trunk/libavformat: oggdec.c oggdec.h oggparseogm.c oggparsespeex.c
conrad
subversion
Sat Dec 12 21:18:43 CET 2009
Author: conrad
Date: Sat Dec 12 21:18:43 2009
New Revision: 20815
Log:
Fix PTS for OGM codecs.
Fixes issue251
Modified:
trunk/libavformat/oggdec.c
trunk/libavformat/oggdec.h
trunk/libavformat/oggparseogm.c
trunk/libavformat/oggparsespeex.c
Modified: trunk/libavformat/oggdec.c
==============================================================================
--- trunk/libavformat/oggdec.c Sat Dec 12 20:44:01 2009 (r20814)
+++ trunk/libavformat/oggdec.c Sat Dec 12 21:18:43 2009 (r20815)
@@ -116,7 +116,7 @@ ogg_reset (struct ogg * ogg)
os->pstart = 0;
os->psize = 0;
os->granule = -1;
- os->lastgp = -1;
+ os->lastpts = AV_NOPTS_VALUE;
os->nsegs = 0;
os->segp = 0;
}
@@ -288,7 +288,6 @@ ogg_read_page (AVFormatContext * s, int
if (get_buffer (bc, os->buf + os->bufpos, size) < size)
return -1;
- os->lastgp = os->granule;
os->bufpos += size;
os->granule = gp;
os->flags = flags;
@@ -303,7 +302,7 @@ static int
ogg_packet (AVFormatContext * s, int *str, int *dstart, int *dsize)
{
struct ogg *ogg = s->priv_data;
- int idx;
+ int idx, i;
struct ogg_stream *os;
int complete = 0;
int segp = 0, psize = 0;
@@ -393,6 +392,15 @@ ogg_packet (AVFormatContext * s, int *st
os->psize = 0;
}
+ // determine whether there are more complete packets in this page
+ // if not, the page's granule will apply to this packet
+ os->page_end = 1;
+ for (i = os->segp; i < os->nsegs; i++)
+ if (os->segments[i] < 255) {
+ os->page_end = 0;
+ break;
+ }
+
os->seq++;
if (os->segp == os->nsegs)
ogg->curidx = -1;
@@ -519,9 +527,20 @@ ogg_read_packet (AVFormatContext * s, AV
return AVERROR(EIO);
pkt->stream_index = idx;
memcpy (pkt->data, os->buf + pstart, psize);
- if (os->lastgp != -1LL){
- pkt->pts = ogg_gptopts (s, idx, os->lastgp);
- os->lastgp = -1;
+
+ if (os->lastpts != AV_NOPTS_VALUE) {
+ pkt->pts = os->lastpts;
+ os->lastpts = 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);
+ else
+ os->lastpts = ogg_gptopts(s, idx, os->granule);
+ os->granule = -1LL;
+ } else
+ av_log(s, AV_LOG_WARNING, "Packet is missing granule\n");
}
pkt->flags = os->pflags;
Modified: trunk/libavformat/oggdec.h
==============================================================================
--- trunk/libavformat/oggdec.h Sat Dec 12 20:44:01 2009 (r20814)
+++ trunk/libavformat/oggdec.h Sat Dec 12 21:18:43 2009 (r20815)
@@ -41,6 +41,11 @@ struct ogg_codec {
int (*header)(AVFormatContext *, int);
int (*packet)(AVFormatContext *, int);
uint64_t (*gptopts)(AVFormatContext *, int, uint64_t);
+ /**
+ * 1 if granule is the start time of the associated packet.
+ * 0 if granule is the end time of the associated packet.
+ */
+ int granule_is_start;
};
struct ogg_stream {
@@ -53,12 +58,14 @@ struct ogg_stream {
unsigned int pduration;
uint32_t serial;
uint32_t seq;
- uint64_t granule, lastgp;
+ uint64_t granule;
+ int64_t lastpts;
int flags;
const struct ogg_codec *codec;
int header;
int nsegs, segp;
uint8_t segments[255];
+ int page_end; ///< current packet is the last one completed in the page
void *private;
};
Modified: trunk/libavformat/oggparseogm.c
==============================================================================
--- trunk/libavformat/oggparseogm.c Sat Dec 12 20:44:01 2009 (r20814)
+++ trunk/libavformat/oggparseogm.c Sat Dec 12 21:18:43 2009 (r20815)
@@ -153,26 +153,30 @@ const struct ogg_codec ff_ogm_video_code
.magic = "\001video",
.magicsize = 6,
.header = ogm_header,
- .packet = ogm_packet
+ .packet = ogm_packet,
+ .granule_is_start = 1,
};
const struct ogg_codec ff_ogm_audio_codec = {
.magic = "\001audio",
.magicsize = 6,
.header = ogm_header,
- .packet = ogm_packet
+ .packet = ogm_packet,
+ .granule_is_start = 1,
};
const struct ogg_codec ff_ogm_text_codec = {
.magic = "\001text",
.magicsize = 5,
.header = ogm_header,
- .packet = ogm_packet
+ .packet = ogm_packet,
+ .granule_is_start = 1,
};
const struct ogg_codec ff_ogm_old_codec = {
.magic = "\001Direct Show Samples embedded in Ogg",
.magicsize = 35,
.header = ogm_dshow_header,
- .packet = ogm_packet
+ .packet = ogm_packet,
+ .granule_is_start = 1,
};
Modified: trunk/libavformat/oggparsespeex.c
==============================================================================
--- trunk/libavformat/oggparsespeex.c Sat Dec 12 20:44:01 2009 (r20814)
+++ trunk/libavformat/oggparsespeex.c Sat Dec 12 21:18:43 2009 (r20815)
@@ -95,15 +95,16 @@ static int speex_packet(AVFormatContext
os->private = spxp;
}
- if (os->flags & OGG_FLAG_EOS && os->lastgp != -1 && os->granule > 0) {
+ if (os->flags & OGG_FLAG_EOS && os->lastpts != AV_NOPTS_VALUE &&
+ os->granule > 0) {
/* first packet of final page. we have to calculate the final packet
duration here because it is the only place we know the next-to-last
granule position. */
- spxp->final_packet_duration = os->granule - os->lastgp -
+ spxp->final_packet_duration = os->granule - os->lastpts -
packet_size * (ogg_page_packets(os) - 1);
}
- if (!os->lastgp && os->granule > 0)
+ if (!os->lastpts && os->granule > 0)
/* first packet */
os->pduration = os->granule - packet_size * (ogg_page_packets(os) - 1);
else if (os->flags & OGG_FLAG_EOS && os->segp == os->nsegs &&
More information about the ffmpeg-cvslog
mailing list