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