Fix PTS for OGM codecs.
Fixes issue251 Originally committed as revision 20815 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
7a14430ed7
commit
5e15c7d95b
@ -116,7 +116,7 @@ ogg_reset (struct ogg * ogg)
|
|||||||
os->pstart = 0;
|
os->pstart = 0;
|
||||||
os->psize = 0;
|
os->psize = 0;
|
||||||
os->granule = -1;
|
os->granule = -1;
|
||||||
os->lastgp = -1;
|
os->lastpts = AV_NOPTS_VALUE;
|
||||||
os->nsegs = 0;
|
os->nsegs = 0;
|
||||||
os->segp = 0;
|
os->segp = 0;
|
||||||
}
|
}
|
||||||
@ -288,7 +288,6 @@ ogg_read_page (AVFormatContext * s, int *str)
|
|||||||
if (get_buffer (bc, os->buf + os->bufpos, size) < size)
|
if (get_buffer (bc, os->buf + os->bufpos, size) < size)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
os->lastgp = os->granule;
|
|
||||||
os->bufpos += size;
|
os->bufpos += size;
|
||||||
os->granule = gp;
|
os->granule = gp;
|
||||||
os->flags = flags;
|
os->flags = flags;
|
||||||
@ -303,7 +302,7 @@ static int
|
|||||||
ogg_packet (AVFormatContext * s, int *str, int *dstart, int *dsize)
|
ogg_packet (AVFormatContext * s, int *str, int *dstart, int *dsize)
|
||||||
{
|
{
|
||||||
struct ogg *ogg = s->priv_data;
|
struct ogg *ogg = s->priv_data;
|
||||||
int idx;
|
int idx, i;
|
||||||
struct ogg_stream *os;
|
struct ogg_stream *os;
|
||||||
int complete = 0;
|
int complete = 0;
|
||||||
int segp = 0, psize = 0;
|
int segp = 0, psize = 0;
|
||||||
@ -393,6 +392,15 @@ ogg_packet (AVFormatContext * s, int *str, int *dstart, int *dsize)
|
|||||||
os->psize = 0;
|
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++;
|
os->seq++;
|
||||||
if (os->segp == os->nsegs)
|
if (os->segp == os->nsegs)
|
||||||
ogg->curidx = -1;
|
ogg->curidx = -1;
|
||||||
@ -519,9 +527,20 @@ ogg_read_packet (AVFormatContext * s, AVPacket * pkt)
|
|||||||
return AVERROR(EIO);
|
return AVERROR(EIO);
|
||||||
pkt->stream_index = idx;
|
pkt->stream_index = idx;
|
||||||
memcpy (pkt->data, os->buf + pstart, psize);
|
memcpy (pkt->data, os->buf + pstart, psize);
|
||||||
if (os->lastgp != -1LL){
|
|
||||||
pkt->pts = ogg_gptopts (s, idx, os->lastgp);
|
if (os->lastpts != AV_NOPTS_VALUE) {
|
||||||
os->lastgp = -1;
|
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;
|
pkt->flags = os->pflags;
|
||||||
|
@ -41,6 +41,11 @@ 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);
|
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 {
|
struct ogg_stream {
|
||||||
@ -53,12 +58,14 @@ struct ogg_stream {
|
|||||||
unsigned int pduration;
|
unsigned int pduration;
|
||||||
uint32_t serial;
|
uint32_t serial;
|
||||||
uint32_t seq;
|
uint32_t seq;
|
||||||
uint64_t granule, lastgp;
|
uint64_t granule;
|
||||||
|
int64_t lastpts;
|
||||||
int flags;
|
int flags;
|
||||||
const struct ogg_codec *codec;
|
const struct ogg_codec *codec;
|
||||||
int header;
|
int header;
|
||||||
int nsegs, segp;
|
int nsegs, segp;
|
||||||
uint8_t segments[255];
|
uint8_t segments[255];
|
||||||
|
int page_end; ///< current packet is the last one completed in the page
|
||||||
void *private;
|
void *private;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -153,26 +153,30 @@ const struct ogg_codec ff_ogm_video_codec = {
|
|||||||
.magic = "\001video",
|
.magic = "\001video",
|
||||||
.magicsize = 6,
|
.magicsize = 6,
|
||||||
.header = ogm_header,
|
.header = ogm_header,
|
||||||
.packet = ogm_packet
|
.packet = ogm_packet,
|
||||||
|
.granule_is_start = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct ogg_codec ff_ogm_audio_codec = {
|
const struct ogg_codec ff_ogm_audio_codec = {
|
||||||
.magic = "\001audio",
|
.magic = "\001audio",
|
||||||
.magicsize = 6,
|
.magicsize = 6,
|
||||||
.header = ogm_header,
|
.header = ogm_header,
|
||||||
.packet = ogm_packet
|
.packet = ogm_packet,
|
||||||
|
.granule_is_start = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct ogg_codec ff_ogm_text_codec = {
|
const struct ogg_codec ff_ogm_text_codec = {
|
||||||
.magic = "\001text",
|
.magic = "\001text",
|
||||||
.magicsize = 5,
|
.magicsize = 5,
|
||||||
.header = ogm_header,
|
.header = ogm_header,
|
||||||
.packet = ogm_packet
|
.packet = ogm_packet,
|
||||||
|
.granule_is_start = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct ogg_codec ff_ogm_old_codec = {
|
const struct ogg_codec ff_ogm_old_codec = {
|
||||||
.magic = "\001Direct Show Samples embedded in Ogg",
|
.magic = "\001Direct Show Samples embedded in Ogg",
|
||||||
.magicsize = 35,
|
.magicsize = 35,
|
||||||
.header = ogm_dshow_header,
|
.header = ogm_dshow_header,
|
||||||
.packet = ogm_packet
|
.packet = ogm_packet,
|
||||||
|
.granule_is_start = 1,
|
||||||
};
|
};
|
||||||
|
@ -95,15 +95,16 @@ static int speex_packet(AVFormatContext *s, int idx)
|
|||||||
os->private = spxp;
|
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
|
/* 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
|
duration here because it is the only place we know the next-to-last
|
||||||
granule position. */
|
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);
|
packet_size * (ogg_page_packets(os) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!os->lastgp && os->granule > 0)
|
if (!os->lastpts && os->granule > 0)
|
||||||
/* first packet */
|
/* first packet */
|
||||||
os->pduration = os->granule - packet_size * (ogg_page_packets(os) - 1);
|
os->pduration = os->granule - packet_size * (ogg_page_packets(os) - 1);
|
||||||
else if (os->flags & OGG_FLAG_EOS && os->segp == os->nsegs &&
|
else if (os->flags & OGG_FLAG_EOS && os->segp == os->nsegs &&
|
||||||
|
Loading…
Reference in New Issue
Block a user