📄 play_capture_vbidata.c
字号:
/* * * Copyright (c) 2001-2007 Sigma Designs, Inc. * All Rights Reserved. Proprietary and Confidential. * *//** @file play_capture_vbidata.c @brief sample code to print out information retrieved from VBI data @author Christian Wolff, Sean.Sekwon.Choi @date 2007-07-19*/// to enable or disable the debug messages of this source file, put 1 or 0 below#if 1#define LOCALDBG ENABLE#else#define LOCALDBG DISABLE#endif#include "sample_os.h"#define ALLOW_OS_CODE 1#include "../rua/include/rua.h"#include "../rua/include/rua_property.h"#include "../dcc/include/dcc.h"#include "../rmcore/include/rmstatustostring.h"#include "../rmlibcw/include/rmlibcw.h"#include "common.h"#include "play_capture_main.h"#include "play_capture_vbidata.h"// Perform Hamming 8/4 check and return data in low 4 bits, or 0xFF on errorstatic RMuint8 unham[256] = { 0x01,0xff,0x01,0x01,0xff,0x00,0x01,0xff, 0xff,0x02,0x01,0xff,0x0a,0xff,0xff,0x07, 0xff,0x00,0x01,0xff,0x00,0x00,0xff,0x00, 0x06,0xff,0xff,0x0b,0xff,0x00,0x03,0xff, 0xff,0x0c,0x01,0xff,0x04,0xff,0xff,0x07, 0x06,0xff,0xff,0x07,0xff,0x07,0x07,0x07, 0x06,0xff,0xff,0x05,0xff,0x00,0x0d,0xff, 0x06,0x06,0x06,0xff,0x06,0xff,0xff,0x07, 0xff,0x02,0x01,0xff,0x04,0xff,0xff,0x09, 0x02,0x02,0xff,0x02,0xff,0x02,0x03,0xff, 0x08,0xff,0xff,0x05,0xff,0x00,0x03,0xff, 0xff,0x02,0x03,0xff,0x03,0xff,0x03,0x03, 0x04,0xff,0xff,0x05,0x04,0x04,0x04,0xff, 0xff,0x02,0x0f,0xff,0x04,0xff,0xff,0x07, 0xff,0x05,0x05,0x05,0x04,0xff,0xff,0x05, 0x06,0xff,0xff,0x05,0xff,0x0e,0x03,0xff, 0xff,0x0c,0x01,0xff,0x0a,0xff,0xff,0x09, 0x0a,0xff,0xff,0x0b,0x0a,0x0a,0x0a,0xff, 0x08,0xff,0xff,0x0b,0xff,0x00,0x0d,0xff, 0xff,0x0b,0x0b,0x0b,0x0a,0xff,0xff,0x0b, 0x0c,0x0c,0xff,0x0c,0xff,0x0c,0x0d,0xff, 0xff,0x0c,0x0f,0xff,0x0a,0xff,0xff,0x07, 0xff,0x0c,0x0d,0xff,0x0d,0xff,0x0d,0x0d, 0x06,0xff,0xff,0x0b,0xff,0x0e,0x0d,0xff, 0x08,0xff,0xff,0x09,0xff,0x09,0x09,0x09, 0xff,0x02,0x0f,0xff,0x0a,0xff,0xff,0x09, 0x08,0x08,0x08,0xff,0x08,0xff,0xff,0x09, 0x08,0xff,0xff,0x0b,0xff,0x0e,0x03,0xff, 0xff,0x0c,0x0f,0xff,0x04,0xff,0xff,0x09, 0x0f,0xff,0x0f,0x0f,0xff,0x0e,0x0f,0xff, 0x08,0xff,0xff,0x05,0xff,0x0e,0x0d,0xff, 0xff,0x0e,0x0f,0xff,0x0e,0x0e,0xff,0x0e,};static RMascii LatinG0[128] = { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 0 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 1 ' ', '!', '"', '#', '$', '%', '&', '`', '(', ')', '*', '+', ',', '-', '.', '/', // 2 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', // 3 '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', // 4 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', // 5 'e', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', // 6 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '#', // 7};static RMbool odd_par(RMuint8 d){ d ^= (d >> 4); d ^= (d >> 2); d ^= (d >> 1); return (d & 1);}static void tt_print_data(RMuint8 *data, RMuint32 size) { RMuint32 i; for (i = 0; i < size; i++) { if (odd_par(data[i])) { fprintf(stderr, "%c", LatinG0[data[i] & 0x7F]); } else { fprintf(stderr, "?"); } }}// sample code for handling teletext data, only prints page header infoRMstatus capsam_vbidata_handle_teletext_data( RMbool fid, RMuint32 line, RMuint16 *pData, RMuint32 count){ RMuint32 i; RMuint8 h, ttbyte[46]; RMuint32 Mag, Pkt; // Translate 16 bit data to 8 bit, establish byte numbering from ETS 300 706 if (count > 20) count = 20; for (i = 0; i < count; i++) { ttbyte[i * 2 + 4] = pData[i] & 0xFF; ttbyte[i * 2 + 5] = pData[i] >> 8; } fprintf(stderr, "TT@%02ld%c: ", line, fid ? 'B' : 'T'); if ((h = unham[ttbyte[4]]) == 0xFF) { fprintf(stderr, "HmErr[%u] 0x%02X\n", 4, ttbyte[4]); return RM_ERROR; } Mag = h & 0x07; Pkt = h >> 3; if ((h = unham[ttbyte[5]]) == 0xFF) { fprintf(stderr, "HmErr[%u] 0x%02X\n", 5, ttbyte[5]); return RM_ERROR; } Pkt |= (h << 1); fprintf(stderr, "Mag%lu/Pkt%02lu ", Mag, Pkt); if (Pkt == 0) { RMuint32 Pg0, Pg1, S1, S2, S3, S4, Ctl0, Ctl1; if ((Pg0 = unham[ttbyte[6]]) == 0xFF) { fprintf(stderr, "HmErr[%u] 0x%02X\n", 6, ttbyte[6]); return RM_ERROR; } if ((Pg1 = unham[ttbyte[7]]) == 0xFF) { fprintf(stderr, "HmErr[%u] 0x%02X\n", 7, ttbyte[7]); return RM_ERROR; } if ((S1 = unham[ttbyte[8]]) == 0xFF) { fprintf(stderr, "HmErr[%u] 0x%02X\n", 8, ttbyte[8]); return RM_ERROR; } if ((S2 = unham[ttbyte[9]]) == 0xFF) { fprintf(stderr, "HmErr[%u] 0x%02X\n", 9, ttbyte[9]); return RM_ERROR; } if ((S3 = unham[ttbyte[10]]) == 0xFF) { fprintf(stderr, "HmErr[%u] 0x%02X\n", 10, ttbyte[10]); return RM_ERROR; } if ((S4 = unham[ttbyte[11]]) == 0xFF) { fprintf(stderr, "HmErr[%u] 0x%02X\n", 11, ttbyte[11]); return RM_ERROR; } fprintf(stderr, "Pg%lu%lX%lX S%lX%lX-%lX%lX ", Mag, Pg1, Pg0, S4 & 0x03, S3, S2 & 0x07, S1); if ((Ctl0 = unham[ttbyte[12]]) == 0xFF) { fprintf(stderr, "HmErr[%u] 0x%02X\n", 12, ttbyte[12]); return RM_ERROR; } if ((Ctl1 = unham[ttbyte[13]]) == 0xFF) { fprintf(stderr, "HmErr[%u] 0x%02X\n", 13, ttbyte[13]); return RM_ERROR; } fprintf(stderr, "C%ld%ld%ld%ld%ld%ld%ld%ld%ld%ld%ld ", (S2>>3)&1, (S4>>3)&1, (S4>>2)&1, (Ctl1>>3)&1, (Ctl1>>2)&1, (Ctl1>>1)&1, Ctl1&1, (Ctl0>>3)&1, (Ctl0>>2)&1, (Ctl0>>1)&1, Ctl0&1); tt_print_data(&ttbyte[14], count * 2 - 10); } else if ((Pkt >= 1) && (Pkt <= 25)) { tt_print_data(&ttbyte[6], count * 2 - 2); } fprintf(stderr, "\n"); return RM_OK;}// sample code for closed caption data, only prints plain textRMstatus capsam_vbidata_handle_line21cc_data( RMbool fid, RMuint32 line, RMuint16 *pData, RMuint32 count){ static RMbool last_cr = FALSE; RMascii ch1, ch2; //fprintf(stderr, " %02X %02X ", pData[0] & 0x7F, (pData[0] >> 8) & 0x7F); if (fid) return RM_OK; // only handle field 1 data for now ch1 = pData[0] & 0x7F; ch2 = (pData[0] >> 8) & 0x7F; if (ch1 >= 0x20) { if (ch1 <= 0x7E) fprintf(stderr, "%c", ch1); if ((ch2 >= 0x20) && (ch2 <= 0x7E)) fprintf(stderr, "%c", ch2); last_cr = FALSE; } else { switch (ch1) { case 0x00: case 0x11: case 0x13: case 0x19: case 0x1b: break; case 0x14: case 0x1c: if (! last_cr) { fprintf(stderr, "\n"); last_cr = TRUE; } break; default: //fprintf(stderr, " %02X %02X ", ch1, ch2); break; } } return RM_OK;}RMstatus capsam_vbidata_handle_anc_data( RMuint32 type, RMbool fid, RMuint32 line, RMuint16 *pData, RMuint32 count){ switch (type) { case 1: // PAL teletext data return capsam_vbidata_handle_teletext_data(fid, line, pData, count); case 4: // SAA7119 line 21 Closed Captioning return capsam_vbidata_handle_line21cc_data(fid, line, pData, count); default: break; } return RM_OK;}/* TODO:static void handle_vbi_data(struct local_cmdline *local_opt, struct capture_cmdline *capture_opt){ // handle VBIPTS, pVBIData[VBISize] if (local_opt->arg_vbi) { // binary dump to file RMuint32 i; fwrite("VBI:", 1, 4, local_opt->vbidump); fwrite(&(local_opt->VBIPTS), 4, 1, local_opt->vbidump); fwrite(&(local_opt->VBISize), 4, 1, local_opt->vbidump); for (i = 0; i < local_opt->VBISize; i += 2) { RMuint8 lsb, msb; lsb = local_opt->pVBIData[i / 2] & 0xFF; msb = local_opt->pVBIData[i / 2] >> 8; fwrite(&lsb, 1, 1, local_opt->vbidump); fwrite(&msb, 1, 1, local_opt->vbidump); } } if (local_opt->parse_anc) { RMuint32 line, i, n, field, inc, fid, offs, count, ancstart; RMuint16 d; switch ((local_opt->VBIFlags >> 2) & 0x03) { // Flags[3:2]: 00: interlaced data from two fields, 01: data from progressive frame, 10: data from top field, 11: data from bottom field default: case 0: // interlaced inc = 2; fid = (local_opt->VBIFlags & 0x02) ? FALSE : TRUE; break; // Flags[1]: 0: bottom field first, 1: top field first case 1: // progressive inc = 1; fid = 0; break; case 2: // top field inc = 1; fid = 0; break; case 3: // bottom field inc = 1; fid = 1; break; } for (field = 0; field < inc; field++) { for (line = fid; line < local_opt->VBISize / 2 / capture_opt->vbi_w; line += inc) { offs = line * capture_opt->vbi_w; n = 0; ancstart = 0; count = capture_opt->vbi_w; for (i = 0; i < count; i++) { d = local_opt->pVBIData[offs + i]; if (n == 0) { if (d == 0xFF00) n++; else n = 0; } else if (n == 1) { if ((d & 0x00FF) == 0x00FF) { n++; if (local_opt->print_anc) printf(" ANC data in row %2lu%c, DID=%02X ", (line / 2) + 1, (line & 1) ? 'B' : 'T', d >> 8); } else n = 0; } else if (n == 2) { if (local_opt->print_anc) printf("SDID=%02X DC=%02X ", d & 0xFF, d >> 8); ancstart = offs + i; count = i + ((d >> 8) & 0x3F) * 2; if (count > capture_opt->vbi_w) { if (local_opt->print_anc) printf("MISSING %ld bytes at end! ", (count - capture_opt->vbi_w) * 2); ancstart = 0; count = capture_opt->vbi_w; } n++; } else if (n == 3) { if (local_opt->print_anc) printf("ID1=%02X ID2=%02X ", d & 0xFF, d >> 8); n++; } else if (n >= 4) { if (local_opt->print_anc) printf("%02X%02X ", d & 0xFF, d >> 8); n++; } } if (local_opt->print_anc && n >= 2) printf("\n"); if (ancstart) { RMuint8 SDID, DC, ID1, ID2, CS, cs, BC; RMuint32 i, line, type, dc, bc, payload; RMbool fid; SDID = local_opt->pVBIData[ancstart + 0] & 0xFF; DC = local_opt->pVBIData[ancstart + 0] >> 8; dc = DC & 0x3F; ID1 = local_opt->pVBIData[ancstart + 1] & 0xFF; ID2 = local_opt->pVBIData[ancstart + 1] >> 8; fid = ((ID1 >> 6) & 0x01); // TODO check parity of DC, ID1, ID2 line = ((ID1 & 0x3F) << 3) | ((ID2 >> 4) & 0x07); type = ID2 & 0x0F; BC = local_opt->pVBIData[ancstart + dc * 2 - 1] >> 8; CS = local_opt->pVBIData[ancstart + dc * 2 - 1] & 0xFF; bc = BC & 0x3F; // should be payload * 2 payload = dc * 2 - 3; cs = local_opt->pVBIData[ancstart - 1] >> 8; // DID for (i = 0; i < dc * 2; i ++) { cs += (local_opt->pVBIData[ancstart + i] & 0xFF); cs += (local_opt->pVBIData[ancstart + i] >> 8); } handle_anc_data(type, fid, line, &(local_opt->pVBIData[ancstart + 2]), bc / 2); if (local_opt->print_anc) printf("CS:%02X, bc=%lu, line=%lu, type = %lu, fid=%c\n", cs, bc, line, type, fid ? 'B' : 'T'); } } fid = 1 - fid; } } if (local_opt->dump_vbi) { // hex dump to screen RMuint32 i; RMbool bottom_first = ! (local_opt->VBIFlags & 0x02); RMuint32 frame_info = (local_opt->VBIFlags >> 2) & 0x03; printf("VBI data, %ld bytes, PTS 0x%08lX, line: %ld bytes, %s field 1st, %s fld./fr.:\n", local_opt->VBISize, local_opt->VBIPTS, capture_opt->vbi_w, bottom_first ? "bottom" : "top", (frame_info == 0) ? "intl." : (frame_info == 1) ? "progr." : (frame_info == 2) ? "top" : "bottom"); for (i = 0; i < local_opt->VBISize; i += 2) { if (i % (capture_opt->vbi_w * 2) == 0) printf(" "); printf("%02X%02X ", local_opt->pVBIData[i / 2] & 0xFF, local_opt->pVBIData[i / 2] >> 8); if (i % (capture_opt->vbi_w * 2) == (capture_opt->vbi_w * 2) - 2) printf("\n"); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -