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