The patch number 14356 was added via Douglas Schilling Landgraf 
<dougsl...@redhat.com>
to http://linuxtv.org/hg/v4l-dvb master development tree.

Kernel patches in this development tree may be modified to be backward
compatible with older kernels. Compatibility modifications will be
removed before inclusion into the mainstream Kernel

If anyone has any objections, please let us know by sending a message to:
        Linux Media Mailing List <linux-me...@vger.kernel.org>

------

From: Mike Isely  <is...@pobox.com>
pvrusb2: Enforce a 300msec stabilization interval during stream strart


Martin Dauskardt <martin.dauska...@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.

Priority: normal

Signed-off-by: Mike Isely <is...@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mche...@redhat.com>
Signed-off-by: Douglas Schilling Landgraf <dougsl...@redhat.com>


---

 linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h |   12 ++
 linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c          |   41 +++++++++-
 linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h          |    1 
 3 files changed, 49 insertions(+), 5 deletions(-)

diff -r 58ae12f18e80 -r e68bf1a59932 
linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h  Tue Mar 02 
23:52:36 2010 -0300
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h  Wed Mar 03 
18:23:31 2010 -0300
@@ -233,8 +233,9 @@
        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 @@
        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;
 
diff -r 58ae12f18e80 -r e68bf1a59932 
linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c   Tue Mar 02 23:52:36 
2010 -0300
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c   Wed Mar 03 18:23:31 
2010 -0300
@@ -49,6 +49,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.dauska...@gmx.de> reports that
@@ -335,6 +339,7 @@
 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);
@@ -2479,6 +2484,11 @@
        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;
@@ -2697,6 +2707,7 @@
  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) {
@@ -2764,6 +2775,7 @@
                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) {
@@ -4547,7 +4559,7 @@
 
        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;
@@ -4614,6 +4626,17 @@
 }
 
 
+/* 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)
 {
@@ -4652,8 +4675,13 @@
                }
                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)) {
@@ -4691,10 +4719,16 @@
                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;
 }
 
@@ -4892,7 +4926,8 @@
                        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 ?
diff -r 58ae12f18e80 -r e68bf1a59932 
linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h   Tue Mar 02 23:52:36 
2010 -0300
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h   Wed Mar 03 18:23:31 
2010 -0300
@@ -312,6 +312,7 @@
        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;


---

Patch is available at: 
http://linuxtv.org/hg/v4l-dvb/rev/e68bf1a599325064c4857ea831433bd9ae7b64bc

_______________________________________________
linuxtv-commits mailing list
linuxtv-commits@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to