linux/drivers/media/pci/ivtv/ivtv-vbi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3    Vertical Blank Interval support functions
   4    Copyright (C) 2004-2007  Hans Verkuil <hverkuil@xs4all.nl>
   5
   6 */
   7
   8#include "ivtv-driver.h"
   9#include "ivtv-i2c.h"
  10#include "ivtv-ioctl.h"
  11#include "ivtv-queue.h"
  12#include "ivtv-cards.h"
  13#include "ivtv-vbi.h"
  14
  15static void ivtv_set_vps(struct ivtv *itv, int enabled)
  16{
  17        struct v4l2_sliced_vbi_data data;
  18
  19        if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
  20                return;
  21        data.id = V4L2_SLICED_VPS;
  22        data.field = 0;
  23        data.line = enabled ? 16 : 0;
  24        data.data[2] = itv->vbi.vps_payload.data[0];
  25        data.data[8] = itv->vbi.vps_payload.data[1];
  26        data.data[9] = itv->vbi.vps_payload.data[2];
  27        data.data[10] = itv->vbi.vps_payload.data[3];
  28        data.data[11] = itv->vbi.vps_payload.data[4];
  29        ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data);
  30}
  31
  32static void ivtv_set_cc(struct ivtv *itv, int mode, const struct vbi_cc *cc)
  33{
  34        struct v4l2_sliced_vbi_data data;
  35
  36        if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
  37                return;
  38        data.id = V4L2_SLICED_CAPTION_525;
  39        data.field = 0;
  40        data.line = (mode & 1) ? 21 : 0;
  41        data.data[0] = cc->odd[0];
  42        data.data[1] = cc->odd[1];
  43        ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data);
  44        data.field = 1;
  45        data.line = (mode & 2) ? 21 : 0;
  46        data.data[0] = cc->even[0];
  47        data.data[1] = cc->even[1];
  48        ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data);
  49}
  50
  51static void ivtv_set_wss(struct ivtv *itv, int enabled, int mode)
  52{
  53        struct v4l2_sliced_vbi_data data;
  54
  55        if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
  56                return;
  57        /* When using a 50 Hz system, always turn on the
  58           wide screen signal with 4x3 ratio as the default.
  59           Turning this signal on and off can confuse certain
  60           TVs. As far as I can tell there is no reason not to
  61           transmit this signal. */
  62        if ((itv->std_out & V4L2_STD_625_50) && !enabled) {
  63                enabled = 1;
  64                mode = 0x08;  /* 4x3 full format */
  65        }
  66        data.id = V4L2_SLICED_WSS_625;
  67        data.field = 0;
  68        data.line = enabled ? 23 : 0;
  69        data.data[0] = mode & 0xff;
  70        data.data[1] = (mode >> 8) & 0xff;
  71        ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data);
  72}
  73
  74static int odd_parity(u8 c)
  75{
  76        c ^= (c >> 4);
  77        c ^= (c >> 2);
  78        c ^= (c >> 1);
  79
  80        return c & 1;
  81}
  82
  83static void ivtv_write_vbi_line(struct ivtv *itv,
  84                                const struct v4l2_sliced_vbi_data *d,
  85                                struct vbi_cc *cc, int *found_cc)
  86{
  87        struct vbi_info *vi = &itv->vbi;
  88
  89        if (d->id == V4L2_SLICED_CAPTION_525 && d->line == 21) {
  90                if (d->field) {
  91                        cc->even[0] = d->data[0];
  92                        cc->even[1] = d->data[1];
  93                } else {
  94                        cc->odd[0] = d->data[0];
  95                        cc->odd[1] = d->data[1];
  96                }
  97                *found_cc = 1;
  98        } else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) {
  99                struct vbi_vps vps;
 100
 101                vps.data[0] = d->data[2];
 102                vps.data[1] = d->data[8];
 103                vps.data[2] = d->data[9];
 104                vps.data[3] = d->data[10];
 105                vps.data[4] = d->data[11];
 106                if (memcmp(&vps, &vi->vps_payload, sizeof(vps))) {
 107                        vi->vps_payload = vps;
 108                        set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
 109                }
 110        } else if (d->id == V4L2_SLICED_WSS_625 &&
 111                   d->line == 23 && d->field == 0) {
 112                int wss = d->data[0] | d->data[1] << 8;
 113
 114                if (vi->wss_payload != wss) {
 115                        vi->wss_payload = wss;
 116                        set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
 117                }
 118        }
 119}
 120
 121static void ivtv_write_vbi_cc_lines(struct ivtv *itv, const struct vbi_cc *cc)
 122{
 123        struct vbi_info *vi = &itv->vbi;
 124
 125        if (vi->cc_payload_idx < ARRAY_SIZE(vi->cc_payload)) {
 126                memcpy(&vi->cc_payload[vi->cc_payload_idx], cc,
 127                       sizeof(struct vbi_cc));
 128                vi->cc_payload_idx++;
 129                set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
 130        }
 131}
 132
 133static void ivtv_write_vbi(struct ivtv *itv,
 134                           const struct v4l2_sliced_vbi_data *sliced,
 135                           size_t cnt)
 136{
 137        struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
 138        int found_cc = 0;
 139        size_t i;
 140
 141        for (i = 0; i < cnt; i++)
 142                ivtv_write_vbi_line(itv, sliced + i, &cc, &found_cc);
 143
 144        if (found_cc)
 145                ivtv_write_vbi_cc_lines(itv, &cc);
 146}
 147
 148ssize_t
 149ivtv_write_vbi_from_user(struct ivtv *itv,
 150                         const struct v4l2_sliced_vbi_data __user *sliced,
 151                         size_t cnt)
 152{
 153        struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
 154        int found_cc = 0;
 155        size_t i;
 156        struct v4l2_sliced_vbi_data d;
 157        ssize_t ret = cnt * sizeof(struct v4l2_sliced_vbi_data);
 158
 159        for (i = 0; i < cnt; i++) {
 160                if (copy_from_user(&d, sliced + i,
 161                                   sizeof(struct v4l2_sliced_vbi_data))) {
 162                        ret = -EFAULT;
 163                        break;
 164                }
 165                ivtv_write_vbi_line(itv, &d, &cc, &found_cc);
 166        }
 167
 168        if (found_cc)
 169                ivtv_write_vbi_cc_lines(itv, &cc);
 170
 171        return ret;
 172}
 173
 174static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp)
 175{
 176        int line = 0;
 177        int i;
 178        u32 linemask[2] = { 0, 0 };
 179        unsigned short size;
 180        static const u8 mpeg_hdr_data[] = {
 181                0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x0c, 0x66,
 182                0x24, 0x01, 0x01, 0xd1, 0xd3, 0xfa, 0xff, 0xff,
 183                0x00, 0x00, 0x01, 0xbd, 0x00, 0x1a, 0x84, 0x80,
 184                0x07, 0x21, 0x00, 0x5d, 0x63, 0xa7, 0xff, 0xff
 185        };
 186        const int sd = sizeof(mpeg_hdr_data);   /* start of vbi data */
 187        int idx = itv->vbi.frame % IVTV_VBI_FRAMES;
 188        u8 *dst = &itv->vbi.sliced_mpeg_data[idx][0];
 189
 190        for (i = 0; i < lines; i++) {
 191                int f, l;
 192
 193                if (itv->vbi.sliced_data[i].id == 0)
 194                        continue;
 195
 196                l = itv->vbi.sliced_data[i].line - 6;
 197                f = itv->vbi.sliced_data[i].field;
 198                if (f)
 199                        l += 18;
 200                if (l < 32)
 201                        linemask[0] |= (1 << l);
 202                else
 203                        linemask[1] |= (1 << (l - 32));
 204                dst[sd + 12 + line * 43] =
 205                        ivtv_service2vbi(itv->vbi.sliced_data[i].id);
 206                memcpy(dst + sd + 12 + line * 43 + 1, itv->vbi.sliced_data[i].data, 42);
 207                line++;
 208        }
 209        memcpy(dst, mpeg_hdr_data, sizeof(mpeg_hdr_data));
 210        if (line == 36) {
 211                /* All lines are used, so there is no space for the linemask
 212                   (the max size of the VBI data is 36 * 43 + 4 bytes).
 213                   So in this case we use the magic number 'ITV0'. */
 214                memcpy(dst + sd, "ITV0", 4);
 215                memmove(dst + sd + 4, dst + sd + 12, line * 43);
 216                size = 4 + ((43 * line + 3) & ~3);
 217        } else {
 218                memcpy(dst + sd, "itv0", 4);
 219                cpu_to_le32s(&linemask[0]);
 220                cpu_to_le32s(&linemask[1]);
 221                memcpy(dst + sd + 4, &linemask[0], 8);
 222                size = 12 + ((43 * line + 3) & ~3);
 223        }
 224        dst[4+16] = (size + 10) >> 8;
 225        dst[5+16] = (size + 10) & 0xff;
 226        dst[9+16] = 0x21 | ((pts_stamp >> 29) & 0x6);
 227        dst[10+16] = (pts_stamp >> 22) & 0xff;
 228        dst[11+16] = 1 | ((pts_stamp >> 14) & 0xff);
 229        dst[12+16] = (pts_stamp >> 7) & 0xff;
 230        dst[13+16] = 1 | ((pts_stamp & 0x7f) << 1);
 231        itv->vbi.sliced_mpeg_size[idx] = sd + size;
 232}
 233
 234static int ivtv_convert_ivtv_vbi(struct ivtv *itv, u8 *p)
 235{
 236        u32 linemask[2];
 237        int i, l, id2;
 238        int line = 0;
 239
 240        if (!memcmp(p, "itv0", 4)) {
 241                memcpy(linemask, p + 4, 8);
 242                p += 12;
 243        } else if (!memcmp(p, "ITV0", 4)) {
 244                linemask[0] = 0xffffffff;
 245                linemask[1] = 0xf;
 246                p += 4;
 247        } else {
 248                /* unknown VBI data, convert to empty VBI frame */
 249                linemask[0] = linemask[1] = 0;
 250        }
 251        for (i = 0; i < 36; i++) {
 252                int err = 0;
 253
 254                if (i < 32 && !(linemask[0] & (1 << i)))
 255                        continue;
 256                if (i >= 32 && !(linemask[1] & (1 << (i - 32))))
 257                        continue;
 258                id2 = *p & 0xf;
 259                switch (id2) {
 260                case IVTV_SLICED_TYPE_TELETEXT_B:
 261                        id2 = V4L2_SLICED_TELETEXT_B;
 262                        break;
 263                case IVTV_SLICED_TYPE_CAPTION_525:
 264                        id2 = V4L2_SLICED_CAPTION_525;
 265                        err = !odd_parity(p[1]) || !odd_parity(p[2]);
 266                        break;
 267                case IVTV_SLICED_TYPE_VPS:
 268                        id2 = V4L2_SLICED_VPS;
 269                        break;
 270                case IVTV_SLICED_TYPE_WSS_625:
 271                        id2 = V4L2_SLICED_WSS_625;
 272                        break;
 273                default:
 274                        id2 = 0;
 275                        break;
 276                }
 277                if (err == 0) {
 278                        l = (i < 18) ? i + 6 : i - 18 + 6;
 279                        itv->vbi.sliced_dec_data[line].line = l;
 280                        itv->vbi.sliced_dec_data[line].field = i >= 18;
 281                        itv->vbi.sliced_dec_data[line].id = id2;
 282                        memcpy(itv->vbi.sliced_dec_data[line].data, p + 1, 42);
 283                        line++;
 284                }
 285                p += 43;
 286        }
 287        while (line < 36) {
 288                itv->vbi.sliced_dec_data[line].id = 0;
 289                itv->vbi.sliced_dec_data[line].line = 0;
 290                itv->vbi.sliced_dec_data[line].field = 0;
 291                line++;
 292        }
 293        return line * sizeof(itv->vbi.sliced_dec_data[0]);
 294}
 295
 296/* Compress raw VBI format, removes leading SAV codes and surplus space after the
 297   field.
 298   Returns new compressed size. */
 299static u32 compress_raw_buf(struct ivtv *itv, u8 *buf, u32 size)
 300{
 301        u32 line_size = itv->vbi.raw_decoder_line_size;
 302        u32 lines = itv->vbi.count;
 303        u8 sav1 = itv->vbi.raw_decoder_sav_odd_field;
 304        u8 sav2 = itv->vbi.raw_decoder_sav_even_field;
 305        u8 *q = buf;
 306        u8 *p;
 307        int i;
 308
 309        for (i = 0; i < lines; i++) {
 310                p = buf + i * line_size;
 311
 312                /* Look for SAV code */
 313                if (p[0] != 0xff || p[1] || p[2] || (p[3] != sav1 && p[3] != sav2)) {
 314                        break;
 315                }
 316                memcpy(q, p + 4, line_size - 4);
 317                q += line_size - 4;
 318        }
 319        return lines * (line_size - 4);
 320}
 321
 322
 323/* Compressed VBI format, all found sliced blocks put next to one another
 324   Returns new compressed size */
 325static u32 compress_sliced_buf(struct ivtv *itv, u32 line, u8 *buf, u32 size, u8 sav)
 326{
 327        u32 line_size = itv->vbi.sliced_decoder_line_size;
 328        struct v4l2_decode_vbi_line vbi;
 329        int i;
 330        unsigned lines = 0;
 331
 332        /* find the first valid line */
 333        for (i = 0; i < size; i++, buf++) {
 334                if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav)
 335                        break;
 336        }
 337
 338        size -= i;
 339        if (size < line_size) {
 340                return line;
 341        }
 342        for (i = 0; i < size / line_size; i++) {
 343                u8 *p = buf + i * line_size;
 344
 345                /* Look for SAV code  */
 346                if (p[0] != 0xff || p[1] || p[2] || p[3] != sav) {
 347                        continue;
 348                }
 349                vbi.p = p + 4;
 350                v4l2_subdev_call(itv->sd_video, vbi, decode_vbi_line, &vbi);
 351                if (vbi.type && !(lines & (1 << vbi.line))) {
 352                        lines |= 1 << vbi.line;
 353                        itv->vbi.sliced_data[line].id = vbi.type;
 354                        itv->vbi.sliced_data[line].field = vbi.is_second_field;
 355                        itv->vbi.sliced_data[line].line = vbi.line;
 356                        memcpy(itv->vbi.sliced_data[line].data, vbi.p, 42);
 357                        line++;
 358                }
 359        }
 360        return line;
 361}
 362
 363void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
 364                           u64 pts_stamp, int streamtype)
 365{
 366        u8 *p = (u8 *) buf->buf;
 367        u32 size = buf->bytesused;
 368        int y;
 369
 370        /* Raw VBI data */
 371        if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && ivtv_raw_vbi(itv)) {
 372                u8 type;
 373
 374                ivtv_buf_swap(buf);
 375
 376                type = p[3];
 377
 378                size = buf->bytesused = compress_raw_buf(itv, p, size);
 379
 380                /* second field of the frame? */
 381                if (type == itv->vbi.raw_decoder_sav_even_field) {
 382                        /* Dirty hack needed for backwards
 383                           compatibility of old VBI software. */
 384                        p += size - 4;
 385                        memcpy(p, &itv->vbi.frame, 4);
 386                        itv->vbi.frame++;
 387                }
 388                return;
 389        }
 390
 391        /* Sliced VBI data with data insertion */
 392        if (streamtype == IVTV_ENC_STREAM_TYPE_VBI) {
 393                int lines;
 394
 395                ivtv_buf_swap(buf);
 396
 397                /* first field */
 398                lines = compress_sliced_buf(itv, 0, p, size / 2,
 399                        itv->vbi.sliced_decoder_sav_odd_field);
 400                /* second field */
 401                /* experimentation shows that the second half does not always begin
 402                   at the exact address. So start a bit earlier (hence 32). */
 403                lines = compress_sliced_buf(itv, lines, p + size / 2 - 32, size / 2 + 32,
 404                        itv->vbi.sliced_decoder_sav_even_field);
 405                /* always return at least one empty line */
 406                if (lines == 0) {
 407                        itv->vbi.sliced_data[0].id = 0;
 408                        itv->vbi.sliced_data[0].line = 0;
 409                        itv->vbi.sliced_data[0].field = 0;
 410                        lines = 1;
 411                }
 412                buf->bytesused = size = lines * sizeof(itv->vbi.sliced_data[0]);
 413                memcpy(p, &itv->vbi.sliced_data[0], size);
 414
 415                if (itv->vbi.insert_mpeg) {
 416                        copy_vbi_data(itv, lines, pts_stamp);
 417                }
 418                itv->vbi.frame++;
 419                return;
 420        }
 421
 422        /* Sliced VBI re-inserted from an MPEG stream */
 423        if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) {
 424                /* If the size is not 4-byte aligned, then the starting address
 425                   for the swapping is also shifted. After swapping the data the
 426                   real start address of the VBI data is exactly 4 bytes after the
 427                   original start. It's a bit fiddly but it works like a charm.
 428                   Non-4-byte alignment happens when an lseek is done on the input
 429                   mpeg file to a non-4-byte aligned position. So on arrival here
 430                   the VBI data is also non-4-byte aligned. */
 431                int offset = size & 3;
 432                int cnt;
 433
 434                if (offset) {
 435                        p += 4 - offset;
 436                }
 437                /* Swap Buffer */
 438                for (y = 0; y < size; y += 4) {
 439                       swab32s((u32 *)(p + y));
 440                }
 441
 442                cnt = ivtv_convert_ivtv_vbi(itv, p + offset);
 443                memcpy(buf->buf, itv->vbi.sliced_dec_data, cnt);
 444                buf->bytesused = cnt;
 445
 446                ivtv_write_vbi(itv, itv->vbi.sliced_dec_data,
 447                               cnt / sizeof(itv->vbi.sliced_dec_data[0]));
 448                return;
 449        }
 450}
 451
 452void ivtv_disable_cc(struct ivtv *itv)
 453{
 454        struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
 455
 456        clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
 457        ivtv_set_cc(itv, 0, &cc);
 458        itv->vbi.cc_payload_idx = 0;
 459}
 460
 461
 462void ivtv_vbi_work_handler(struct ivtv *itv)
 463{
 464        struct vbi_info *vi = &itv->vbi;
 465        struct v4l2_sliced_vbi_data data;
 466        struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
 467
 468        /* Lock */
 469        if (itv->output_mode == OUT_PASSTHROUGH) {
 470                if (itv->is_50hz) {
 471                        data.id = V4L2_SLICED_WSS_625;
 472                        data.field = 0;
 473
 474                        if (v4l2_subdev_call(itv->sd_video, vbi, g_vbi_data, &data) == 0) {
 475                                ivtv_set_wss(itv, 1, data.data[0] & 0xf);
 476                                vi->wss_missing_cnt = 0;
 477                        } else if (vi->wss_missing_cnt == 4) {
 478                                ivtv_set_wss(itv, 1, 0x8);  /* 4x3 full format */
 479                        } else {
 480                                vi->wss_missing_cnt++;
 481                        }
 482                }
 483                else {
 484                        int mode = 0;
 485
 486                        data.id = V4L2_SLICED_CAPTION_525;
 487                        data.field = 0;
 488                        if (v4l2_subdev_call(itv->sd_video, vbi, g_vbi_data, &data) == 0) {
 489                                mode |= 1;
 490                                cc.odd[0] = data.data[0];
 491                                cc.odd[1] = data.data[1];
 492                        }
 493                        data.field = 1;
 494                        if (v4l2_subdev_call(itv->sd_video, vbi, g_vbi_data, &data) == 0) {
 495                                mode |= 2;
 496                                cc.even[0] = data.data[0];
 497                                cc.even[1] = data.data[1];
 498                        }
 499                        if (mode) {
 500                                vi->cc_missing_cnt = 0;
 501                                ivtv_set_cc(itv, mode, &cc);
 502                        } else if (vi->cc_missing_cnt == 4) {
 503                                ivtv_set_cc(itv, 0, &cc);
 504                        } else {
 505                                vi->cc_missing_cnt++;
 506                        }
 507                }
 508                return;
 509        }
 510
 511        if (test_and_clear_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags)) {
 512                ivtv_set_wss(itv, 1, vi->wss_payload & 0xf);
 513        }
 514
 515        if (test_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags)) {
 516                if (vi->cc_payload_idx == 0) {
 517                        clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
 518                        ivtv_set_cc(itv, 3, &cc);
 519                }
 520                while (vi->cc_payload_idx) {
 521                        cc = vi->cc_payload[0];
 522
 523                        memmove(vi->cc_payload, vi->cc_payload + 1,
 524                                        sizeof(vi->cc_payload) - sizeof(vi->cc_payload[0]));
 525                        vi->cc_payload_idx--;
 526                        if (vi->cc_payload_idx && cc.odd[0] == 0x80 && cc.odd[1] == 0x80)
 527                                continue;
 528
 529                        ivtv_set_cc(itv, 3, &cc);
 530                        break;
 531                }
 532        }
 533
 534        if (test_and_clear_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags)) {
 535                ivtv_set_vps(itv, 1);
 536        }
 537}
 538