linux/drivers/media/platform/vivid/vivid-kthread-out.c
<<
>>
Prefs
   1/*
   2 * vivid-kthread-out.h - video/vbi output thread support functions.
   3 *
   4 * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
   5 *
   6 * This program is free software; you may redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; version 2 of the License.
   9 *
  10 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  11 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  12 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  13 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  14 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  15 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  16 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  17 * SOFTWARE.
  18 */
  19
  20#include <linux/module.h>
  21#include <linux/errno.h>
  22#include <linux/kernel.h>
  23#include <linux/init.h>
  24#include <linux/sched.h>
  25#include <linux/slab.h>
  26#include <linux/font.h>
  27#include <linux/mutex.h>
  28#include <linux/videodev2.h>
  29#include <linux/kthread.h>
  30#include <linux/freezer.h>
  31#include <linux/random.h>
  32#include <linux/v4l2-dv-timings.h>
  33#include <asm/div64.h>
  34#include <media/videobuf2-vmalloc.h>
  35#include <media/v4l2-dv-timings.h>
  36#include <media/v4l2-ioctl.h>
  37#include <media/v4l2-fh.h>
  38#include <media/v4l2-event.h>
  39
  40#include "vivid-core.h"
  41#include "vivid-vid-common.h"
  42#include "vivid-vid-cap.h"
  43#include "vivid-vid-out.h"
  44#include "vivid-radio-common.h"
  45#include "vivid-radio-rx.h"
  46#include "vivid-radio-tx.h"
  47#include "vivid-sdr-cap.h"
  48#include "vivid-vbi-cap.h"
  49#include "vivid-vbi-out.h"
  50#include "vivid-osd.h"
  51#include "vivid-ctrls.h"
  52#include "vivid-kthread-out.h"
  53
  54static void vivid_thread_vid_out_tick(struct vivid_dev *dev)
  55{
  56        struct vivid_buffer *vid_out_buf = NULL;
  57        struct vivid_buffer *vbi_out_buf = NULL;
  58
  59        dprintk(dev, 1, "Video Output Thread Tick\n");
  60
  61        /* Drop a certain percentage of buffers. */
  62        if (dev->perc_dropped_buffers &&
  63            prandom_u32_max(100) < dev->perc_dropped_buffers)
  64                return;
  65
  66        spin_lock(&dev->slock);
  67        /*
  68         * Only dequeue buffer if there is at least one more pending.
  69         * This makes video loopback possible.
  70         */
  71        if (!list_empty(&dev->vid_out_active) &&
  72            !list_is_singular(&dev->vid_out_active)) {
  73                vid_out_buf = list_entry(dev->vid_out_active.next,
  74                                         struct vivid_buffer, list);
  75                list_del(&vid_out_buf->list);
  76        }
  77        if (!list_empty(&dev->vbi_out_active) &&
  78            (dev->field_out != V4L2_FIELD_ALTERNATE ||
  79             (dev->vbi_out_seq_count & 1))) {
  80                vbi_out_buf = list_entry(dev->vbi_out_active.next,
  81                                         struct vivid_buffer, list);
  82                list_del(&vbi_out_buf->list);
  83        }
  84        spin_unlock(&dev->slock);
  85
  86        if (!vid_out_buf && !vbi_out_buf)
  87                return;
  88
  89        if (vid_out_buf) {
  90                vid_out_buf->vb.sequence = dev->vid_out_seq_count;
  91                if (dev->field_out == V4L2_FIELD_ALTERNATE) {
  92                        /*
  93                         * The sequence counter counts frames, not fields.
  94                         * So divide by two.
  95                         */
  96                        vid_out_buf->vb.sequence /= 2;
  97                }
  98                vid_out_buf->vb.vb2_buf.timestamp =
  99                        ktime_get_ns() + dev->time_wrap_offset;
 100                vb2_buffer_done(&vid_out_buf->vb.vb2_buf, dev->dqbuf_error ?
 101                                VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
 102                dprintk(dev, 2, "vid_out buffer %d done\n",
 103                        vid_out_buf->vb.vb2_buf.index);
 104        }
 105
 106        if (vbi_out_buf) {
 107                if (dev->stream_sliced_vbi_out)
 108                        vivid_sliced_vbi_out_process(dev, vbi_out_buf);
 109
 110                vbi_out_buf->vb.sequence = dev->vbi_out_seq_count;
 111                vbi_out_buf->vb.vb2_buf.timestamp =
 112                        ktime_get_ns() + dev->time_wrap_offset;
 113                vb2_buffer_done(&vbi_out_buf->vb.vb2_buf, dev->dqbuf_error ?
 114                                VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
 115                dprintk(dev, 2, "vbi_out buffer %d done\n",
 116                        vbi_out_buf->vb.vb2_buf.index);
 117        }
 118        dev->dqbuf_error = false;
 119}
 120
 121static int vivid_thread_vid_out(void *data)
 122{
 123        struct vivid_dev *dev = data;
 124        u64 numerators_since_start;
 125        u64 buffers_since_start;
 126        u64 next_jiffies_since_start;
 127        unsigned long jiffies_since_start;
 128        unsigned long cur_jiffies;
 129        unsigned wait_jiffies;
 130        unsigned numerator;
 131        unsigned denominator;
 132
 133        dprintk(dev, 1, "Video Output Thread Start\n");
 134
 135        set_freezable();
 136
 137        /* Resets frame counters */
 138        dev->out_seq_offset = 0;
 139        if (dev->seq_wrap)
 140                dev->out_seq_count = 0xffffff80U;
 141        dev->jiffies_vid_out = jiffies;
 142        dev->vid_out_seq_start = dev->vbi_out_seq_start = 0;
 143        dev->out_seq_resync = false;
 144
 145        for (;;) {
 146                try_to_freeze();
 147                if (kthread_should_stop())
 148                        break;
 149
 150                mutex_lock(&dev->mutex);
 151                cur_jiffies = jiffies;
 152                if (dev->out_seq_resync) {
 153                        dev->jiffies_vid_out = cur_jiffies;
 154                        dev->out_seq_offset = dev->out_seq_count + 1;
 155                        dev->out_seq_count = 0;
 156                        dev->out_seq_resync = false;
 157                }
 158                numerator = dev->timeperframe_vid_out.numerator;
 159                denominator = dev->timeperframe_vid_out.denominator;
 160
 161                if (dev->field_out == V4L2_FIELD_ALTERNATE)
 162                        denominator *= 2;
 163
 164                /* Calculate the number of jiffies since we started streaming */
 165                jiffies_since_start = cur_jiffies - dev->jiffies_vid_out;
 166                /* Get the number of buffers streamed since the start */
 167                buffers_since_start = (u64)jiffies_since_start * denominator +
 168                                      (HZ * numerator) / 2;
 169                do_div(buffers_since_start, HZ * numerator);
 170
 171                /*
 172                 * After more than 0xf0000000 (rounded down to a multiple of
 173                 * 'jiffies-per-day' to ease jiffies_to_msecs calculation)
 174                 * jiffies have passed since we started streaming reset the
 175                 * counters and keep track of the sequence offset.
 176                 */
 177                if (jiffies_since_start > JIFFIES_RESYNC) {
 178                        dev->jiffies_vid_out = cur_jiffies;
 179                        dev->out_seq_offset = buffers_since_start;
 180                        buffers_since_start = 0;
 181                }
 182                dev->out_seq_count = buffers_since_start + dev->out_seq_offset;
 183                dev->vid_out_seq_count = dev->out_seq_count - dev->vid_out_seq_start;
 184                dev->vbi_out_seq_count = dev->out_seq_count - dev->vbi_out_seq_start;
 185
 186                vivid_thread_vid_out_tick(dev);
 187                mutex_unlock(&dev->mutex);
 188
 189                /*
 190                 * Calculate the number of 'numerators' streamed since we started,
 191                 * not including the current buffer.
 192                 */
 193                numerators_since_start = buffers_since_start * numerator;
 194
 195                /* And the number of jiffies since we started */
 196                jiffies_since_start = jiffies - dev->jiffies_vid_out;
 197
 198                /* Increase by the 'numerator' of one buffer */
 199                numerators_since_start += numerator;
 200                /*
 201                 * Calculate when that next buffer is supposed to start
 202                 * in jiffies since we started streaming.
 203                 */
 204                next_jiffies_since_start = numerators_since_start * HZ +
 205                                           denominator / 2;
 206                do_div(next_jiffies_since_start, denominator);
 207                /* If it is in the past, then just schedule asap */
 208                if (next_jiffies_since_start < jiffies_since_start)
 209                        next_jiffies_since_start = jiffies_since_start;
 210
 211                wait_jiffies = next_jiffies_since_start - jiffies_since_start;
 212                schedule_timeout_interruptible(wait_jiffies ? wait_jiffies : 1);
 213        }
 214        dprintk(dev, 1, "Video Output Thread End\n");
 215        return 0;
 216}
 217
 218static void vivid_grab_controls(struct vivid_dev *dev, bool grab)
 219{
 220        v4l2_ctrl_grab(dev->ctrl_has_crop_out, grab);
 221        v4l2_ctrl_grab(dev->ctrl_has_compose_out, grab);
 222        v4l2_ctrl_grab(dev->ctrl_has_scaler_out, grab);
 223        v4l2_ctrl_grab(dev->ctrl_tx_mode, grab);
 224        v4l2_ctrl_grab(dev->ctrl_tx_rgb_range, grab);
 225}
 226
 227int vivid_start_generating_vid_out(struct vivid_dev *dev, bool *pstreaming)
 228{
 229        dprintk(dev, 1, "%s\n", __func__);
 230
 231        if (dev->kthread_vid_out) {
 232                u32 seq_count = dev->out_seq_count + dev->seq_wrap * 128;
 233
 234                if (pstreaming == &dev->vid_out_streaming)
 235                        dev->vid_out_seq_start = seq_count;
 236                else
 237                        dev->vbi_out_seq_start = seq_count;
 238                *pstreaming = true;
 239                return 0;
 240        }
 241
 242        /* Resets frame counters */
 243        dev->jiffies_vid_out = jiffies;
 244        dev->vid_out_seq_start = dev->seq_wrap * 128;
 245        dev->vbi_out_seq_start = dev->seq_wrap * 128;
 246
 247        dev->kthread_vid_out = kthread_run(vivid_thread_vid_out, dev,
 248                        "%s-vid-out", dev->v4l2_dev.name);
 249
 250        if (IS_ERR(dev->kthread_vid_out)) {
 251                v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
 252                return PTR_ERR(dev->kthread_vid_out);
 253        }
 254        *pstreaming = true;
 255        vivid_grab_controls(dev, true);
 256
 257        dprintk(dev, 1, "returning from %s\n", __func__);
 258        return 0;
 259}
 260
 261void vivid_stop_generating_vid_out(struct vivid_dev *dev, bool *pstreaming)
 262{
 263        dprintk(dev, 1, "%s\n", __func__);
 264
 265        if (dev->kthread_vid_out == NULL)
 266                return;
 267
 268        *pstreaming = false;
 269        if (pstreaming == &dev->vid_out_streaming) {
 270                /* Release all active buffers */
 271                while (!list_empty(&dev->vid_out_active)) {
 272                        struct vivid_buffer *buf;
 273
 274                        buf = list_entry(dev->vid_out_active.next,
 275                                         struct vivid_buffer, list);
 276                        list_del(&buf->list);
 277                        vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
 278                        dprintk(dev, 2, "vid_out buffer %d done\n",
 279                                buf->vb.vb2_buf.index);
 280                }
 281        }
 282
 283        if (pstreaming == &dev->vbi_out_streaming) {
 284                while (!list_empty(&dev->vbi_out_active)) {
 285                        struct vivid_buffer *buf;
 286
 287                        buf = list_entry(dev->vbi_out_active.next,
 288                                         struct vivid_buffer, list);
 289                        list_del(&buf->list);
 290                        vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
 291                        dprintk(dev, 2, "vbi_out buffer %d done\n",
 292                                buf->vb.vb2_buf.index);
 293                }
 294        }
 295
 296        if (dev->vid_out_streaming || dev->vbi_out_streaming)
 297                return;
 298
 299        /* shutdown control thread */
 300        vivid_grab_controls(dev, false);
 301        mutex_unlock(&dev->mutex);
 302        kthread_stop(dev->kthread_vid_out);
 303        dev->kthread_vid_out = NULL;
 304        mutex_lock(&dev->mutex);
 305}
 306