Commit 6f28a05e authored by Sean Young's avatar Sean Young Committed by conrad

Fix for inefficient oggz_seek_units()

The function guess() seems to me to be a stab-in-the-dark since it does
not know how long the file is in actual units. Here are the changes:

1) If guess() returns a position beyond the end of the file, reset to the end
2) Before guessing, determine the length in units.
3) Fix the output when DEBUG is defined.

See http://lists.xiph.org/pipermail/ogg-dev/2009-May/001390.html
parent 718a73d3
......@@ -314,7 +314,7 @@ if test $SIZEOF_OGGZ_OFF_T = 4 ; then
OGGZ_OFF_MAX="0x7FFFFFFF"
PRI_OGGZ_OFF_T="l"
elif test $SIZEOF_OGGZ_OFF_T = 8 ; then
PRI_OGGZ_OFF_T=PRId64
PRI_OGGZ_OFF_T="ll"
fi
dnl The following configured variables are written into the public header
......
......@@ -506,9 +506,15 @@ guess (ogg_int64_t unit_at, ogg_int64_t unit_target,
if (unit_at == unit_begin) return offset_begin;
guess_ratio =
GUESS_MULTIPLIER * (unit_target - unit_begin) /
(unit_at - unit_begin);
if (unit_end != -1) {
guess_ratio =
GUESS_MULTIPLIER * (unit_target - unit_begin) /
(unit_end - unit_begin);
} else {
guess_ratio =
GUESS_MULTIPLIER * (unit_target - unit_begin) /
(unit_at - unit_begin);
}
#ifdef DEBUG
printf ("oggz_seek::guess: guess_ratio %lld = (%lld - %lld) / (%lld - %lld)\n",
......@@ -657,7 +663,16 @@ oggz_seek_set (OGGZ * oggz, ogg_int64_t unit_target)
unit_at = reader->current_unit;
unit_begin = 0;
unit_end = -1;
og = &oggz->current_page;
if (oggz_seek_raw (oggz, 0, SEEK_END) >= 0) {
ogg_int64_t granulepos;
if (oggz_get_prev_start_page (oggz, og, &granulepos, &serialno) >= 0) {
unit_end = oggz_get_unit (oggz, serialno, granulepos);
}
}
og = &oggz->current_page;
......@@ -682,6 +697,10 @@ oggz_seek_set (OGGZ * oggz, ogg_int64_t unit_target)
break;
}
if (offset_guess > offset_end) {
offset_guess = offset_end;
}
offset_at = oggz_seek_raw (oggz, offset_guess, SEEK_SET);
if (offset_at == -1) {
goto notfound;
......
......@@ -361,7 +361,7 @@ revert_packet (OGGZ * oggz, ogg_packet * op, long serialno, int flush)
#ifdef DEBUG
printf ("feeding packet (%010lu) %ld bytes %s, %s\n",
current_serialno, op->bytes,
serialno, op->bytes,
op->b_o_s ? "bos" : "not bos",
op->e_o_s ? "eos" : "not eos");
#endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment