summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Conrad <lessen42@gmail.com>2010-01-11 05:51:09 +0000
committerDavid Conrad <lessen42@gmail.com>2010-01-11 05:51:09 +0000
commit2d4970d88dd507de1595b8ee3b65cc5da73af5ea (patch)
tree51dc56697b7b49be44c6712da414a41eb8d93276
parent7ffd8332c7fa25174fad540d71e79f538d45a9a3 (diff)
oggdec: Set dts when known
Originally committed as revision 21134 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--libavformat/oggdec.c19
-rw-r--r--libavformat/oggdec.h8
-rw-r--r--libavformat/oggparsedirac.c9
-rw-r--r--libavformat/oggparsetheora.c5
4 files changed, 31 insertions, 10 deletions
diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c
index 33b453c584..26a6af20cb 100644
--- a/libavformat/oggdec.c
+++ b/libavformat/oggdec.c
@@ -119,6 +119,7 @@ ogg_reset (struct ogg * ogg)
os->psize = 0;
os->granule = -1;
os->lastpts = AV_NOPTS_VALUE;
+ os->lastdts = AV_NOPTS_VALUE;
os->nsegs = 0;
os->segp = 0;
}
@@ -428,16 +429,18 @@ ogg_get_headers (AVFormatContext * s)
}
static uint64_t
-ogg_gptopts (AVFormatContext * s, int i, uint64_t gp)
+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);
+ pts = os->codec->gptopts(s, i, gp, dts);
} else {
pts = gp;
+ if (dts)
+ *dts = pts;
}
return pts;
@@ -474,7 +477,7 @@ ogg_get_length (AVFormatContext * s)
if (idx != -1){
s->streams[idx]->duration =
- ogg_gptopts (s, idx, ogg->streams[idx].granule);
+ ogg_gptopts (s, idx, ogg->streams[idx].granule, NULL);
}
ogg->size = size;
@@ -534,12 +537,16 @@ ogg_read_packet (AVFormatContext * s, AVPacket * pkt)
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->pts = ogg_gptopts(s, idx, os->granule, &pkt->dts);
else
- os->lastpts = ogg_gptopts(s, idx, os->granule);
+ 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");
@@ -579,7 +586,7 @@ ogg_read_timestamp (AVFormatContext * s, int stream_index, int64_t * pos_arg,
while (url_ftell(bc) < pos_limit && !ogg_read_page (s, &i)) {
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);
+ pts = ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
// FIXME: this is the position of the packet after the one with above
// pts.
*pos_arg = url_ftell(bc);
diff --git a/libavformat/oggdec.h b/libavformat/oggdec.h
index 4db3fa6132..7c677a1de4 100644
--- a/libavformat/oggdec.h
+++ b/libavformat/oggdec.h
@@ -40,7 +40,12 @@ struct ogg_codec {
*/
int (*header)(AVFormatContext *, int);
int (*packet)(AVFormatContext *, int);
- uint64_t (*gptopts)(AVFormatContext *, int, uint64_t);
+ /**
+ * Translate a granule into a timestamp.
+ * Will set dts if non-null and known.
+ * @return pts
+ */
+ uint64_t (*gptopts)(AVFormatContext *, int, uint64_t, int64_t *dts);
/**
* 1 if granule is the start time of the associated packet.
* 0 if granule is the end time of the associated packet.
@@ -60,6 +65,7 @@ struct ogg_stream {
uint32_t seq;
uint64_t granule;
int64_t lastpts;
+ int64_t lastdts;
int flags;
const struct ogg_codec *codec;
int header;
diff --git a/libavformat/oggparsedirac.c b/libavformat/oggparsedirac.c
index fc1a193205..5a907ec178 100644
--- a/libavformat/oggparsedirac.c
+++ b/libavformat/oggparsedirac.c
@@ -47,7 +47,8 @@ static int dirac_header(AVFormatContext *s, int idx)
}
// various undocument things: granule is signed (only for dirac!)
-static uint64_t dirac_gptopts(AVFormatContext *s, int idx, int64_t gp)
+static uint64_t dirac_gptopts(AVFormatContext *s, int idx, int64_t gp,
+ int64_t *dts_out)
{
struct ogg *ogg = s->priv_data;
struct ogg_stream *os = ogg->streams + idx;
@@ -59,6 +60,9 @@ static uint64_t dirac_gptopts(AVFormatContext *s, int idx, int64_t gp)
if (!dist)
os->pflags |= PKT_FLAG_KEY;
+ if (dts_out)
+ *dts_out = dts;
+
return pts;
}
@@ -79,7 +83,8 @@ static int old_dirac_header(AVFormatContext *s, int idx)
return 1;
}
-static uint64_t old_dirac_gptopts(AVFormatContext *s, int idx, uint64_t gp)
+static uint64_t old_dirac_gptopts(AVFormatContext *s, int idx, uint64_t gp,
+ int64_t *dts)
{
struct ogg *ogg = s->priv_data;
struct ogg_stream *os = ogg->streams + idx;
diff --git a/libavformat/oggparsetheora.c b/libavformat/oggparsetheora.c
index 0d74116d17..8b35a47224 100644
--- a/libavformat/oggparsetheora.c
+++ b/libavformat/oggparsetheora.c
@@ -123,7 +123,7 @@ theora_header (AVFormatContext * s, int idx)
}
static uint64_t
-theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp)
+theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp, int64_t *dts)
{
struct ogg *ogg = ctx->priv_data;
struct ogg_stream *os = ogg->streams + idx;
@@ -137,6 +137,9 @@ theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp)
if(!pframe)
os->pflags |= PKT_FLAG_KEY;
+ if (dts)
+ *dts = iframe + pframe;
+
return iframe + pframe;
}