|
|
|
@ -531,9 +531,10 @@ ogg_read_packet (AVFormatContext * s, AVPacket * pkt) |
|
|
|
|
struct ogg_stream *os; |
|
|
|
|
int idx = -1; |
|
|
|
|
int pstart, psize; |
|
|
|
|
int64_t fpos; |
|
|
|
|
int64_t fpos, pts, dts; |
|
|
|
|
|
|
|
|
|
//Get an ogg packet
|
|
|
|
|
retry: |
|
|
|
|
do{ |
|
|
|
|
if (ogg_packet (s, &idx, &pstart, &psize, &fpos) < 0) |
|
|
|
|
return AVERROR(EIO); |
|
|
|
@ -542,13 +543,21 @@ ogg_read_packet (AVFormatContext * s, AVPacket * pkt) |
|
|
|
|
ogg = s->priv_data; |
|
|
|
|
os = ogg->streams + idx; |
|
|
|
|
|
|
|
|
|
// pflags might not be set until after this
|
|
|
|
|
pts = ogg_calc_pts(s, idx, &dts); |
|
|
|
|
|
|
|
|
|
if (os->keyframe_seek && !(os->pflags & PKT_FLAG_KEY)) |
|
|
|
|
goto retry; |
|
|
|
|
os->keyframe_seek = 0; |
|
|
|
|
|
|
|
|
|
//Alloc a pkt
|
|
|
|
|
if (av_new_packet (pkt, psize) < 0) |
|
|
|
|
return AVERROR(EIO); |
|
|
|
|
pkt->stream_index = idx; |
|
|
|
|
memcpy (pkt->data, os->buf + pstart, psize); |
|
|
|
|
|
|
|
|
|
pkt->pts = ogg_calc_pts(s, idx, &pkt->dts); |
|
|
|
|
pkt->pts = pts; |
|
|
|
|
pkt->dts = dts; |
|
|
|
|
pkt->flags = os->pflags; |
|
|
|
|
pkt->duration = os->pduration; |
|
|
|
|
pkt->pos = fpos; |
|
|
|
@ -577,6 +586,7 @@ ogg_read_timestamp (AVFormatContext * s, int stream_index, int64_t * pos_arg, |
|
|
|
|
int64_t pos_limit) |
|
|
|
|
{ |
|
|
|
|
struct ogg *ogg = s->priv_data; |
|
|
|
|
struct ogg_stream *os = ogg->streams + stream_index; |
|
|
|
|
ByteIOContext *bc = s->pb; |
|
|
|
|
int64_t pts = AV_NOPTS_VALUE; |
|
|
|
|
int i; |
|
|
|
@ -586,6 +596,8 @@ ogg_read_timestamp (AVFormatContext * s, int stream_index, int64_t * pos_arg, |
|
|
|
|
while (url_ftell(bc) < pos_limit && !ogg_packet(s, &i, NULL, NULL, pos_arg)) { |
|
|
|
|
if (i == stream_index) { |
|
|
|
|
pts = ogg_calc_pts(s, i, NULL); |
|
|
|
|
if (os->keyframe_seek && !(os->pflags & PKT_FLAG_KEY)) |
|
|
|
|
pts = AV_NOPTS_VALUE; |
|
|
|
|
} |
|
|
|
|
if (pts != AV_NOPTS_VALUE) |
|
|
|
|
break; |
|
|
|
@ -594,6 +606,24 @@ ogg_read_timestamp (AVFormatContext * s, int stream_index, int64_t * pos_arg, |
|
|
|
|
return pts; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int ogg_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) |
|
|
|
|
{ |
|
|
|
|
struct ogg *ogg = s->priv_data; |
|
|
|
|
struct ogg_stream *os = ogg->streams + stream_index; |
|
|
|
|
int ret; |
|
|
|
|
|
|
|
|
|
// Try seeking to a keyframe first. If this fails (very possible),
|
|
|
|
|
// av_seek_frame will fall back to ignoring keyframes
|
|
|
|
|
if (s->streams[stream_index]->codec->codec_type == CODEC_TYPE_VIDEO |
|
|
|
|
&& !(flags & AVSEEK_FLAG_ANY)) |
|
|
|
|
os->keyframe_seek = 1; |
|
|
|
|
|
|
|
|
|
ret = av_seek_frame_binary(s, stream_index, timestamp, flags); |
|
|
|
|
if (ret < 0) |
|
|
|
|
os->keyframe_seek = 0; |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int ogg_probe(AVProbeData *p) |
|
|
|
|
{ |
|
|
|
|
if (p->buf[0] == 'O' && p->buf[1] == 'g' && |
|
|
|
@ -612,7 +642,7 @@ AVInputFormat ogg_demuxer = { |
|
|
|
|
ogg_read_header, |
|
|
|
|
ogg_read_packet, |
|
|
|
|
ogg_read_close, |
|
|
|
|
NULL, |
|
|
|
|
ogg_read_seek, |
|
|
|
|
ogg_read_timestamp, |
|
|
|
|
.extensions = "ogg", |
|
|
|
|
.metadata_conv = ff_vorbiscomment_metadata_conv, |
|
|
|
|