V4L/DVB: pvrusb2: Enforce a 300msec stabilization interval during stream strart

Martin Dauskardt <martin.dauskardt@gmx.de> has determined that the
encoder has a much better chance of starting cleanly if we
deliberately hold off starting it util the video digitizer has had a
chance to run for at least 300msec first.  These changes implement an
enforced 300msec wait in the state machine that orchestrates streaming
start / stop.

Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Mike Isely 2010-02-06 02:10:38 -03:00 committed by Mauro Carvalho Chehab
parent 7cae112ebe
commit 6e9313755a
3 changed files with 49 additions and 5 deletions

View File

@ -233,8 +233,9 @@ struct pvr2_hdw {
int state_encoder_waitok; /* Encoder pre-wait done */
int state_encoder_runok; /* Encoder has run for >= .25 sec */
int state_decoder_run; /* Decoder is running */
int state_decoder_ready; /* Decoder is stabilized & streamable */
int state_usbstream_run; /* FX2 is streaming */
int state_decoder_quiescent; /* Decoder idle for > 50msec */
int state_decoder_quiescent; /* Decoder idle for minimal interval */
int state_pipeline_config; /* Pipeline is configured */
int state_pipeline_req; /* Somebody wants to stream */
int state_pipeline_pause; /* Pipeline must be paused */
@ -255,9 +256,16 @@ struct pvr2_hdw {
void (*state_func)(void *);
void *state_data;
/* Timer for measuring decoder settling time */
/* Timer for measuring required decoder settling time before we're
allowed to fire it up again. */
struct timer_list quiescent_timer;
/* Timer for measuring decoder stabilization time, which is the
amount of time we need to let the decoder run before we can
trust its output (otherwise the encoder might see garbage and
then fail to start correctly). */
struct timer_list decoder_stabilization_timer;
/* Timer for measuring encoder pre-wait time */
struct timer_list encoder_wait_timer;

View File

@ -48,6 +48,10 @@
before we are allowed to start it running. */
#define TIME_MSEC_DECODER_WAIT 50
/* This defines a minimum interval that the decoder must be allowed to run
before we can safely begin using its streaming output. */
#define TIME_MSEC_DECODER_STABILIZATION_WAIT 300
/* This defines a minimum interval that the encoder must remain quiet
before we are allowed to configure it. I had this originally set to
50msec, but Martin Dauskardt <martin.dauskardt@gmx.de> reports that
@ -334,6 +338,7 @@ static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw);
static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw);
static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw);
static void pvr2_hdw_quiescent_timeout(unsigned long);
static void pvr2_hdw_decoder_stabilization_timeout(unsigned long);
static void pvr2_hdw_encoder_wait_timeout(unsigned long);
static void pvr2_hdw_encoder_run_timeout(unsigned long);
static int pvr2_issue_simple_cmd(struct pvr2_hdw *,u32);
@ -2462,6 +2467,11 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
hdw->quiescent_timer.data = (unsigned long)hdw;
hdw->quiescent_timer.function = pvr2_hdw_quiescent_timeout;
init_timer(&hdw->decoder_stabilization_timer);
hdw->decoder_stabilization_timer.data = (unsigned long)hdw;
hdw->decoder_stabilization_timer.function =
pvr2_hdw_decoder_stabilization_timeout;
init_timer(&hdw->encoder_wait_timer);
hdw->encoder_wait_timer.data = (unsigned long)hdw;
hdw->encoder_wait_timer.function = pvr2_hdw_encoder_wait_timeout;
@ -2675,6 +2685,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
fail:
if (hdw) {
del_timer_sync(&hdw->quiescent_timer);
del_timer_sync(&hdw->decoder_stabilization_timer);
del_timer_sync(&hdw->encoder_run_timer);
del_timer_sync(&hdw->encoder_wait_timer);
if (hdw->workqueue) {
@ -2742,6 +2753,7 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
hdw->workqueue = NULL;
}
del_timer_sync(&hdw->quiescent_timer);
del_timer_sync(&hdw->decoder_stabilization_timer);
del_timer_sync(&hdw->encoder_run_timer);
del_timer_sync(&hdw->encoder_wait_timer);
if (hdw->fw_buffer) {
@ -4453,7 +4465,7 @@ static int state_check_enable_encoder_run(struct pvr2_hdw *hdw)
switch (hdw->pathway_state) {
case PVR2_PATHWAY_ANALOG:
if (hdw->state_decoder_run) {
if (hdw->state_decoder_run && hdw->state_decoder_ready) {
/* In analog mode, if the decoder is running, then
run the encoder. */
return !0;
@ -4520,6 +4532,17 @@ static void pvr2_hdw_quiescent_timeout(unsigned long data)
}
/* Timeout function for decoder stabilization timer. */
static void pvr2_hdw_decoder_stabilization_timeout(unsigned long data)
{
struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
hdw->state_decoder_ready = !0;
trace_stbit("state_decoder_ready", hdw->state_decoder_ready);
hdw->state_stale = !0;
queue_work(hdw->workqueue, &hdw->workpoll);
}
/* Timeout function for encoder wait timer. */
static void pvr2_hdw_encoder_wait_timeout(unsigned long data)
{
@ -4558,8 +4581,13 @@ static int state_eval_decoder_run(struct pvr2_hdw *hdw)
}
hdw->state_decoder_quiescent = 0;
hdw->state_decoder_run = 0;
/* paranoia - solve race if timer just completed */
/* paranoia - solve race if timer(s) just completed */
del_timer_sync(&hdw->quiescent_timer);
/* Kill the stabilization timer, in case we're killing the
encoder before the previous stabilization interval has
been properly timed. */
del_timer_sync(&hdw->decoder_stabilization_timer);
hdw->state_decoder_ready = 0;
} else {
if (!hdw->state_decoder_quiescent) {
if (!timer_pending(&hdw->quiescent_timer)) {
@ -4597,10 +4625,16 @@ static int state_eval_decoder_run(struct pvr2_hdw *hdw)
if (hdw->flag_decoder_missed) return 0;
if (pvr2_decoder_enable(hdw,!0) < 0) return 0;
hdw->state_decoder_quiescent = 0;
hdw->state_decoder_ready = 0;
hdw->state_decoder_run = !0;
hdw->decoder_stabilization_timer.expires =
jiffies +
(HZ * TIME_MSEC_DECODER_STABILIZATION_WAIT / 1000);
add_timer(&hdw->decoder_stabilization_timer);
}
trace_stbit("state_decoder_quiescent",hdw->state_decoder_quiescent);
trace_stbit("state_decoder_run",hdw->state_decoder_run);
trace_stbit("state_decoder_ready", hdw->state_decoder_ready);
return !0;
}
@ -4798,7 +4832,8 @@ static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which,
buf,acnt,
"worker:%s%s%s%s%s%s%s",
(hdw->state_decoder_run ?
" <decode:run>" :
(hdw->state_decoder_ready ?
"<decode:run>" : " <decode:start>") :
(hdw->state_decoder_quiescent ?
"" : " <decode:stop>")),
(hdw->state_decoder_quiescent ?

View File

@ -306,6 +306,7 @@ struct pvr2_hdw_debug_info {
int state_encoder_ok;
int state_encoder_run;
int state_decoder_run;
int state_decoder_ready;
int state_usbstream_run;
int state_decoder_quiescent;
int state_pipeline_config;