diff options
author | Mike Isely <isely@pobox.com> | 2010-02-06 00:10:38 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-02-26 13:11:05 -0500 |
commit | 6e9313755aacdb9fd4eec58cbd9653212e2e2cdc (patch) | |
tree | cb43fe2414bf378c483d36aab3256a8f7472e20c /drivers/media/video | |
parent | 7cae112ebe10e186c3bdae1f20865941717e37a2 (diff) |
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>
Diffstat (limited to 'drivers/media/video')
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h | 12 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-hdw.c | 41 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-hdw.h | 1 |
3 files changed, 49 insertions, 5 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h index de5485f506b1..cb4057bb07a0 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h | |||
@@ -233,8 +233,9 @@ struct pvr2_hdw { | |||
233 | int state_encoder_waitok; /* Encoder pre-wait done */ | 233 | int state_encoder_waitok; /* Encoder pre-wait done */ |
234 | int state_encoder_runok; /* Encoder has run for >= .25 sec */ | 234 | int state_encoder_runok; /* Encoder has run for >= .25 sec */ |
235 | int state_decoder_run; /* Decoder is running */ | 235 | int state_decoder_run; /* Decoder is running */ |
236 | int state_decoder_ready; /* Decoder is stabilized & streamable */ | ||
236 | int state_usbstream_run; /* FX2 is streaming */ | 237 | int state_usbstream_run; /* FX2 is streaming */ |
237 | int state_decoder_quiescent; /* Decoder idle for > 50msec */ | 238 | int state_decoder_quiescent; /* Decoder idle for minimal interval */ |
238 | int state_pipeline_config; /* Pipeline is configured */ | 239 | int state_pipeline_config; /* Pipeline is configured */ |
239 | int state_pipeline_req; /* Somebody wants to stream */ | 240 | int state_pipeline_req; /* Somebody wants to stream */ |
240 | int state_pipeline_pause; /* Pipeline must be paused */ | 241 | int state_pipeline_pause; /* Pipeline must be paused */ |
@@ -255,9 +256,16 @@ struct pvr2_hdw { | |||
255 | void (*state_func)(void *); | 256 | void (*state_func)(void *); |
256 | void *state_data; | 257 | void *state_data; |
257 | 258 | ||
258 | /* Timer for measuring decoder settling time */ | 259 | /* Timer for measuring required decoder settling time before we're |
260 | allowed to fire it up again. */ | ||
259 | struct timer_list quiescent_timer; | 261 | struct timer_list quiescent_timer; |
260 | 262 | ||
263 | /* Timer for measuring decoder stabilization time, which is the | ||
264 | amount of time we need to let the decoder run before we can | ||
265 | trust its output (otherwise the encoder might see garbage and | ||
266 | then fail to start correctly). */ | ||
267 | struct timer_list decoder_stabilization_timer; | ||
268 | |||
261 | /* Timer for measuring encoder pre-wait time */ | 269 | /* Timer for measuring encoder pre-wait time */ |
262 | struct timer_list encoder_wait_timer; | 270 | struct timer_list encoder_wait_timer; |
263 | 271 | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index ad9ed51f7b9d..79b2a544ccba 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c | |||
@@ -48,6 +48,10 @@ | |||
48 | before we are allowed to start it running. */ | 48 | before we are allowed to start it running. */ |
49 | #define TIME_MSEC_DECODER_WAIT 50 | 49 | #define TIME_MSEC_DECODER_WAIT 50 |
50 | 50 | ||
51 | /* This defines a minimum interval that the decoder must be allowed to run | ||
52 | before we can safely begin using its streaming output. */ | ||
53 | #define TIME_MSEC_DECODER_STABILIZATION_WAIT 300 | ||
54 | |||
51 | /* This defines a minimum interval that the encoder must remain quiet | 55 | /* This defines a minimum interval that the encoder must remain quiet |
52 | before we are allowed to configure it. I had this originally set to | 56 | before we are allowed to configure it. I had this originally set to |
53 | 50msec, but Martin Dauskardt <martin.dauskardt@gmx.de> reports that | 57 | 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); | |||
334 | static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw); | 338 | static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw); |
335 | static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw); | 339 | static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw); |
336 | static void pvr2_hdw_quiescent_timeout(unsigned long); | 340 | static void pvr2_hdw_quiescent_timeout(unsigned long); |
341 | static void pvr2_hdw_decoder_stabilization_timeout(unsigned long); | ||
337 | static void pvr2_hdw_encoder_wait_timeout(unsigned long); | 342 | static void pvr2_hdw_encoder_wait_timeout(unsigned long); |
338 | static void pvr2_hdw_encoder_run_timeout(unsigned long); | 343 | static void pvr2_hdw_encoder_run_timeout(unsigned long); |
339 | static int pvr2_issue_simple_cmd(struct pvr2_hdw *,u32); | 344 | static int pvr2_issue_simple_cmd(struct pvr2_hdw *,u32); |
@@ -2462,6 +2467,11 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | |||
2462 | hdw->quiescent_timer.data = (unsigned long)hdw; | 2467 | hdw->quiescent_timer.data = (unsigned long)hdw; |
2463 | hdw->quiescent_timer.function = pvr2_hdw_quiescent_timeout; | 2468 | hdw->quiescent_timer.function = pvr2_hdw_quiescent_timeout; |
2464 | 2469 | ||
2470 | init_timer(&hdw->decoder_stabilization_timer); | ||
2471 | hdw->decoder_stabilization_timer.data = (unsigned long)hdw; | ||
2472 | hdw->decoder_stabilization_timer.function = | ||
2473 | pvr2_hdw_decoder_stabilization_timeout; | ||
2474 | |||
2465 | init_timer(&hdw->encoder_wait_timer); | 2475 | init_timer(&hdw->encoder_wait_timer); |
2466 | hdw->encoder_wait_timer.data = (unsigned long)hdw; | 2476 | hdw->encoder_wait_timer.data = (unsigned long)hdw; |
2467 | hdw->encoder_wait_timer.function = pvr2_hdw_encoder_wait_timeout; | 2477 | hdw->encoder_wait_timer.function = pvr2_hdw_encoder_wait_timeout; |
@@ -2675,6 +2685,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | |||
2675 | fail: | 2685 | fail: |
2676 | if (hdw) { | 2686 | if (hdw) { |
2677 | del_timer_sync(&hdw->quiescent_timer); | 2687 | del_timer_sync(&hdw->quiescent_timer); |
2688 | del_timer_sync(&hdw->decoder_stabilization_timer); | ||
2678 | del_timer_sync(&hdw->encoder_run_timer); | 2689 | del_timer_sync(&hdw->encoder_run_timer); |
2679 | del_timer_sync(&hdw->encoder_wait_timer); | 2690 | del_timer_sync(&hdw->encoder_wait_timer); |
2680 | if (hdw->workqueue) { | 2691 | if (hdw->workqueue) { |
@@ -2742,6 +2753,7 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw) | |||
2742 | hdw->workqueue = NULL; | 2753 | hdw->workqueue = NULL; |
2743 | } | 2754 | } |
2744 | del_timer_sync(&hdw->quiescent_timer); | 2755 | del_timer_sync(&hdw->quiescent_timer); |
2756 | del_timer_sync(&hdw->decoder_stabilization_timer); | ||
2745 | del_timer_sync(&hdw->encoder_run_timer); | 2757 | del_timer_sync(&hdw->encoder_run_timer); |
2746 | del_timer_sync(&hdw->encoder_wait_timer); | 2758 | del_timer_sync(&hdw->encoder_wait_timer); |
2747 | if (hdw->fw_buffer) { | 2759 | if (hdw->fw_buffer) { |
@@ -4453,7 +4465,7 @@ static int state_check_enable_encoder_run(struct pvr2_hdw *hdw) | |||
4453 | 4465 | ||
4454 | switch (hdw->pathway_state) { | 4466 | switch (hdw->pathway_state) { |
4455 | case PVR2_PATHWAY_ANALOG: | 4467 | case PVR2_PATHWAY_ANALOG: |
4456 | if (hdw->state_decoder_run) { | 4468 | if (hdw->state_decoder_run && hdw->state_decoder_ready) { |
4457 | /* In analog mode, if the decoder is running, then | 4469 | /* In analog mode, if the decoder is running, then |
4458 | run the encoder. */ | 4470 | run the encoder. */ |
4459 | return !0; | 4471 | return !0; |
@@ -4520,6 +4532,17 @@ static void pvr2_hdw_quiescent_timeout(unsigned long data) | |||
4520 | } | 4532 | } |
4521 | 4533 | ||
4522 | 4534 | ||
4535 | /* Timeout function for decoder stabilization timer. */ | ||
4536 | static void pvr2_hdw_decoder_stabilization_timeout(unsigned long data) | ||
4537 | { | ||
4538 | struct pvr2_hdw *hdw = (struct pvr2_hdw *)data; | ||
4539 | hdw->state_decoder_ready = !0; | ||
4540 | trace_stbit("state_decoder_ready", hdw->state_decoder_ready); | ||
4541 | hdw->state_stale = !0; | ||
4542 | queue_work(hdw->workqueue, &hdw->workpoll); | ||
4543 | } | ||
4544 | |||
4545 | |||
4523 | /* Timeout function for encoder wait timer. */ | 4546 | /* Timeout function for encoder wait timer. */ |
4524 | static void pvr2_hdw_encoder_wait_timeout(unsigned long data) | 4547 | static void pvr2_hdw_encoder_wait_timeout(unsigned long data) |
4525 | { | 4548 | { |
@@ -4558,8 +4581,13 @@ static int state_eval_decoder_run(struct pvr2_hdw *hdw) | |||
4558 | } | 4581 | } |
4559 | hdw->state_decoder_quiescent = 0; | 4582 | hdw->state_decoder_quiescent = 0; |
4560 | hdw->state_decoder_run = 0; | 4583 | hdw->state_decoder_run = 0; |
4561 | /* paranoia - solve race if timer just completed */ | 4584 | /* paranoia - solve race if timer(s) just completed */ |
4562 | del_timer_sync(&hdw->quiescent_timer); | 4585 | del_timer_sync(&hdw->quiescent_timer); |
4586 | /* Kill the stabilization timer, in case we're killing the | ||
4587 | encoder before the previous stabilization interval has | ||
4588 | been properly timed. */ | ||
4589 | del_timer_sync(&hdw->decoder_stabilization_timer); | ||
4590 | hdw->state_decoder_ready = 0; | ||
4563 | } else { | 4591 | } else { |
4564 | if (!hdw->state_decoder_quiescent) { | 4592 | if (!hdw->state_decoder_quiescent) { |
4565 | if (!timer_pending(&hdw->quiescent_timer)) { | 4593 | if (!timer_pending(&hdw->quiescent_timer)) { |
@@ -4597,10 +4625,16 @@ static int state_eval_decoder_run(struct pvr2_hdw *hdw) | |||
4597 | if (hdw->flag_decoder_missed) return 0; | 4625 | if (hdw->flag_decoder_missed) return 0; |
4598 | if (pvr2_decoder_enable(hdw,!0) < 0) return 0; | 4626 | if (pvr2_decoder_enable(hdw,!0) < 0) return 0; |
4599 | hdw->state_decoder_quiescent = 0; | 4627 | hdw->state_decoder_quiescent = 0; |
4628 | hdw->state_decoder_ready = 0; | ||
4600 | hdw->state_decoder_run = !0; | 4629 | hdw->state_decoder_run = !0; |
4630 | hdw->decoder_stabilization_timer.expires = | ||
4631 | jiffies + | ||
4632 | (HZ * TIME_MSEC_DECODER_STABILIZATION_WAIT / 1000); | ||
4633 | add_timer(&hdw->decoder_stabilization_timer); | ||
4601 | } | 4634 | } |
4602 | trace_stbit("state_decoder_quiescent",hdw->state_decoder_quiescent); | 4635 | trace_stbit("state_decoder_quiescent",hdw->state_decoder_quiescent); |
4603 | trace_stbit("state_decoder_run",hdw->state_decoder_run); | 4636 | trace_stbit("state_decoder_run",hdw->state_decoder_run); |
4637 | trace_stbit("state_decoder_ready", hdw->state_decoder_ready); | ||
4604 | return !0; | 4638 | return !0; |
4605 | } | 4639 | } |
4606 | 4640 | ||
@@ -4798,7 +4832,8 @@ static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which, | |||
4798 | buf,acnt, | 4832 | buf,acnt, |
4799 | "worker:%s%s%s%s%s%s%s", | 4833 | "worker:%s%s%s%s%s%s%s", |
4800 | (hdw->state_decoder_run ? | 4834 | (hdw->state_decoder_run ? |
4801 | " <decode:run>" : | 4835 | (hdw->state_decoder_ready ? |
4836 | "<decode:run>" : " <decode:start>") : | ||
4802 | (hdw->state_decoder_quiescent ? | 4837 | (hdw->state_decoder_quiescent ? |
4803 | "" : " <decode:stop>")), | 4838 | "" : " <decode:stop>")), |
4804 | (hdw->state_decoder_quiescent ? | 4839 | (hdw->state_decoder_quiescent ? |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h index 56e70eae20c1..51d3009ab57f 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h | |||
@@ -306,6 +306,7 @@ struct pvr2_hdw_debug_info { | |||
306 | int state_encoder_ok; | 306 | int state_encoder_ok; |
307 | int state_encoder_run; | 307 | int state_encoder_run; |
308 | int state_decoder_run; | 308 | int state_decoder_run; |
309 | int state_decoder_ready; | ||
309 | int state_usbstream_run; | 310 | int state_usbstream_run; |
310 | int state_decoder_quiescent; | 311 | int state_decoder_quiescent; |
311 | int state_pipeline_config; | 312 | int state_pipeline_config; |