From: Andre Noll Date: Fri, 20 Dec 2013 12:28:15 +0000 (+0100) Subject: Merge branch 't/opusdec-latency' X-Git-Tag: v0.5.1~2 X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=commitdiff_plain;h=3c12dafcba31763652ad6e58f1a6a3da88a74a1a;hp=14c16b653919e96f75566a7936223af2ebc5f2f3 Merge branch 't/opusdec-latency' A single patch which was cooking since 2013-11-17 with no problems. 14c16b opusdec: Latency improvements. --- diff --git a/NEWS b/NEWS index fc6ccffb..6c92bd7b 100644 --- a/NEWS +++ b/NEWS @@ -5,8 +5,13 @@ NEWS 0.5.1 (to be announced) "temporary implication" ---------------------------------------------- - - audiod improvements and fixes. - - buffer tree robustness improvements. +Lots of fixes and improvements all over the place. + + - Audiod improvements and fixes. + - Buffer tree robustness improvements. + - Cleanup of the mood subsystem. + - Fixes and cleanups for the flac decoder. + - Latency improvements for the ogg/opus decoder. ---------------------------------------- 0.5.0 (2013-08-23) "invertible validity" diff --git a/afs.h b/afs.h index a63968f1..8a6b927c 100644 --- a/afs.h +++ b/afs.h @@ -279,13 +279,9 @@ int aft_get_row_of_path(const char *path, struct osl_row **row); int open_and_update_audio_file(struct osl_row *aft_row, long score, struct audio_file_data *afd); int load_afd(int shmid, struct audio_file_data *afd); -int load_afsi(struct afs_info *afsi, struct osl_object *obj); -void save_afsi(struct afs_info *afsi, struct osl_object *obj); int get_afsi_of_row(const struct osl_row *row, struct afs_info *afsi); int get_afhi_of_row(const struct osl_row *row, struct afh_info *afhi); -int get_afsi_of_path(const char *path, struct afs_info *afsi); int get_audio_file_path_of_row(const struct osl_row *row, char **path); -int get_afsi_object_of_row(const struct osl_row *row, struct osl_object *obj); int audio_file_loop(void *private_data, osl_rbtree_loop_func *func); void aft_check_callback(int fd, __a_unused const struct osl_object *query); diff --git a/aft.c b/aft.c index 377740d1..f529416a 100644 --- a/aft.c +++ b/aft.c @@ -163,7 +163,7 @@ enum afsi_offsets { AFSI_SIZE = 32 }; -/** +/* * Convert a struct afs_info to an osl object. * * \param afsi Pointer to the audio file info to be converted. @@ -171,7 +171,7 @@ enum afsi_offsets { * * \sa load_afsi(). */ -void save_afsi(struct afs_info *afsi, struct osl_object *obj) +static void save_afsi(struct afs_info *afsi, struct osl_object *obj) { char *buf = obj->data; @@ -186,17 +186,17 @@ void save_afsi(struct afs_info *afsi, struct osl_object *obj) memset(buf + AFSI_AUDIO_FORMAT_UNUSED_OFFSET, 0, 2); } -/** - * Get the audio file selector info struct stored in an osl object. +/* + * Get the audio file selector info struct stored in an osl object. * * \param afsi Points to the audio_file info structure to be filled in. * \param obj The osl object holding the data. * - * \return Positive on success, negative on errors. Possible errors: \p E_BAD_AFS. + * \return Standard. * * \sa save_afsi(). */ -int load_afsi(struct afs_info *afsi, struct osl_object *obj) +static int load_afsi(struct afs_info *afsi, struct osl_object *obj) { char *buf = obj->data; if (obj->size < AFSI_SIZE) @@ -493,15 +493,16 @@ static int aft_get_row_of_hash(unsigned char *hash, struct osl_row **row) return osl(osl_get_row(audio_file_table, AFTCOL_HASH, &obj, row)); } -/** - * Get the osl object holding the audio file selector info of a row. +/* + * Get the audio file selector info object of a row. * * \param row Pointer to a row in the audio file table. * \param obj Result pointer. * * \return Standard. */ -int get_afsi_object_of_row(const struct osl_row *row, struct osl_object *obj) +static int get_afsi_object_of_row(const struct osl_row *row, + struct osl_object *obj) { return osl(osl_get_object(audio_file_table, row, AFTCOL_AFSI, obj)); } @@ -541,15 +542,15 @@ int get_afsi_of_row(const struct osl_row *row, struct afs_info *afsi) return load_afsi(afsi, &obj); } -/** +/* * Get the audio file selector info, given the path of an audio table. * * \param path The full path of the audio file. * \param afsi Result pointer. * - * \return Positive on success, negative on errors. + * \return Standard. */ -int get_afsi_of_path(const char *path, struct afs_info *afsi) +static int get_afsi_of_path(const char *path, struct afs_info *afsi) { struct osl_object obj; int ret = get_afsi_object_of_path(path, &obj); diff --git a/configure.ac b/configure.ac index 73e97997..ec346059 100644 --- a/configure.ac +++ b/configure.ac @@ -694,7 +694,7 @@ if test "$have_ogg" = "yes"; then CPPFLAGS="$CPPFLAGS $opus_cppflags" fi if test -n "$with_opus_libs"; then - speex_libs="-L$with_opus_libs" + opus_libs="-L$with_opus_libs" LDFLAGS="$LDFLAGS $opus_libs" fi AC_CHECK_LIB([opus], [opus_multistream_decode], [], [ have_opus="no" ]) @@ -968,7 +968,7 @@ if test "$have_flac" = "yes"; then play_ldflags="$play_ldflags $flac_libs -lFLAC" server_ldflags="$server_ldflags $flac_libs -lFLAC" afh_ldflags="$afh_ldflags $flac_libs -lFLAC" - recv_ldflags="$afh_ldflags $flac_libs -lFLAC" + recv_ldflags="$recv_ldflags $flac_libs -lFLAC" filters="$filters flacdec" audio_format_handlers="$audio_format_handlers flac" audiod_audio_formats="$audiod_audio_formats flac" diff --git a/fd.c b/fd.c index 4d4a859b..f70dedc1 100644 --- a/fd.c +++ b/fd.c @@ -168,7 +168,7 @@ __printf_2_3 int write_va_buffer(int fd, const char *fmt, ...) * * \return Zero or a negative error code. If the underlying call to readv(2) * returned zero (indicating an end of file condition) or failed for some - * reason other than \p EAGAIN, a negative return value is returned. + * reason other than \p EAGAIN, a negative error code is returned. * * In any case, \a num_bytes contains the number of bytes that have been * successfully read from \a fd (zero if the first readv() call failed with diff --git a/flacdec_filter.c b/flacdec_filter.c index 09b319a0..bf881725 100644 --- a/flacdec_filter.c +++ b/flacdec_filter.c @@ -25,7 +25,7 @@ struct private_flacdec_data { * We can not consume directly what was copied by the read callback * because we might need to feed unconsumend bytes to the decoder again * after the read callback ran out of data and returned ABORT. So we - * track how many bytes are unconsumed so far. + * track how many bytes have been fed to libflac but are unconsumed so far. */ size_t unconsumed; }; @@ -63,6 +63,16 @@ static FLAC__StreamDecoderReadStatus read_cb( } if (*bytes > 0) return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; + /** + * Nothing was copied. If the input queue of the btrn is smaller than + * the minimal input queue size, our parent must have been gone, so + * we're not going to get more input. Since our remaining data is not + * sufficient do decode a single frame, we have an EOF condition. + */ + if (btr_get_input_queue_size(btrn) < fn->min_iqs) { + assert(btr_no_parent(btrn)); + return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; + } /* * We are kind of screwed here. Returning CONTINUE with a byte count of * zero leads to an endless loop, so we must return either EOF or @@ -144,7 +154,7 @@ static FLAC__StreamDecoderWriteStatus write_cb( write_int16_host_endian(outbuffer + 4 * k + 2, right); } } - btr_add_output(outbuffer, n * 4, btrn); + btr_add_output(outbuffer, n * channels * 2, btrn); flac_consume(fn); return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; } @@ -222,6 +232,7 @@ static int flacdec_post_select(__a_unused struct sched *s, struct task *t) struct private_flacdec_data *pfd = fn->private_data; struct btr_node *btrn = fn->btrn; int ret; + FLAC__StreamDecoderState state; if (output_queue_full(btrn)) return 0; @@ -240,7 +251,6 @@ static int flacdec_post_select(__a_unused struct sched *s, struct task *t) goto out; } pfd->have_more = false; - FLAC__StreamDecoderState state; FLAC__stream_decoder_process_single(pfd->decoder); state = FLAC__stream_decoder_get_state(pfd->decoder); ret = -E_FLACDEC_EOF; @@ -248,10 +258,12 @@ static int flacdec_post_select(__a_unused struct sched *s, struct task *t) goto out; if (state == FLAC__STREAM_DECODER_ABORTED) { FLAC__stream_decoder_flush(pfd->decoder); - fn->min_iqs = pfd->unconsumed + 1; + pfd->unconsumed = 0; /* feed unconsumed bytes again */ + fn->min_iqs = btr_get_input_queue_size(btrn) + 1; ret = 1; goto out; } + pfd->have_more = true; fn->min_iqs = 0; ret = 1; out: diff --git a/mood.c b/mood.c index e5e84953..d15e011f 100644 --- a/mood.c +++ b/mood.c @@ -455,19 +455,6 @@ void mood_check_callback(int fd, __a_unused const struct osl_object *query) free(pb.buf); } -#if 0 -static unsigned int_log2(uint64_t x) -{ - unsigned res = 0; - - while (x) { - x /= 2; - res++; - } - return res; -} -#endif - static int64_t normalized_value(int64_t x, int64_t n, int64_t sum, int64_t qd) { if (!n || !qd) @@ -475,31 +462,13 @@ static int64_t normalized_value(int64_t x, int64_t n, int64_t sum, int64_t qd) return 100 * (n * x - sum) / (int64_t)int_sqrt(n * qd); } -static long compute_num_played_score(struct afs_info *afsi) +static long compute_score(struct afs_info *afsi, long mood_score) { - return -normalized_value(afsi->num_played, statistics.num, + mood_score -= normalized_value(afsi->num_played, statistics.num, statistics.num_played_sum, statistics.num_played_qd); -} - -static long compute_last_played_score(struct afs_info *afsi) -{ - return -normalized_value(afsi->last_played, statistics.num, + mood_score -= normalized_value(afsi->last_played, statistics.num, statistics.last_played_sum, statistics.last_played_qd); -} - -static long compute_dynamic_score(const struct osl_row *aft_row) -{ - struct afs_info afsi; - int64_t score, nscore = 0, lscore = 0; - int ret; - - ret = get_afsi_of_row(aft_row, &afsi); - if (ret < 0) - return -100; - nscore = compute_num_played_score(&afsi); - lscore = compute_last_played_score(&afsi); - score = nscore + lscore; - return score; + return mood_score / 3; } static int add_afs_statistics(const struct osl_row *row) @@ -691,7 +660,13 @@ static int update_afs_statistics(struct afs_info *old_afsi, struct afs_info *new static int add_to_score_table(const struct osl_row *aft_row, long mood_score) { - long score = (compute_dynamic_score(aft_row) + mood_score) / 3; + long score; + struct afs_info afsi; + int ret = get_afsi_of_row(aft_row, &afsi); + + if (ret < 0) + return ret; + score = compute_score(&afsi, mood_score); return score_add(aft_row, score); } @@ -772,9 +747,7 @@ static int mood_update_audio_file(const struct osl_row *aft_row, if (ret < 0) return ret; } - score += compute_num_played_score(&afsi); - score += compute_last_played_score(&afsi); - score /= 3; + score = compute_score(&afsi, score); PARA_DEBUG_LOG("score: %li\n", score); percent = (score + 100) / 3; if (percent > 100)