mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
oggdec: Set dts when known
Originally committed as revision 21134 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
7ffd8332c7
commit
2d4970d88d
@ -119,6 +119,7 @@ ogg_reset (struct ogg * ogg)
|
|||||||
os->psize = 0;
|
os->psize = 0;
|
||||||
os->granule = -1;
|
os->granule = -1;
|
||||||
os->lastpts = AV_NOPTS_VALUE;
|
os->lastpts = AV_NOPTS_VALUE;
|
||||||
|
os->lastdts = AV_NOPTS_VALUE;
|
||||||
os->nsegs = 0;
|
os->nsegs = 0;
|
||||||
os->segp = 0;
|
os->segp = 0;
|
||||||
}
|
}
|
||||||
@ -428,16 +429,18 @@ ogg_get_headers (AVFormatContext * s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t
|
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 *ogg = s->priv_data;
|
||||||
struct ogg_stream *os = ogg->streams + i;
|
struct ogg_stream *os = ogg->streams + i;
|
||||||
uint64_t pts = AV_NOPTS_VALUE;
|
uint64_t pts = AV_NOPTS_VALUE;
|
||||||
|
|
||||||
if(os->codec->gptopts){
|
if(os->codec->gptopts){
|
||||||
pts = os->codec->gptopts(s, i, gp);
|
pts = os->codec->gptopts(s, i, gp, dts);
|
||||||
} else {
|
} else {
|
||||||
pts = gp;
|
pts = gp;
|
||||||
|
if (dts)
|
||||||
|
*dts = pts;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pts;
|
return pts;
|
||||||
@ -474,7 +477,7 @@ ogg_get_length (AVFormatContext * s)
|
|||||||
|
|
||||||
if (idx != -1){
|
if (idx != -1){
|
||||||
s->streams[idx]->duration =
|
s->streams[idx]->duration =
|
||||||
ogg_gptopts (s, idx, ogg->streams[idx].granule);
|
ogg_gptopts (s, idx, ogg->streams[idx].granule, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
ogg->size = size;
|
ogg->size = size;
|
||||||
@ -534,12 +537,16 @@ ogg_read_packet (AVFormatContext * s, AVPacket * pkt)
|
|||||||
pkt->pts = os->lastpts;
|
pkt->pts = os->lastpts;
|
||||||
os->lastpts = AV_NOPTS_VALUE;
|
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->page_end) {
|
||||||
if (os->granule != -1LL) {
|
if (os->granule != -1LL) {
|
||||||
if (os->codec && os->codec->granule_is_start)
|
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
|
else
|
||||||
os->lastpts = ogg_gptopts(s, idx, os->granule);
|
os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
|
||||||
os->granule = -1LL;
|
os->granule = -1LL;
|
||||||
} else
|
} else
|
||||||
av_log(s, AV_LOG_WARNING, "Packet is missing granule\n");
|
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)) {
|
while (url_ftell(bc) < pos_limit && !ogg_read_page (s, &i)) {
|
||||||
if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
|
if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
|
||||||
ogg->streams[i].codec && i == stream_index) {
|
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
|
// FIXME: this is the position of the packet after the one with above
|
||||||
// pts.
|
// pts.
|
||||||
*pos_arg = url_ftell(bc);
|
*pos_arg = url_ftell(bc);
|
||||||
|
@ -40,7 +40,12 @@ struct ogg_codec {
|
|||||||
*/
|
*/
|
||||||
int (*header)(AVFormatContext *, int);
|
int (*header)(AVFormatContext *, int);
|
||||||
int (*packet)(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.
|
* 1 if granule is the start time of the associated packet.
|
||||||
* 0 if granule is the end 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;
|
uint32_t seq;
|
||||||
uint64_t granule;
|
uint64_t granule;
|
||||||
int64_t lastpts;
|
int64_t lastpts;
|
||||||
|
int64_t lastdts;
|
||||||
int flags;
|
int flags;
|
||||||
const struct ogg_codec *codec;
|
const struct ogg_codec *codec;
|
||||||
int header;
|
int header;
|
||||||
|
@ -47,7 +47,8 @@ static int dirac_header(AVFormatContext *s, int idx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// various undocument things: granule is signed (only for dirac!)
|
// 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 *ogg = s->priv_data;
|
||||||
struct ogg_stream *os = ogg->streams + idx;
|
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)
|
if (!dist)
|
||||||
os->pflags |= PKT_FLAG_KEY;
|
os->pflags |= PKT_FLAG_KEY;
|
||||||
|
|
||||||
|
if (dts_out)
|
||||||
|
*dts_out = dts;
|
||||||
|
|
||||||
return pts;
|
return pts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +83,8 @@ static int old_dirac_header(AVFormatContext *s, int idx)
|
|||||||
return 1;
|
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 *ogg = s->priv_data;
|
||||||
struct ogg_stream *os = ogg->streams + idx;
|
struct ogg_stream *os = ogg->streams + idx;
|
||||||
|
@ -123,7 +123,7 @@ theora_header (AVFormatContext * s, int idx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t
|
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 *ogg = ctx->priv_data;
|
||||||
struct ogg_stream *os = ogg->streams + idx;
|
struct ogg_stream *os = ogg->streams + idx;
|
||||||
@ -137,6 +137,9 @@ theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp)
|
|||||||
if(!pframe)
|
if(!pframe)
|
||||||
os->pflags |= PKT_FLAG_KEY;
|
os->pflags |= PKT_FLAG_KEY;
|
||||||
|
|
||||||
|
if (dts)
|
||||||
|
*dts = iframe + pframe;
|
||||||
|
|
||||||
return iframe + pframe;
|
return iframe + pframe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user