Originally committed as revision 21134 to svn://svn.ffmpeg.org/ffmpeg/trunktags/v0.6
| @@ -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); | |||
| @@ -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; | |||
| @@ -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; | |||
| @@ -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; | |||
| } | |||