}
-static AVOutputFormat ogg_oformat = {
+AVOutputFormat ogg_muxer = {
"ogg",
- "Ogg Vorbis",
- "audio/x-vorbis",
+ "Ogg format",
+ "application/ogg",
"ogg",
sizeof (OggContext),
CODEC_ID_VORBIS,
ost->pos = url_ftell (&s->pb);;
ost->curidx = ogg->curidx;
ost->next = ogg->state;
+ ost->nstreams = ogg->nstreams;
memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
for (i = 0; i < ogg->nstreams; i++){
url_fseek (bc, ost->pos, SEEK_SET);
ogg->curidx = ost->curidx;
- memcpy (ogg->streams, ost->streams,
- ogg->nstreams * sizeof (*ogg->streams));
+ ogg->nstreams = ost->nstreams;
+ memcpy(ogg->streams, ost->streams,
+ ost->nstreams * sizeof(*ogg->streams));
}
av_free (ost);
os = ogg->streams + idx;
os->serial = serial;
os->bufsize = DECODER_BUFFER_SIZE;
+ os->buf = av_malloc(os->bufsize);
os->header = -1;
st = av_new_stream (s, idx);
return AVERROR_NOMEM;
av_set_pts_info(st, 64, 1, 1000000);
- st->start_time = 0;
return idx;
}
ogg_new_buf(ogg_t *ogg, int idx)
{
ogg_stream_t *os = ogg->streams + idx;
- u_char *nb = av_malloc(os->bufsize);
+ uint8_t *nb = av_malloc(os->bufsize);
int size = os->bufpos - os->pstart;
if(os->buf){
memcpy(nb, os->buf + os->pstart, size);
uint32_t seq;
uint32_t crc;
int size, idx;
- char sync[4];
+ uint8_t sync[4];
int sp = 0;
if (get_buffer (bc, sync, 4) < 4)
os = ogg->streams + idx;
- if(os->segp == os->nsegs)
+ if(os->psize > 0)
ogg_new_buf(ogg, idx);
if (get_buffer (bc, os->segments, nsegs) < nsegs)
if (os->bufsize - os->bufpos < size){
uint8_t *nb = av_malloc (os->bufsize *= 2);
- memset (nb, 0, os->bufsize);
memcpy (nb, os->buf, os->bufpos);
av_free (os->buf);
os->buf = nb;
url_fseek (&s->pb, end, SEEK_SET);
while (!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)
idx = i;
}
ogg->size = size;
ogg_restore (s, 0);
+ ogg_save (s);
+ while (!ogg_read_page (s, &i)) {
+ if (i == idx && ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0)
+ break;
+ }
+ if (i == idx) {
+ s->streams[idx]->start_time = ogg_gptopts (s, idx, ogg->streams[idx].granule);
+ s->streams[idx]->duration -= s->streams[idx]->start_time;
+ }
+ ogg_restore (s, 0);
return 0;
}
ogg_t *ogg = s->priv_data;
ByteIOContext *bc = &s->pb;
uint64_t min = 0, max = ogg->size;
- uint64_t tmin = 0, tmax = st->duration;
+ uint64_t tmin = st->start_time, tmax = st->start_time + st->duration;
int64_t pts = AV_NOPTS_VALUE;
ogg_save (s);
- while (min <= max){
+ if ((uint64_t)target_ts < tmin || target_ts < 0)
+ target_ts = tmin;
+ while (min <= max && tmin < tmax){
uint64_t p = min + (max - min) * (target_ts - tmin) / (tmax - tmin);
int i = -1;
pts = ogg_gptopts (s, i, ogg->streams[i].granule);
p = url_ftell (bc);
- if (ABS (pts - target_ts) * st->time_base.num < st->time_base.den)
+ if (FFABS (pts - target_ts) * st->time_base.num < st->time_base.den)
break;
if (pts > target_ts){
+ if (max == p && tmax == pts) {
+ // probably our tmin is wrong, causing us to always end up too late in the file
+ tmin = (target_ts + tmin + 1) / 2;
+ if (tmin == target_ts) {
+ url_fseek(bc, min, SEEK_SET);
+ break;
+ }
+ }
max = p;
tmax = pts;
}else{
+ if (min == p && tmin == pts) {
+ // probably our tmax is wrong, causing us to always end up too early in the file
+ tmax = (target_ts + tmax) / 2;
+ if (tmax == target_ts) {
+ url_fseek(bc, max, SEEK_SET);
+ break;
+ }
+ }
min = p;
tmin = pts;
}
}
- if (ABS (pts - target_ts) * st->time_base.num < st->time_base.den){
+ if (FFABS (pts - target_ts) * st->time_base.num < st->time_base.den){
ogg_restore (s, 1);
ogg_reset (ogg);
}else{
pts = AV_NOPTS_VALUE;
}
- return pts;
+ av_update_cur_dts(s, st, pts);
+ return 0;
#if 0
//later...
static int ogg_probe(AVProbeData *p)
{
- if (p->buf_size < 6)
- return 0;
if (p->buf[0] == 'O' && p->buf[1] == 'g' &&
p->buf[2] == 'g' && p->buf[3] == 'S' &&
p->buf[4] == 0x0 && p->buf[5] <= 0x7 )
return 0;
}
-static AVInputFormat ogg_iformat = {
+AVInputFormat ogg_demuxer = {
"ogg",
"Ogg",
sizeof (ogg_t),
// ogg_read_timestamp,
.extensions = "ogg",
};
-
-int
-ogg_init (void)
-{
-#if 0 // CONFIG_MUXERS
- av_register_output_format (&ogg_oformat);
-#endif
- av_register_input_format (&ogg_iformat);
- return 0;
-}