int nearest_neighbour(User *user, User ** set, int langs) { int i, k; double vote; Repo *repo, *candidates[WATCH_SIZE]; Match *match; int votes = 0; int candidate_count; int matches; if(langs) get_langs(user); /* Each user in the set */ for(i = 0; i < stats.filtered_user_count; i++) { if(user == set[i]) continue; matches = candidate_count = 0; /* Get number of matches, and store the rest in candidates[] */ for(k = 0; k < set[i]->watch_count; k++) { repo = set[i]->watch[k]; if(find(repo, user->watch, user->watch_count)) matches++; else candidates[candidate_count++] = repo; } /* If the watch-list is similar enough (lots of matches) */ if(matches > (user->watch_count * REPO_MATCH_TRESHOLD)) { vote = normalize(matches, set[i]->watch_count, 100); /* Go through candidates, and add them to recommendations */ for(k = 0; k < candidate_count; k++) { repo = candidates[k]; if(langs) vote += match_langs(user->langs, repo->langs, user->lang_count, repo->lang_count); /* repo is already in recommendation list, add a vote */ if(match = find_match(repo, user->recommend, votes)) match->weight += vote; else { user->recommend[votes].repo = repo; user->recommend[votes++].weight = vote + normalize(repo->watchers, stats.max_watchers, 1); } } } } return votes; }
int bluray_id_from_lang(stream_t *s, enum stream_ctrl_type type, const char *lang) { struct bluray_priv_s *b = s->priv; const BLURAY_STREAM_INFO *si; int count; BLURAY_TITLE_INFO *ti = get_langs(b, type, &si, &count); while (count-- > 0) { if (strstr(si->lang, lang)) { bd_free_title_info(ti); return si->pid; } si++; } if (ti) bd_free_title_info(ti); return -1; }
static int bluray_stream_control(stream_t *s, int cmd, void *arg) { struct bluray_priv_s *b = s->priv; switch (cmd) { case STREAM_CTRL_GET_NUM_CHAPTERS: { BLURAY_TITLE_INFO *ti; ti = bd_get_title_info(b->bd, b->current_title, b->current_angle); if (!ti) return STREAM_UNSUPPORTED; *((unsigned int *) arg) = ti->chapter_count; bd_free_title_info(ti); return 1; } case STREAM_CTRL_GET_CURRENT_TITLE: { *((unsigned int *) arg) = b->current_title; return 1; } case STREAM_CTRL_GET_CURRENT_CHAPTER: { *((unsigned int *) arg) = bd_get_current_chapter(b->bd); return 1; } case STREAM_CTRL_SEEK_TO_CHAPTER: { BLURAY_TITLE_INFO *ti; int chapter = *((unsigned int *) arg); int64_t pos; int r; ti = bd_get_title_info(b->bd, b->current_title, b->current_angle); if (!ti) return STREAM_UNSUPPORTED; if (chapter < 0 || chapter > ti->chapter_count) { bd_free_title_info(ti); return STREAM_UNSUPPORTED; } pos = bd_chapter_pos(b->bd, chapter); r = bluray_stream_seek(s, pos); bd_free_title_info(ti); return r ? 1 : STREAM_UNSUPPORTED; } case STREAM_CTRL_GET_TIME_LENGTH: { BLURAY_TITLE_INFO *ti = bd_get_title_info(b->bd, b->current_title, b->current_angle); if (!ti) return STREAM_UNSUPPORTED; *(double *)arg = ti->duration / 90000.0; return STREAM_OK; } case STREAM_CTRL_GET_SIZE: *(uint64_t*)arg = bd_get_title_size(b->bd); return STREAM_OK; case STREAM_CTRL_GET_CURRENT_TIME: *(double *)arg = bd_tell_time(b->bd) / 90000.0; return STREAM_OK; case STREAM_CTRL_SEEK_TO_TIME: { int64_t res; double target = *(double*)arg * 90000.0; BLURAY_TITLE_INFO *ti = bd_get_title_info(b->bd, b->current_title, b->current_angle); // clamp to ensure that out-of-bounds seeks do not simply do nothing. target = FFMAX(target, 0); if (ti && ti->duration > 1) target = FFMIN(target, ti->duration - 1); res = bd_seek_time(b->bd, target); if (res < 0) return STREAM_ERROR; s->pos = res; return 1; } case STREAM_CTRL_GET_NUM_ANGLES: { BLURAY_TITLE_INFO *ti; ti = bd_get_title_info(b->bd, b->current_title, b->current_angle); if (!ti) return STREAM_UNSUPPORTED; *((int *) arg) = ti->angle_count; bd_free_title_info(ti); return 1; } case STREAM_CTRL_GET_ANGLE: { *((int *) arg) = b->current_angle; return 1; } case STREAM_CTRL_SET_ANGLE: { BLURAY_TITLE_INFO *ti; int angle = *((int *) arg); ti = bd_get_title_info(b->bd, b->current_title, b->current_angle); if (!ti) return STREAM_UNSUPPORTED; if (angle < 0 || angle > ti->angle_count) { bd_free_title_info(ti); return STREAM_UNSUPPORTED; } b->current_angle = angle; bd_seamless_angle_change(b->bd, angle); bd_free_title_info(ti); return 1; } case STREAM_CTRL_GET_LANG: { struct stream_lang_req *req = arg; const BLURAY_STREAM_INFO *si; int count; BLURAY_TITLE_INFO *ti = get_langs(b, req->type, &si, &count); while (count-- > 0) { if (si->pid == req->id) { memcpy(req->buf, si->lang, 4); req->buf[4] = 0; bd_free_title_info(ti); return STREAM_OK; } si++; } if (ti) bd_free_title_info(ti); return STREAM_ERROR; } default: break; } return STREAM_UNSUPPORTED; }