From: Andre Noll Date: Sat, 30 Jan 2010 21:57:09 +0000 (+0100) Subject: Merge remote branch 'fml/next' X-Git-Tag: v0.4.2~64 X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=commitdiff_plain;h=a2fb56bdfa2726d401de8c1c3cd569ba96a5ccc3;hp=88817381ee586d591bccbed2a132f6f1b181db4e Merge remote branch 'fml/next' --- diff --git a/audiod.c b/audiod.c index 1734c703..72276ffe 100644 --- a/audiod.c +++ b/audiod.c @@ -603,23 +603,22 @@ struct btr_node *audiod_get_btr_root(void) return slot[newest_slot].receiver_node->btrn; } -/* returns slot num on success. */ -static int open_current_receiver(void) +/* whether a new instance of a decoder should be started. */ +static bool must_start_decoder(void) { int ret, cafn = stat_task->current_audio_format_num; if (cafn < 0 || !stat_task->ct) - return -1; + return false; /* Do nothing if the 'N' flag is set or the 'P' flag is unset */ if (stat_task->vss_status != VSS_STATUS_FLAG_PLAYING) - return -1; + return false; ret = receiver_running(cafn); if (ret != 0) /* already running */ - return -1; + return false; if (tv_diff(now, &afi[cafn].restart_barrier, NULL) < 0) - return -1; - /* start a new receiver */ - return open_receiver(cafn); + return false; + return true; } static unsigned compute_time_diff(const struct timeval *status_time) @@ -654,9 +653,9 @@ static unsigned compute_time_diff(const struct timeval *status_time) &tmp); stat_task->sa_time_diff = tmp; PARA_INFO_LOG("time diff (cur/avg): %s%lums/%s%lums\n", - sign > 0? "+" : "-", + sign < 0? "-" : "+", tv2ms(&diff), - sa_time_diff_sign ? "+" : "-", + sa_time_diff_sign < 0? "-" : "+", tv2ms(&stat_task->sa_time_diff) ); out: @@ -1098,7 +1097,9 @@ static void start_stop_decoders(void) if (audiod_status != AUDIOD_ON || !(stat_task->vss_status & VSS_STATUS_FLAG_PLAYING)) return kill_all_decoders(-E_NOT_PLAYING); - ret = open_current_receiver(); + if (!must_start_decoder()) + return; + ret = open_receiver(stat_task->current_audio_format_num); if (ret < 0) return; sl = slot + ret; @@ -1113,10 +1114,20 @@ static void start_stop_decoders(void) static void status_pre_select(struct sched *s, struct task *t) { struct status_task *st = container_of(t, struct status_task, task); - int ret; + int ret, cafn = stat_task->current_audio_format_num; + if (must_start_decoder()) + goto min_delay; ret = btr_node_status(st->btrn, 0, BTR_NT_LEAF); - sched_request_barrier(&st->restart_barrier, s); + if (ret > 0) + goto min_delay; + if (!st->ct) + sched_request_barrier_or_min_delay(&st->restart_barrier, s); + if (cafn >= 0) + sched_request_barrier(&afi[cafn].restart_barrier, s); + return; +min_delay: + sched_min_delay(s); } /* restart the client task if necessary */ diff --git a/client_common.c b/client_common.c index ded01b13..934758dd 100644 --- a/client_common.c +++ b/client_common.c @@ -404,6 +404,7 @@ out: free(home); if (ret < 0) { PARA_ERROR_LOG("%s\n", para_strerror(-ret)); + btr_remove_node(ct->btrn); btr_free_node(ct->btrn); client_close(ct); *ct_ptr = NULL; diff --git a/sched.c b/sched.c index 5c185715..b6efb1ae 100644 --- a/sched.c +++ b/sched.c @@ -289,4 +289,11 @@ void sched_request_barrier(struct timeval *barrier, struct sched *s) sched_request_timeout(&diff, s); } +void sched_request_barrier_or_min_delay(struct timeval *barrier, struct sched *s) +{ + struct timeval diff; + if (tv_diff(now, barrier, &diff) > 0) + return sched_min_delay(s); + sched_request_timeout(&diff, s); +} diff --git a/sched.h b/sched.h index 27c72391..452e749e 100644 --- a/sched.h +++ b/sched.h @@ -83,3 +83,4 @@ void sched_min_delay(struct sched *s); void sched_request_timeout(struct timeval *timeout, struct sched *s); void sched_request_timeout_ms(long unsigned ms, struct sched *s); void sched_request_barrier(struct timeval *barrier, struct sched *s); +void sched_request_barrier_or_min_delay(struct timeval *barrier, struct sched *s); diff --git a/time.c b/time.c index 0cb9babe..a591e8cd 100644 --- a/time.c +++ b/time.c @@ -131,43 +131,44 @@ void tv_divide(const unsigned long divisor, const struct timeval *tv, /** * Compute a convex combination of two time values. * - * \param a The first coefiicent. + * \param a The first coefficient. * \param tv1 The first time value. - * \param b The second coefiicent. + * \param b The second coefficient. * \param tv2 The second time value. * \param result Contains the convex combination upon return. * - * compute x := (a * tv1 + b * tv2) / (|a| + |b|) and store |x| in \a result. + * Compute x := (a * tv1 + b * tv2) / (|a| + |b|) and store |x| in \a result. * Both \a a and \a b may be negative. * - * \return One if \a x is positive, -1 otherwise. + * \return Zero, 1 or -1, if \a x is zero, positive or negative, respectively. */ int tv_convex_combination(const long a, const struct timeval *tv1, const long b, const struct timeval *tv2, struct timeval *result) { struct timeval tmp1, tmp2, tmp3; - int ret = 1, subtract = ((a > 0 && b < 0) || (a < 0 && b > 0)); - unsigned long a1 = PARA_ABS(a), b1 = PARA_ABS(b); + int ret = 1; + unsigned long a1, b1; + if (a == 0 && b == 0) { + result->tv_sec = 0; + result->tv_usec = 0; + return 0; + } + a1 = PARA_ABS(a); + b1 = PARA_ABS(b); tv_scale(a1, tv1, &tmp1); tv_scale(b1, tv2, &tmp2); - if (subtract) + if ((a > 0 && b < 0) || (a < 0 && b > 0)) /* subtract */ ret = tv_diff(&tmp1, &tmp2, &tmp3); else tv_add(&tmp1, &tmp2, &tmp3); - if (a1 + b1) - tv_divide(a1 + b1, &tmp3, result); - else { - result->tv_sec = 0; - result->tv_usec = 0; - } + tv_divide(a1 + b1, &tmp3, result); if (!a || !b) { if (a + b < 0) ret = -1; - } else - if (a < 0) - ret = -ret; + } else if (a < 0) + ret = -ret; return ret; } diff --git a/wmadec_filter.c b/wmadec_filter.c index d78c72bd..96fb5008 100644 --- a/wmadec_filter.c +++ b/wmadec_filter.c @@ -1255,11 +1255,12 @@ next_buffer: fn->min_iqs += 4096; goto next_buffer; } - fn->min_iqs = WMA_FRAME_SKIP + pwd->ahi.block_align; + fn->min_iqs = 2 * (WMA_FRAME_SKIP + pwd->ahi.block_align); fn->private_data = pwd; converted = pwd->ahi.header_len; goto success; } + fn->min_iqs = WMA_FRAME_SKIP + pwd->ahi.block_align; for (;;) { char *out; int out_size = WMA_OUTPUT_BUFFER_SIZE;