- // Update the last suitable starting point for the stream,
- // if the queued data contains such a starting point.
- assert(queued_data_last_starting_point_copy < ssize_t(queued_data_copy.size()));
- if (queued_data_last_starting_point_copy >= 0) {
- last_suitable_starting_point = bytes_received;
- for (int i = 0; i < queued_data_last_starting_point_copy; ++i) {
- last_suitable_starting_point += queued_data_copy[i].iov_len;
+ // Add suitable starting points for the stream, if the queued data
+ // contains such starting points. Note that we drop starting points
+ // if they're less than 10 kB apart, so that we don't get a huge
+ // amount of them for e.g. each and every MPEG-TS 188-byte cell.
+ // The 10 kB value is somewhat arbitrary, but at least it should make
+ // the RAM cost of saving the position ~0.1% (or less) of the actual
+ // data, and 10 kB is a very fine granularity in most streams.
+ static const int minimum_start_point_distance = 10240;
+ size_t byte_position = bytes_received;
+ for (size_t i = 0; i < queued_data_copy.size(); ++i) {
+ if (queued_data_copy[i].suitable_for_stream_start == SUITABLE_FOR_STREAM_START) {
+ size_t num_points = suitable_starting_points.size();
+ if (num_points >= 2 &&
+ suitable_starting_points[num_points - 1] - suitable_starting_points[num_points - 2] < minimum_start_point_distance) {
+ // p[n-1] - p[n-2] < 10 kB, so drop p[n-1].
+ suitable_starting_points.pop_back();
+ }
+ suitable_starting_points.push_back(byte_position);