[NUT-devel] [nut]: r247 - trunk/libnut/demuxer.c
ods15
subversion at mplayerhq.hu
Sat Nov 18 19:33:58 CET 2006
Author: ods15
Date: Sat Nov 18 19:33:58 2006
New Revision: 247
Modified:
trunk/libnut/demuxer.c
Log:
Add backwards ability to smart_find_syncpoint, for backwards seeks
Modified: trunk/libnut/demuxer.c
==============================================================================
--- trunk/libnut/demuxer.c (original)
+++ trunk/libnut/demuxer.c Sat Nov 18 19:33:58 2006
@@ -837,20 +837,20 @@
return err;
}
-static int smart_find_syncpoint(nut_context_t * nut, syncpoint_t * sp) {
+static int smart_find_syncpoint(nut_context_t * nut, syncpoint_t * sp, int backwards) {
struct find_syncpoint_state_s * fss = &nut->find_syncpoint_state;
syncpoint_list_t * sl = &nut->syncpoints;
int i = fss->i, err = 0;
- off_t pos = i ? fss->pos : bctello(nut->i);
+ off_t pos = fss->i ? fss->pos : bctello(nut->i);
if (!(nut->dopts.cache_syncpoints & 1) || !sl->len) return find_syncpoint(nut, 0, sp, 0);
if (!i) {
for (i = 0; i < sl->len; i++) if (sl->s[i].pos+15 > pos) break;
- if (i && !sl->s[i-1].seen_next) return find_syncpoint(nut, 0, sp, 0);
+ if (i == sl->len || (i && !sl->s[i-1].seen_next)) return find_syncpoint(nut, 0, sp, 0);
seek_buf(nut->i, sl->s[i].pos, SEEK_SET);
- }
+ } else i--;
fss->i = i + 1;
fss->pos = pos;
@@ -860,23 +860,32 @@
if (sp->seen_next) { // failure
int j, begin = fss->begin ? fss->begin - 1 : i;
fss->begin = begin + 1;
- while (sl->s[i].seen_next) {
- if (!fss->seeked) seek_buf(nut->i, sl->s[i+1].pos, SEEK_SET);
+ while (i < backwards*2 || sl->s[i-backwards*2].seen_next) {
+ int o = backwards ? -1 : +1;
+ if (!fss->seeked) seek_buf(nut->i, sl->s[i+o].pos, SEEK_SET);
fss->seeked = 1;
- CHECK(find_syncpoint(nut, 0, sp, sl->s[i+1].pos + 15 + 8));
+ CHECK(find_syncpoint(nut, 0, sp, sl->s[i+o].pos + 15 + 8));
fss->seeked = 0;
- fss->i = ++i + 1;
- if (!sp->seen_next) break;
+ fss->i = (i+=o) + 1;
+ if (!sp->seen_next || !i) break;
}
if (sp->seen_next) { // still nothing! let's linear search the whole area
- if (!fss->seeked) seek_buf(nut->i, begin > 0 ? sl->s[begin-1].pos+15 : 0, SEEK_SET);
+ if (!fss->seeked) {
+ if (backwards) seek_buf(nut->i, sl->s[begin].pos - nut->max_distance, SEEK_SET);
+ else seek_buf(nut->i, begin > 0 ? sl->s[begin-1].pos+15 : 0, SEEK_SET);
+ }
fss->seeked = 1;
- CHECK(find_syncpoint(nut, 0, sp, 0));
+ CHECK(find_syncpoint(nut, backwards, sp, 0));
fss->seeked = 0;
}
CHECK(add_syncpoint(nut, *sp, NULL, NULL, &i));
- assert(i >= begin);
+ assert((i >= begin && !backwards) || (i <= begin && backwards));
+ if (backwards) { // swap vars
+ int tmp = begin;
+ begin = i + 1;
+ i = tmp + 1;
+ }
sl->s[i].pts_valid = 0;
sl->s[i].seen_next = 0;
for (j = 0; j < nut->stream_count; j++) {
@@ -890,10 +899,10 @@
sl->len -= i-begin;
- if (sp->pos < pos) { // wow, how silly!
+ if (sp->pos < pos && !backwards) { // wow, how silly!
fss->pos = fss->i = fss->begin = fss->seeked = 0;
seek_buf(nut->i, pos, SEEK_SET);
- return smart_find_syncpoint(nut, sp);
+ return smart_find_syncpoint(nut, sp, backwards);
}
}
fss->pos = fss->i = fss->begin = fss->seeked = 0;
@@ -906,7 +915,7 @@
int err = 0;
if (nut->seek_status) { // in error mode!
syncpoint_t s;
- CHECK(smart_find_syncpoint(nut, &s));
+ CHECK(smart_find_syncpoint(nut, &s, 0));
nut->i->buf_ptr = get_buf(nut->i, s.pos); // go back to begginning of syncpoint
flush_buf(nut->i);
clear_dts_cache(nut);
@@ -918,8 +927,8 @@
if (err > NUT_ERR_OUT_OF_MEM) { // some error occured!
fprintf(stderr, "NUT: %s\n", nut_error(err));
// rewind as much as possible
- if (nut->i->isc.seek) seek_buf(nut->i, nut->last_syncpoint + 8, SEEK_SET);
- else nut->i->buf_ptr = nut->i->buf;
+ if (nut->i->isc.seek) seek_buf(nut->i, nut->last_syncpoint + 16, SEEK_SET);
+ else nut->i->buf_ptr = nut->i->buf + MIN(16, nut->i->read_len);
nut->seek_status = 1; // enter error mode
return nut_read_next_packet(nut, pd);
@@ -1021,7 +1030,7 @@
seek_buf(nut->i, 0, SEEK_SET);
nut->seek_status = 1;
}
- CHECK(smart_find_syncpoint(nut, &sp));
+ CHECK(smart_find_syncpoint(nut, &sp, 0));
CHECK(add_syncpoint(nut, sp, NULL, NULL, NULL));
nut->i->buf_ptr = get_buf(nut->i, sp.pos); // rewind to the syncpoint, this is where playback starts...
nut->seek_status = 0;
@@ -1162,8 +1171,7 @@
if (!nut->seek_status) seek_buf(nut->i, start, SEEK_SET);
nut->seek_status = 1;
// find closest syncpoint by linear search, SHOULD be one pointed by back_ptr...
- buf_before = bctello(nut->i);
- CHECK(smart_find_syncpoint(nut, &s));
+ CHECK(smart_find_syncpoint(nut, &s, !!end));
clear_dts_cache(nut);
nut->last_syncpoint = 0; // last_key is invalid
seek_buf(nut->i, s.pos, SEEK_SET); // go back to syncpoint. This will not need a seek.
@@ -1294,10 +1302,8 @@
clear_dts_cache(nut);
}
nut->seek_status = 0;
- } else if (buf_before) {
- if (buf_before >= nut->i->file_pos) nut->i->buf_ptr = get_buf(nut->i, buf_before); // rewind
- else nut->i->buf_ptr = nut->i->buf; // special case, possible with smart_/find_syncpoint
- }
+ } else if (buf_before) nut->i->buf_ptr = get_buf(nut->i, buf_before); // rewind smart
+ else nut->i->buf_ptr = nut->i->buf; // just rewind
return err;
}
More information about the NUT-devel
mailing list