Calculate correct packet durations when demuxing Ogg/Speex. This involves
determining if there is any delay in the first packet and/or any truncation in the final packet. Originally committed as revision 20216 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
933e866735
commit
15299b3821
@ -380,6 +380,7 @@ ogg_packet (AVFormatContext * s, int *str, int *dstart, int *dsize)
|
||||
|
||||
if (os->header > -1 && os->seq > os->header){
|
||||
os->pflags = 0;
|
||||
os->pduration = 0;
|
||||
if (os->codec && os->codec->packet)
|
||||
os->codec->packet (s, idx);
|
||||
if (str)
|
||||
@ -524,6 +525,7 @@ ogg_read_packet (AVFormatContext * s, AVPacket * pkt)
|
||||
}
|
||||
|
||||
pkt->flags = os->pflags;
|
||||
pkt->duration = os->pduration;
|
||||
|
||||
return psize;
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ struct ogg_stream {
|
||||
unsigned int pstart;
|
||||
unsigned int psize;
|
||||
unsigned int pflags;
|
||||
unsigned int pduration;
|
||||
uint32_t serial;
|
||||
uint32_t seq;
|
||||
uint64_t granule, lastgp;
|
||||
|
@ -30,6 +30,10 @@
|
||||
#include "avformat.h"
|
||||
#include "oggdec.h"
|
||||
|
||||
struct speex_params {
|
||||
int final_packet_duration;
|
||||
};
|
||||
|
||||
static int speex_header(AVFormatContext *s, int idx) {
|
||||
struct ogg *ogg = s->priv_data;
|
||||
struct ogg_stream *os = ogg->streams + idx;
|
||||
@ -69,8 +73,52 @@ static int speex_header(AVFormatContext *s, int idx) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ogg_page_packets(struct ogg_stream *os)
|
||||
{
|
||||
int i;
|
||||
int packets = 0;
|
||||
for (i = 0; i < os->nsegs; i++)
|
||||
if (os->segments[i] < 255)
|
||||
packets++;
|
||||
return packets;
|
||||
}
|
||||
|
||||
static int speex_packet(AVFormatContext *s, int idx)
|
||||
{
|
||||
struct ogg *ogg = s->priv_data;
|
||||
struct ogg_stream *os = ogg->streams + idx;
|
||||
struct speex_params *spxp = os->private;
|
||||
int packet_size = s->streams[idx]->codec->frame_size;
|
||||
|
||||
if (!spxp) {
|
||||
spxp = av_mallocz(sizeof(*spxp));
|
||||
os->private = spxp;
|
||||
}
|
||||
|
||||
if (os->flags & OGG_FLAG_EOS && os->lastgp != -1 && 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 -
|
||||
packet_size * (ogg_page_packets(os) - 1);
|
||||
}
|
||||
|
||||
if (!os->lastgp && 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 &&
|
||||
spxp->final_packet_duration)
|
||||
/* final packet */
|
||||
os->pduration = spxp->final_packet_duration;
|
||||
else
|
||||
os->pduration = packet_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct ogg_codec ff_speex_codec = {
|
||||
.magic = "Speex ",
|
||||
.magicsize = 8,
|
||||
.header = speex_header
|
||||
.header = speex_header,
|
||||
.packet = speex_packet
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user