[NUT-devel] NUT SVN: r63 - in trunk: libnut nututils
ods15 at natsuki.mplayerhq.hu
ods15 at natsuki.mplayerhq.hu
Fri Feb 24 08:31:25 CET 2006
Author: ods15
Date: 2006-02-24 08:31:25 +0100 (Fri, 24 Feb 2006)
New Revision: 63
Modified:
trunk/libnut/demuxer.c
trunk/libnut/muxer.c
trunk/libnut/priv.h
trunk/nututils/demux_avi.c
Log:
EOR for libnut seeking and index
Modified: trunk/libnut/demuxer.c
===================================================================
--- trunk/libnut/demuxer.c 2006-02-12 17:56:55 UTC (rev 62)
+++ trunk/libnut/demuxer.c 2006-02-24 07:31:25 UTC (rev 63)
@@ -301,7 +301,7 @@
return err;
}
-static int add_syncpoint(nut_context_t * nut, syncpoint_t sp, uint64_t * pts) {
+static int add_syncpoint(nut_context_t * nut, syncpoint_t sp, uint64_t * pts, uint64_t * eor) {
syncpoint_list_t * sl = &nut->syncpoints;
int i, j;
@@ -309,12 +309,14 @@
off_t pos = sl->s[i].pos >> 1;
if (pos > sp.pos) continue;
if (sp.pos < pos + 8) { // syncpoint already in list
- sl->s[i].pos = (sp.pos << 1) | (sl->s[i].pos & 1);
+ sl->s[i].pos = (sp.pos << 1) | (sl->s[i].pos & 1); // refine accuracy of syncpoint position
if (pts) {
sl->s[i].pos |= 1;
for (j = 0; j < nut->stream_count; j++) {
assert(!sl->pts[i * nut->stream_count + j] || sl->pts[i * nut->stream_count + j] == pts[j]);
sl->pts[i * nut->stream_count + j] = pts[j];
+ assert(!sl->eor[i * nut->stream_count + j] || sl->eor[i * nut->stream_count + j] == eor[j]);
+ sl->eor[i * nut->stream_count + j] = eor[j];
}
}
return i;
@@ -326,14 +328,19 @@
sl->alloc_len += PREALLOC_SIZE/4;
sl->s = realloc(sl->s, sl->alloc_len * sizeof(syncpoint_t));
sl->pts = realloc(sl->pts, sl->alloc_len * nut->stream_count * sizeof(uint64_t));
+ sl->eor = realloc(sl->eor, sl->alloc_len * nut->stream_count * sizeof(uint64_t));
}
memmove(sl->s + i + 1, sl->s + i, (sl->len - i) * sizeof(syncpoint_t));
memmove(sl->pts + (i + 1) * nut->stream_count, sl->pts + i * nut->stream_count, (sl->len - i) * nut->stream_count * sizeof(uint64_t));
+ memmove(sl->eor + (i + 1) * nut->stream_count, sl->eor + i * nut->stream_count, (sl->len - i) * nut->stream_count * sizeof(uint64_t));
sl->s[i] = sp;
sl->s[i].pos <<= 1; // flag
if (pts) sl->s[i].pos |= 1;
- for (j = 0; j < nut->stream_count; j++) sl->pts[i * nut->stream_count + j] = pts ? pts[j] : 0;
+ for (j = 0; j < nut->stream_count; j++) {
+ sl->pts[i * nut->stream_count + j] = pts ? pts[j] : 0;
+ sl->eor[i * nut->stream_count + j] = eor ? eor[j] : 0;
+ }
sl->len++;
return i;
}
@@ -363,12 +370,18 @@
if (/*nut->dopts.cache_syncpoints*/1) {
int i;
uint64_t pts[nut->stream_count];
+ uint64_t eor[nut->stream_count];
for (i = 0; i < nut->stream_count; i++) {
pts[i] = nut->sc[i].last_key;
nut->sc[i].last_key = 0;
+ eor[i] = nut->sc[i].eor;
+ nut->sc[i].eor = 0;
}
- i = add_syncpoint(nut, s, after_seek ? NULL : pts);
- if (!after_seek) nut->syncpoints.s[i - 1].back_ptr |= 1;
+ if (after_seek) add_syncpoint(nut, s, NULL, NULL);
+ else {
+ i = add_syncpoint(nut, s, pts, eor);
+ nut->syncpoints.s[i - 1].back_ptr |= 1;
+ }
} /*else {
if (!nut->syncpoints.len) add_syncpoint(nut, s);
}*/
@@ -380,7 +393,6 @@
input_buffer_t * tmp = new_mem_buffer();
int err = 0;
syncpoint_list_t * sl = &nut->syncpoints;
- uint64_t * p;
uint64_t x;
int i;
@@ -399,7 +411,8 @@
GET_V(tmp, x);
sl->alloc_len = sl->len = x;
sl->s = realloc(sl->s, sl->alloc_len * sizeof(syncpoint_t));
- p = sl->pts = realloc(sl->pts, sl->alloc_len * sizeof(uint64_t) * nut->stream_count);
+ sl->pts = realloc(sl->pts, sl->alloc_len * sizeof(uint64_t) * nut->stream_count);
+ sl->eor = realloc(sl->eor, sl->alloc_len * sizeof(uint64_t) * nut->stream_count);
for (i = 0; i < sl->len; i++) {
GET_V(tmp, x);
@@ -410,7 +423,7 @@
}
for (i = 0; i < nut->stream_count; i++) {
int j;
- uint64_t last_pts = 0;
+ uint64_t last_pts = 0; // all of pts[] array is off by one. using 0 for last pts is equivalent to -1 in spec.
for (j = 0; j < sl->len; ) {
int type, n, flag;
GET_V(tmp, x);
@@ -420,19 +433,26 @@
if (type) {
flag = x & 1;
x >>= 1;
- while (x--) p[n++ * nut->stream_count + i] = flag;
- if (n < sl->len) p[n++ * nut->stream_count + i] = !flag;
+ while (x--) sl->pts[n++ * nut->stream_count + i] = flag;
+ if (n < sl->len) sl->pts[n++ * nut->stream_count + i] = !flag;
} else {
while (x != 1) {
- p[n++ * nut->stream_count + i] = x & 1;
+ sl->pts[n++ * nut->stream_count + i] = x & 1;
x >>= 1;
+ if (n == sl->len) break;
}
}
for(; j < n; j++) {
- if (!p[j * nut->stream_count + i]) continue;
- GET_V(tmp, x);
- last_pts += x;
- p[j * nut->stream_count + i] = last_pts + 1;
+ int A, B = 0;
+ if (!sl->pts[j * nut->stream_count + i]) continue;
+ GET_V(tmp, A);
+ if (!A) {
+ GET_V(tmp, A);
+ GET_V(tmp, B);
+ sl->eor[j * nut->stream_count + i] = last_pts + A + B;
+ }
+ sl->pts[j * nut->stream_count + i] = last_pts + A;
+ last_pts += A + B;
}
}
}
@@ -558,6 +578,8 @@
sc->last_pts = pd->pts;
sc->last_dts = get_dts(sc->decode_delay, sc->pts_cache, pd->pts);
if (pd->flags & NUT_KEY_STREAM_FLAG && !sc->last_key) sc->last_key = pd->pts + 1;
+ if (pd->flags & NUT_EOR_STREAM_FLAG) sc->eor = pd->pts + 1;
+ else sc->eor = 0;
}
static int find_syncpoint(nut_context_t * nut, int backwards, syncpoint_t * res, off_t stop) {
@@ -690,6 +712,7 @@
nut->sc[i].last_pts = 0;
nut->sc[i].last_dts = 0;
nut->sc[i].last_key = 0;
+ nut->sc[i].eor = 0;
nut->sc[i].sh.max_pts = 0;
nut->sc[i].sh.fourcc = NULL;
nut->sc[i].sh.codec_specific = NULL;
@@ -822,7 +845,7 @@
if (!nut->seek_status) seek_buf(nut->i, 0, SEEK_SET);
nut->seek_status = 1;
CHECK(find_syncpoint(nut, 0, &s, 0));
- add_syncpoint(nut, s, NULL);
+ add_syncpoint(nut, s, NULL, NULL);
nut->seek_status = 0;
}
@@ -832,7 +855,7 @@
if (!nut->seek_status) seek_buf(nut->i, 0, SEEK_END);
nut->seek_status = 1;
CHECK(find_syncpoint(nut, 1, &s, 0));
- i = add_syncpoint(nut, s, NULL);
+ i = add_syncpoint(nut, s, NULL, NULL);
assert(i == sl->len-1);
sl->s[i].back_ptr |= 1;
nut->seek_status = 0;
@@ -925,7 +948,7 @@
lop = s.pts;
}
if (1/*nut->dopts.cache_syncpoints || sl->len == 2*/) {
- int tmp = add_syncpoint(nut, s, NULL);
+ int tmp = add_syncpoint(nut, s, NULL, NULL);
if (!res) i = tmp;
}/* else if (sl->len == 3) {
if (s.pts > pts) {
@@ -1021,7 +1044,10 @@
if (n) break; // pts for all active streams higher than requested pts
}
if (pd.flags & NUT_KEY_STREAM_FLAG) {
- if (pd.pts <= pts[pd.stream]>>1) good_key[pd.stream] = begin<<1;
+ if (pd.pts <= pts[pd.stream]>>1) {
+ good_key[pd.stream] = begin<<1;
+ if (pd.flags & NUT_EOR_STREAM_FLAG) good_key[pd.stream] = 0;
+ }
if (!end && pd.pts >= pts[pd.stream]>>1) { // forward seek end
if (saw_syncpoint) nut->last_syncpoint = 0;
nut->i->buf_ptr = buf_before;
@@ -1157,6 +1183,7 @@
int sync[nut->stream_count];
int good_sync = -2;
int last_sync = 0;
+ int backup = -1;
for (i = 0; i < nut->stream_count; i++) sync[i] = -1;
for (i = 1; i < sl->len; i++) {
@@ -1164,19 +1191,25 @@
if (!(sl->s[i].pos & 1)) continue;
for (j = 0; j < nut->stream_count; j++) {
uint64_t tmp = sl->pts[i * nut->stream_count + j];
+ if (pts[j]&1 && tmp--) { // -- because all pts array os off-by-one. zero indicate no keyframe.
+ if ((pts[j] >> 1) < tmp) { if (!last_sync) last_sync = i; }
+ else sync[j] = (i-1);
+ }
+ tmp = sl->eor[i * nut->stream_count + j];
if (pts[j]&1 && tmp--) {
- if ((pts[j] >> 1) < tmp) {
- if (!last_sync) last_sync = i;
- } else sync[j] = (i-1);
+ if ((pts[j] >> 1) < tmp) { if (!last_sync) last_sync = i; }
+ else sync[j] = -(i+1); // flag stream eor
}
}
}
for (i = 0; i < nut->stream_count; i++) {
if (!(pts[i] & 1)) continue;
+ if (sync[i] < -1) { backup = MAX(backup, -sync[i] - 1); continue; } // eor stream
if (good_sync == -2 || good_sync > sync[i]) good_sync = sync[i];
}
+ if (good_sync == -2) good_sync = backup; // all active streams are eor, just pick a random point, sort of.
- if ((sl->s[sl->len-1].back_ptr & 1) && last_sync && good_sync != -1) {
+ if ((sl->s[sl->len-1].back_ptr & 1) && last_sync && good_sync >= 0) {
for (i = good_sync; i <= last_sync; i++) if (!(sl->s[i].pos & 1)) break;
if (i != last_sync+1 && good_sync <= last_sync) good_sync = -1;
} else good_sync = -1;
@@ -1215,6 +1248,7 @@
nut->syncpoints.alloc_len = 0;
nut->syncpoints.s = NULL;
nut->syncpoints.pts = NULL;
+ nut->syncpoints.eor = NULL;
nut->fti = NULL;
nut->sc = NULL;
@@ -1239,6 +1273,7 @@
free(nut->syncpoints.s);
free(nut->syncpoints.pts);
+ free(nut->syncpoints.eor);
free(nut->sc);
free(nut->seek_state);
free_buffer(nut->i);
Modified: trunk/libnut/muxer.c
===================================================================
--- trunk/libnut/muxer.c 2006-02-12 17:56:55 UTC (rev 62)
+++ trunk/libnut/muxer.c 2006-02-24 07:31:25 UTC (rev 63)
@@ -154,13 +154,17 @@
s->alloc_len += PREALLOC_SIZE;
s->s = realloc(s->s, s->alloc_len * sizeof(syncpoint_t));
s->pts = realloc(s->pts, s->alloc_len * nut->stream_count * sizeof(uint64_t));
+ s->eor = realloc(s->eor, s->alloc_len * nut->stream_count * sizeof(uint64_t));
}
- for (i = 0; i < nut->stream_count; i++) s->pts[s->len * nut->stream_count + i] = nut->sc[i].last_key;
+ for (i = 0; i < nut->stream_count; i++) {
+ s->pts[s->len * nut->stream_count + i] = nut->sc[i].last_key;
+ s->eor[s->len * nut->stream_count + i] = nut->sc[i].eor > 0 ? nut->sc[i].eor : 0;
+ }
s->s[s->len].pos = nut->last_syncpoint;
s->len++;
- for (i = 0; i < nut->stream_count; i++) keys[i] = !!nut->sc[i].eor; // FIXME for eor in index
+ for (i = 0; i < nut->stream_count; i++) keys[i] = !!nut->sc[i].eor;
for (i = s->len; --i; ) {
int j;
int n = 1;
@@ -177,6 +181,7 @@
for (i = 0; i < nut->stream_count; i++) {
nut->sc[i].last_pts = convert_ts(nut, pts, stream, i);
nut->sc[i].last_key = 0;
+ if (nut->sc[i].eor) nut->sc[i].eor = -1; // so we know to ignore this stream in future syncpoints
}
put_bytes(bc, 8, SYNCPOINT_STARTCODE);
@@ -395,7 +400,7 @@
}
for (i = 0; i < nut->stream_count; i++) {
- uint64_t a, last = 0;
+ uint64_t a, last = 0; // all of pts[] array is off by one. using 0 for last pts is equivalent to -1 in spec.
int j;
for (j = 0; j < s->len; ) {
int k;
@@ -423,8 +428,15 @@
j += k;
for (k = j - k; k < j; k++) {
if (!s->pts[k * nut->stream_count + i]) continue;
- put_v(tmp, s->pts[k * nut->stream_count + i] - last - 1);
- last = s->pts[k * nut->stream_count + i] - 1;
+ if (s->eor[k * nut->stream_count + i]) {
+ put_v(tmp, 0);
+ put_v(tmp, s->pts[k * nut->stream_count + i] - last);
+ put_v(tmp, s->eor[k * nut->stream_count + i] - s->pts[k * nut->stream_count + i]);
+ last = s->eor[k * nut->stream_count + i];
+ } else {
+ put_v(tmp, s->pts[k * nut->stream_count + i] - last);
+ last = s->pts[k * nut->stream_count + i];
+ }
}
}
}
@@ -502,6 +514,7 @@
nut->syncpoints.alloc_len = 0;
nut->syncpoints.s = NULL;
nut->syncpoints.pts = NULL;
+ nut->syncpoints.eor = NULL;
nut->last_syncpoint = 0;
for (nut->stream_count = 0; s[nut->stream_count].type >= 0; nut->stream_count++);
@@ -579,6 +592,7 @@
free(nut->syncpoints.s);
free(nut->syncpoints.pts);
+ free(nut->syncpoints.eor);
free_buffer(nut->tmp_buffer);
free_buffer(nut->o); // flushes file
Modified: trunk/libnut/priv.h
===================================================================
--- trunk/libnut/priv.h 2006-02-12 17:56:55 UTC (rev 62)
+++ trunk/libnut/priv.h 2006-02-24 07:31:25 UTC (rev 63)
@@ -83,6 +83,7 @@
int alloc_len;
syncpoint_t * s;
uint64_t * pts; // each elem is stream_count items, +1 to real pts, 0 means there is no key
+ uint64_t * eor; // same as pts, is the pts of last eor in syncpoint region _IF_ eor is set by syncpoint.
} syncpoint_list_t;
typedef struct {
@@ -100,7 +101,7 @@
int decode_delay;
nut_stream_header_t sh;
int64_t * pts_cache;
- int eor;
+ int64_t eor;
// reorder.c
int64_t next_pts;
reorder_packet_t * packets;
Modified: trunk/nututils/demux_avi.c
===================================================================
--- trunk/nututils/demux_avi.c 2006-02-12 17:56:55 UTC (rev 62)
+++ trunk/nututils/demux_avi.c 2006-02-24 07:31:25 UTC (rev 63)
@@ -413,12 +413,13 @@
if (avi->cur >= avi->packets) return -1;
- if ((avi->stream[0].last_pts % 100) < N && avi->buf) {
+ if ((avi->stream[0].last_pts % 1000) < N && avi->buf) {
p->next_pts = 0;
p->len = 5;
p->flags = NUT_KEY_STREAM_FLAG;
- p->stream = 2 + (avi->stream[0].last_pts % 100);
+ p->stream = 2;//2 + (avi->stream[0].last_pts % 100);
p->pts = avi->stream[0].last_pts;
+ if (avi->stream[0].last_pts % 1000) p->flags |= NUT_EOR_STREAM_FLAG;
*buf = (void*)avi;
free(avi->buf);
avi->buf = NULL;
More information about the NUT-devel
mailing list